Merge branch 'develop' into codex/packet-auth-policy

Resolve conflicts against the NodeDB signer/key primitives (#11050) and the
admin-key PKI decrypt budget (#11100).

- NodeDB: drop this branch's hasSeenXeddsaSigner in favour of develop's
  isKnownXeddsaSigner. They answer the same question, but develop's reads the
  dedicated warm signer bit (warmSignerOf) rather than the WarmProtected
  category, and TrafficManagementModule already depends on it. Keep develop's
  copyPublicKey/copyPublicKeyAuthoritative, isVerifiedSignerForKey and
  commitRemoteKey/KeyCommitTrust.
- checkXeddsaReceivePolicy: keep this branch's Strict/Balanced/Compatible
  policy, which is a superset of develop's balanced-only downgrade gate, and
  call isKnownXeddsaSigner from it. develop's !pki_encrypted term is dropped
  because the policy returns early for PKI packets before that check.
- perhapsDecode: keep develop's key resolution (NodeDB then pending-key, only
  for real PKI candidates) plus its admin-key token bucket, and re-apply this
  branch's pkiAttempted flag feeding the DECODE_OPAQUE verdict. Keep both
  passesRoutingAuthGate and adminKeyFallbackAllowed/Refund.
- test_A17: model eviction the way NodeDB actually does it, passing the warm
  signer bit as well as the XeddsaSigner category, since isKnownXeddsaSigner
  reads the former.

Native suite: 38 suites, 743/743 cases, no sanitizer findings.
This commit is contained in:
Ben Meadors
2026-07-21 06:09:57 -05:00
57 changed files with 4366 additions and 618 deletions
+4 -1
View File
@@ -729,8 +729,11 @@ void test_A17_strict_verifies_signer_from_warm_key_store(void)
// Model its next hot-store eviction and prove Balanced still remembers the signer without
// allocating a hot node merely to evaluate an unsigned packet.
// Mirror what NodeDB eviction actually stores for a signer: warmProtectedCategory() yields
// XeddsaSigner *and* the dedicated warm signer bit is set from nodeInfoLiteHasXeddsaSigned().
// isKnownXeddsaSigner() reads that signer bit, not the protected category.
TEST_ASSERT_TRUE(mockNodeDB->warmStore.absorb(REMOTE_NODE, 2, pub, meshtastic_Config_DeviceConfig_Role_CLIENT,
static_cast<uint8_t>(WarmProtected::XeddsaSigner)));
static_cast<uint8_t>(WarmProtected::XeddsaSigner), /*signer=*/true));
mockNodeDB->clearTestNodes();
setPolicy(meshtastic_Config_SecurityConfig_PacketSignaturePolicy_PACKET_SIGNATURE_POLICY_BALANCED);
meshtastic_MeshPacket unsignedPacket =