Allow key verification to work for unknown nodes. (#10669)

* Allow key verification to work for unknown nodes.

* trunk

* More reliable admin key decryption

* Add admin key fallback tests

* Actually check haveRemoteKey

* Logging cleanup

* Address review feedback

- Persist the committed key + manually-verified flag in
  commitVerifiedRemoteNode via saveToDisk(SEGMENT_NODEDATABASE),
  replacing the "todo: initiate save"
- Guard the CryptoEngine pending-key slot with a dedicated internal
  lock; the Router reads it while already holding the non-recursive
  cryptLock, so the accessors cannot reuse that lock
- Draw the security number from the hardware RNG (CryptRNG fallback)
  under cryptLock instead of random(); on nRF52 the entropy fill
  toggles the same CC310 the BLE task's packet crypto uses
- Return true after fully handling the hash2 response (restores
  develop behavior; consistent with the hash1 branch)
- Take uint32_t in the number-picker callbacks so 8-digit hex
  nodenums can't truncate through int
- Trim over-long comments flagged by review

* feat(tests): add deterministic tests for admin session-key behavior

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
Jonathan Bennett
2026-07-14 21:38:41 -05:00
committed by GitHub
co-authored by GitHub Claude Opus 4.8 Ben Meadors
parent fc91a69ca4
commit 952c825167
12 changed files with 632 additions and 65 deletions
+5 -2
View File
@@ -343,7 +343,7 @@ void Screen::showNodePicker(const char *message, uint32_t durationMs, std::funct
}
// Called to trigger a banner with custom message and duration
void Screen::showNumberPicker(const char *message, uint32_t durationMs, uint8_t digits,
void Screen::showNumberPicker(const char *message, uint32_t durationMs, uint8_t digits, bool useBase16,
std::function<void(uint32_t)> bannerCallback)
{
#ifdef USE_EINK
@@ -356,7 +356,10 @@ void Screen::showNumberPicker(const char *message, uint32_t durationMs, uint8_t
NotificationRenderer::alertBannerCallback = bannerCallback;
NotificationRenderer::pauseBanner = false;
NotificationRenderer::curSelected = 0;
NotificationRenderer::current_notification_type = notificationTypeEnum::number_picker;
if (useBase16)
NotificationRenderer::current_notification_type = notificationTypeEnum::hex_picker;
else
NotificationRenderer::current_notification_type = notificationTypeEnum::number_picker;
NotificationRenderer::numDigits = digits;
NotificationRenderer::currentNumber = 0;
+2 -1
View File
@@ -344,7 +344,8 @@ class Screen : public concurrency::OSThread
void showOverlayBanner(BannerOverlayOptions);
void showNodePicker(const char *message, uint32_t durationMs, std::function<void(uint32_t)> bannerCallback);
void showNumberPicker(const char *message, uint32_t durationMs, uint8_t digits, std::function<void(uint32_t)> bannerCallback);
void showNumberPicker(const char *message, uint32_t durationMs, uint8_t digits, bool useBase16,
std::function<void(uint32_t)> bannerCallback);
void showTextInput(const char *header, const char *initialText, uint32_t durationMs,
std::function<void(const std::string &)> textCallback);
+5 -4
View File
@@ -2323,8 +2323,10 @@ void menuHandler::testMenu()
void menuHandler::numberTest()
{
screen->showNumberPicker("Pick a number\n ", 30000, 4,
[](int number_picked) -> void { LOG_WARN("Nodenum: %u", number_picked); });
screen->showNumberPicker("Verify Nodenum:\n ", 30000, 8, true, [](uint32_t number_picked) -> void {
LOG_DEBUG("Nodenum: 0x%08x", number_picked);
keyVerificationModule->sendInitialRequest(number_picked);
});
}
void menuHandler::wifiBaseMenu()
@@ -2508,8 +2510,7 @@ void menuHandler::keyVerificationFinalPrompt()
options.notificationType = graphics::notificationTypeEnum::selection_picker;
options.bannerCallback = [=](int selected) {
if (selected == 1) {
auto remoteNodePtr = nodeDB->getMeshNode(keyVerificationModule->getCurrentRemoteNode());
remoteNodePtr->bitfield |= NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
keyVerificationModule->commitVerifiedRemoteNode();
}
};
screen->showOverlayBanner(options);