Key verification flow on BaseUI (#7240)

This commit is contained in:
Jonathan Bennett
2025-07-10 09:45:36 -05:00
committed by GitHub
parent a7e516d6f6
commit 0795b21c2b
11 changed files with 211 additions and 126 deletions

View File

@@ -2,6 +2,7 @@
#include "KeyVerificationModule.h"
#include "MeshService.h"
#include "RTC.h"
#include "graphics/draw/MenuHandler.h"
#include "main.h"
#include "modules/AdminModule.h"
#include <SHA256.h>
@@ -48,18 +49,22 @@ AdminMessageHandleResult KeyVerificationModule::handleAdminMessageForModule(cons
bool KeyVerificationModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_KeyVerification *r)
{
updateState();
if (mp.pki_encrypted == false)
if (mp.pki_encrypted == false) {
return false;
if (mp.from != currentRemoteNode) // because the inital connection request is handled in allocReply()
}
if (mp.from != currentRemoteNode) { // because the inital connection request is handled in allocReply()
return false;
}
if (currentState == KEY_VERIFICATION_IDLE) {
return false; // if we're idle, the only acceptable message is an init, which should be handled by allocReply()
}
} else if (currentState == KEY_VERIFICATION_SENDER_HAS_INITIATED && r->nonce == currentNonce && r->hash2.size == 32 &&
r->hash1.size == 0) {
if (currentState == KEY_VERIFICATION_SENDER_HAS_INITIATED && r->nonce == currentNonce && r->hash2.size == 32 &&
r->hash1.size == 0) {
memcpy(hash2, r->hash2.bytes, 32);
if (screen)
screen->showSimpleBanner("Enter Security Number", 30000);
IF_SCREEN(screen->showNumberPicker("Enter Security Number", 60000, 6, [](int number_picked) -> void {
keyVerificationModule->processSecurityNumber(number_picked);
});)
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_WARNING;
@@ -79,23 +84,19 @@ bool KeyVerificationModule::handleReceivedProtobuf(const meshtastic_MeshPacket &
memset(message, 0, sizeof(message));
sprintf(message, "Verification: \n");
generateVerificationCode(message + 15);
static const char *optionsArray[] = {"ACCEPT", "REJECT"};
static const char *optionsArray[] = {"Reject", "Accept"};
LOG_INFO("Hash1 matches!");
if (screen) {
graphics::BannerOverlayOptions options;
options.message = message;
options.durationMs = 30000;
options.optionsArrayPtr = optionsArray;
options.optionsCount = 2;
options.notificationType = graphics::notificationTypeEnum::selection_picker;
options.bannerCallback = [=](int selected) {
if (selected == 0) {
auto remoteNodePtr = nodeDB->getMeshNode(currentRemoteNode);
remoteNodePtr->bitfield |= NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
}
};
screen->showOverlayBanner(options);
}
IF_SCREEN(graphics::BannerOverlayOptions options; options.message = message; options.durationMs = 30000;
options.optionsArrayPtr = optionsArray; options.optionsCount = 2;
options.notificationType = graphics::notificationTypeEnum::selection_picker;
options.bannerCallback =
[=](int selected) {
if (selected == 1) {
auto remoteNodePtr = nodeDB->getMeshNode(currentRemoteNode);
remoteNodePtr->bitfield |= NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
}
};
screen->showOverlayBanner(options);)
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_WARNING;
sprintf(cn->message, "Final confirmation for incoming manual key verification %s", message);
@@ -120,6 +121,7 @@ bool KeyVerificationModule::sendInitialRequest(NodeNum remoteNode)
// generate nonce
updateState();
if (currentState != KEY_VERIFICATION_IDLE) {
graphics::menuHandler::menuQueue = graphics::menuHandler::throttle_message;
return false;
}
currentNonce = random();
@@ -190,11 +192,8 @@ meshtastic_MeshPacket *KeyVerificationModule::allocReply()
responsePacket = allocDataProtobuf(response);
responsePacket->pki_encrypted = true;
if (screen) {
snprintf(message, 25, "Security Number \n%03u %03u", currentSecurityNumber / 1000, currentSecurityNumber % 1000);
screen->showSimpleBanner(message, 30000);
LOG_WARN("%s", message);
}
IF_SCREEN(snprintf(message, 25, "Security Number \n%03u %03u", currentSecurityNumber / 1000, currentSecurityNumber % 1000);
screen->showSimpleBanner(message, 30000); LOG_WARN("%s", message);)
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_WARNING;
sprintf(cn->message, "Incoming Key Verification.\nSecurity Number\n%03u %03u", currentSecurityNumber / 1000,
@@ -258,12 +257,7 @@ void KeyVerificationModule::processSecurityNumber(uint32_t incomingNumber)
p->priority = meshtastic_MeshPacket_Priority_HIGH;
service->sendToMesh(p, RX_SRC_LOCAL, true);
currentState = KEY_VERIFICATION_SENDER_AWAITING_USER;
memset(message, 0, sizeof(message));
sprintf(message, "Verification: \n");
generateVerificationCode(message + 15); // send the toPhone packet
if (screen) {
screen->showSimpleBanner(message, 30000);
}
IF_SCREEN(screen->requestMenu(graphics::menuHandler::key_verification_final_prompt);)
meshtastic_ClientNotification *cn = clientNotificationPool.allocZeroed();
cn->level = meshtastic_LogRecord_Level_WARNING;
sprintf(cn->message, "Final confirmation for outgoing manual key verification %s", message);
@@ -282,7 +276,7 @@ void KeyVerificationModule::processSecurityNumber(uint32_t incomingNumber)
void KeyVerificationModule::updateState()
{
if (currentState != KEY_VERIFICATION_IDLE) {
// check for the 30 second timeout
// check for the 60 second timeout
if (currentNonceTimestamp < getTime() - 60) {
resetToIdle();
} else {