Browse Source

OpenSSL: Multiple algorithms

Splitting up keypair generation functions
master
David Lanzendörfer 2 months ago
parent
commit
a1a803d630
1 changed files with 387 additions and 28 deletions
  1. +387
    -28
      src/openssl_crypto.c

+ 387
- 28
src/openssl_crypto.c View File

@ -564,13 +564,17 @@ pgp_rsa_private_check(const pgp_seckey_t *seckey)
return res;
}
int pgp_dsa_private_check(const pgp_dsa_seckey_t *secdsa)
int pgp_eddsa_private_check(const pgp_seckey_t *seckey)
{
return 1;
}
int pgp_dsa_private_check(const pgp_seckey_t *seckey)
{
return 1;
}
int pgp_elgamal_private_check(const pgp_elgamal_seckey_t *seckey)
int pgp_elgamal_private_check(const pgp_seckey_t *seckey)
{
return 1;
}
@ -784,30 +788,10 @@ pgp_rsa_generate_keypair(pgp_key_t *keydata,
pgp_push_checksum_writer(output, seckey);
switch (seckey->pubkey.alg) {
case PGP_PKA_DSA:
return pgp_write_mpi(output, seckey->key.dsa.x);
case PGP_PKA_RSA:
case PGP_PKA_RSA_ENCRYPT_ONLY:
case PGP_PKA_RSA_SIGN_ONLY:
if (!pgp_write_mpi(output, seckey->key.rsa.d) ||
!pgp_write_mpi(output, seckey->key.rsa.p) ||
!pgp_write_mpi(output, seckey->key.rsa.q) ||
!pgp_write_mpi(output, seckey->key.rsa.u)) {
return 0;
}
break;
case PGP_PKA_ELGAMAL:
return pgp_write_mpi(output, seckey->key.elgamal.x);
case PGP_PKA_EDDSA:
case PGP_PKA_ECDH:
// TODO
printf("%s:%d, %s: Elliptic curves pub(%d)\n",__FILE__,__LINE__,__FUNCTION__,seckey->pubkey.alg);
return 0;
default:
(void) fprintf(stderr, "Bad seckey->pubkey.alg\n");
if (!pgp_write_mpi(output, seckey->key.rsa.d) ||
!pgp_write_mpi(output, seckey->key.rsa.p) ||
!pgp_write_mpi(output, seckey->key.rsa.q) ||
!pgp_write_mpi(output, seckey->key.rsa.u)) {
return 0;
}
@ -825,7 +809,382 @@ pgp_rsa_generate_keypair(pgp_key_t *keydata,
return 1;
}
pgp_dsa_sig_t *
/**
\ingroup HighLevel_KeyGenerate
\brief Generates an DSA keypair
\param numbits Modulus size
\param e Public Exponent
\param keydata Pointer to keydata struct to hold new key
\return 1 if key generated successfully; otherwise 0
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
*/
unsigned
pgp_dsa_generate_keypair(pgp_key_t *keydata,
const char *hashalg,
const char *cipher,
const uint8_t *passphrase,
const size_t pplen)
{
pgp_seckey_t *seckey;
DSA *dsa;
BN_CTX *ctx;
pgp_output_t *output;
pgp_memory_t *mem;
int res;
ctx = BN_CTX_new();
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
seckey = pgp_get_writable_seckey(keydata);
/* generate the key pair */
dsa = DSA_new();
res = DSA_generate_key(dsa);
if (!res){
DSA_free(dsa);
return 0;
};
/* populate pgp key from ssl key */
seckey->pubkey.version = PGP_V4;
seckey->pubkey.birthtime = time(NULL);
seckey->pubkey.days_valid = 0;
seckey->pubkey.alg = PGP_PKA_DSA;
seckey->pubkey.key.dsa.p = (BIGNUM *)DSA_get0_p(dsa);
seckey->pubkey.key.dsa.q = (BIGNUM *)DSA_get0_q(dsa);
seckey->pubkey.key.dsa.g = (BIGNUM *)DSA_get0_g(dsa);
seckey->pubkey.key.dsa.y = (BIGNUM *)DSA_get0_pub_key(dsa);
/* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */
seckey->s2k_usage = PGP_S2KU_NONE;
/* seckey->s2k_specifier = PGP_S2KS_SALTED;*/
seckey->s2k_specifier = PGP_S2KS_SIMPLE;
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
seckey->hash_alg = PGP_HASH_SHA1;
}
seckey->alg = pgp_str_to_cipher(cipher);
seckey->octetc = 0;
seckey->checksum = 0;
seckey->key.dsa.x = (BIGNUM *)DSA_get0_priv_key(dsa);
BN_CTX_free(ctx);
DSA_free(dsa);
pgp_keyid(keydata->pubkeyid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg);
/* Generate checksum */
output = NULL;
mem = NULL;
pgp_setup_memory_write(&output, &mem, 128);
pgp_push_checksum_writer(output, seckey);
if(!pgp_write_mpi(output, seckey->key.dsa.x)) {
return 0;
}
/* close rather than pop, since its the only one on the stack */
pgp_writer_close(output);
pgp_teardown_memory_write(output, mem);
/* should now have checksum in seckey struct */
/* test */
if (pgp_get_debug_level(__FILE__)) {
pgp_dsa_private_check(seckey);
}
return 1;
}
/**
\ingroup HighLevel_KeyGenerate
\brief Generates an ElGamal keypair
\param numbits Modulus size
\param e Public Exponent
\param keydata Pointer to keydata struct to hold new key
\return 1 if key generated successfully; otherwise 0
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
*/
unsigned
pgp_elgamal_generate_keypair(pgp_key_t *keydata,
const int numbits,
const unsigned long e,
const char *hashalg,
const char *cipher,
const uint8_t *passphrase,
const size_t pplen)
{
pgp_seckey_t *seckey;
DH *dh;
BN_CTX *ctx;
pgp_output_t *output;
pgp_memory_t *mem;
int res;
ctx = BN_CTX_new();
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
seckey = pgp_get_writable_seckey(keydata);
/* generate the key pair */
dh = DH_new();
res = DH_generate_key(dh);
if (!res){
DH_free(dh);
return 0;
};
/* populate pgp key from ssl key */
seckey->pubkey.version = PGP_V4;
seckey->pubkey.birthtime = time(NULL);
seckey->pubkey.days_valid = 0;
seckey->pubkey.alg = PGP_PKA_ELGAMAL;
seckey->pubkey.key.elgamal.p = (BIGNUM *)DH_get0_p(dh);
seckey->pubkey.key.elgamal.g = (BIGNUM *)DH_get0_g(dh);
seckey->pubkey.key.elgamal.y = (BIGNUM *)DH_get0_pub_key(dh);
/* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */
seckey->s2k_usage = PGP_S2KU_NONE;
/* seckey->s2k_specifier = PGP_S2KS_SALTED;*/
seckey->s2k_specifier = PGP_S2KS_SIMPLE;
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
seckey->hash_alg = PGP_HASH_SHA1;
}
seckey->alg = pgp_str_to_cipher(cipher);
seckey->octetc = 0;
seckey->checksum = 0;
seckey->key.elgamal.x = (BIGNUM *)DH_get0_priv_key(dh);
BN_CTX_free(ctx);
DH_free(dh);
pgp_keyid(keydata->pubkeyid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg);
/* Generate checksum */
output = NULL;
mem = NULL;
pgp_setup_memory_write(&output, &mem, 128);
pgp_push_checksum_writer(output, seckey);
if(! pgp_write_mpi(output, seckey->key.elgamal.x) ) {
return 0;
}
/* close rather than pop, since its the only one on the stack */
pgp_writer_close(output);
pgp_teardown_memory_write(output, mem);
/* should now have checksum in seckey struct */
/* test */
if (pgp_get_debug_level(__FILE__)) {
pgp_elgamal_private_check(seckey);
}
return 1;
}
/**
\ingroup HighLevel_KeyGenerate
\brief Generates an ECDH keypair
\param numbits Modulus size
\param keydata Pointer to keydata struct to hold new key
\return 1 if key generated successfully; otherwise 0
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
\RFC: https://datatracker.ietf.org/doc/html/rfc6637
*/
unsigned
pgp_ecdh_generate_keypair(pgp_key_t *keydata,
const int numbits,
const char *hashalg,
const char *cipher,
const uint8_t *passphrase,
const size_t pplen)
{
pgp_seckey_t *seckey;
DH *dh;
BN_CTX *ctx;
pgp_output_t *output;
pgp_memory_t *mem;
int res;
ctx = BN_CTX_new();
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
seckey = pgp_get_writable_seckey(keydata);
/* generate the key pair */
dh = DH_new();
res = DH_generate_key(dh);
if (!res){
DH_free(dh);
return 0;
};
/* populate pgp key from ssl key */
seckey->pubkey.version = PGP_V4;
seckey->pubkey.birthtime = time(NULL);
seckey->pubkey.days_valid = 0;
seckey->pubkey.alg = PGP_PKA_ECDH;
seckey->pubkey.key.elgamal.p = (BIGNUM *)DH_get0_p(dh);
seckey->pubkey.key.elgamal.g = (BIGNUM *)DH_get0_g(dh);
seckey->pubkey.key.elgamal.y = (BIGNUM *)DH_get0_pub_key(dh);
/* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */
seckey->s2k_usage = PGP_S2KU_NONE;
/* seckey->s2k_specifier = PGP_S2KS_SALTED;*/
seckey->s2k_specifier = PGP_S2KS_SIMPLE;
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
seckey->hash_alg = PGP_HASH_SHA1;
}
seckey->alg = pgp_str_to_cipher(cipher);
seckey->octetc = 0;
seckey->checksum = 0;
seckey->key.elgamal.x = (BIGNUM *)DH_get0_priv_key(dh);
BN_CTX_free(ctx);
DH_free(dh);
pgp_keyid(keydata->pubkeyid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg);
/* Generate checksum */
output = NULL;
mem = NULL;
pgp_setup_memory_write(&output, &mem, 128);
pgp_push_checksum_writer(output, seckey);
//if(! pgp_write_mpi(output, seckey->key.ecdh.x) ) {
// return 0;
//}
// TODO
printf("%s:%d, %s: Elliptic curves pub(%d)\n",__FILE__,__LINE__,__FUNCTION__,seckey->pubkey.alg);
/* close rather than pop, since its the only one on the stack */
pgp_writer_close(output);
pgp_teardown_memory_write(output, mem);
/* should now have checksum in seckey struct */
/* test */
if (pgp_get_debug_level(__FILE__)) {
pgp_eddsa_private_check(seckey);
}
return 1;
}
/**
\ingroup HighLevel_KeyGenerate
\brief Generates an EdDSA keypair
\param numbits Modulus size
\param keydata Pointer to keydata struct to hold new key
\return 1 if key generated successfully; otherwise 0
\note It is the caller's responsibility to call pgp_keydata_free(keydata)
\RFC: https://datatracker.ietf.org/doc/html/rfc8032
*/
unsigned
pgp_eddsa_generate_keypair(pgp_key_t *keydata,
const int numbits,
const char *hashalg,
const char *cipher,
const uint8_t *passphrase,
const size_t pplen)
{
pgp_seckey_t *seckey;
DH *dh;
BN_CTX *ctx;
pgp_output_t *output;
pgp_memory_t *mem;
int res;
ctx = BN_CTX_new();
pgp_keydata_init(keydata, PGP_PTAG_CT_SECRET_KEY);
seckey = pgp_get_writable_seckey(keydata);
/* generate the key pair */
dh = DH_new();
res = DH_generate_key(dh);
if (!res){
DH_free(dh);
return 0;
};
/* populate pgp key from ssl key */
seckey->pubkey.version = PGP_V4;
seckey->pubkey.birthtime = time(NULL);
seckey->pubkey.days_valid = 0;
seckey->pubkey.alg = PGP_PKA_EDDSA;
seckey->pubkey.key.elgamal.p = (BIGNUM *)DH_get0_p(dh);
seckey->pubkey.key.elgamal.g = (BIGNUM *)DH_get0_g(dh);
seckey->pubkey.key.elgamal.y = (BIGNUM *)DH_get0_pub_key(dh);
/* seckey->s2k_usage = PGP_S2KU_ENCRYPTED_AND_HASHED; */
seckey->s2k_usage = PGP_S2KU_NONE;
/* seckey->s2k_specifier = PGP_S2KS_SALTED;*/
seckey->s2k_specifier = PGP_S2KS_SIMPLE;
if ((seckey->hash_alg = pgp_str_to_hash_alg(hashalg)) == PGP_HASH_UNKNOWN) {
seckey->hash_alg = PGP_HASH_SHA1;
}
seckey->alg = pgp_str_to_cipher(cipher);
seckey->octetc = 0;
seckey->checksum = 0;
seckey->key.elgamal.x = (BIGNUM *)DH_get0_priv_key(dh);
BN_CTX_free(ctx);
DH_free(dh);
pgp_keyid(keydata->pubkeyid, PGP_KEY_ID_SIZE, &keydata->key.seckey.pubkey, seckey->hash_alg);
pgp_fingerprint(&keydata->pubkeyfpr, &keydata->key.seckey.pubkey, seckey->hash_alg);
/* Generate checksum */
output = NULL;
mem = NULL;
pgp_setup_memory_write(&output, &mem, 128);
pgp_push_checksum_writer(output, seckey);
//if(! pgp_write_mpi(output, seckey->key.ecdh.x) ) {
// return 0;
//}
// TODO
printf("%s:%d, %s: Elliptic curves pub(%d)\n",__FILE__,__LINE__,__FUNCTION__,seckey->pubkey.alg);
/* close rather than pop, since its the only one on the stack */
pgp_writer_close(output);
pgp_teardown_memory_write(output, mem);
/* should now have checksum in seckey struct */
/* test */
if (pgp_get_debug_level(__FILE__)) {
pgp_eddsa_private_check(seckey);
}
return 1;
}
pgp_dsa_sig_t *
pgp_dsa_sign(uint8_t *hashbuf,
unsigned hashsize,
const pgp_dsa_seckey_t *secdsa,


Loading…
Cancel
Save