Gate the PKI-decrypt key on signer-proven, not the opportunistic cache (#11116)
This commit is contained in:
co-authored by
GitHub
parent
11c510ff1b
commit
f09f2b1366
@@ -3783,6 +3783,22 @@ bool NodeDB::copyPublicKey(NodeNum n, meshtastic_NodeInfoLite_public_key_t &out)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NodeDB::copyPublicKeyForDecrypt(NodeNum n, meshtastic_NodeInfoLite_public_key_t &out)
|
||||||
|
{
|
||||||
|
if (copyPublicKeyAuthoritative(n, out))
|
||||||
|
return true;
|
||||||
|
#if HAS_TRAFFIC_MANAGEMENT
|
||||||
|
// A cold-tier cache key backs an authenticated decrypt only when signer-proven; unverified TOFU
|
||||||
|
// cache keys must not. Outbound encryption still uses the opportunistic copyPublicKey().
|
||||||
|
bool signerProven = false;
|
||||||
|
if (trafficManagementModule && trafficManagementModule->copyPublicKey(n, out.bytes, &signerProven) && signerProven) {
|
||||||
|
out.size = 32;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool NodeDB::isVerifiedSignerForKey(NodeNum n, const uint8_t *key32)
|
bool NodeDB::isVerifiedSignerForKey(NodeNum n, const uint8_t *key32)
|
||||||
{
|
{
|
||||||
if (!key32)
|
if (!key32)
|
||||||
|
|||||||
@@ -364,6 +364,10 @@ class NodeDB
|
|||||||
/// opportunistic caches) - the pin reference for caches that mirror NodeDB's key hygiene.
|
/// opportunistic caches) - the pin reference for caches that mirror NodeDB's key hygiene.
|
||||||
bool copyPublicKeyAuthoritative(NodeNum n, meshtastic_NodeInfoLite_public_key_t &out);
|
bool copyPublicKeyAuthoritative(NodeNum n, meshtastic_NodeInfoLite_public_key_t &out);
|
||||||
|
|
||||||
|
/// Key for the inbound-decrypt path: authoritative (hot/warm), or a cold-tier cache key only when
|
||||||
|
/// it is signer-proven. Keeps unverified TOFU cache keys from backing pki_encrypted attribution.
|
||||||
|
bool copyPublicKeyForDecrypt(NodeNum n, meshtastic_NodeInfoLite_public_key_t &out);
|
||||||
|
|
||||||
/// True if n is a known XEdDSA signer for exactly `key32` (hot signed bitfield or warm
|
/// True if n is a known XEdDSA signer for exactly `key32` (hot signed bitfield or warm
|
||||||
/// signer bit); the key match stops a rotated key inheriting a stale signer verdict.
|
/// signer bit); the key match stops a rotated key inheriting a stale signer verdict.
|
||||||
bool isVerifiedSignerForKey(NodeNum n, const uint8_t *key32);
|
bool isVerifiedSignerForKey(NodeNum n, const uint8_t *key32);
|
||||||
|
|||||||
+6
-6
@@ -815,13 +815,13 @@ DecodeState perhapsDecode(meshtastic_MeshPacket *p)
|
|||||||
(ourNode = nodeDB->getMeshNode(p->to)) != nullptr && ourNode->public_key.size > 0) {
|
(ourNode = nodeDB->getMeshNode(p->to)) != nullptr && ourNode->public_key.size > 0) {
|
||||||
pkiAttempted = true;
|
pkiAttempted = true;
|
||||||
LOG_DEBUG("Attempt PKI decryption");
|
LOG_DEBUG("Attempt PKI decryption");
|
||||||
// Resolve the sender's public key only for actual PKI-decrypt candidates: prefer NodeDB
|
// Resolve the sender's key only for actual PKI-decrypt candidates, not every encrypted channel
|
||||||
// (hot store or warm tier), else a not-yet-committed key held during an in-progress
|
// packet: copyPublicKeyForDecrypt() can fall through to a linear scan of TrafficManagement's large
|
||||||
// key-verification handshake. On a full NodeDB miss, copyPublicKey() falls through to a
|
// NodeInfo cache. It returns authoritative keys (hot/warm), or a cold-tier cache key only when it is
|
||||||
// linear scan of TrafficManagement's large NodeInfo cache, so it must not run for every
|
// signer-proven - an unverified TOFU cache key must not back authenticated (pki_encrypted, p->from)
|
||||||
// encrypted channel packet from an unknown sender - only for packets we might decrypt.
|
// DM attribution.
|
||||||
meshtastic_NodeInfoLite_public_key_t remotePublic = {0, {0}};
|
meshtastic_NodeInfoLite_public_key_t remotePublic = {0, {0}};
|
||||||
bool haveRemoteKey = nodeDB->copyPublicKey(p->from, remotePublic);
|
bool haveRemoteKey = nodeDB->copyPublicKeyForDecrypt(p->from, remotePublic);
|
||||||
// A pending key is an unverified identity claim supplied by whoever opened the handshake, so it is
|
// 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.
|
// accepted only for the exchange itself (checked after decode). perhapsEncode applies the same rule.
|
||||||
bool havePendingKey = false;
|
bool havePendingKey = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user