Skip to content

Commit

Permalink
added support for EC without ECParam and Pubkey
Browse files Browse the repository at this point in the history
  • Loading branch information
feventura committed Feb 23, 2024
1 parent b723cc9 commit 4796730
Showing 1 changed file with 64 additions and 11 deletions.
75 changes: 64 additions & 11 deletions oqsprov/oqsprov_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@ static OQSX_KEY *oqsx_key_op(const X509_ALGOR *palg, const unsigned char *p,
ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
goto err_key_op;
}
key->privkeylen_cmp[i] = privlen;
} else
privlen = key->privkeylen_cmp[i];
} else { // PQC key
Expand Down Expand Up @@ -883,16 +884,18 @@ static int oqsx_key_recreate_classickey(OQSX_KEY *key, oqsx_key_op_t op)
if (get_oqsname_fromtls(name) == 0) {
const unsigned char *enc_privkey = key->comp_privkey[i];
if (!key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
->raw_key_support)
->raw_key_support) {
EVP_PKEY *npk;
key->classical_pkey = d2i_PrivateKey(
key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
->keytype,
NULL, &enc_privkey, key->privkeylen_cmp[i]);
else
} else {
key->classical_pkey = EVP_PKEY_new_raw_private_key(
key->oqsx_provider_ctx.oqsx_evp_ctx->evp_info
->keytype,
NULL, enc_privkey, key->privkeylen_cmp[i]);
}
if (!key->classical_pkey) {
ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING);
OPENSSL_free(name);
Expand Down Expand Up @@ -1072,7 +1075,7 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
STACK_OF(ASN1_TYPE) *sk = NULL;
ASN1_TYPE *aType = NULL;
unsigned char *concat_key, *buf;
int count, aux, i, buflen, rsa_diff = 0;
int count, aux, i, buflen, key_diff = 0;

if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf))
return 0;
Expand All @@ -1094,13 +1097,17 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
return NULL;
} else {
count = sk_ASN1_TYPE_num(sk);
plen = 2 * plen; // get more than necessary in case its needed
concat_key = OPENSSL_zalloc(plen);
PKCS8_PRIV_KEY_INFO *p8inf_internal = NULL;
const X509_ALGOR *palg_internal;
int keytype, nid;

aux = 0;
for (i = 0; i < count; i++) {
aType = sk_ASN1_TYPE_pop(sk);
p8inf_internal = PKCS8_PRIV_KEY_INFO_new();
nid = 1;
char *name;
if ((name
= get_cmpname(OBJ_obj2nid(palg->algorithm), count - 1 - i))
Expand All @@ -1118,7 +1125,7 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,

p8inf_internal
= d2i_PKCS8_PRIV_KEY_INFO(&p8inf_internal, &buf2, buflen);
if (!PKCS8_pkey_get0(NULL, &buf, &buflen, NULL,
if (!PKCS8_pkey_get0(NULL, &buf, &buflen, &palg_internal,
p8inf_internal)) {
OPENSSL_free(name);
ASN1_TYPE_free(aType);
Expand All @@ -1128,30 +1135,76 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf,
return NULL;
}

aux += buflen;
memcpy(concat_key + plen - 1 - aux, buf, buflen);
keytype = OBJ_obj2nid(palg_internal->algorithm);

// Checking OPTIONAL params on EC
if (keytype == EVP_PKEY_EC) {
nid = OBJ_obj2nid(palg_internal->parameter->value.object);
for (int j = 0; j < OSSL_NELEM(nids_sig); j++) {
if ((nids_sig[j].nid == nid)
&& (nids_sig[j].length_private_key > buflen)) {
EC_KEY *ec_pkey;
const unsigned char *buf3 = buf;
unsigned char *buf4, *buf5;

if (buflen
!= nids_sig[j].kex_length_secret
+ 7) { // no ECParameter and no
// Pubkey
OPENSSL_free(name);
ASN1_TYPE_free(aType);
PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
OPENSSL_clear_free(concat_key, plen);
sk_ASN1_TYPE_free(sk);
return NULL;
}
ec_pkey = EC_KEY_new_by_curve_name(nid);
ec_pkey = d2i_ECPrivateKey(&ec_pkey, &buf3, buflen);
EC_KEY_set_enc_flags(ec_pkey, 0);
buf4 = OPENSSL_malloc(
nids_sig[j].length_private_key);
buf5 = buf4;
buflen = i2d_ECPrivateKey(ec_pkey, &buf5);

aux += buflen;
memcpy(concat_key + plen - 1 - aux, buf4, buflen);
nid = 0; // use as flag to not memcpy twice

OPENSSL_clear_free(buf4, buflen);
EC_KEY_free(ec_pkey);
break;
}
}
}

// if is a RSA key the actual encoding size might be different
// from max size we calculate that difference for to facilitate
// the key reconstruction
if (!strncmp(name, "rsa", 3) || !strncmp(name, "pss", 3)) {
if (keytype == EVP_PKEY_RSA) {
if (name[3] == '3') // 3072
rsa_diff = nids_sig[5].length_private_key - buflen;
key_diff = nids_sig[5].length_private_key - buflen;
else // 2048
rsa_diff = nids_sig[6].length_private_key - buflen;
key_diff = nids_sig[6].length_private_key - buflen;
}

if (nid) {
aux += buflen;
memcpy(concat_key + plen - 1 - aux, buf, buflen);
}

OPENSSL_free(name);
PKCS8_PRIV_KEY_INFO_free(p8inf_internal);
ASN1_TYPE_free(aType);
}

p = OPENSSL_memdup(concat_key + plen - 1 - aux, aux);
OPENSSL_clear_free(concat_key, plen);
plen = aux;
plen = aux; // update plen to correct size
sk_ASN1_TYPE_free(sk);
}
}

oqsx = oqsx_key_op(palg, p, plen + rsa_diff, KEY_OP_PRIVATE, libctx, propq);
oqsx = oqsx_key_op(palg, p, plen + key_diff, KEY_OP_PRIVATE, libctx, propq);
if (get_keytype(OBJ_obj2nid(palg->algorithm)) != KEY_TYPE_CMP_SIG) {
ASN1_OCTET_STRING_free(oct);
} else {
Expand Down

0 comments on commit 4796730

Please sign in to comment.