Skip to content

Gate the PKI-decrypt key on signer-proven, not the opportunistic cache#11116

Merged
caveman99 merged 3 commits into
developfrom
router-decrypt-authoritative-key
Jul 22, 2026
Merged

Gate the PKI-decrypt key on signer-proven, not the opportunistic cache#11116
caveman99 merged 3 commits into
developfrom
router-decrypt-authoritative-key

Conversation

@caveman99

@caveman99 caveman99 commented Jul 21, 2026

Copy link
Copy Markdown
Member

Follow-up to #11050. That PR made NodeDB::copyPublicKey fall through to the ephemeral TrafficManagement NodeInfo cache, and Router::perhapsDecode used it to resolve the sender key on the inbound PKI-decrypt path, so a DM decrypted with an unverified TOFU cache key was stamped pki_encrypted and attributed to p->from.

New NodeDB::copyPublicKeyForDecrypt resolves authoritative keys (hot/warm, TOFU baseline unchanged) and accepts a cold-tier cache key only when it is signer-proven. A previously-authenticated node evicted to the cache still resolves; an unverified TOFU cache entry no longer backs authenticated DM attribution. The outbound encrypt-to path keeps the opportunistic copyPublicKey lookup.

Summary by CodeRabbit

  • Bug Fixes
    • Improved secure message decryption to resolve sender public keys only from verified, authoritative sources.
    • If a cached cold-tier key is used, it is now accepted only when it is signer-proven (avoids unverified TOFU cache keys for attribution).
    • Updated decryption gating so only genuine PKI-decrypt candidates trigger pending-key handling and any related fallback flow, reducing incorrect decrypt behavior.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 82fc93ff-99ed-426a-b10e-e31e5a52ac91

📥 Commits

Reviewing files that changed from the base of the PR and between 4bc4cdd and 4940b8b.

📒 Files selected for processing (1)
  • src/mesh/NodeDB.cpp

📝 Walkthrough

Walkthrough

NodeDB now exposes a decrypt-specific public-key lookup that accepts authoritative or signer-proven cached keys. Router::perhapsDecode() uses this lookup to gate PKI decryption, pending-key handling, and admin-key fallback behavior.

Changes

PKI key resolution

Layer / File(s) Summary
Decrypt-specific key lookup
src/mesh/NodeDB.h, src/mesh/NodeDB.cpp
Adds copyPublicKeyForDecrypt(), which accepts authoritative hot/warm keys or signer-proven TrafficManagement cache keys and rejects unverified cached keys.
PKI decryption gating
src/mesh/Router.cpp
perhapsDecode() uses the new lookup when preparing PKI decryption candidates, so haveRemoteKey controls decryption and pending-key handling without relying on TOFU keys.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: enhancement

Suggested reviewers: thebentern, jp-bennett

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description summarizes the change but omits the required attestations and device/testing checklist from the template. Add the Attestations section with test confirmation and any affected-device regression checks, or state that testing was not performed.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change to PKI-decrypt key selection.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch router-decrypt-authoritative-key

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/mesh/Router.cpp (1)

627-631: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Condense the explanatory comment.

As per coding guidelines, code comments should be kept to a maximum of one or two lines, avoiding multi-paragraph explanatory blocks.

