Skip to content

Commit

Permalink
added oid to privkey and fix keys format
Browse files Browse the repository at this point in the history
  • Loading branch information
feventura committed Feb 15, 2024
1 parent 63bb39d commit 05eaba2
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 26 deletions.
78 changes: 58 additions & 20 deletions oqsprov/oqs_encode_key2any.c
Original file line number Diff line number Diff line change
Expand Up @@ -547,16 +547,16 @@ 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));
int i;

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];
Expand All @@ -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]);
Expand All @@ -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]);
Expand Down Expand Up @@ -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 *));
Expand All @@ -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)
Expand All @@ -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) {
Expand All @@ -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);
Expand All @@ -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)
Expand All @@ -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]);

Expand All @@ -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);

Expand All @@ -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;
}

Expand Down
5 changes: 5 additions & 0 deletions oqsprov/oqs_prov.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
32 changes: 26 additions & 6 deletions oqsprov/oqsprov_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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
Expand All @@ -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);
}

Expand Down Expand Up @@ -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 *));

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 05eaba2

Please sign in to comment.