Clive BlackledgeandClaude Opus 5 579d26e1b2 fix(NodeDB): don't let an empty contact key erase a stored public key (#11432)
Clients send `add_contact` before every text-message DM, because a phone
often holds a larger contact database (with public keys) than the radio
can keep. That makes `addFromContact()` the highest-volume key-write path
on the device - and it had no protection against key erasure.

Its only key guard covered the manually-verified case: if the local entry
was marked manually verified and the incoming contact was not, a key
mismatch aborted the update. Every ordinary entry fell straight through to
`CopyUserToNodeInfoLite()`, which assigns `public_key` unconditionally. So
a SharedContact with `has_user` set and an empty `public_key` overwrote a
peer's stored, XEdDSA-proven key with zeros - and `addFromContact()` calls
`saveNodeDatabaseToDisk()`, so the erasure survived a reboot. Subsequent
DMs to that peer then failed with PKI_SEND_FAIL_PUBLIC_KEY, with no way to
recover until the peer's NodeInfo was re-exchanged.

`public_key` is a singular (non-optional) bytes field, so "absent" and
"empty" both decode to size 0; a client that simply has no key for a
contact is indistinguishable on the wire from one asking to clear it.

The fix is deliberately narrow: keep the stored key when the entry already
holds a full 32-byte key and the incoming contact does not. A well-formed
32-byte contact key still updates the entry exactly as before.

Deliberately NOT changed here:
- `updateUser()`'s first-key-wins pin is not applied to this path. Clients
  legitimately use add_contact to supply keys the radio never had and to
  update them (QR-code contact sharing); a blanket pin would break that
  documented flow. Only erasure is refused.
- `CopyUserToNodeInfoLite()` itself is untouched - it has many other
  callers (self-record refresh, updateUser, warm-tier rehydration), so the
  guard lives at this call site.
- The manually-verified branch is unchanged.
- Node-number validation (reserved/broadcast/self) on this path remains
  open and is tracked separately.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 12:22:53 +00:00
2026-08-06 14:05:07 +00:00
2021-10-09 17:15:12 +11:00
2026-08-06 14:05:07 +00:00
2024-09-24 15:24:08 -05:00
2026-08-11 14:56:11 +02:00
2026-07-01 19:01:27 -05:00
2026-01-29 10:06:58 -06:00
2024-11-28 06:26:51 -06:00
2024-09-04 15:33:28 -07:00
2026-07-28 11:09:40 +00:00
2026-01-29 10:06:58 -06:00
2026-01-29 10:06:58 -06:00
2026-07-01 19:01:27 -05:00
2025-01-13 12:24:05 +08:00
2026-01-29 10:06:58 -06:00

Meshtastic Logo

Meshtastic Firmware

GitHub release downloads CI CLA assistant Fiscal Contributors Vercel

meshtastic%2Ffirmware | Trendshift

Overview

This repository contains the official device firmware for Meshtastic, an open-source LoRa mesh networking project designed for long-range, low-power communication without relying on internet or cellular infrastructure. The firmware supports various hardware platforms, including ESP32, nRF52, RP2040/RP2350, and Linux-based devices.

Meshtastic enables text messaging, location sharing, and telemetry over a decentralized mesh network, making it ideal for outdoor adventures, emergency preparedness, and remote operations.

Get Started

Join our community and help improve Meshtastic! 🚀

Stats

Alt

S
Description
No description provided
Readme GPL-3.0
88 MiB
Languages
C++ 72.7%
C 23.5%
Python 2%
Shell 1.2%
Batchfile 0.2%
Other 0.2%