♻️ Proposed refactor
-        // 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.
+        // Use authoritative sender key for authenticated DM attribution.
+        // Pending keys from in-progress handshakes are tried below.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mesh/Router.cpp` around lines 627 - 631, Condense the explanatory comment
above the sender public-key resolution logic to one or two lines, retaining only
that PKI-decrypt attribution must use authoritative keys and not the
opportunistic TOFU cache. Remove the detailed implementation and handshake
explanation while leaving the code unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/mesh/Router.cpp`:
- Around line 627-631: Condense the explanatory comment above the sender
public-key resolution logic to one or two lines, retaining only that PKI-decrypt
attribution must use authoritative keys and not the opportunistic TOFU cache.
Remove the detailed implementation and handshake explanation while leaving the
code unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6081b298-0ab9-4f31-bb8b-f66d11fceef8

📥 Commits

Reviewing files that changed from the base of the PR and between 1872e5b and d427030.

📒 Files selected for processing (1)
  • src/mesh/Router.cpp

@caveman99
caveman99 force-pushed the router-decrypt-authoritative-key branch from d427030 to c3da38f Compare July 21, 2026 10:24
Resolve the inbound sender key via NodeDB::copyPublicKeyForDecrypt: authoritative (hot/warm) as before, plus a TrafficManagement cold-tier cache key only when it is signer-proven. An unverified TOFU cache key no longer backs pki_encrypted attribution, while a previously-authenticated node evicted to the cache still resolves. Outbound encrypt-to keying is unchanged.
@caveman99
caveman99 force-pushed the router-decrypt-authoritative-key branch from c3da38f to 60738f0 Compare July 21, 2026 10:28
@caveman99 caveman99 changed the title Use the authoritative key on the PKI decrypt path Gate the PKI-decrypt key on signer-proven, not the opportunistic cache Jul 21, 2026
@caveman99

Copy link
Copy Markdown
Member Author

Switched to option 1 from the review: copyPublicKeyForDecrypt accepts a cold-tier cache key only when signer-proven, keeping the hot/warm TOFU baseline and the outbound opportunistic path unchanged.

@NomDeTom

Copy link
Copy Markdown
Collaborator

warm store doesn't differentiate manually verified & xeddsa properly. There's a piece of work to do to re-allocate the spurious protected flag, and then split it properly. The protected flag is used at migration, but it's unused after that.

@github-actions

github-actions Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

⚡ Try this PR in the Web Flasher

Flash this PR in the Web Flasher

firmware commit boards expires

Warning

This is an automated, unreviewed CI test build. Back up your device configuration
before flashing, and only flash devices you are able to recover.

Supported boards built by this PR (30)
Device Board Platform
Crowpanel Adv 3.5 TFT elecrow-adv-35-tft esp32-s3
Heltec HT62 heltec-ht62-esp32c3-sx1262 esp32-c3
Heltec Mesh Node 096 heltec-mesh-node-t096 nrf52840
Heltec Mesh Node T1 heltec-mesh-node-t1 nrf52840
Heltec Mesh Node T114 heltec-mesh-node-t114 nrf52840
Heltec V3 heltec-v3 esp32-s3
Heltec V4 heltec-v4 esp32-s3
Meshnology W10 meshnology_w10 esp32-s3
Raspberry Pi Pico pico rp2040
Raspberry Pi Pico W picow rp2040
RAK WisMesh Pocket V3 rak_wismesh_pocket nrf52840
RAK WisMesh Pod rak_wismesh_pod nrf52840
RAK WisMesh Repeater Mini V2 rak_wismesh_repeater_mini nrf52840
RAK WisMesh Tag rak_wismeshtag nrf52840
RAK WisBlock 11200 rak11200 esp32
RAK WisBlock 11310 rak11310 rp2040
RAK3312 rak3312 esp32-s3
RAK WisBlock 4631 rak4631 nrf52840
Seeed SenseCAP Mesh-Tracker-X1 seeed_mesh_tracker_X1 nrf52840
Seeed Wio Tracker L1 seeed_wio_tracker_L1 nrf52840
Seeed Xiao NRF52840 Kit seeed_xiao_nrf52840_kit nrf52840
Seeed Xiao ESP32-S3 seeed-xiao-s3 esp32-s3
Station G2 station-g2 esp32-s3
Station G3 station-g3 esp32-s3
LILYGO T-Deck t-deck-tft esp32-s3
LILYGO T-Echo t-echo nrf52840
LILYGO T-Echo Plus t-echo-plus nrf52840
LILYGO T-Impulse Plus t-impulse-plus nrf52840
LilyGo T3-C6 tlora-c6 esp32-c6
Seeed SenseCAP T1000-E tracker-t1000-e nrf52840

Build artifacts expire on 2026-08-21. Updated for 4940b8b.

…horitative-key

# Conflicts:
#	src/mesh/Router.cpp
@caveman99 caveman99 added the bugfix Pull request that fixes bugs label Jul 22, 2026
@caveman99
caveman99 merged commit f09f2b1 into develop Jul 22, 2026
104 checks passed
@caveman99
caveman99 deleted the router-decrypt-authoritative-key branch July 22, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Pull request that fixes bugs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants