@ -5,6 +5,7 @@
# include "secure_channel.h"
# include "debug_config.h"
# include "../lib/platform_compat.h"
# include "../lib/sha256.h"
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
@ -278,91 +279,80 @@ int config_ensure_keys_and_node_id(const char *filename) {
global - > my_public_key_hex [ 0 ] ? strlen ( global - > my_public_key_hex ) : 0 ,
( unsigned long long ) global - > my_node_id ) ;
// Check if we need to generate anything
int need_priv_key = ! is_valid_priv_key ( global - > my_private_key_hex ) ;
int need_pub_key = 0 ;
int need_node_id = 0 ;
int need_pub_key = ! is_valid_pub_key ( global - > my_public_key_hex ) ;
int need_node_id = ! is_valid_node_id ( global - > my_node_id ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_CONFIG , " Validation results - need_priv_key=%d, need_pub_key=%d, need_node_id=%d " ,
need_priv_key , need_pub_key , need_node_id ) ;
if ( ! need_priv_key & & ! need_pub_key & & ! need_node_id ) {
free_config ( config ) ;
return 0 ;
}
// Generate keys if needed
char new_priv_key [ PRIV_HEXKEY_LEN ] = { 0 } ;
char new_pub_key [ PUB_HEXKEY_LEN ] = { 0 } ;
uint64_t new_node_id = 0 ;
uint8_t priv_bin [ SC_PRIVKEY_SIZE ] ;
// ── Step 1: ensure valid privkey ──
if ( need_priv_key ) {
// Generate new keypair if private key is invalid
DEBUG_WARN ( DEBUG_CATEGORY_CONFIG , " Generating NEW keypair — private key was invalid/missing in %s " , filename ) ;
struct SC_MYKEYS mykeys ;
if ( sc_generate_keypair ( & mykeys ) ! = SC_OK ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to generate keypair " ) ;
free_config ( config ) ;
return - 1 ;
}
bytes_to_hex ( mykeys . private_key , SC_PRIVKEY_SIZE , new_priv_key , sizeof ( new_priv_key ) ) ;
bytes_to_hex ( mykeys . public_key , SC_PUBKEY_SIZE , new_pub_key , sizeof ( new_pub_key ) ) ;
} else if ( need_pub_key ) {
// Compute public key from existing private key
DEBUG_WARN ( DEBUG_CATEGORY_CONFIG , " Computing public key from existing private key (pubkey was invalid/missing in %s) " , filename ) ;
uint8_t priv_bin [ SC_PRIVKEY_SIZE ] ;
uint8_t pub_bin [ SC_PUBKEY_SIZE ] ;
// Convert private key from hex to binary
memcpy ( priv_bin , mykeys . private_key , SC_PRIVKEY_SIZE ) ;
} else {
// Convert existing privkey hex → binary
for ( int i = 0 ; i < SC_PRIVKEY_SIZE ; i + + ) {
unsigned int byte ;
if ( sscanf ( global - > my_private_key_hex + i * 2 , " %2x " , & byte ) ! = 1 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Invalid private key hex format " ) ;
free_config ( config ) ;
return - 1 ;
}
priv_bin [ i ] = ( uint8_t ) byte ;
}
// Compute public key
if ( sc_compute_public_key_from_private ( priv_bin , pub_bin ) ! = SC_OK ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to compute public key from private key " ) ;
free_config ( config ) ;
return - 1 ;
}
// Convert to hex
bytes_to_hex ( priv_bin , SC_PRIVKEY_SIZE , new_priv_key , sizeof ( new_priv_key ) ) ;
}
bytes_to_hex ( pub_bin , SC_PUBKEY_SIZE , new_pub_key , sizeof ( new_pub_key ) ) ;
// ── Step 2: derive pubkey from privkey (always check) ──
uint8_t pub_bin [ SC_PUBKEY_SIZE ] ;
if ( sc_compute_public_key_from_private ( priv_bin , pub_bin ) ! = SC_OK ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to compute public key from private key " ) ;
free_config ( config ) ;
return - 1 ;
}
bytes_to_hex ( pub_bin , SC_PUBKEY_SIZE , new_pub_key , sizeof ( new_pub_key ) ) ;
if ( ! is_valid_pub_key ( global - > my_public_key_hex ) | | strcmp ( global - > my_public_key_hex , new_pub_key ) ! = 0 ) {
need_pub_key = 1 ;
DEBUG_WARN ( DEBUG_CATEGORY_CONFIG , " Pubkey mismatch (or missing), fixing: config=%s derived=%s " ,
global - > my_public_key_hex [ 0 ] ? global - > my_public_key_hex : " NULL " , new_pub_key ) ;
}
// ── Step 3: derive node_id from privkey via SHA-256 ──
{
uint8_t sha_hash [ 32 ] ;
SC_SHA256_CTX ctx ;
sc_sha256_init ( & ctx ) ;
sc_sha256_update ( & ctx , priv_bin , SC_PRIVKEY_SIZE ) ;
sc_sha256_final ( & ctx , sha_hash ) ;
memcpy ( & new_node_id , sha_hash , 8 ) ;
new_node_id & = 0x7FFFFFFFFFFFFFFFULL ;
}
if ( need_node_id ) {
if ( random_bytes ( ( uint8_t * ) & new_node_id , sizeof ( new_node_id ) ) ! = 0 ) {
DEBUG_ERROR ( DEBUG_CATEGORY_CONFIG , " Failed to generate random node_id " ) ;
free_config ( config ) ;
return - 1 ;
}
new_node_id & = 0x7FFFFFFFFFFFFFFF ;
DEBUG_WARN ( DEBUG_CATEGORY_CONFIG , " Generating NEW random node_id=%016llx (old=%016llx). WARNING: existing invites will break! file=%s " ,
( unsigned long long ) new_node_id , ( unsigned long long ) global - > my_node_id , filename ) ;
if ( ! is_valid_node_id ( global - > my_node_id ) | | global - > my_node_id ! = new_node_id ) {
need_node_id = 1 ;
DEBUG_WARN ( DEBUG_CATEGORY_CONFIG , " Node_id mismatch (or missing), fixing: config=%016llx derived=%016llx file=%s " ,
( unsigned long long ) global - > my_node_id , ( unsigned long long ) new_node_id , filename ) ;
}
DEBUG_DEBUG ( DEBUG_CATEGORY_CONFIG , " Validation results - need_priv_key=%d, need_pub_key=%d, need_node_id=%d " ,
need_priv_key , need_pub_key , need_node_id ) ;
if ( ! need_priv_key & & ! need_pub_key & & ! need_node_id ) {
free_config ( config ) ;
return 0 ;
}
free_config ( config ) ;
@ -389,7 +379,8 @@ int config_ensure_keys_and_node_id(const char *filename) {
size_t work_len = file_size ;
int ret = 0 ;
int write_keys = ( need_priv_key | | need_pub_key | | need_node_id ) ;
if ( need_node_id ) {
char node_id_hex [ HEXNODEID_LEN + 1 ] ;
snprintf ( node_id_hex , sizeof ( node_id_hex ) , " %016llx " , ( unsigned long long ) new_node_id ) ;
@ -400,14 +391,14 @@ int config_ensure_keys_and_node_id(const char *filename) {
}
}
if ( need_priv_key & & ret = = 0 ) {
if ( write_keys & & ret = = 0 ) {
DEBUG_WARN ( DEBUG_CATEGORY_CONFIG , " Writing my_private_key to %s " , filename ) ;
if ( insert_or_replace_option ( & work_buf , & work_len , & buf_capacity , " my_private_key " , new_priv_key ) < 0 ) {
ret = - 1 ;
}
}
if ( need_pub_key & & ret = = 0 ) {
if ( write_keys & & ret = = 0 ) {
DEBUG_WARN ( DEBUG_CATEGORY_CONFIG , " Writing my_public_key to %s " , filename ) ;
if ( insert_or_replace_option ( & work_buf , & work_len , & buf_capacity , " my_public_key " , new_pub_key ) < 0 ) {
ret = - 1 ;