Skip to content

Commit 69dbf8a

Browse files
Yerazeclaude
andcommitted
fix: PKI_UNKNOWN_PUBKEY errors now correctly flag key mismatch
PKI_UNKNOWN_PUBKEY and PKI_SEND_FAIL_PUBLIC_KEY routing errors were suppressed when the target node wasn't in the radio's device database. The guard assumed this was only expected after factory reset/purge, but it also suppressed legitimate key mismatch detection for nodes the radio simply doesn't know about. Removed the isNodeInDeviceDb() guard from both routing error paths (request packets and message-tracked packets). The key mismatch flag will now clear naturally via the resolution logic in PR #2365 when keys are re-synced. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a801b9e commit 69dbf8a

File tree

1 file changed

+24
-41
lines changed

1 file changed

+24
-41
lines changed

src/server/meshtasticManager.ts

Lines changed: 24 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5344,26 +5344,20 @@ class MeshtasticManager {
53445344

53455345
// PKI errors from our local node (couldn't encrypt to target)
53465346
if (isPkiError(errorReason) && fromNodeId === localNodeId) {
5347-
// PKI_UNKNOWN_PUBKEY when node isn't in the radio's DB is expected after
5348-
// factory reset or purge — don't flag it as a security issue
5349-
if ((errorReason === RoutingError.PKI_UNKNOWN_PUBKEY || errorReason === RoutingError.PKI_SEND_FAIL_PUBLIC_KEY) && !this.isNodeInDeviceDb(toNum)) {
5350-
logger.info(`🔐 PKI key error for node ${toNodeId} — node not in radio's database (expected after factory reset/purge)`);
5351-
} else {
5352-
const errorDescription = errorReason === RoutingError.PKI_FAILED
5353-
? 'PKI encryption failed — your radio\'s stored key for this node may be outdated. Click "Exchange Node Info" to re-sync keys with the radio.'
5354-
: 'Your radio does not have this node\'s public key (even though MeshMonitor does). Click "Exchange Node Info" to push the key to your radio, or purge the node to force a fresh key exchange.';
5347+
const errorDescription = errorReason === RoutingError.PKI_FAILED
5348+
? 'PKI encryption failed — your radio\'s stored key for this node may be outdated. Click "Exchange Node Info" to re-sync keys with the radio.'
5349+
: 'Your radio does not have this node\'s public key (even though MeshMonitor does). Click "Exchange Node Info" to push the key to your radio, or purge the node to force a fresh key exchange.';
53555350

5356-
logger.warn(`🔐 PKI error on request for node ${toNodeId}: ${errorDescription}`);
5351+
logger.warn(`🔐 PKI error on request for node ${toNodeId}: ${errorDescription}`);
53575352

5358-
await databaseService.nodes.upsertNode({
5359-
nodeNum: toNum,
5360-
nodeId: toNodeId,
5361-
keyMismatchDetected: true,
5362-
keySecurityIssueDetails: errorDescription
5363-
});
5364-
dataEventEmitter.emitNodeUpdate(toNum, { keyMismatchDetected: true, keySecurityIssueDetails: errorDescription });
5365-
this.handlePkiError(toNum);
5366-
}
5353+
await databaseService.nodes.upsertNode({
5354+
nodeNum: toNum,
5355+
nodeId: toNodeId,
5356+
keyMismatchDetected: true,
5357+
keySecurityIssueDetails: errorDescription
5358+
});
5359+
dataEventEmitter.emitNodeUpdate(toNum, { keyMismatchDetected: true, keySecurityIssueDetails: errorDescription });
5360+
this.handlePkiError(toNum);
53675361
}
53685362

53695363
// NO_CHANNEL from the target node (it couldn't decrypt our request)
@@ -5397,35 +5391,24 @@ class MeshtasticManager {
53975391
// Detect PKI/encryption errors and flag the target node
53985392
// Only flag if the error is from our local radio (we couldn't encrypt to target)
53995393
if (isPkiError(errorReason) && fromNodeId === localNodeId) {
5400-
// PKI_FAILED or PKI_UNKNOWN_PUBKEY - indicates key mismatch
54015394
if (originalMessage.toNodeNum) {
54025395
const targetNodeNum = originalMessage.toNodeNum;
54035396

5404-
// PKI_UNKNOWN_PUBKEY when node isn't in the radio's DB is expected after
5405-
// factory reset or purge — don't flag it as a security issue
5406-
if ((errorReason === RoutingError.PKI_UNKNOWN_PUBKEY || errorReason === RoutingError.PKI_SEND_FAIL_PUBLIC_KEY) && !this.isNodeInDeviceDb(targetNodeNum)) {
5407-
logger.info(`🔐 PKI key error for node ${targetNodeId} — node not in radio's database (expected after factory reset/purge)`);
5408-
} else {
5409-
const errorDescription = errorReason === RoutingError.PKI_FAILED
5410-
? 'PKI encryption failed — your radio\'s stored key for this node may be outdated. Click "Exchange Node Info" to re-sync keys with the radio.'
5411-
: 'Your radio does not have this node\'s public key (even though MeshMonitor does). Click "Exchange Node Info" to push the key to your radio, or purge the node to force a fresh key exchange.';
5397+
const errorDescription = errorReason === RoutingError.PKI_FAILED
5398+
? 'PKI encryption failed — your radio\'s stored key for this node may be outdated. Click "Exchange Node Info" to re-sync keys with the radio.'
5399+
: 'Your radio does not have this node\'s public key (even though MeshMonitor does). Click "Exchange Node Info" to push the key to your radio, or purge the node to force a fresh key exchange.';
54125400

5413-
logger.warn(`🔐 PKI error detected for node ${targetNodeId}: ${errorDescription}`);
5414-
5415-
// Flag the node with the key security issue
5416-
await databaseService.nodes.upsertNode({
5417-
nodeNum: targetNodeNum,
5418-
nodeId: targetNodeId,
5419-
keyMismatchDetected: true,
5420-
keySecurityIssueDetails: errorDescription
5421-
});
5401+
logger.warn(`🔐 PKI error detected for node ${targetNodeId}: ${errorDescription}`);
54225402

5423-
// Emit event to notify UI of the key issue
5424-
dataEventEmitter.emitNodeUpdate(targetNodeNum, { keyMismatchDetected: true, keySecurityIssueDetails: errorDescription });
5403+
await databaseService.nodes.upsertNode({
5404+
nodeNum: targetNodeNum,
5405+
nodeId: targetNodeId,
5406+
keyMismatchDetected: true,
5407+
keySecurityIssueDetails: errorDescription
5408+
});
54255409

5426-
// Penalize Link Quality for PKI error (-5)
5427-
this.handlePkiError(targetNodeNum);
5428-
}
5410+
dataEventEmitter.emitNodeUpdate(targetNodeNum, { keyMismatchDetected: true, keySecurityIssueDetails: errorDescription });
5411+
this.handlePkiError(targetNodeNum);
54295412
}
54305413
}
54315414

0 commit comments

Comments
 (0)