199 lines
5.9 KiB
C
199 lines
5.9 KiB
C
/*
|
|
* Test program for key generation
|
|
* Standalone version that doesn't require FastCGI
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sqlite3.h>
|
|
#include "../nostr_core_lib/nostr_core/nostr_common.h"
|
|
#include "../nostr_core_lib/nostr_core/utils.h"
|
|
|
|
// Forward declarations
|
|
int generate_random_private_key_bytes(unsigned char *key_bytes, size_t len);
|
|
int generate_server_keypair(const char *db_path);
|
|
int store_blossom_private_key(const char *db_path, const char *seckey);
|
|
|
|
// Generate random private key bytes using /dev/urandom
|
|
int generate_random_private_key_bytes(unsigned char *key_bytes, size_t len) {
|
|
FILE *fp = fopen("/dev/urandom", "rb");
|
|
if (!fp) {
|
|
fprintf(stderr, "ERROR: Cannot open /dev/urandom for key generation\n");
|
|
return -1;
|
|
}
|
|
|
|
size_t bytes_read = fread(key_bytes, 1, len, fp);
|
|
fclose(fp);
|
|
|
|
if (bytes_read != len) {
|
|
fprintf(stderr, "ERROR: Failed to read %zu bytes from /dev/urandom\n", len);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Store blossom private key in dedicated table
|
|
int store_blossom_private_key(const char *db_path, const char *seckey) {
|
|
sqlite3 *db;
|
|
sqlite3_stmt *stmt;
|
|
int rc;
|
|
|
|
// Validate key format
|
|
if (!seckey || strlen(seckey) != 64) {
|
|
fprintf(stderr, "ERROR: Invalid blossom private key format\n");
|
|
return -1;
|
|
}
|
|
|
|
// Create blossom_seckey table if it doesn't exist
|
|
rc = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL);
|
|
if (rc) {
|
|
fprintf(stderr, "ERROR: Can't open database: %s\n", sqlite3_errmsg(db));
|
|
return -1;
|
|
}
|
|
|
|
// Create table
|
|
const char *create_sql = "CREATE TABLE IF NOT EXISTS blossom_seckey (id INTEGER PRIMARY KEY CHECK (id = 1), seckey TEXT NOT NULL, created_at INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), CHECK (length(seckey) = 64))";
|
|
rc = sqlite3_exec(db, create_sql, NULL, NULL, NULL);
|
|
if (rc != SQLITE_OK) {
|
|
fprintf(stderr, "ERROR: Failed to create blossom_seckey table: %s\n", sqlite3_errmsg(db));
|
|
sqlite3_close(db);
|
|
return -1;
|
|
}
|
|
|
|
// Store key
|
|
const char *sql = "INSERT OR REPLACE INTO blossom_seckey (id, seckey) VALUES (1, ?)";
|
|
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
|
if (rc != SQLITE_OK) {
|
|
fprintf(stderr, "ERROR: SQL prepare failed: %s\n", sqlite3_errmsg(db));
|
|
sqlite3_close(db);
|
|
return -1;
|
|
}
|
|
|
|
sqlite3_bind_text(stmt, 1, seckey, -1, SQLITE_STATIC);
|
|
rc = sqlite3_step(stmt);
|
|
sqlite3_finalize(stmt);
|
|
sqlite3_close(db);
|
|
|
|
if (rc != SQLITE_DONE) {
|
|
fprintf(stderr, "ERROR: Failed to store blossom private key\n");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Generate server keypair and store in database
|
|
int generate_server_keypair(const char *db_path) {
|
|
printf("Generating server keypair...\n");
|
|
unsigned char seckey_bytes[32];
|
|
char seckey_hex[65];
|
|
char pubkey_hex[65];
|
|
|
|
// Generate random private key
|
|
printf("Generating random private key...\n");
|
|
if (generate_random_private_key_bytes(seckey_bytes, 32) != 0) {
|
|
fprintf(stderr, "Failed to generate random bytes\n");
|
|
return -1;
|
|
}
|
|
|
|
// Validate the private key
|
|
if (nostr_ec_private_key_verify(seckey_bytes) != NOSTR_SUCCESS) {
|
|
fprintf(stderr, "ERROR: Generated invalid private key\n");
|
|
return -1;
|
|
}
|
|
|
|
// Convert to hex
|
|
nostr_bytes_to_hex(seckey_bytes, 32, seckey_hex);
|
|
|
|
// Derive public key
|
|
unsigned char pubkey_bytes[32];
|
|
if (nostr_ec_public_key_from_private_key(seckey_bytes, pubkey_bytes) != NOSTR_SUCCESS) {
|
|
fprintf(stderr, "ERROR: Failed to derive public key\n");
|
|
return -1;
|
|
}
|
|
|
|
// Convert public key to hex
|
|
nostr_bytes_to_hex(pubkey_bytes, 32, pubkey_hex);
|
|
|
|
// Store private key securely
|
|
if (store_blossom_private_key(db_path, seckey_hex) != 0) {
|
|
fprintf(stderr, "ERROR: Failed to store blossom private key\n");
|
|
return -1;
|
|
}
|
|
|
|
// Store public key in config
|
|
sqlite3 *db;
|
|
sqlite3_stmt *stmt;
|
|
int rc;
|
|
|
|
rc = sqlite3_open_v2(db_path, &db, SQLITE_OPEN_READWRITE, NULL);
|
|
if (rc) {
|
|
fprintf(stderr, "ERROR: Can't open database for config: %s\n", sqlite3_errmsg(db));
|
|
return -1;
|
|
}
|
|
|
|
const char *sql = "INSERT OR REPLACE INTO config (key, value, description) VALUES (?, ?, ?)";
|
|
rc = sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
|
|
if (rc != SQLITE_OK) {
|
|
fprintf(stderr, "ERROR: SQL prepare failed: %s\n", sqlite3_errmsg(db));
|
|
sqlite3_close(db);
|
|
return -1;
|
|
}
|
|
|
|
sqlite3_bind_text(stmt, 1, "blossom_pubkey", -1, SQLITE_STATIC);
|
|
sqlite3_bind_text(stmt, 2, pubkey_hex, -1, SQLITE_STATIC);
|
|
sqlite3_bind_text(stmt, 3, "Blossom server's public key for Nostr communication", -1, SQLITE_STATIC);
|
|
|
|
rc = sqlite3_step(stmt);
|
|
sqlite3_finalize(stmt);
|
|
sqlite3_close(db);
|
|
|
|
if (rc != SQLITE_DONE) {
|
|
fprintf(stderr, "ERROR: Failed to store blossom public key in config\n");
|
|
return -1;
|
|
}
|
|
|
|
// Display keys for admin setup
|
|
printf("========================================\n");
|
|
printf("SERVER KEYPAIR GENERATED SUCCESSFULLY\n");
|
|
printf("========================================\n");
|
|
printf("Blossom Public Key: %s\n", pubkey_hex);
|
|
printf("Blossom Private Key: %s\n", seckey_hex);
|
|
printf("========================================\n");
|
|
printf("IMPORTANT: Save the private key securely!\n");
|
|
printf("This key is used for decrypting admin messages.\n");
|
|
printf("========================================\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
const char *db_path = "db/ginxsom.db";
|
|
|
|
if (argc > 1) {
|
|
db_path = argv[1];
|
|
}
|
|
|
|
printf("Test Key Generation\n");
|
|
printf("===================\n");
|
|
printf("Database: %s\n\n", db_path);
|
|
|
|
// Initialize nostr crypto
|
|
printf("Initializing nostr crypto system...\n");
|
|
if (nostr_crypto_init() != NOSTR_SUCCESS) {
|
|
fprintf(stderr, "FATAL: Failed to initialize nostr crypto\n");
|
|
return 1;
|
|
}
|
|
printf("Crypto system initialized\n\n");
|
|
|
|
// Generate keypair
|
|
if (generate_server_keypair(db_path) != 0) {
|
|
fprintf(stderr, "FATAL: Key generation failed\n");
|
|
return 1;
|
|
}
|
|
|
|
printf("\nKey generation test completed successfully!\n");
|
|
return 0;
|
|
} |