Ed25519 self-signature in NODEINFO + fix sync sequence and zero-key bug

Add x25519_self_sig[64] to TOPOMSG_NODE/TOPO_NODE:
- topo_node.h: add field to both structs (wire format + memory)
- topo_node.c: compute Ed25519_sign(ed25519_privkey, x25519_pubkey) for own node
- topo_node.c: serialize/deserialize x25519_self_sig
- topo_group.c: verify Ed25519 self-sig on NODEINFO receive, reject forgery

Fix Ed25519 pubkey zero-key bug:
- topo_node_sqlite.c: get_ed25519_pubkey rejects all-zero key (MUST be non-zero)

Delay db_sync until Ed25519 key is available:
- db_sync.c: db_sync_on_conn_up checks db_get_ed25519_pubkey before starting
- db_sync.c: db_sync_peer_check_cb also checks Ed25519 key availability
- This prevents sync starting before NODEINFO with verified Ed25519 arrives
This commit is contained in:
Evgeny committed 2026-07-23 19:55:15 +03:00
1 parent 3890d2038d
commit 85269d1da3
5 files changed
+32 -6

No files matched your search

+3
View File
@@ -151,6 +151,7 @@ int topo_node_serialize(struct TOPO_GROUP* group, struct TOPO_NODEQ* nq, uint8_t
msg.ver = ni->ver;
memcpy(msg.public_key, ni->public_key, SC_PUBKEY_SIZE);
memcpy(msg.ed25519_public_key, ni->ed25519_public_key, SC_PUBKEY_SIZE);
memcpy(msg.x25519_self_sig, ni->x25519_self_sig, 64);
msg.node_name_len = ni->node_name ? (uint8_t)strlen(ni->node_name) : 0;
msg.local_v4_sockets = topo_list_count((struct _topo_head*)ni->v4_sock_meta);
msg.local_v4_addrs = topo_list_count((struct _topo_head*)ni->v4_addrs);
@@ -230,6 +231,7 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
ni->ver = msg->ver;
memcpy(ni->public_key, msg->public_key, SC_PUBKEY_SIZE);
memcpy(ni->ed25519_public_key, msg->ed25519_public_key, SC_PUBKEY_SIZE);
memcpy(ni->x25519_self_sig, msg->x25519_self_sig, 64);
const uint8_t* dp = data + TOPOMSG_NODE_HDR_SIZE;
@@ -664,6 +666,7 @@ int topo_group_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct TOPO_GR
ni->ver = (old_ver % 255) + 1;
memcpy(ni->public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE);
memcpy(ni->ed25519_public_key, group->ed25519_public_key, SC_PUBKEY_SIZE);
sc_ed25519_sign(instance->my_ed25519_privkey, instance->my_keys.public_key, SC_PUBKEY_SIZE, ni->x25519_self_sig);
if (name_len) { ni->node_name = u_malloc(name_len + 1); if (ni->node_name) { memcpy(ni->node_name, instance->name, name_len); ni->node_name[name_len] = 0; } }
lq->node = topo_node_registry_acquire(instance->topo_groups, ni);