From 9c260ad7923d9bb9364867dda527e8be7ac01136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 30 Jul 2026 00:30:30 +0200 Subject: [PATCH] Signature key resolution and a send-path leak (#11283) * Verify signatures against authoritative keys only * Release the packet on the unset-variant send error --- src/mesh/Router.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index 3abcf64b3..b60942bcd 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -465,6 +465,8 @@ ErrorCode Router::send(meshtastic_MeshPacket *p) if (!(p->which_payload_variant == meshtastic_MeshPacket_encrypted_tag || p->which_payload_variant == meshtastic_MeshPacket_decoded_tag)) { + // Error returns from here own the packet, as the position-precision path below does. + packetPool.release(p); return meshtastic_Routing_Error_BAD_REQUEST; } @@ -633,7 +635,9 @@ bool checkXeddsaReceivePolicy(meshtastic_MeshPacket *p) if (p->decoded.xeddsa_signature.size == XEDDSA_SIGNATURE_SIZE) { meshtastic_NodeInfoLite_public_key_t senderKey = {0, {0}}; meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(p->from); - if (nodeDB->copyPublicKey(p->from, senderKey)) { + // Authoritative keys only: verifying against an opportunistic cache key would let a planted + // key mark its own node a signer, the trust loop #11116 closed on the decrypt path. + if (nodeDB->copyPublicKeyAuthoritative(p->from, senderKey)) { p->xeddsa_signed = crypto->xeddsa_verify(senderKey.bytes, p->from, p->id, p->decoded.portnum, p->decoded.payload.bytes, p->decoded.payload.size, p->decoded.xeddsa_signature.bytes);