diff --git a/src/topo_node_sqlite.c b/src/topo_node_sqlite.c index e5b51983..9a86f280 100644 --- a/src/topo_node_sqlite.c +++ b/src/topo_node_sqlite.c @@ -431,7 +431,8 @@ int topo_node_sqlite_channel_peers_all(sqlite3* db, const char* channel_id, } sqlite3_finalize(ast); - size_t peer_needed = 8 + 32 + 32 + 1 + 64 + 8 + 64 + 8 + 1 + (size_t)nl + 1; + uint8_t flags = (join_sig && join_ts) ? PEERS_FLAG_HAS_JOIN : 0; + size_t peer_needed = 8 + 32 + 32 + 1 + (flags & PEERS_FLAG_HAS_JOIN ? 64+8 : 0) + 64 + 8 + 1 + (size_t)nl + 1; size_t addr_sz = off - addr_start; if (addr_cnt > 0) { if (off + peer_needed > buf_sz) { sqlite3_finalize(stmt); return -2; } @@ -444,7 +445,6 @@ int topo_node_sqlite_channel_peers_all(sqlite3* db, const char* channel_id, memcpy(buf + off, &node_id, 8); off += 8; memcpy(buf + off, x25519, 32); off += 32; memcpy(buf + off, ed_pub, 32); off += 32; - uint8_t flags = (join_sig && join_ts) ? PEERS_FLAG_HAS_JOIN : 0; buf[off++] = flags; if (flags & PEERS_FLAG_HAS_JOIN) { memcpy(buf + off, join_sig, 64); off += 64; diff --git a/tools/chatgui/transport/chat_sync.c b/tools/chatgui/transport/chat_sync.c index 130bb360..546912af 100644 --- a/tools/chatgui/transport/chat_sync.c +++ b/tools/chatgui/transport/chat_sync.c @@ -1258,36 +1258,48 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer, uint16_t pc; memcpy(&pc, p, 2); p += 2; DEBUG_TRACE(DEBUG_CATEGORY_DB_SYNC, "%s: WELCOME ch=%s from=%016llx peers=%u", CS_ID, ch_id, (unsigned long long)peer, pc); for (uint16_t i = 0; i < pc; i++) { - if ((size_t)(p - pl) + 8 + 32 + 32 + 64 + 8 + 1 + 1 > len) break; + if ((size_t)(p - pl) + 8 + 32 + 32 + 1 + 64 + 8 + 1 > len) break; /* min: id+x25519+ed+flags+update_sig(64+8)+nl+ac */ uint64_t node_id; memcpy(&node_id, p, 8); p += 8; const uint8_t* x25519 = p; p += 32; const uint8_t* ed_pub = p; p += 32; - const uint8_t* join_sig = p; p += 64; - uint64_t join_ts; memcpy(&join_ts, p, 8); p += 8; + uint8_t flags = *p++; + const uint8_t* join_sig = NULL; uint64_t join_ts = 0; + if (flags & PEERS_FLAG_HAS_JOIN) { + if (p + 64 + 8 > pl + len) break; + join_sig = p; p += 64; + memcpy(&join_ts, p, 8); p += 8; + } + const uint8_t* update_sig = p; p += 64; + uint64_t update_ts; memcpy(&update_ts, p, 8); p += 8; + (void)update_sig; (void)update_ts; uint8_t nl = *p++; char peer_name[256] = ""; if (nl && p + nl <= pl + len) { memcpy(peer_name, p, nl); peer_name[nl] = '\0'; p += nl; } uint8_t ac = *p++; - /* verify join_sig — all fields present in WELCOME wire */ - uint8_t vmsg[256]; size_t vlen = 0; - vlen += snprintf((char*)vmsg + vlen, sizeof(vmsg) - vlen, "%s", ch_id) + 1; - memcpy(vmsg + vlen, &node_id, 8); vlen += 8; - memcpy(vmsg + vlen, x25519, 32); vlen += 32; - { const char* nm = peer_name[0] ? peer_name : ""; - size_t nls = strlen(nm); memcpy(vmsg + vlen, nm, nls); vlen += nls; vmsg[vlen++] = '\0'; } - memcpy(vmsg + vlen, &join_ts, 8); vlen += 8; - { EVP_PKEY* pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, ed_pub, 32); - if (pkey) { - EVP_MD_CTX* ver = EVP_MD_CTX_new(); - if (ver) { - if (EVP_DigestVerifyInit(ver, NULL, NULL, NULL, pkey) != 1 - || EVP_DigestVerify(ver, join_sig, 64, vmsg, vlen) != 1) - DEBUG_ERROR(DEBUG_CATEGORY_DB_SYNC, "%s: WELCOME invalid join_sig node=0x%016llx", CS_ID, (unsigned long long)node_id); - EVP_MD_CTX_free(ver); + /* verify join_sig if present */ + if (join_sig) { + uint8_t vmsg[256]; size_t vlen = 0; + vlen += snprintf((char*)vmsg + vlen, sizeof(vmsg) - vlen, "%s", ch_id) + 1; + memcpy(vmsg + vlen, &node_id, 8); vlen += 8; + memcpy(vmsg + vlen, x25519, 32); vlen += 32; + { const char* nm = peer_name[0] ? peer_name : ""; + size_t nls = strlen(nm); memcpy(vmsg + vlen, nm, nls); vlen += nls; vmsg[vlen++] = '\0'; } + memcpy(vmsg + vlen, &join_ts, 8); vlen += 8; + EVP_PKEY* pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, ed_pub, 32); + if (pkey) { + EVP_MD_CTX* ver = EVP_MD_CTX_new(); + if (ver) { + if (EVP_DigestVerifyInit(ver, NULL, NULL, NULL, pkey) != 1 + || EVP_DigestVerify(ver, join_sig, 64, vmsg, vlen) != 1) { + DEBUG_ERROR(DEBUG_CATEGORY_DB_SYNC, "%s: WELCOME invalid join_sig node=0x%016llx — skipping", CS_ID, (unsigned long long)node_id); + EVP_MD_CTX_free(ver); EVP_PKEY_free(pkey); + continue; + } + EVP_MD_CTX_free(ver); + } + EVP_PKEY_free(pkey); } - EVP_PKEY_free(pkey); - } } int rc = topo_node_sqlite_member_put(db, ch_id, node_id, join_sig, join_ts, NULL, 0, x25519, ed_pub, peer_name, NULL); @@ -1323,8 +1335,8 @@ static void cs_handle_welcome(struct chat_sync* cs, uint64_t peer, DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "%s: [ADDR_SYNC] WELCOME INSERT v6 node=0x%016llx sock=%d port=%d", CS_ID, (unsigned long long)node_id, sid, port); } - member_sync_cancel(g_cs->inst, peer, ch_id); - member_sync_set_online(g_cs->inst, peer, 0); + member_sync_cancel(g_cs->inst, node_id, ch_id); + member_sync_set_online(g_cs->inst, node_id, 0); } cs_refresh_channels(cs);