Browse Source

fix: derive node_id from pubkey instead of privkey

sc_derive_node_id() hashed the private key, while invite links
(joindialog.cpp) hashed the public key — giving two different
node_ids for the same keypair.

Removed sc_derive_node_id(), kept only sc_derive_node_id_from_pubkey().
All callers updated to use pubkey-based derivation.
topo_upd
Evgeny 3 months ago
parent
commit
c594375023
  1. 4
      src/config_updater.c
  2. 6
      src/secure_channel.c
  3. 2
      src/secure_channel.h
  4. 8
      src/utun_instance.c
  5. 19
      tools/chatgui/src/joindialog.cpp

4
src/config_updater.c

@ -293,8 +293,8 @@ int config_ensure_keys_and_node_id(const char *filename) {
global->my_public_key_hex[0] ? global->my_public_key_hex : "NULL", new_pub_key); global->my_public_key_hex[0] ? global->my_public_key_hex : "NULL", new_pub_key);
} }
// ── Step 3: derive node_id from privkey ── // ── Step 3: derive node_id from pubkey ──
new_node_id = sc_derive_node_id(priv_bin); new_node_id = sc_derive_node_id_from_pubkey(pub_bin);
if (!is_valid_node_id(global->my_node_id) || global->my_node_id != new_node_id) { if (!is_valid_node_id(global->my_node_id) || global->my_node_id != new_node_id) {
need_node_id = 1; need_node_id = 1;
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Node_id mismatch (or missing), fixing: config=%016llx derived=%016llx file=%s", DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "Node_id mismatch (or missing), fixing: config=%016llx derived=%016llx file=%s",

6
src/secure_channel.c

@ -422,10 +422,10 @@ sc_status_t sc_derive_ed25519_pubkey(const uint8_t *x25519_privkey, uint8_t *ed2
return SC_OK; return SC_OK;
} }
uint64_t sc_derive_node_id(const uint8_t *private_key) { uint64_t sc_derive_node_id_from_pubkey(const uint8_t *public_key) {
if (!private_key) { DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_derive_node_id: NULL private_key"); return 0; } if (!public_key) { DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "sc_derive_node_id_from_pubkey: NULL public_key"); return 0; }
uint8_t sha_hash[SC_HASH_SIZE]; SC_SHA256_CTX ctx; uint8_t sha_hash[SC_HASH_SIZE]; SC_SHA256_CTX ctx;
sc_sha256_init(&ctx); sc_sha256_update(&ctx, private_key, SC_PRIVKEY_SIZE); sc_sha256_final(&ctx, sha_hash); sc_sha256_init(&ctx); sc_sha256_update(&ctx, public_key, SC_PUBKEY_SIZE); sc_sha256_final(&ctx, sha_hash);
uint64_t node_id; uint64_t node_id;
memcpy(&node_id, sha_hash, 8); memcpy(&node_id, sha_hash, 8);
node_id &= 0x7FFFFFFFFFFFFFFFULL; node_id &= 0x7FFFFFFFFFFFFFFFULL;

2
src/secure_channel.h

@ -114,7 +114,7 @@ sc_status_t sc_ed25519_verify(const uint8_t pubkey[32], const uint8_t* msg, size
sc_status_t sc_derive_ed25519_pubkey(const uint8_t *x25519_privkey, uint8_t *ed25519_pubkey_out); sc_status_t sc_derive_ed25519_pubkey(const uint8_t *x25519_privkey, uint8_t *ed25519_pubkey_out);
uint64_t sc_derive_node_id(const uint8_t *private_key); uint64_t sc_derive_node_id_from_pubkey(const uint8_t *public_key);
#ifdef __cplusplus #ifdef __cplusplus

8
src/utun_instance.c

@ -90,10 +90,12 @@ static int instance_init_common(struct UTUN_INSTANCE* instance, struct UASYNC* u
return -1; return -1;
} }
// Derive node_id from privkey if not set in config // Derive node_id from pubkey if not set in config
if (!instance->node_id) { if (!instance->node_id) {
instance->node_id = sc_derive_node_id(instance->my_keys.private_key); uint8_t pubkey[SC_PUBKEY_SIZE];
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "node_id derived from privkey: %016llx", (unsigned long long)instance->node_id); sc_compute_public_key_from_private(instance->my_keys.private_key, pubkey);
instance->node_id = sc_derive_node_id_from_pubkey(pubkey);
DEBUG_INFO(DEBUG_CATEGORY_CONFIG, "node_id derived from pubkey: %016llx", (unsigned long long)instance->node_id);
} }
if (sc_derive_ed25519_pubkey(instance->my_keys.private_key, instance->my_ed25519_pubkey) != SC_OK) { if (sc_derive_ed25519_pubkey(instance->my_keys.private_key, instance->my_ed25519_pubkey) != SC_OK) {

19
tools/chatgui/src/joindialog.cpp

@ -14,6 +14,7 @@
#include <cstring> #include <cstring>
extern "C" { extern "C" {
#include "../../../src/secure_channel.h"
#include "../../../lib/sha256.h" #include "../../../lib/sha256.h"
} }
@ -92,14 +93,7 @@ JoinDialog::JoinDialog(UtunNode* node, DbManager* db, QWidget* parent)
setStatus(""); setStatus("");
return; return;
} }
uint8_t hash[32]; uint64_t nodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData());
SC_SHA256_CTX ctx;
sc_sha256_init(&ctx);
sc_sha256_update(&ctx, (const uint8_t*)d.pubkey.constData(), 32);
sc_sha256_final(&ctx, hash);
uint64_t nodeId;
memcpy(&nodeId, hash, sizeof(nodeId));
nodeId &= 0x7FFFFFFFFFFFFFFFULL;
QStringList addrList; QStringList addrList;
for (const auto& a : d.addrs) { for (const auto& a : d.addrs) {
@ -162,14 +156,7 @@ void JoinDialog::onConnectClicked() {
return; return;
} }
uint8_t hash[32]; uint64_t nodeId = sc_derive_node_id_from_pubkey((const uint8_t*)d.pubkey.constData());
SC_SHA256_CTX ctx;
sc_sha256_init(&ctx);
sc_sha256_update(&ctx, (const uint8_t*)d.pubkey.constData(), 32);
sc_sha256_final(&ctx, hash);
uint64_t nodeId;
memcpy(&nodeId, hash, sizeof(nodeId));
nodeId &= 0x7FFFFFFFFFFFFFFFULL;
GUI_INFO("join: decoded invite ch=%llu pubkey=%016llx... nodeId=0x%016llx addrs=%d", GUI_INFO("join: decoded invite ch=%llu pubkey=%016llx... nodeId=0x%016llx addrs=%d",
d.channelId, *(const uint64_t*)d.pubkey.constData(), nodeId, d.addrs.size()); d.channelId, *(const uint64_t*)d.pubkey.constData(), nodeId, d.addrs.size());

Loading…
Cancel
Save