Browse Source

Fix: Auto-generated my_public_key was empty in config

Fixed critical bug where my_public_key was not being generated when auto-adding
to config file. The issue had multiple root causes:

1. Buffer size bug: HEXKEY_LEN constant was too small (64) for public key (needs 129)
2. Silent failure in bytes_to_hex() when buffer too small
3. Wrong validation length checks causing incorrect need_* detection
4. Keypair regeneration instead of deriving public key from private key
5. Node ID conditional logic bug inserting it only when private key was invalid

Changes:
- Added PRIV_HEXKEY_LEN (65) and PUB_HEXKEY_LEN (129) constants
- Added is_valid_priv_key() and is_valid_pub_key() with correct length checks
- Added sc_compute_public_key_from_private() to derive public key when possible
- Fixed node_id insertion logic to check need_node_id instead of need_priv_key
- Updated bytes_to_hex() to null-terminate on error

Tested with real config file - public key now correctly generates as 128 hex chars.
v2_dev
Evgeny 2 months ago
parent
commit
b737b718cf
  1. 63
      src/config_updater.c
  2. 15
      src/secure_channel.c
  3. 1
      src/secure_channel.h

63
src/config_updater.c

@ -12,12 +12,16 @@
#include <fcntl.h>
#include <sys/stat.h>
#define HEXKEY_LEN 64 // 32 bytes * 2 hex chars
#define HEXNODEID_LEN 16 // 8 bytes * 2 hex chars
#define PRIV_HEXKEY_LEN 65 // 32 bytes * 2 hex chars + null
#define PUB_HEXKEY_LEN 129 // 64 bytes * 2 hex chars + null
#define HEXNODEID_LEN 17 // 8 bytes * 2 hex chars + null
#define MAX_LINE_LEN 1024
void bytes_to_hex(const uint8_t *bytes, size_t len, char *hex_str, size_t hex_len) {
if (!bytes || !hex_str || hex_len < len * 2 + 1) return;
if (!bytes || !hex_str || hex_len < len * 2 + 1) {
if (hex_str && hex_len > 0) hex_str[0] = '\0';
return;
}
for (size_t i = 0; i < len; i++) {
snprintf(hex_str + i * 2, hex_len - i * 2, "%02x", bytes[i]);
}
@ -25,9 +29,17 @@ void bytes_to_hex(const uint8_t *bytes, size_t len, char *hex_str, size_t hex_le
}
static int is_valid_hex_key(const char *key) {
if (!key || strlen(key) != HEXKEY_LEN) return 0;
for (int i = 0; i < HEXKEY_LEN; i++) {
static int is_valid_priv_key(const char *key) {
if (!key || strlen(key) != 64) return 0;
for (int i = 0; i < 64; i++) {
if (!isxdigit((unsigned char)key[i])) return 0;
}
return 1;
}
static int is_valid_pub_key(const char *key) {
if (!key || strlen(key) != 128) return 0;
for (int i = 0; i < 128; i++) {
if (!isxdigit((unsigned char)key[i])) return 0;
}
return 1;
@ -204,8 +216,8 @@ int config_ensure_keys_and_node_id(const char *filename) {
struct global_config *global = &config->global;
// Check if we need to generate anything
int need_priv_key = !is_valid_hex_key(global->my_private_key_hex);
int need_pub_key = !is_valid_hex_key(global->my_public_key_hex);
int need_priv_key = !is_valid_priv_key(global->my_private_key_hex);
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);
if (!need_priv_key && !need_pub_key && !need_node_id) {
@ -214,11 +226,12 @@ int config_ensure_keys_and_node_id(const char *filename) {
}
// Generate keys if needed
char new_priv_key[HEXKEY_LEN + 1] = {0};
char new_pub_key[HEXKEY_LEN + 1] = {0};
char new_priv_key[PRIV_HEXKEY_LEN] = {0};
char new_pub_key[PUB_HEXKEY_LEN] = {0};
uint64_t new_node_id = 0;
if (need_priv_key || need_pub_key) {
if (need_priv_key) {
// Generate new keypair if private key is invalid
struct SC_MYKEYS mykeys;
if (sc_generate_keypair(&mykeys) != SC_OK) {
DEBUG_ERROR(DEBUG_CATEGORY_CONFIG, "Failed to generate keypair");
@ -227,6 +240,32 @@ int config_ensure_keys_and_node_id(const char *filename) {
}
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
uint8_t priv_bin[SC_PRIVKEY_SIZE];
uint8_t pub_bin[SC_PUBKEY_SIZE];
// Convert private key from hex to 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));
}
if (need_node_id) {
@ -268,7 +307,7 @@ int config_ensure_keys_and_node_id(const char *filename) {
int ret = 0;
if (need_priv_key) {
if (need_node_id) {
char node_id_hex[HEXNODEID_LEN + 1];
snprintf(node_id_hex, sizeof(node_id_hex), "%llx", (unsigned long long)new_node_id);
if (insert_or_replace_option(&work_buf, &work_len, &buf_capacity, "my_node_id", node_id_hex) < 0) {

15
src/secure_channel.c

@ -341,3 +341,18 @@ sc_status_t sc_decrypt(sc_context_t *ctx,
return SC_OK;
}
sc_status_t sc_compute_public_key_from_private(const uint8_t *private_key, uint8_t *public_key) {
if (!private_key || !public_key) {
return SC_ERR_INVALID_ARG;
}
if (!curve) {
curve = uECC_secp256r1();
}
if (!uECC_compute_public_key(private_key, public_key, curve)) {
return SC_ERR_CRYPTO;
}
return SC_OK;
}

1
src/secure_channel.h

@ -56,6 +56,7 @@ sc_status_t sc_init_ctx(sc_context_t *ctx, struct SC_MYKEYS *mykeys);
sc_status_t sc_generate_keypair(struct SC_MYKEYS *keys);
sc_status_t sc_init_local_keys(struct SC_MYKEYS *mykeys, const char *public_key, const char *private_key);
sc_status_t sc_set_peer_public_key(sc_context_t *ctx, const char *peer_public_key, int mode);// mode: 0-bin 1-hex key format
sc_status_t sc_compute_public_key_from_private(const uint8_t *private_key, uint8_t *public_key);
// Криптографические операции
sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len);

Loading…
Cancel
Save