mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-10-23 00:11:20 +00:00
fix import regression caused by vcontact
This commit is contained in:
1 parent
0ea958000c
commit
6b04772182
5 files changed
+113
-5
No files matched your search
@@ -228,10 +228,7 @@ void CompanionMesh::begin()
|
||||
/* Derive the v-contact pubkey from our identity: stable per node, unique
|
||||
* per device. Deliberately NOT a real keypair — no private key exists
|
||||
* anywhere, so nothing addressed to this key is decryptable by anyone. */
|
||||
static const char vc_salt[] = "zc-vcontact";
|
||||
mesh::Utils::sha256(_vcontact_pubkey, PUB_KEY_SIZE,
|
||||
(const uint8_t *)vc_salt, sizeof(vc_salt) - 1,
|
||||
self_id.pub_key, PUB_KEY_SIZE);
|
||||
deriveVContactKey();
|
||||
/* Stamp lastmod only if a time source already ran (hardware RTC restore
|
||||
* happens before begin()). Otherwise stay deferred (lastmod = 0) until
|
||||
* vcontactClockSynced() — an advert stamped now would show as 1970. */
|
||||
@@ -978,6 +975,17 @@ void CompanionMesh::vcontactNotify(const char *text)
|
||||
vcontactQueueText(text);
|
||||
}
|
||||
|
||||
void CompanionMesh::deriveVContactKey()
|
||||
{
|
||||
/* v-contact pubkey = SHA256("zc-vcontact" || self pubkey). Re-run whenever
|
||||
* the identity changes (boot, CMD_IMPORT_PRIVATE_KEY) so the key always
|
||||
* tracks the current identity. */
|
||||
static const char vc_salt[] = "zc-vcontact";
|
||||
mesh::Utils::sha256(_vcontact_pubkey, PUB_KEY_SIZE,
|
||||
(const uint8_t *)vc_salt, sizeof(vc_salt) - 1,
|
||||
self_id.pub_key, PUB_KEY_SIZE);
|
||||
}
|
||||
|
||||
void CompanionMesh::vcontactPushAdvert()
|
||||
{
|
||||
if (!isVContactEnabled()) return;
|
||||
@@ -1096,6 +1104,27 @@ bool CompanionMesh::vcontactHandleFrame(const uint8_t *data, size_t len)
|
||||
}
|
||||
return false;
|
||||
|
||||
case CMD_GET_ADVERT_PATH:
|
||||
/* The v-contact appears in the app's contact list, so the app queries
|
||||
* its advert path (at connect, and around a config/identity import). The
|
||||
* v-contact has no over-the-air advert, so the real handler's
|
||||
* findAdvertPath() misses and returns ERR_NOT_FOUND — which the app
|
||||
* surfaces as a fatal "not found" that aborts the whole operation. The
|
||||
* v-contact IS this node (loopback), so its path is direct (zero hops):
|
||||
* answer that here, before the real handler runs. Frame layout matches
|
||||
* the real handler: [cmd][reserved][7-byte pubkey prefix]. */
|
||||
if (len >= 2 + 7 && isVContactKey(&data[2], 7)) {
|
||||
uint8_t rsp[6];
|
||||
size_t i = 0;
|
||||
rsp[i++] = PACKET_ADVERT_PATH;
|
||||
put_le32(&rsp[i], _vcontact_lastmod ? _vcontact_lastmod
|
||||
: (uint32_t)getRTCClock()->getCurrentTime()); i += 4;
|
||||
rsp[i++] = 0; // path_len = 0 → direct (zero hop)
|
||||
writeFrame(rsp, i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
case CMD_ADD_UPDATE_CONTACT:
|
||||
case CMD_RESET_PATH:
|
||||
/* Never let the v-contact into the real contacts table (it must stay
|
||||
@@ -2858,7 +2887,18 @@ bool CompanionMesh::handleProtocolFrame(const uint8_t *data, size_t len)
|
||||
mesh::LocalIdentity new_identity;
|
||||
new_identity.readFrom(&data[1], PRV_KEY_SIZE);
|
||||
if (_store->saveMainIdentity(new_identity)) {
|
||||
/* The v-contact key is derived from our identity, so it
|
||||
* changes with the new key. Tell the connected app to drop
|
||||
* the old v-contact (old key), re-derive, then re-advertise
|
||||
* the new one — otherwise the app's cached loopback contact
|
||||
* points at a key we no longer recognise (messaging + its
|
||||
* advert-path query break until a reboot re-syncs). Order
|
||||
* matters: delete uses the CURRENT (old) key. */
|
||||
bool vc_was_enabled = isVContactEnabled();
|
||||
if (vc_was_enabled) vcontactPushDeleted();
|
||||
self_id = new_identity;
|
||||
deriveVContactKey();
|
||||
if (vc_was_enabled) vcontactPushAdvert();
|
||||
/* Reload contacts to invalidate ECDH shared secrets */
|
||||
resetContacts();
|
||||
_store->loadContacts(this);
|
||||
|
||||
Reference in new issue
Block a user