aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/quic_client.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport/quic_client.py')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/quic_client.py12
1 files changed, 12 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/quic_client.py b/packages/meshbay-node/src/meshbay_node/transport/quic_client.py
index 273f225..8f3fb74 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/quic_client.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/quic_client.py
@@ -26,6 +26,7 @@ from meshbay_common.handshake import (
NONCE_LEN,
ROLE_CLIENT,
ROLE_NODE,
+ challenge_transcript,
check_version,
handshake_transcript,
make_proof,
@@ -211,6 +212,17 @@ class QuicChunkClient:
"session — refusing to handshake without channel binding")
binding = quic_binding(self._peer_cert_der)
+ # MNP 3.4: a signed challenge proves the node key before we send anything
+ # else. A wrong signature is refused; an absent one is an older node.
+ if reply.get("sig"):
+ try:
+ Ed25519PublicKey.from_public_bytes(
+ base64.b64decode(reply.get("node_pk", ""))
+ ).verify(base64.b64decode(reply["sig"]), challenge_transcript(
+ self._group_id, nonce_c, nonce_s, binding))
+ except Exception as exc:
+ raise ConnectionError(f"Node challenge signature invalid: {exc}") from exc
+
self._proto._send(self._ctrl_stream, {
"type": MNP.HANDSHAKE_RESPONSE,
"v": MNP_VERSION,