Gate identity learning on signature in NodeDB::updateUser (#11084)
This commit is contained in:
co-authored by
GitHub
parent
405a6bfd8a
commit
5ded0ec8c5
+8
-1
@@ -3310,13 +3310,20 @@ void NodeDB::addFromContact(meshtastic_SharedContact contact)
|
||||
|
||||
/** Update user info and channel for this node based on received user data
|
||||
*/
|
||||
bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelIndex)
|
||||
bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelIndex, bool xeddsaSigned)
|
||||
{
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(nodeId);
|
||||
if (!info) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Once a node has proven it signs, only a signed update may change its identity. The public-key guard
|
||||
// below is no help - an attacker can replay the victim's real (public) key. Our own record is exempt.
|
||||
if (nodeId != getNodeNum() && nodeInfoLiteHasXeddsaSigned(info) && !xeddsaSigned) {
|
||||
LOG_WARN("Refusing unsigned identity update for node 0x%08x that previously signed", nodeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI)
|
||||
if (p.public_key.size == 32 && nodeId != nodeDB->getNodeNum()) {
|
||||
printBytes("Incoming Pubkey: ", p.public_key.bytes, 32);
|
||||
|
||||
+3
-3
@@ -255,9 +255,9 @@ class NodeDB
|
||||
*/
|
||||
void updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxSource src = RX_SRC_RADIO);
|
||||
|
||||
/** Update user info and channel for this node based on received user data
|
||||
*/
|
||||
bool updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelIndex = 0);
|
||||
/** Update user info and channel for this node based on received user data.
|
||||
* A known signer's identity is only learned when xeddsaSigned; defaults false so callers fail closed. */
|
||||
bool updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelIndex = 0, bool xeddsaSigned = false);
|
||||
|
||||
/*
|
||||
* Sets a node either favorite or unfavorite. Returns true if the node ends
|
||||
|
||||
@@ -61,7 +61,9 @@ bool NodeInfoModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, mes
|
||||
// Coerce user.id to be derived from the node number
|
||||
snprintf(p.id, sizeof(p.id), "!%08x", getFrom(&mp));
|
||||
|
||||
bool hasChanged = nodeDB->updateUser(getFrom(&mp), p, mp.channel);
|
||||
// updateUser() refuses the identity write for a known signer sending unsigned (all unicast
|
||||
// NodeInfo), so the exchange above still proceeds but cannot spoof the stored name.
|
||||
bool hasChanged = nodeDB->updateUser(getFrom(&mp), p, mp.channel, mp.xeddsa_signed);
|
||||
|
||||
bool wasBroadcast = isBroadcast(mp.to);
|
||||
|
||||
|
||||
@@ -734,7 +734,7 @@ ProcessMessage TrafficManagementModule::handleReceived(const meshtastic_MeshPack
|
||||
meshtastic_User requester = meshtastic_User_init_zero;
|
||||
if (!unauthenticatedSigner &&
|
||||
pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, &meshtastic_User_msg, &requester)) {
|
||||
nodeDB->updateUser(getFrom(&mp), requester, mp.channel);
|
||||
nodeDB->updateUser(getFrom(&mp), requester, mp.channel, mp.xeddsa_signed);
|
||||
}
|
||||
logAction("respond", &mp, "nodeinfo-cache");
|
||||
incrementStat(&stats.nodeinfo_cache_hits);
|
||||
|
||||
Reference in New Issue
Block a user