added rsa-gen mode
This commit is contained in:
parent
f933d30863
commit
b1ca05759e
@ -6,17 +6,12 @@ void ClientCredential_free(ClientCredential* cred){
|
||||
return;
|
||||
free(cred->username.data);
|
||||
free(cred->aes_key.data);
|
||||
free(cred->token.data);
|
||||
RSA_destroyPrivateKey(&cred->sk);
|
||||
RSA_destroyPublicKey(&cred->pk);
|
||||
free(cred);
|
||||
}
|
||||
|
||||
#define __passhash_lvl_iter 1e5
|
||||
#define __rsa_key_size 2048
|
||||
|
||||
Result(ClientCredential*) ClientCredential_create(str username, str password){
|
||||
Deferral(32);
|
||||
Deferral(8);
|
||||
ClientCredential* cred = (ClientCredential*)malloc(sizeof(ClientCredential));
|
||||
memset(cred, 0, sizeof(ClientCredential));
|
||||
bool success = false;
|
||||
@ -37,37 +32,15 @@ Result(ClientCredential*) ClientCredential_create(str username, str password){
|
||||
StringBuilder_append_str(&sb, password);
|
||||
StringBuilder_append_str(&sb, username);
|
||||
Array(u8) password_and_username = str_castTo_Array(StringBuilder_getStr(&sb));
|
||||
// lvl 1 hash - is used to generate RSA keys
|
||||
Array(u8) passhash_lvl1 = Array_alloc(u8, password_hash_size);
|
||||
cred->aes_key = Array_alloc(u8, password_hash_size);
|
||||
cred->token = Array_alloc(u8, password_hash_size);
|
||||
Defer(
|
||||
free(passhash_lvl1.data);
|
||||
if(!success){
|
||||
free(cred->aes_key.data);
|
||||
free(cred->token.data);
|
||||
}
|
||||
);
|
||||
hash_password(password_and_username, passhash_lvl1.data, __passhash_lvl_iter);
|
||||
// lvl 2 hash - is used as AES key
|
||||
hash_password(passhash_lvl1, cred->aes_key.data, __passhash_lvl_iter);
|
||||
// lvl 3 hash - is used to authorize client on server
|
||||
hash_password(cred->aes_key, cred->token.data, __passhash_lvl_iter);
|
||||
// lvl 1 hash - is used as AES key for user data
|
||||
hash_password(password_and_username, cred->aes_key.data, __passhash_lvl_iter);
|
||||
|
||||
// generate client rsa keys from password hash
|
||||
br_hmac_drbg_context passhash_based_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
br_hmac_drbg_init(&passhash_based_rng, &br_sha256_vtable, passhash_lvl1.data, password_hash_size);
|
||||
// TODO: does client really need it's own RSA private key? At least i should generate it once using seedFromTime and save in a file encrypted by user_data_aes_enc
|
||||
try_void(RSA_generateKeyPair(__rsa_key_size, &cred->sk, &cred->pk, &passhash_based_rng.vtable));
|
||||
Defer(
|
||||
if(!success){
|
||||
RSA_destroyPrivateKey(&cred->sk);
|
||||
RSA_destroyPublicKey(&cred->pk);
|
||||
}
|
||||
);
|
||||
|
||||
DecryptorRSA_construct(&cred->rsa_dec, &cred->sk);
|
||||
EncryptorRSA_construct(&cred->rsa_enc, &cred->pk);
|
||||
DecryptorAES_construct(&cred->user_data_aes_dec, cred->aes_key);
|
||||
EncryptorAES_construct(&cred->user_data_aes_enc, cred->aes_key);
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ void ServerConnection_close(ServerConnection* conn){
|
||||
/// @param server_link_cstr address:port:public_key
|
||||
/// @return
|
||||
Result(void) ServerLink_parse(cstr server_link_cstr, EndpointIPv4* server_end_out, br_rsa_public_key* server_key_out){
|
||||
Deferral(16);
|
||||
Deferral(8);
|
||||
str server_link_str = str_from_cstr(server_link_cstr);
|
||||
i32 sep_pos = 0;
|
||||
|
||||
|
||||
@ -7,11 +7,6 @@ Result(void) client_run();
|
||||
typedef struct ClientCredential {
|
||||
str username;
|
||||
Array(u8) aes_key;
|
||||
Array(u8) token;
|
||||
br_rsa_private_key sk;
|
||||
br_rsa_public_key pk;
|
||||
EncryptorRSA rsa_enc;
|
||||
DecryptorRSA rsa_dec;
|
||||
EncryptorAES user_data_aes_enc;
|
||||
DecryptorAES user_data_aes_dec;
|
||||
} ClientCredential;
|
||||
|
||||
@ -11,20 +11,16 @@ Result(void) RSA_generateKeyPair(u32 key_size,
|
||||
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
||||
const br_prng_class** rng_vtable_ptr)
|
||||
{
|
||||
Deferral(16);
|
||||
Deferral(8);
|
||||
bool success = false;
|
||||
rng_init_sha256_seedFromTime(rng_vtable_ptr);
|
||||
|
||||
void* sk_buf = malloc(BR_RSA_KBUF_PRIV_SIZE(key_size));
|
||||
Defer(
|
||||
if(!success)
|
||||
free(sk_buf)
|
||||
);
|
||||
|
||||
void* pk_buf = malloc(BR_RSA_KBUF_PUB_SIZE(key_size));
|
||||
Defer(
|
||||
if(!success)
|
||||
free(pk_buf)
|
||||
if(!success){
|
||||
free(sk_buf);
|
||||
free(pk_buf);
|
||||
}
|
||||
);
|
||||
|
||||
success = br_rsa_i31_keygen(rng_vtable_ptr, sk, sk_buf, pk, pk_buf, key_size, DEFAULT_PUBLIC_EXPONENT);
|
||||
@ -35,8 +31,28 @@ Result(void) RSA_generateKeyPair(u32 key_size,
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
Result(void) RSA_generateKeyPairFromTime(u32 key_size,
|
||||
br_rsa_private_key* sk, br_rsa_public_key* pk)
|
||||
{
|
||||
Deferral(8);
|
||||
br_hmac_drbg_context time_based_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
rng_init_sha256_seedFromTime(&time_based_rng.vtable);
|
||||
try_void(RSA_generateKeyPair(key_size, sk, pk, &time_based_rng.vtable));
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
Result(void) RSA_generateKeyPairFromPassword(u32 key_size,
|
||||
br_rsa_private_key* sk, br_rsa_public_key* pk, str password)
|
||||
{
|
||||
Deferral(8);
|
||||
br_hmac_drbg_context password_based_rng = { .vtable = &br_hmac_drbg_vtable };
|
||||
br_hmac_drbg_init(&password_based_rng, &br_sha256_vtable, password.data, password.size);
|
||||
try_void(RSA_generateKeyPair(key_size, sk, pk, &password_based_rng.vtable));
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
Result(void) RSA_computePublicKey(const br_rsa_private_key* sk, br_rsa_public_key* pk){
|
||||
Deferral(16);
|
||||
Deferral(8);
|
||||
br_rsa_compute_modulus compute_modulus = br_rsa_i31_compute_modulus;
|
||||
br_rsa_compute_pubexp compute_pubexp = br_rsa_i31_compute_pubexp;
|
||||
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
void hash_password(Array(u8) password, u8* out_buffer, i32 iterations);
|
||||
#define password_hash_size 32
|
||||
|
||||
#define __passhash_lvl_iter 1e5
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// rng.c //
|
||||
@ -86,6 +87,8 @@ void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32*
|
||||
// RSA.c //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define __rsa_key_size_default 3072
|
||||
|
||||
/// @brief generate random key pair based on system time
|
||||
/// @param key_size size of public key in bits (2048/3072/4096)
|
||||
/// @param sk key for decryption
|
||||
@ -95,6 +98,12 @@ Result(void) RSA_generateKeyPair(u32 key_size,
|
||||
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
||||
const br_prng_class** rng_vtable_ptr);
|
||||
|
||||
Result(void) RSA_generateKeyPairFromTime(u32 key_size,
|
||||
br_rsa_private_key* sk, br_rsa_public_key* pk);
|
||||
|
||||
Result(void) RSA_generateKeyPairFromPassword(u32 key_size,
|
||||
br_rsa_private_key* sk, br_rsa_public_key* pk, str password);
|
||||
|
||||
static inline void RSA_destroyPrivateKey(br_rsa_private_key* sk){
|
||||
free(sk->p);
|
||||
}
|
||||
|
||||
48
src/main.c
48
src/main.c
@ -5,6 +5,7 @@
|
||||
typedef enum ProgramMode {
|
||||
Client,
|
||||
Server,
|
||||
RsaGen,
|
||||
} ProgramMode;
|
||||
|
||||
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL))
|
||||
@ -14,6 +15,7 @@ int main(const int argc, cstr const* argv){
|
||||
|
||||
ProgramMode mode = Client;
|
||||
cstr server_endpoint_cstr;
|
||||
u32 key_size = 0;
|
||||
|
||||
for(int argi = 1; argi < argc; argi++){
|
||||
str arg_str = str_from_cstr(argv[argi]);
|
||||
@ -23,6 +25,7 @@ int main(const int argc, cstr const* argv){
|
||||
"no arguments Interactive client mode.\n"
|
||||
"-h, --help Show this message.\n"
|
||||
"-l, --listen [addr:port] Start server.\n"
|
||||
"--rsa-gen [size(2048/3072/4096)] Generate RSA private and public keys based on stdin data (64Kb max)\n"
|
||||
);
|
||||
Return 0;
|
||||
}
|
||||
@ -39,6 +42,21 @@ int main(const int argc, cstr const* argv){
|
||||
}
|
||||
server_endpoint_cstr = argv[argi];
|
||||
}
|
||||
else if(arg_is("--rsa-gen")){
|
||||
if(mode != Client){
|
||||
printf("program mode is set already\n");
|
||||
Return 1;
|
||||
}
|
||||
|
||||
mode = RsaGen;
|
||||
if(++argi >= argc){
|
||||
printfe("ERROR: no key size specified\n");
|
||||
Return 1;
|
||||
}
|
||||
if(sscanf(argv[argi], "%u", &key_size) != 1){
|
||||
printfe("ERROR: no key size specified\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
printfe("ERROR: unknown argument '%s'\n"
|
||||
"Use '-h' to see list of avaliable arguments\n",
|
||||
@ -57,6 +75,36 @@ int main(const int argc, cstr const* argv){
|
||||
case Server:
|
||||
try_fatal_void(server_run(server_endpoint_cstr));
|
||||
break;
|
||||
case RsaGen:{
|
||||
size_t input_max_size = 64*1024;
|
||||
char* input_buf = malloc(input_max_size);
|
||||
Defer(free(input_buf));
|
||||
size_t read_n = fread(input_buf, 1, input_max_size, stdin);
|
||||
if(read_n == 0){
|
||||
printfe("ERROR: no input\n");
|
||||
Return 1;
|
||||
}
|
||||
str input_str = str_construct(input_buf, read_n, false);
|
||||
printfe("generating RSA key pair...\n");
|
||||
br_rsa_private_key sk;
|
||||
br_rsa_public_key pk;
|
||||
try_fatal_void(RSA_generateKeyPairFromPassword(key_size, &sk, &pk, input_str));
|
||||
Defer(
|
||||
RSA_destroyPrivateKey(&sk);
|
||||
RSA_destroyPublicKey(&pk);
|
||||
);
|
||||
puts("-----BEGIN RSA PRIVATE KEY-----");
|
||||
str sk_str = RSA_serializePrivateKey_base64(&sk);
|
||||
puts(sk_str.data);
|
||||
free(sk_str.data);
|
||||
puts("-----END RSA PRIVATE KEY-------");
|
||||
puts("-----BEGIN RSA PUBLIC KEY------");
|
||||
str pk_str = RSA_serializePublicKey_base64(&pk);
|
||||
puts(pk_str.data);
|
||||
free(pk_str.data);
|
||||
puts("-----END RSA PUBLIC KEY--------");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printfe("ERROR: invalid program mode %i\n", mode);
|
||||
Return 1;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user