From 26c8f7aa5a023464fd05c6c17c0abcd5bd9e95db Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 3 Nov 2026 12:07:47 +0100 Subject: [PATCH] Build DM identity module and reject conflicting group keys --- src/Makefile.am | 4 ++++ src/dm/dm_identity.c | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 963e68b16..730b13510 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -204,6 +204,8 @@ utun_CORE_SOURCES = \ chat/chat_headless_control.c \ chat/chat_whisper.h \ dm/dm_core.c \ + dm/dm_identity.c \ + dm/dm_identity.h \ dm/dm_history.c \ dm/dm_history.h \ dm/dm_crypto.c \ @@ -405,6 +407,8 @@ libutun_a_SOURCES = \ chat/chat_whisper.c \ chat/chat_whisper.h \ dm/dm_core.c \ + dm/dm_identity.c \ + dm/dm_identity.h \ dm/dm_history.c \ dm/dm_history.h \ dm/dm_crypto.c \ diff --git a/src/dm/dm_identity.c b/src/dm/dm_identity.c index c6a6ab486..66a2c84f8 100644 --- a/src/dm/dm_identity.c +++ b/src/dm/dm_identity.c @@ -65,12 +65,15 @@ int dm_party_resolve(struct UTUN_INSTANCE* inst, uint64_t node, enum dm_mode mod } } else { sqlite3_stmt* st = NULL; + uint8_t member_x[32] = {0}; int member_x_size = 0; int rc = sqlite3_prepare_v2(inst->topo_sqlite_db, - "SELECT x25519_pubkey,ed25519_pubkey FROM nodes WHERE node_id=?", -1, &st, NULL); + "SELECT x25519_pubkey,ed25519_pubkey,devgroup_x FROM nodes WHERE node_id=?", -1, &st, NULL); if (rc == SQLITE_OK) rc = sqlite3_bind_int64(st, 1, (sqlite3_int64)node); if (rc == SQLITE_OK) rc = sqlite3_step(st); if (rc == SQLITE_ROW && sqlite3_column_bytes(st, 0) == 32 && sqlite3_column_bytes(st, 1) == 32) { memcpy(party.x, sqlite3_column_blob(st, 0), 32); memcpy(party.ed, sqlite3_column_blob(st, 1), 32); + member_x_size = sqlite3_column_bytes(st, 2); + if (member_x_size == 32) memcpy(member_x, sqlite3_column_blob(st, 2), 32); } else { sqlite3_finalize(st); return identity_error(inst, "missing or damaged device keys", node); @@ -85,6 +88,8 @@ int dm_party_resolve(struct UTUN_INSTANCE* inst, uint64_t node, enum dm_mode mod struct devgroup_record record; struct devgroup_profile profile; if (devgroup_latest(inst->topo_sqlite_db, id, &record, &profile) != 1) return identity_error(inst, "subgroup profile unavailable", node); + if (member_x_size != 32 || memcmp(member_x, record.x, 32)) + return identity_error(inst, "subgroup profile and membership use different encryption keys", node); party.kind = DM_PARTY_GROUP; party.node = 0; memcpy(party.ed, record.ed, 32); memcpy(party.x, record.x, 32); }