added rsa-gen mode
This commit is contained in:
parent
f933d30863
commit
b1ca05759e
@ -6,17 +6,12 @@ void ClientCredential_free(ClientCredential* cred){
|
|||||||
return;
|
return;
|
||||||
free(cred->username.data);
|
free(cred->username.data);
|
||||||
free(cred->aes_key.data);
|
free(cred->aes_key.data);
|
||||||
free(cred->token.data);
|
|
||||||
RSA_destroyPrivateKey(&cred->sk);
|
|
||||||
RSA_destroyPublicKey(&cred->pk);
|
|
||||||
free(cred);
|
free(cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define __passhash_lvl_iter 1e5
|
|
||||||
#define __rsa_key_size 2048
|
|
||||||
|
|
||||||
Result(ClientCredential*) ClientCredential_create(str username, str password){
|
Result(ClientCredential*) ClientCredential_create(str username, str password){
|
||||||
Deferral(32);
|
Deferral(8);
|
||||||
ClientCredential* cred = (ClientCredential*)malloc(sizeof(ClientCredential));
|
ClientCredential* cred = (ClientCredential*)malloc(sizeof(ClientCredential));
|
||||||
memset(cred, 0, sizeof(ClientCredential));
|
memset(cred, 0, sizeof(ClientCredential));
|
||||||
bool success = false;
|
bool success = false;
|
||||||
@ -37,37 +32,15 @@ Result(ClientCredential*) ClientCredential_create(str username, str password){
|
|||||||
StringBuilder_append_str(&sb, password);
|
StringBuilder_append_str(&sb, password);
|
||||||
StringBuilder_append_str(&sb, username);
|
StringBuilder_append_str(&sb, username);
|
||||||
Array(u8) password_and_username = str_castTo_Array(StringBuilder_getStr(&sb));
|
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->aes_key = Array_alloc(u8, password_hash_size);
|
||||||
cred->token = Array_alloc(u8, password_hash_size);
|
|
||||||
Defer(
|
Defer(
|
||||||
free(passhash_lvl1.data);
|
|
||||||
if(!success){
|
if(!success){
|
||||||
free(cred->aes_key.data);
|
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);
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
// lvl 1 hash - is used as AES key for user data
|
||||||
|
hash_password(password_and_username, cred->aes_key.data, __passhash_lvl_iter);
|
||||||
|
|
||||||
DecryptorRSA_construct(&cred->rsa_dec, &cred->sk);
|
|
||||||
EncryptorRSA_construct(&cred->rsa_enc, &cred->pk);
|
|
||||||
DecryptorAES_construct(&cred->user_data_aes_dec, cred->aes_key);
|
DecryptorAES_construct(&cred->user_data_aes_dec, cred->aes_key);
|
||||||
EncryptorAES_construct(&cred->user_data_aes_enc, 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
|
/// @param server_link_cstr address:port:public_key
|
||||||
/// @return
|
/// @return
|
||||||
Result(void) ServerLink_parse(cstr server_link_cstr, EndpointIPv4* server_end_out, br_rsa_public_key* server_key_out){
|
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);
|
str server_link_str = str_from_cstr(server_link_cstr);
|
||||||
i32 sep_pos = 0;
|
i32 sep_pos = 0;
|
||||||
|
|
||||||
|
|||||||
@ -7,11 +7,6 @@ Result(void) client_run();
|
|||||||
typedef struct ClientCredential {
|
typedef struct ClientCredential {
|
||||||
str username;
|
str username;
|
||||||
Array(u8) aes_key;
|
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;
|
EncryptorAES user_data_aes_enc;
|
||||||
DecryptorAES user_data_aes_dec;
|
DecryptorAES user_data_aes_dec;
|
||||||
} ClientCredential;
|
} ClientCredential;
|
||||||
|
|||||||
@ -11,20 +11,16 @@ Result(void) RSA_generateKeyPair(u32 key_size,
|
|||||||
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
||||||
const br_prng_class** rng_vtable_ptr)
|
const br_prng_class** rng_vtable_ptr)
|
||||||
{
|
{
|
||||||
Deferral(16);
|
Deferral(8);
|
||||||
bool success = false;
|
bool success = false;
|
||||||
rng_init_sha256_seedFromTime(rng_vtable_ptr);
|
|
||||||
|
|
||||||
void* sk_buf = malloc(BR_RSA_KBUF_PRIV_SIZE(key_size));
|
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));
|
void* pk_buf = malloc(BR_RSA_KBUF_PUB_SIZE(key_size));
|
||||||
Defer(
|
Defer(
|
||||||
if(!success)
|
if(!success){
|
||||||
free(pk_buf)
|
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);
|
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;
|
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){
|
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_modulus compute_modulus = br_rsa_i31_compute_modulus;
|
||||||
br_rsa_compute_pubexp compute_pubexp = br_rsa_i31_compute_pubexp;
|
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);
|
void hash_password(Array(u8) password, u8* out_buffer, i32 iterations);
|
||||||
#define password_hash_size 32
|
#define password_hash_size 32
|
||||||
|
|
||||||
|
#define __passhash_lvl_iter 1e5
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// rng.c //
|
// rng.c //
|
||||||
@ -86,6 +87,8 @@ void DecryptorAES_decrypt(DecryptorAES* ptr, Array(u8) src, Array(u8) dst, u32*
|
|||||||
// RSA.c //
|
// RSA.c //
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define __rsa_key_size_default 3072
|
||||||
|
|
||||||
/// @brief generate random key pair based on system time
|
/// @brief generate random key pair based on system time
|
||||||
/// @param key_size size of public key in bits (2048/3072/4096)
|
/// @param key_size size of public key in bits (2048/3072/4096)
|
||||||
/// @param sk key for decryption
|
/// @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,
|
br_rsa_private_key* sk, br_rsa_public_key* pk,
|
||||||
const br_prng_class** rng_vtable_ptr);
|
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){
|
static inline void RSA_destroyPrivateKey(br_rsa_private_key* sk){
|
||||||
free(sk->p);
|
free(sk->p);
|
||||||
}
|
}
|
||||||
|
|||||||
54
src/main.c
54
src/main.c
@ -5,6 +5,7 @@
|
|||||||
typedef enum ProgramMode {
|
typedef enum ProgramMode {
|
||||||
Client,
|
Client,
|
||||||
Server,
|
Server,
|
||||||
|
RsaGen,
|
||||||
} ProgramMode;
|
} ProgramMode;
|
||||||
|
|
||||||
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL))
|
#define arg_is(LITERAL) str_equals(arg_str, STR(LITERAL))
|
||||||
@ -14,15 +15,17 @@ int main(const int argc, cstr const* argv){
|
|||||||
|
|
||||||
ProgramMode mode = Client;
|
ProgramMode mode = Client;
|
||||||
cstr server_endpoint_cstr;
|
cstr server_endpoint_cstr;
|
||||||
|
u32 key_size = 0;
|
||||||
|
|
||||||
for(int argi = 1; argi < argc; argi++){
|
for(int argi = 1; argi < argc; argi++){
|
||||||
str arg_str = str_from_cstr(argv[argi]);
|
str arg_str = str_from_cstr(argv[argi]);
|
||||||
if(arg_is("-h") || arg_is("--help")){
|
if(arg_is("-h") || arg_is("--help")){
|
||||||
printf(
|
printf(
|
||||||
"USAGE:\n"
|
"USAGE:\n"
|
||||||
"no arguments Interactive client mode.\n"
|
"no arguments Interactive client mode.\n"
|
||||||
"-h, --help Show this message.\n"
|
"-h, --help Show this message.\n"
|
||||||
"-l, --listen [addr:port] Start server.\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;
|
Return 0;
|
||||||
}
|
}
|
||||||
@ -39,6 +42,21 @@ int main(const int argc, cstr const* argv){
|
|||||||
}
|
}
|
||||||
server_endpoint_cstr = argv[argi];
|
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 {
|
else {
|
||||||
printfe("ERROR: unknown argument '%s'\n"
|
printfe("ERROR: unknown argument '%s'\n"
|
||||||
"Use '-h' to see list of avaliable arguments\n",
|
"Use '-h' to see list of avaliable arguments\n",
|
||||||
@ -57,6 +75,36 @@ int main(const int argc, cstr const* argv){
|
|||||||
case Server:
|
case Server:
|
||||||
try_fatal_void(server_run(server_endpoint_cstr));
|
try_fatal_void(server_run(server_endpoint_cstr));
|
||||||
break;
|
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:
|
default:
|
||||||
printfe("ERROR: invalid program mode %i\n", mode);
|
printfe("ERROR: invalid program mode %i\n", mode);
|
||||||
Return 1;
|
Return 1;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user