mirror of
https://github.com/esphome/esphome.git
synced 2026-10-02 14:22:58 +08:00
Keep an invalid curve point a plain handshake error, not a key failure
This commit is contained in:
+5
-3
@@ -479,12 +479,14 @@ class NoiseSocketWrapper:
|
||||
raise OTAError(f"Device rejected the noise handshake: {reason}")
|
||||
try:
|
||||
self._handshake.read_message(payload[1:])
|
||||
except (ValueError, self._invalid_tag) as err:
|
||||
# InvalidTag is a wrong key; ValueError covers a device sending an
|
||||
# invalid curve point, which cryptography rejects during the DH
|
||||
except self._invalid_tag as err:
|
||||
raise OTAKeyRejected(
|
||||
"Noise handshake failed; is the OTA encryption key correct?"
|
||||
) from err
|
||||
except ValueError as err:
|
||||
# An invalid curve point, rejected by cryptography during the DH;
|
||||
# the device is broken, not the key
|
||||
raise OTAError(f"Noise handshake failed: {err}") from err
|
||||
self._encrypt, self._decrypt = self._handshake.get_ciphers()
|
||||
|
||||
def sendall(self, data: bytes) -> None:
|
||||
|
||||
@@ -550,21 +550,21 @@ def test_handshake_reject_with_other_reason() -> None:
|
||||
|
||||
|
||||
def test_handshake_garbage_second_message() -> None:
|
||||
"""A valid-looking point with a garbage MAC fails cleanly."""
|
||||
"""A valid-looking point with a garbage MAC is a key failure."""
|
||||
wrapper = _wrapper(_frame(b"\x00" + bytes(range(48))))
|
||||
with pytest.raises(
|
||||
espota2.OTAError, match="handshake failed; is the OTA encryption key"
|
||||
espota2.OTAKeyRejected, match="handshake failed; is the OTA encryption key"
|
||||
):
|
||||
wrapper.do_handshake()
|
||||
|
||||
|
||||
def test_handshake_invalid_curve_point() -> None:
|
||||
"""An all-zero x25519 point is rejected as a clean error, not a crash."""
|
||||
"""An all-zero x25519 point is a clean error, not a crash, and not a
|
||||
key failure: it must not spend the old_key retry."""
|
||||
wrapper = _wrapper(_frame(b"\x00" + bytes(48)))
|
||||
with pytest.raises(
|
||||
espota2.OTAError, match="handshake failed; is the OTA encryption key"
|
||||
):
|
||||
with pytest.raises(espota2.OTAError, match="handshake failed: ") as info:
|
||||
wrapper.do_handshake()
|
||||
assert not isinstance(info.value, espota2.OTAKeyRejected)
|
||||
|
||||
|
||||
def test_recv_closed_at_frame_boundary_returns_empty() -> None:
|
||||
|
||||
Reference in New Issue
Block a user