From 658c085cdbd4b1612c1faf1894df7495799898dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 21 Jul 2026 11:18:08 +0200 Subject: [PATCH] Use the authoritative key on the PKI decrypt path Resolve the inbound sender key via copyPublicKeyAuthoritative (hot/warm) instead of the opportunistic copyPublicKey, so authenticated DM attribution (pki_encrypted, p->from) does not rest on the ephemeral TMM NodeInfo cache. Outbound encrypt-to keying and the key-verification pending-key path are unchanged. --- src/mesh/Router.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mesh/Router.cpp b/src/mesh/Router.cpp index f8cd05b5160..9a47310ce36 100644 --- a/src/mesh/Router.cpp +++ b/src/mesh/Router.cpp @@ -624,13 +624,13 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p) meshtastic_NodeInfoLite *ourNode = nullptr; if (p->channel == 0 && isToUs(p) && p->to > 0 && !isBroadcast(p->to) && rawSize > MESHTASTIC_PKC_OVERHEAD && (ourNode = nodeDB->getMeshNode(p->to)) != nullptr && ourNode->public_key.size > 0) { - // Resolve the sender's public key only for actual PKI-decrypt candidates: prefer NodeDB - // (hot store or warm tier), else a not-yet-committed key held during an in-progress - // key-verification handshake. On a full NodeDB miss, copyPublicKey() falls through to a - // linear scan of TrafficManagement's large NodeInfo cache, so it must not run for every - // encrypted channel packet from an unknown sender - only for packets we might decrypt. + // Resolve the sender's public key only for actual PKI-decrypt candidates. Use + // copyPublicKeyAuthoritative (hot store or warm tier only), not the opportunistic + // copyPublicKey: authenticated DM attribution (pki_encrypted, p->from) must rest on + // authoritative keys, never on the ephemeral TOFU TrafficManagement NodeInfo cache. A + // not-yet-committed key from an in-progress key-verification handshake is tried below. meshtastic_NodeInfoLite_public_key_t remotePublic = {0, {0}}; - bool haveRemoteKey = nodeDB->copyPublicKey(p->from, remotePublic); + bool haveRemoteKey = nodeDB->copyPublicKeyAuthoritative(p->from, remotePublic); // A pending key is an unverified identity claim supplied by whoever opened the handshake, so it is // accepted only for the exchange itself (checked after decode). perhapsEncode applies the same rule. bool havePendingKey = false;