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.
This commit is contained in:
1 parent
50dfa71e81
commit
b737b718cf
3 files changed
+67
-12
No files matched your search
+51
-12
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user