From 05eaba2c1243b24b2f0de805ee99b997fe3e082f Mon Sep 17 00:00:00 2001 From: Felipe Ventura Date: Thu, 15 Feb 2024 14:04:53 -0600 Subject: [PATCH] added oid to privkey and fix keys format --- oqsprov/oqs_encode_key2any.c | 78 +++++++++++++++++++++++++++--------- oqsprov/oqs_prov.h | 5 +++ oqsprov/oqsprov_keys.c | 32 ++++++++++++--- 3 files changed, 89 insertions(+), 26 deletions(-) diff --git a/oqsprov/oqs_encode_key2any.c b/oqsprov/oqs_encode_key2any.c index 074d5939..ca8caa75 100644 --- a/oqsprov/oqs_encode_key2any.c +++ b/oqsprov/oqs_encode_key2any.c @@ -547,8 +547,8 @@ static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) return -1; ASN1_TYPE **aType = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_TYPE *)); - ASN1_OCTET_STRING **aString - = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_OCTET_STRING *)); + ASN1_BIT_STRING **aString + = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_BIT_STRING *)); unsigned char **temp = OPENSSL_malloc(oqsxkey->numkeys * sizeof(unsigned char *)); size_t *templen = OPENSSL_malloc(oqsxkey->numkeys * sizeof(size_t)); @@ -556,7 +556,7 @@ static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) for (i = 0; i < oqsxkey->numkeys; i++) { aType[i] = ASN1_TYPE_new(); - aString[i] = ASN1_OCTET_STRING_new(); + aString[i] = ASN1_BIT_STRING_new(); temp[i] = NULL; buflen = oqsxkey->pubkeylen_cmp[i]; @@ -565,14 +565,15 @@ static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) oct.data = buf; oct.length = buflen; - templen[i] = i2d_ASN1_OCTET_STRING(&oct, &temp[i]); + oct.flags = 0; + templen[i] = i2d_ASN1_BIT_STRING(&oct, &temp[i]); ASN1_STRING_set(aString[i], temp[i], templen[i]); ASN1_TYPE_set1(aType[i], V_ASN1_SEQUENCE, aString[i]); if (!sk_ASN1_TYPE_push(sk, aType[i])) { for (int j = 0; j <= i; j++) { OPENSSL_cleanse(aString[j]->data, aString[j]->length); - ASN1_OCTET_STRING_free(aString[j]); + ASN1_BIT_STRING_free(aString[j]); OPENSSL_cleanse(aType[j]->value.sequence->data, aType[j]->value.sequence->length); OPENSSL_clear_free(temp[j], templen[j]); @@ -592,7 +593,7 @@ static int oqsx_spki_pub_to_der(const void *vxkey, unsigned char **pder) for (i = 0; i < oqsxkey->numkeys; i++) { OPENSSL_cleanse(aString[i]->data, aString[i]->length); - ASN1_OCTET_STRING_free(aString[i]); + ASN1_BIT_STRING_free(aString[i]); OPENSSL_cleanse(aType[i]->value.sequence->data, aType[i]->value.sequence->length); OPENSSL_clear_free(temp[i], templen[i]); @@ -705,6 +706,7 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) ERR_raise(ERR_LIB_USER, ERR_R_MALLOC_FAILURE); keybloblen = 0; // signal error } + OPENSSL_secure_clear_free(buf, buflen); } else { ASN1_TYPE **aType = OPENSSL_malloc(oqsxkey->numkeys * sizeof(ASN1_TYPE *)); @@ -713,6 +715,7 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) unsigned char **temp = OPENSSL_malloc(oqsxkey->numkeys * sizeof(unsigned char *)); size_t *templen = OPENSSL_malloc(oqsxkey->numkeys * sizeof(size_t)); + PKCS8_PRIV_KEY_INFO *p8inf_internal = NULL; int i; if ((sk = sk_ASN1_TYPE_new_null()) == NULL) @@ -721,7 +724,10 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) for (i = 0; i < oqsxkey->numkeys; i++) { aType[i] = ASN1_TYPE_new(); aString[i] = ASN1_OCTET_STRING_new(); + p8inf_internal = PKCS8_PRIV_KEY_INFO_new(); temp[i] = NULL; + int nid, version; + void *pval; if ((name = get_cmpname(OBJ_sn2nid(oqsxkey->tls_name), i)) == NULL) { @@ -743,13 +749,16 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) OPENSSL_free(aString); OPENSSL_free(temp); OPENSSL_free(templen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); OPENSSL_free(name); return -1; } if (get_oqsname_fromtls(name) == 0) { - if (oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->keytype - == EVP_PKEY_RSA) { // get the RSA real key size + + nid = oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info + ->keytype; + if (nid == EVP_PKEY_RSA) { // get the RSA real key size unsigned char *enc_len = OPENSSL_strndup(oqsxkey->comp_privkey[i], 4); OPENSSL_cleanse(enc_len, 2); @@ -776,13 +785,16 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) OPENSSL_free(aString); OPENSSL_free(temp); OPENSSL_free(templen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); OPENSSL_free(name); return -1; } } else buflen = oqsxkey->privkeylen_cmp[i]; - } else + } else { + nid = OBJ_sn2nid(name); buflen = oqsxkey->privkeylen_cmp[i] + oqsxkey->pubkeylen_cmp[i]; + } buf = OPENSSL_secure_malloc(buflen); if (get_oqsname_fromtls(name) @@ -791,12 +803,40 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) oqsxkey->privkeylen_cmp[i]); memcpy(buf + oqsxkey->privkeylen_cmp[i], oqsxkey->comp_pubkey[i], oqsxkey->pubkeylen_cmp[i]); - } else + } else { memcpy(buf, oqsxkey->comp_privkey[i], buflen); + } - oct.data = buf; - oct.length = buflen; - templen[i] = i2d_ASN1_OCTET_STRING(&oct, &temp[i]); + if (nid == EVP_PKEY_EC) { + version = V_ASN1_OBJECT; + pval = OBJ_nid2obj( + oqsxkey->oqsx_provider_ctx.oqsx_evp_ctx->evp_info->nid); + } else { + version = V_ASN1_UNDEF; + pval = NULL; + } + if (!PKCS8_pkey_set0(p8inf_internal, OBJ_nid2obj(nid), 0, version, + pval, buf, buflen)) { + for (int j = 0; j <= i; j++) { + OPENSSL_cleanse(aString[j]->data, aString[j]->length); + ASN1_OCTET_STRING_free(aString[j]); + OPENSSL_cleanse(aType[j]->value.sequence->data, + aType[j]->value.sequence->length); + OPENSSL_clear_free(temp[j], templen[j]); + } + + sk_ASN1_TYPE_pop_free(sk, &ASN1_TYPE_free); + OPENSSL_free(name); + OPENSSL_free(aType); + OPENSSL_free(aString); + OPENSSL_free(temp); + OPENSSL_free(templen); + OPENSSL_cleanse(buf, buflen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + return -1; + } + + templen[i] = i2d_PKCS8_PRIV_KEY_INFO(p8inf_internal, &temp[i]); ASN1_STRING_set(aString[i], temp[i], templen[i]); ASN1_TYPE_set1(aType[i], V_ASN1_SEQUENCE, aString[i]); @@ -815,15 +855,14 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) OPENSSL_free(aString); OPENSSL_free(temp); OPENSSL_free(templen); - OPENSSL_secure_clear_free(buf, buflen); + OPENSSL_cleanse(buf, buflen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); return -1; } OPENSSL_free(name); - if (i + 1 - < oqsxkey - ->numkeys) { // clear buf and oct if is not the last call - OPENSSL_secure_clear_free(buf, buflen); - } + + OPENSSL_cleanse(buf, buflen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); } keybloblen = i2d_ASN1_SEQUENCE_ANY(sk, pder); @@ -841,7 +880,6 @@ static int oqsx_pki_priv_to_der(const void *vxkey, unsigned char **pder) OPENSSL_free(temp); OPENSSL_free(templen); } - OPENSSL_secure_clear_free(buf, buflen); return keybloblen; } diff --git a/oqsprov/oqs_prov.h b/oqsprov/oqs_prov.h index 1bf1c02e..6cfa7fbd 100644 --- a/oqsprov/oqs_prov.h +++ b/oqsprov/oqs_prov.h @@ -205,6 +205,11 @@ char *get_cmpname(int nid, int index); int get_oqsalg_idx(int nid); int get_composite_idx(int idx); +/* Workaround for not functioning EC PARAM initialization + * TBD, check https://github.com/openssl/openssl/issues/16989 + */ +EVP_PKEY *setECParams(EVP_PKEY *eck, int nid); + /* Register given NID with tlsname in OSSL3 registry */ int oqs_set_nid(char *tlsname, int nid); diff --git a/oqsprov/oqsprov_keys.c b/oqsprov/oqsprov_keys.c index 57080102..1e50f80b 100644 --- a/oqsprov/oqsprov_keys.c +++ b/oqsprov/oqsprov_keys.c @@ -1069,8 +1069,7 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, const X509_ALGOR *palg; STACK_OF(ASN1_TYPE) *sk = NULL; ASN1_TYPE *aType = NULL; - const unsigned char *buf; - unsigned char *concat_key; + unsigned char *concat_key, *buf; int count, aux, i, buflen, rsa_diff = 0; if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf)) @@ -1094,20 +1093,39 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, } else { count = sk_ASN1_TYPE_num(sk); concat_key = OPENSSL_zalloc(plen); + PKCS8_PRIV_KEY_INFO *p8inf_internal = NULL; aux = 0; for (i = 0; i < count; i++) { aType = sk_ASN1_TYPE_pop(sk); + p8inf_internal = PKCS8_PRIV_KEY_INFO_new(); char *name; if ((name = get_cmpname(OBJ_obj2nid(palg->algorithm), count - 1 - i)) == NULL) { OPENSSL_free(name); + ASN1_TYPE_free(aType); + OPENSSL_clear_free(concat_key, plen); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); + sk_ASN1_TYPE_free(sk); ERR_raise(ERR_LIB_USER, OQSPROV_R_INVALID_ENCODING); return NULL; } - buf = aType->value.sequence->data; buflen = aType->value.sequence->length; + const unsigned char *buf2 = aType->value.sequence->data; + + p8inf_internal + = d2i_PKCS8_PRIV_KEY_INFO(&p8inf_internal, &buf2, buflen); + if (!PKCS8_pkey_get0(NULL, &buf, &buflen, NULL, + p8inf_internal)) { + 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; + } + aux += buflen; memcpy(concat_key + plen - 1 - aux, buf, buflen); // if is a RSA key the actual encoding size might be different @@ -1120,6 +1138,7 @@ OQSX_KEY *oqsx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, rsa_diff = nids_sig[6].length_private_key - buflen; } OPENSSL_free(name); + PKCS8_PRIV_KEY_INFO_free(p8inf_internal); ASN1_TYPE_free(aType); } @@ -1300,8 +1319,8 @@ OQSX_KEY *oqsx_key_new(OSSL_LIB_CTX *libctx, char *oqs_name, char *tls_name, ret->numkeys = 2; ret->privkeylen = 0; ret->pubkeylen = 0; - ret->privkeylen_cmp = OPENSSL_malloc(ret->numkeys * sizeof(void *)); - ret->pubkeylen_cmp = OPENSSL_malloc(ret->numkeys * sizeof(void *)); + ret->privkeylen_cmp = OPENSSL_malloc(ret->numkeys * sizeof(size_t)); + ret->pubkeylen_cmp = OPENSSL_malloc(ret->numkeys * sizeof(size_t)); ret->comp_privkey = OPENSSL_malloc(ret->numkeys * sizeof(void *)); ret->comp_pubkey = OPENSSL_malloc(ret->numkeys * sizeof(void *)); @@ -1547,8 +1566,9 @@ static EVP_PKEY *oqsx_key_gen_evp_key(OQSX_EVP_CTX *ctx, unsigned char *pubkey, size_t pubkeylen = 0, privkeylen = 0; - if (encode) + if (encode) { // hybrid aux = SIZE_OF_UINT32; + } if (ctx->keyParam) kgctx = EVP_PKEY_CTX_new(ctx->keyParam, NULL);