From cf333799979755dd46193b49c15db0afd262c6a0 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 18 Mar 2021 10:41:53 +0100 Subject: [PATCH] PROV: Add type specific PKCS#8 decoding to the DER->key decoders This required refactoring a number of functions from the diverse EVP_PKEY_ASN1_METHOD implementations to become shared backend functions. It also meant modifying a few of them to return pointers to our internal RSA / DSA/ DH / EC_KEY, ... structures instead of manipulating an EVP_PKEY pointer directly, letting the caller do the latter. Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/14314) --- crypto/dh/dh_ameth.c | 50 +-- crypto/dh/dh_backend.c | 66 ++++ crypto/dsa/dsa_ameth.c | 63 +--- crypto/dsa/dsa_backend.c | 73 +++++ crypto/ec/ec_ameth.c | 84 +---- crypto/ec/ec_backend.c | 79 +++++ crypto/ec/ecx_backend.c | 109 +++++++ crypto/ec/ecx_meth.c | 155 +++------- crypto/rsa/rsa_ameth.c | 163 +--------- crypto/rsa/rsa_backend.c | 155 ++++++++++ crypto/rsa/rsa_lib.c | 12 + include/crypto/dh.h | 3 + include/crypto/dsa.h | 3 + include/crypto/ec.h | 7 + include/crypto/ecx.h | 16 + include/crypto/rsa.h | 10 + include/crypto/types.h | 6 + include/crypto/x509.h | 2 +- .../encode_decode/decode_der2key.c | 289 +++++++++--------- 19 files changed, 762 insertions(+), 583 deletions(-) diff --git a/crypto/dh/dh_ameth.c b/crypto/dh/dh_ameth.c index 08656877f3..ffaf41d802 100644 --- a/crypto/dh/dh_ameth.c +++ b/crypto/dh/dh_ameth.c @@ -163,53 +163,15 @@ static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) static int dh_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - const void *pval; - const ASN1_STRING *pstr; - const X509_ALGOR *palg; - ASN1_INTEGER *privkey = NULL; - DH *dh = NULL; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - if (ptype != V_ASN1_SEQUENCE) - goto decerr; - if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) - goto decerr; - - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - if ((dh = d2i_dhp(pkey, &pm, pmlen)) == NULL) - goto decerr; + int ret = 0; + DH *dh = ossl_dh_key_from_pkcs8(p8, NULL, NULL); - /* We have parameters now set private key */ - if ((dh->priv_key = BN_secure_new()) == NULL - || !ASN1_INTEGER_to_BN(privkey, dh->priv_key)) { - ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR); - goto dherr; + if (dh != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); } - /* Calculate public key, increments dirty_cnt */ - if (!DH_generate_key(dh)) - goto dherr; - - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, dh); - ASN1_STRING_clear_free(privkey); - - return 1; - - decerr: - ERR_raise(ERR_LIB_DH, EVP_R_DECODE_ERROR); - dherr: - DH_free(dh); - ASN1_STRING_clear_free(privkey); - return 0; + return ret; } static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) diff --git a/crypto/dh/dh_backend.c b/crypto/dh/dh_backend.c index c848cb4870..8da830f9d8 100644 --- a/crypto/dh/dh_backend.c +++ b/crypto/dh/dh_backend.c @@ -13,6 +13,7 @@ */ #include "internal/deprecated.h" +#include #include #include "internal/param_build_set.h" #include "crypto/dh.h" @@ -115,3 +116,68 @@ int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]) return 1; } + +#ifndef FIPS_MODULE +DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + const void *pval; + const ASN1_STRING *pstr; + const X509_ALGOR *palg; + BIGNUM *privkey_bn = NULL; + ASN1_INTEGER *privkey = NULL; + DH *dh = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) + return 0; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) + goto decerr; + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + switch (OBJ_obj2nid(palg->algorithm)) { + case NID_dhKeyAgreement: + dh = d2i_DHparams(NULL, &pm, pmlen); + break; + case NID_dhpublicnumber: + dh = d2i_DHxparams(NULL, &pm, pmlen); + break; + default: + goto decerr; + } + if (dh == NULL) + goto decerr; + + /* We have parameters now set private key */ + if ((privkey_bn = BN_secure_new()) == NULL + || !ASN1_INTEGER_to_BN(privkey, privkey_bn)) { + ERR_raise(ERR_LIB_DH, DH_R_BN_ERROR); + goto dherr; + } + if (!DH_set0_key(dh, NULL, privkey_bn)) + goto dherr; + /* Calculate public key, increments dirty_cnt */ + if (!DH_generate_key(dh)) + goto dherr; + + goto done; + + decerr: + ERR_raise(ERR_LIB_DH, EVP_R_DECODE_ERROR); + dherr: + DH_free(dh); + dh = NULL; + done: + ASN1_STRING_clear_free(privkey); + return dh; +} +#endif diff --git a/crypto/dsa/dsa_ameth.c b/crypto/dsa/dsa_ameth.c index 50ecd3ed3b..e4c739daf9 100644 --- a/crypto/dsa/dsa_ameth.c +++ b/crypto/dsa/dsa_ameth.c @@ -149,69 +149,14 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) static int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { - const unsigned char *p, *pm; - int pklen, pmlen; - int ptype; - const void *pval; - const ASN1_STRING *pstr; - const X509_ALGOR *palg; - ASN1_INTEGER *privkey = NULL; - BN_CTX *ctx = NULL; - - DSA *dsa = NULL; - int ret = 0; + DSA *dsa = ossl_dsa_key_from_pkcs8(p8, NULL, NULL); - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) - goto decerr; - if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE) - goto decerr; - - pstr = pval; - pm = pstr->data; - pmlen = pstr->length; - if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) - goto decerr; - /* We have parameters now set private key */ - if ((dsa->priv_key = BN_secure_new()) == NULL - || !ASN1_INTEGER_to_BN(privkey, dsa->priv_key)) { - ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); - goto dsaerr; - } - /* Calculate public key */ - if ((dsa->pub_key = BN_new()) == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - if ((ctx = BN_CTX_new()) == NULL) { - ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); - goto dsaerr; - } - - BN_set_flags(dsa->priv_key, BN_FLG_CONSTTIME); - if (!BN_mod_exp(dsa->pub_key, dsa->params.g, dsa->priv_key, dsa->params.p, - ctx)) { - ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); - goto dsaerr; + if (dsa != NULL) { + ret = 1; + EVP_PKEY_assign_DSA(pkey, dsa); } - dsa->dirty_cnt++; - EVP_PKEY_assign_DSA(pkey, dsa); - - ret = 1; - goto done; - - decerr: - ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); - dsaerr: - DSA_free(dsa); - done: - BN_CTX_free(ctx); - ASN1_STRING_clear_free(privkey); return ret; } diff --git a/crypto/dsa/dsa_backend.c b/crypto/dsa/dsa_backend.c index e6f8f3645e..f3e54aeb13 100644 --- a/crypto/dsa/dsa_backend.c +++ b/crypto/dsa/dsa_backend.c @@ -14,6 +14,7 @@ #include "internal/deprecated.h" #include +#include #include "crypto/dsa.h" /* @@ -54,3 +55,75 @@ int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[]) BN_free(pub_key); return 0; } + +#ifndef FIPS_MODULE +DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + const void *pval; + const ASN1_STRING *pstr; + const X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + const BIGNUM *dsa_p, *dsa_g; + BIGNUM *dsa_pubkey = NULL, *dsa_privkey = NULL; + BN_CTX *ctx = NULL; + + DSA *dsa = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if ((privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) + goto decerr; + if (privkey->type == V_ASN1_NEG_INTEGER || ptype != V_ASN1_SEQUENCE) + goto decerr; + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) + goto decerr; + /* We have parameters now set private key */ + if ((dsa_privkey = BN_secure_new()) == NULL + || !ASN1_INTEGER_to_BN(privkey, dsa_privkey)) { + ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); + goto dsaerr; + } + /* Calculate public key */ + if ((dsa_pubkey = BN_new()) == NULL) { + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + if ((ctx = BN_CTX_new()) == NULL) { + ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + + dsa_p = DSA_get0_p(dsa); + dsa_g = DSA_get0_g(dsa); + BN_set_flags(dsa_privkey, BN_FLG_CONSTTIME); + if (!BN_mod_exp(dsa_pubkey, dsa_g, dsa_privkey, dsa_p, ctx)) { + ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); + goto dsaerr; + } + DSA_set0_key(dsa, dsa_pubkey, dsa_privkey); + + goto done; + + decerr: + ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); + dsaerr: + BN_free(dsa_privkey); + BN_free(dsa_pubkey); + DSA_free(dsa); + dsa = NULL; + done: + BN_CTX_free(ctx); + ASN1_STRING_clear_free(privkey); + return dsa; +} +#endif diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c index d447fa4d1c..69370d6bc1 100644 --- a/crypto/ec/ec_ameth.c +++ b/crypto/ec/ec_ameth.c @@ -100,59 +100,10 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) return 0; } -static EC_KEY *eckey_type2param(int ptype, const void *pval, - OSSL_LIB_CTX *libctx, const char *propq) -{ - EC_KEY *eckey = NULL; - EC_GROUP *group = NULL; - - if ((eckey = EC_KEY_new_ex(libctx, propq)) == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); - goto ecerr; - } - - if (ptype == V_ASN1_SEQUENCE) { - const ASN1_STRING *pstr = pval; - const unsigned char *pm = pstr->data; - int pmlen = pstr->length; - - - if (d2i_ECParameters(&eckey, &pm, pmlen) == NULL) { - ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); - goto ecerr; - } - } else if (ptype == V_ASN1_OBJECT) { - const ASN1_OBJECT *poid = pval; - - /* - * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID - */ - - group = EC_GROUP_new_by_curve_name_ex(libctx, propq, OBJ_obj2nid(poid)); - if (group == NULL) - goto ecerr; - EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); - if (EC_KEY_set_group(eckey, group) == 0) - goto ecerr; - EC_GROUP_free(group); - } else { - ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); - goto ecerr; - } - - return eckey; - - ecerr: - EC_KEY_free(eckey); - EC_GROUP_free(group); - return NULL; -} - static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) { const unsigned char *p = NULL; - const void *pval; - int ptype, pklen; + int pklen; EC_KEY *eckey = NULL; X509_ALGOR *palg; OSSL_LIB_CTX *libctx = NULL; @@ -161,9 +112,7 @@ static int eckey_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) if (!ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey) || !X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - eckey = eckey_type2param(ptype, pval, libctx, propq); + eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq); if (!eckey) return 0; @@ -202,32 +151,15 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) static int eckey_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, const char *propq) { - const unsigned char *p = NULL; - const void *pval; - int ptype, pklen; - EC_KEY *eckey = NULL; - const X509_ALGOR *palg; - - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) - return 0; - X509_ALGOR_get0(NULL, &ptype, &pval, palg); - - eckey = eckey_type2param(ptype, pval, libctx, propq); - if (eckey == NULL) - goto err; + int ret = 0; + EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq); - /* We have parameters now set private key */ - if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { - ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); - goto err; + if (eckey != NULL) { + ret = 1; + EVP_PKEY_assign_EC_KEY(pkey, eckey); } - EVP_PKEY_assign_EC_KEY(pkey, eckey); - return 1; - - err: - EC_KEY_free(eckey); - return 0; + return ret; } static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c index c4a5a81fda..9716ffc2f2 100644 --- a/crypto/ec/ec_backend.c +++ b/crypto/ec/ec_backend.c @@ -570,3 +570,82 @@ int ossl_ec_pt_format_param2id(const OSSL_PARAM *p, int *id) } return 0; } + +#ifndef FIPS_MODULE +EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + int ptype = 0; + const void *pval = NULL; + EC_KEY *eckey = NULL; + EC_GROUP *group = NULL; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + if ((eckey = EC_KEY_new_ex(libctx, propq)) == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto ecerr; + } + + if (ptype == V_ASN1_SEQUENCE) { + const ASN1_STRING *pstr = pval; + const unsigned char *pm = pstr->data; + int pmlen = pstr->length; + + + if (d2i_ECParameters(&eckey, &pm, pmlen) == NULL) { + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); + goto ecerr; + } + } else if (ptype == V_ASN1_OBJECT) { + const ASN1_OBJECT *poid = pval; + + /* + * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID + */ + + group = EC_GROUP_new_by_curve_name_ex(libctx, propq, OBJ_obj2nid(poid)); + if (group == NULL) + goto ecerr; + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(eckey, group) == 0) + goto ecerr; + EC_GROUP_free(group); + } else { + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); + goto ecerr; + } + + return eckey; + + ecerr: + EC_KEY_free(eckey); + EC_GROUP_free(group); + return NULL; +} + +EC_KEY *ossl_ec_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p = NULL; + int pklen; + EC_KEY *eckey = NULL; + const X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8inf)) + return 0; + eckey = ossl_ec_key_param_from_x509_algor(palg, libctx, propq); + if (eckey == NULL) + goto err; + + /* We have parameters now set private key */ + if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { + ERR_raise(ERR_LIB_EC, EC_R_DECODE_ERROR); + goto err; + } + + return eckey; + err: + EC_KEY_free(eckey); + return NULL; +} +#endif diff --git a/crypto/ec/ecx_backend.c b/crypto/ec/ecx_backend.c index 17dd507c35..8f8fdc7705 100644 --- a/crypto/ec/ecx_backend.c +++ b/crypto/ec/ecx_backend.c @@ -7,9 +7,11 @@ * https://www.openssl.org/source/license.html */ +#include #include #include #include +#include #include #include "crypto/ecx.h" #include "ecx_backend.h" @@ -90,3 +92,110 @@ int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], return 1; } +#ifndef FIPS_MODULE +ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg, + const unsigned char *p, int plen, + int id, ecx_key_op_t op, + OSSL_LIB_CTX *libctx, const char *propq) +{ + ECX_KEY *key = NULL; + unsigned char *privkey, *pubkey; + + if (op != KEY_OP_KEYGEN) { + if (palg != NULL) { + int ptype; + + /* Algorithm parameters must be absent */ + X509_ALGOR_get0(NULL, &ptype, NULL, palg); + if (ptype != V_ASN1_UNDEF) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + if (id == EVP_PKEY_NONE) + id = OBJ_obj2nid(palg->algorithm); + else if (id != OBJ_obj2nid(palg->algorithm)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + } + + if (p == NULL || id == EVP_PKEY_NONE || plen != KEYLENID(id)) { + ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); + return 0; + } + } + + key = ossl_ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq); + if (key == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + return 0; + } + pubkey = key->pubkey; + + if (op == KEY_OP_PUBLIC) { + memcpy(pubkey, p, plen); + } else { + privkey = ossl_ecx_key_allocate_privkey(key); + if (privkey == NULL) { + ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); + goto err; + } + if (op == KEY_OP_KEYGEN) { + if (id != EVP_PKEY_NONE) { + if (RAND_priv_bytes_ex(libctx, privkey, KEYLENID(id)) <= 0) + goto err; + if (id == EVP_PKEY_X25519) { + privkey[0] &= 248; + privkey[X25519_KEYLEN - 1] &= 127; + privkey[X25519_KEYLEN - 1] |= 64; + } else if (id == EVP_PKEY_X448) { + privkey[0] &= 252; + privkey[X448_KEYLEN - 1] |= 128; + } + } + } else { + memcpy(privkey, p, KEYLENID(id)); + } + if (!ossl_ecx_public_from_private(key)) { + ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY); + goto err; + } + } + + return key; + err: + ossl_ecx_key_free(key); + return NULL; +} + +ECX_KEY *ossl_ecx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + ECX_KEY *ecx = NULL; + const unsigned char *p; + int plen; + ASN1_OCTET_STRING *oct = NULL; + const X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8inf)) + return 0; + + oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); + if (oct == NULL) { + p = NULL; + plen = 0; + } else { + p = ASN1_STRING_get0_data(oct); + plen = ASN1_STRING_length(oct); + } + + /* + * EVP_PKEY_NONE means that ecx_key_op() has to figure out the key type + * on its own. + */ + ecx = ossl_ecx_key_op(palg, p, plen, EVP_PKEY_NONE, KEY_OP_PRIVATE, + libctx, propq); + ASN1_OCTET_STRING_free(oct); + return ecx; +} +#endif diff --git a/crypto/ec/ecx_meth.c b/crypto/ec/ecx_meth.c index 68f943fc82..d476af0e3c 100644 --- a/crypto/ec/ecx_meth.c +++ b/crypto/ec/ecx_meth.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include "internal/cryptlib.h" @@ -28,80 +27,6 @@ #include "curve448/curve448_local.h" #include "ecx_backend.h" -typedef enum { - KEY_OP_PUBLIC, - KEY_OP_PRIVATE, - KEY_OP_KEYGEN -} ecx_key_op_t; - -/* Setup EVP_PKEY using public, private or generation */ -static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg, - const unsigned char *p, int plen, ecx_key_op_t op, - OSSL_LIB_CTX *libctx, const char *propq) -{ - ECX_KEY *key = NULL; - unsigned char *privkey, *pubkey; - - if (op != KEY_OP_KEYGEN) { - if (palg != NULL) { - int ptype; - - /* Algorithm parameters must be absent */ - X509_ALGOR_get0(NULL, &ptype, NULL, palg); - if (ptype != V_ASN1_UNDEF) { - ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); - return 0; - } - } - - if (p == NULL || plen != KEYLENID(id)) { - ERR_raise(ERR_LIB_EC, EC_R_INVALID_ENCODING); - return 0; - } - } - - key = ossl_ecx_key_new(libctx, KEYNID2TYPE(id), 1, propq); - if (key == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); - return 0; - } - pubkey = key->pubkey; - - if (op == KEY_OP_PUBLIC) { - memcpy(pubkey, p, plen); - } else { - privkey = ossl_ecx_key_allocate_privkey(key); - if (privkey == NULL) { - ERR_raise(ERR_LIB_EC, ERR_R_MALLOC_FAILURE); - goto err; - } - if (op == KEY_OP_KEYGEN) { - if (RAND_priv_bytes_ex(libctx, privkey, KEYLENID(id)) <= 0) - goto err; - if (id == EVP_PKEY_X25519) { - privkey[0] &= 248; - privkey[X25519_KEYLEN - 1] &= 127; - privkey[X25519_KEYLEN - 1] |= 64; - } else if (id == EVP_PKEY_X448) { - privkey[0] &= 252; - privkey[X448_KEYLEN - 1] |= 128; - } - } else { - memcpy(privkey, p, KEYLENID(id)); - } - if (!ossl_ecx_public_from_private(key)) { - ERR_raise(ERR_LIB_EC, EC_R_FAILED_MAKING_PUBLIC_KEY); - goto err; - } - } - - EVP_PKEY_assign(pkey, id, key); - return 1; - err: - ossl_ecx_key_free(key); - return 0; -} - static int ecx_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { const ECX_KEY *ecxkey = pkey->pkey.ecx; @@ -132,11 +57,18 @@ static int ecx_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) const unsigned char *p; int pklen; X509_ALGOR *palg; + ECX_KEY *ecx; + int ret = 0; if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) return 0; - return ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, pklen, - KEY_OP_PUBLIC, NULL, NULL); + ecx = ossl_ecx_key_op(palg, p, pklen, pkey->ameth->pkey_id, + KEY_OP_PUBLIC, NULL, NULL); + if (ecx != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + } + return ret; } static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) @@ -153,28 +85,15 @@ static int ecx_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) static int ecx_priv_decode_ex(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8, OSSL_LIB_CTX *libctx, const char *propq) { - const unsigned char *p; - int plen; - ASN1_OCTET_STRING *oct = NULL; - const X509_ALGOR *palg; - int rv; - - if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8)) - return 0; + int ret = 0; + ECX_KEY *ecx = ossl_ecx_key_from_pkcs8(p8, libctx, propq); - oct = d2i_ASN1_OCTET_STRING(NULL, &p, plen); - if (oct == NULL) { - p = NULL; - plen = 0; - } else { - p = ASN1_STRING_get0_data(oct); - plen = ASN1_STRING_length(oct); + if (ecx != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); } - rv = ecx_key_op(pkey, pkey->ameth->pkey_id, palg, p, plen, KEY_OP_PRIVATE, - libctx, propq); - ASN1_STRING_clear_free(oct); - return rv; + return ret; } static int ecx_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) @@ -298,10 +217,16 @@ static int ecx_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) { switch (op) { - case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: - return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, arg2, arg1, - KEY_OP_PUBLIC, NULL, NULL); + case ASN1_PKEY_CTRL_SET1_TLS_ENCPT: { + ECX_KEY *ecx = ossl_ecx_key_op(NULL, arg2, arg1, pkey->ameth->pkey_id, + KEY_OP_PUBLIC, NULL, NULL); + if (ecx != NULL) { + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + return 1; + } + return 0; + } case ASN1_PKEY_CTRL_GET1_TLS_ENCPT: if (pkey->pkey.ecx != NULL) { unsigned char **ppt = arg2; @@ -336,23 +261,37 @@ static int ecx_set_priv_key(EVP_PKEY *pkey, const unsigned char *priv, size_t len) { OSSL_LIB_CTX *libctx = NULL; + ECX_KEY *ecx = NULL; if (pkey->keymgmt != NULL) libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt)); - return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, priv, len, - KEY_OP_PRIVATE, libctx, NULL); + ecx = ossl_ecx_key_op(NULL, priv, len, pkey->ameth->pkey_id, + KEY_OP_PRIVATE, libctx, NULL); + + if (ecx != NULL) { + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + return 1; + } + return 0; } static int ecx_set_pub_key(EVP_PKEY *pkey, const unsigned char *pub, size_t len) { OSSL_LIB_CTX *libctx = NULL; + ECX_KEY *ecx = NULL; if (pkey->keymgmt != NULL) libctx = ossl_provider_libctx(EVP_KEYMGMT_provider(pkey->keymgmt)); - return ecx_key_op(pkey, pkey->ameth->pkey_id, NULL, pub, len, - KEY_OP_PUBLIC, libctx, NULL); + ecx = ossl_ecx_key_op(NULL, pub, len, pkey->ameth->pkey_id, + KEY_OP_PUBLIC, libctx, NULL); + + if (ecx != NULL) { + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, ecx); + return 1; + } + return 0; } static int ecx_get_priv_key(const EVP_PKEY *pkey, unsigned char *priv, @@ -750,8 +689,14 @@ const EVP_PKEY_ASN1_METHOD ossl_ed448_asn1_meth = { static int pkey_ecx_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { - return ecx_key_op(pkey, ctx->pmeth->pkey_id, NULL, NULL, 0, KEY_OP_KEYGEN, - NULL, NULL); + ECX_KEY *ecx = ossl_ecx_key_op(NULL, NULL, 0, ctx->pmeth->pkey_id, + KEY_OP_PUBLIC, NULL, NULL); + + if (ecx != NULL) { + EVP_PKEY_assign(pkey, ctx->pmeth->pkey_id, ecx); + return 1; + } + return 0; } static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key, diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c index 9e9366757d..067b7db12d 100644 --- a/crypto/rsa/rsa_ameth.c +++ b/crypto/rsa/rsa_ameth.c @@ -25,9 +25,6 @@ #include "crypto/rsa.h" #include "rsa_local.h" -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg); -static int rsa_sync_to_pss_params_30(RSA *rsa); - /* Set any parameters associated with pkey */ static int rsa_param_encode(const EVP_PKEY *pkey, ASN1_STRING **pstr, int *pstrtype) @@ -53,29 +50,6 @@ static int rsa_param_encode(const EVP_PKEY *pkey, return 1; } /* Decode any parameters and set them in RSA structure */ -static int rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) -{ - const ASN1_OBJECT *algoid; - const void *algp; - int algptype; - - X509_ALGOR_get0(&algoid, &algptype, &algp, alg); - if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) - return 1; - if (algptype == V_ASN1_UNDEF) - return 1; - if (algptype != V_ASN1_SEQUENCE) { - ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS); - return 0; - } - rsa->pss = rsa_pss_decode(alg); - if (rsa->pss == NULL) - return 0; - if (!rsa_sync_to_pss_params_30(rsa)) - return 0; - return 1; -} - static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { unsigned char *penc = NULL; @@ -107,7 +81,7 @@ static int rsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) return 0; if ((rsa = d2i_RSAPublicKey(NULL, &p, pklen)) == NULL) return 0; - if (!rsa_param_decode(rsa, alg)) { + if (!ossl_rsa_param_decode(rsa, alg)) { RSA_free(rsa); return 0; } @@ -194,38 +168,14 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) static int rsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) { - const unsigned char *p; - RSA *rsa; - int pklen; - const X509_ALGOR *alg; + int ret = 0; + RSA *rsa = ossl_rsa_key_from_pkcs8(p8, NULL, NULL); - if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8)) - return 0; - rsa = d2i_RSAPrivateKey(NULL, &p, pklen); - if (rsa == NULL) { - ERR_raise(ERR_LIB_RSA, ERR_R_RSA_LIB); - return 0; - } - if (!rsa_param_decode(rsa, alg)) { - RSA_free(rsa); - return 0; + if (rsa != NULL) { + ret = 1; + EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); } - - RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); - switch (pkey->ameth->pkey_id) { - case EVP_PKEY_RSA: - RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA); - break; - case EVP_PKEY_RSA_PSS: - RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS); - break; - default: - /* Leave the type bits zero */ - break; - } - - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa); - return 1; + return ret; } static int int_rsa_size(const EVP_PKEY *pkey) @@ -444,33 +394,12 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, return pkey_rsa_print(bp, pkey, indent, 1); } -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) -{ - RSA_PSS_PARAMS *pss; - - pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS), - alg->parameter); - - if (pss == NULL) - return NULL; - - if (pss->maskGenAlgorithm != NULL) { - pss->maskHash = ossl_x509_algor_mgf1_decode(pss->maskGenAlgorithm); - if (pss->maskHash == NULL) { - RSA_PSS_PARAMS_free(pss); - return NULL; - } - } - - return pss; -} - static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { if (OBJ_obj2nid(sigalg->algorithm) == EVP_PKEY_RSA_PSS) { int rv; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); + RSA_PSS_PARAMS *pss = ossl_rsa_pss_decode(sigalg); rv = rsa_pss_param_print(bp, 0, pss, indent); RSA_PSS_PARAMS_free(pss); @@ -601,7 +530,7 @@ int ossl_rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx, return -1; } /* Decode PSS parameters */ - pss = rsa_pss_decode(sigalg); + pss = ossl_rsa_pss_decode(sigalg); if (!ossl_rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) { ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS); @@ -656,36 +585,6 @@ static int rsa_pss_verify_param(const EVP_MD **pmd, const EVP_MD **pmgf1md, return 1; } -static int rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, - const EVP_MD **pmd, - const EVP_MD **pmgf1md, - int *psaltlen, int *ptrailerField) -{ - RSA_PSS_PARAMS_30 pss_params; - - /* Get the defaults from the ONE place */ - (void)ossl_rsa_pss_params_30_set_defaults(&pss_params); - - if (pss == NULL) - return 0; - *pmd = ossl_x509_algor_get_md(pss->hashAlgorithm); - if (*pmd == NULL) - return 0; - *pmgf1md = ossl_x509_algor_get_md(pss->maskHash); - if (*pmgf1md == NULL) - return 0; - if (pss->saltLength) - *psaltlen = ASN1_INTEGER_get(pss->saltLength); - else - *psaltlen = ossl_rsa_pss_params_30_saltlen(&pss_params); - if (pss->trailerField) - *ptrailerField = ASN1_INTEGER_get(pss->trailerField); - else - *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params);; - - return 1; -} - int ossl_rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, const EVP_MD **pmgf1md, int *psaltlen) { @@ -699,45 +598,11 @@ int ossl_rsa_pss_get_param(const RSA_PSS_PARAMS *pss, const EVP_MD **pmd, */ int trailerField = 0; - return rsa_pss_get_param_unverified(pss, pmd, pmgf1md, psaltlen, - &trailerField) + return ossl_rsa_pss_get_param_unverified(pss, pmd, pmgf1md, psaltlen, + &trailerField) && rsa_pss_verify_param(pmd, pmgf1md, psaltlen, &trailerField); } -static int rsa_sync_to_pss_params_30(RSA *rsa) -{ - if (rsa != NULL && rsa->pss != NULL) { - const EVP_MD *md = NULL, *mgf1md = NULL; - int md_nid, mgf1md_nid, saltlen, trailerField; - RSA_PSS_PARAMS_30 pss_params; - - /* - * We don't care about the validity of the fields here, we just - * want to synchronise values. Verifying here makes it impossible - * to even read a key with invalid values, making it hard to test - * a bad situation. - * - * Other routines use ossl_rsa_pss_get_param(), so the values will be - * checked, eventually. - */ - if (!rsa_pss_get_param_unverified(rsa->pss, &md, &mgf1md, - &saltlen, &trailerField)) - return 0; - md_nid = EVP_MD_type(md); - mgf1md_nid = EVP_MD_type(mgf1md); - if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) - || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) - || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, - mgf1md_nid) - || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) - || !ossl_rsa_pss_params_30_set_trailerfield(&pss_params, - trailerField)) - return 0; - rsa->pss_params = pss_params; - } - return 1; -} - /* * Customised RSA item verification routine. This is called when a signature * is encountered requiring special handling. We currently only handle PSS. @@ -806,7 +671,7 @@ static int rsa_sig_info_set(X509_SIG_INFO *siginf, const X509_ALGOR *sigalg, if (OBJ_obj2nid(sigalg->algorithm) != EVP_PKEY_RSA_PSS) return 0; /* Decode PSS parameters */ - pss = rsa_pss_decode(sigalg); + pss = ossl_rsa_pss_decode(sigalg); if (!ossl_rsa_pss_get_param(pss, &md, &mgf1md, &saltlen)) goto err; mdnid = EVP_MD_type(md); @@ -894,8 +759,8 @@ static int rsa_int_export_to(const EVP_PKEY *from, int rsa_type, int md_nid, mgf1md_nid, saltlen, trailerfield; RSA_PSS_PARAMS_30 pss_params; - if (!rsa_pss_get_param_unverified(rsa->pss, &md, &mgf1md, - &saltlen, &trailerfield)) + if (!ossl_rsa_pss_get_param_unverified(rsa->pss, &md, &mgf1md, + &saltlen, &trailerfield)) goto err; md_nid = EVP_MD_type(md); mgf1md_nid = EVP_MD_type(mgf1md); diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c index 8c16a56db5..01ee875058 100644 --- a/crypto/rsa/rsa_backend.c +++ b/crypto/rsa/rsa_backend.c @@ -16,9 +16,11 @@ #include #include #include +#include #include #include "internal/sizes.h" #include "internal/param_build_set.h" +#include "crypto/asn1.h" #include "crypto/rsa.h" #include "e_os.h" /* strcasecmp for Windows() */ @@ -319,3 +321,156 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, EVP_MD_free(mgf1md); return ret; } + +#ifndef FIPS_MODULE +RSA_PSS_PARAMS *ossl_rsa_pss_decode(const X509_ALGOR *alg) +{ + RSA_PSS_PARAMS *pss; + + pss = ASN1_TYPE_unpack_sequence(ASN1_ITEM_rptr(RSA_PSS_PARAMS), + alg->parameter); + + if (pss == NULL) + return NULL; + + if (pss->maskGenAlgorithm != NULL) { + pss->maskHash = ossl_x509_algor_mgf1_decode(pss->maskGenAlgorithm); + if (pss->maskHash == NULL) { + RSA_PSS_PARAMS_free(pss); + return NULL; + } + } + + return pss; +} + +static int ossl_rsa_sync_to_pss_params_30(RSA *rsa) +{ + const RSA_PSS_PARAMS *legacy_pss = NULL; + RSA_PSS_PARAMS_30 *pss = NULL; + + if (rsa != NULL + && (legacy_pss = RSA_get0_pss_params(rsa)) != NULL + && (pss = ossl_rsa_get0_pss_params_30(rsa)) != NULL) { + const EVP_MD *md = NULL, *mgf1md = NULL; + int md_nid, mgf1md_nid, saltlen, trailerField; + RSA_PSS_PARAMS_30 pss_params; + + /* + * We don't care about the validity of the fields here, we just + * want to synchronise values. Verifying here makes it impossible + * to even read a key with invalid values, making it hard to test + * a bad situation. + * + * Other routines use ossl_rsa_pss_get_param(), so the values will + * be checked, eventually. + */ + if (!ossl_rsa_pss_get_param_unverified(legacy_pss, &md, &mgf1md, + &saltlen, &trailerField)) + return 0; + md_nid = EVP_MD_type(md); + mgf1md_nid = EVP_MD_type(mgf1md); + if (!ossl_rsa_pss_params_30_set_defaults(&pss_params) + || !ossl_rsa_pss_params_30_set_hashalg(&pss_params, md_nid) + || !ossl_rsa_pss_params_30_set_maskgenhashalg(&pss_params, + mgf1md_nid) + || !ossl_rsa_pss_params_30_set_saltlen(&pss_params, saltlen) + || !ossl_rsa_pss_params_30_set_trailerfield(&pss_params, + trailerField)) + return 0; + *pss = pss_params; + } + return 1; +} + +int ossl_rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, + const EVP_MD **pmd, const EVP_MD **pmgf1md, + int *psaltlen, int *ptrailerField) +{ + RSA_PSS_PARAMS_30 pss_params; + + /* Get the defaults from the ONE place */ + (void)ossl_rsa_pss_params_30_set_defaults(&pss_params); + + if (pss == NULL) + return 0; + *pmd = ossl_x509_algor_get_md(pss->hashAlgorithm); + if (*pmd == NULL) + return 0; + *pmgf1md = ossl_x509_algor_get_md(pss->maskHash); + if (*pmgf1md == NULL) + return 0; + if (pss->saltLength) + *psaltlen = ASN1_INTEGER_get(pss->saltLength); + else + *psaltlen = ossl_rsa_pss_params_30_saltlen(&pss_params); + if (pss->trailerField) + *ptrailerField = ASN1_INTEGER_get(pss->trailerField); + else + *ptrailerField = ossl_rsa_pss_params_30_trailerfield(&pss_params);; + + return 1; +} + +int ossl_rsa_param_decode(RSA *rsa, const X509_ALGOR *alg) +{ + RSA_PSS_PARAMS *pss; + const ASN1_OBJECT *algoid; + const void *algp; + int algptype; + + X509_ALGOR_get0(&algoid, &algptype, &algp, alg); + if (OBJ_obj2nid(algoid) != EVP_PKEY_RSA_PSS) + return 1; + if (algptype == V_ASN1_UNDEF) + return 1; + if (algptype != V_ASN1_SEQUENCE) { + ERR_raise(ERR_LIB_RSA, RSA_R_INVALID_PSS_PARAMETERS); + return 0; + } + if ((pss = ossl_rsa_pss_decode(alg)) == NULL + || !ossl_rsa_set0_pss_params(rsa, pss)) { + RSA_PSS_PARAMS_free(pss); + return 0; + } + if (!ossl_rsa_sync_to_pss_params_30(rsa)) + return 0; + return 1; +} + +RSA *ossl_rsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *p; + RSA *rsa; + int pklen; + const X509_ALGOR *alg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &alg, p8inf)) + return 0; + rsa = d2i_RSAPrivateKey(NULL, &p, pklen); + if (rsa == NULL) { + ERR_raise(ERR_LIB_RSA, ERR_R_RSA_LIB); + return NULL; + } + if (!ossl_rsa_param_decode(rsa, alg)) { + RSA_free(rsa); + return NULL; + } + + RSA_clear_flags(rsa, RSA_FLAG_TYPE_MASK); + switch (OBJ_obj2nid(alg->algorithm)) { + case EVP_PKEY_RSA: + RSA_set_flags(rsa, RSA_FLAG_TYPE_RSA); + break; + case EVP_PKEY_RSA_PSS: + RSA_set_flags(rsa, RSA_FLAG_TYPE_RSASSAPSS); + break; + default: + /* Leave the type bits zero */ + break; + } + + return rsa; +} +#endif diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 89cd4da527..bfd274a66a 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -657,6 +657,18 @@ const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *r) #endif } +/* Internal */ +int ossl_rsa_set0_pss_params(RSA *r, RSA_PSS_PARAMS *pss) +{ +#ifdef FIPS_MODULE + return 0; +#else + RSA_PSS_PARAMS_free(r->pss); + r->pss = pss; + return 1; +#endif +} + /* Internal */ RSA_PSS_PARAMS_30 *ossl_rsa_get0_pss_params_30(RSA *r) { diff --git a/include/crypto/dh.h b/include/crypto/dh.h index d8b597a0f1..b16ac8f42f 100644 --- a/include/crypto/dh.h +++ b/include/crypto/dh.h @@ -14,6 +14,7 @@ # include # include # include +# include # include "internal/ffc.h" DH *ossl_dh_new_by_nid_ex(OSSL_LIB_CTX *libctx, int nid); @@ -35,6 +36,8 @@ int ossl_dh_params_fromdata(DH *dh, const OSSL_PARAM params[]); int ossl_dh_key_fromdata(DH *dh, const OSSL_PARAM params[]); int ossl_dh_params_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); int ossl_dh_key_todata(DH *dh, OSSL_PARAM_BLD *bld, OSSL_PARAM params[]); +DH *ossl_dh_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); int ossl_dh_check_pub_key_partial(const DH *dh, const BIGNUM *pub_key, int *ret); int ossl_dh_check_priv_key(const DH *dh, const BIGNUM *priv_key, int *ret); diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h index 0c15c51da0..38c49c3295 100644 --- a/include/crypto/dsa.h +++ b/include/crypto/dsa.h @@ -13,6 +13,7 @@ # include # include +# include # include "internal/ffc.h" #define DSA_PARAMGEN_TYPE_FIPS_186_4 0 /* Use FIPS186-4 standard */ @@ -31,6 +32,8 @@ int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, FFC_PARAMS *ossl_dsa_get0_params(DSA *dsa); int ossl_dsa_ffc_params_fromdata(DSA *dsa, const OSSL_PARAM params[]); int ossl_dsa_key_fromdata(DSA *dsa, const OSSL_PARAM params[]); +DSA *ossl_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); int ossl_dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, const BIGNUM *priv_key, BIGNUM *pub_key); diff --git a/include/crypto/ec.h b/include/crypto/ec.h index a3d87e9d1a..c679fd8d11 100644 --- a/include/crypto/ec.h +++ b/include/crypto/ec.h @@ -25,6 +25,7 @@ int evp_pkey_ctx_set_ec_param_enc_prov(EVP_PKEY_CTX *ctx, int param_enc); # ifndef OPENSSL_NO_EC # include # include +# include # include "crypto/types.h" /*- @@ -78,6 +79,12 @@ int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[]); int ossl_ec_key_fromdata(EC_KEY *ecx, const OSSL_PARAM params[], int include_private); int ossl_ec_key_otherparams_fromdata(EC_KEY *ec, const OSSL_PARAM params[]); +EC_KEY *ossl_ec_key_param_from_x509_algor(const X509_ALGOR *palg, + OSSL_LIB_CTX *libctx, + const char *propq); +EC_KEY *ossl_ec_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); + int ossl_ec_set_ecdh_cofactor_mode(EC_KEY *ec, int mode); int ossl_ec_encoding_name2id(const char *name); int ossl_ec_encoding_param2id(const OSSL_PARAM *p, int *id); diff --git a/include/crypto/ecx.h b/include/crypto/ecx.h index 101a5748e8..dfc70fb4e6 100644 --- a/include/crypto/ecx.h +++ b/include/crypto/ecx.h @@ -20,7 +20,9 @@ # include # include # include +# include # include "internal/refcount.h" +# include "crypto/types.h" # define X25519_KEYLEN 32 # define X448_KEYLEN 56 @@ -76,6 +78,7 @@ struct ecx_key_st { typedef struct ecx_key_st ECX_KEY; +size_t ossl_ecx_key_length(ECX_KEY_TYPE type); ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, const char *propq); void ossl_ecx_key_set0_libctx(ECX_KEY *key, OSSL_LIB_CTX *libctx); @@ -124,9 +127,22 @@ ossl_x448_public_from_private(uint8_t out_public_value[56], /* Backend support */ +typedef enum { + KEY_OP_PUBLIC, + KEY_OP_PRIVATE, + KEY_OP_KEYGEN +} ecx_key_op_t; + +ECX_KEY *ossl_ecx_key_op(const X509_ALGOR *palg, + const unsigned char *p, int plen, + int pkey_id, ecx_key_op_t op, + OSSL_LIB_CTX *libctx, const char *propq); + int ossl_ecx_public_from_private(ECX_KEY *key); int ossl_ecx_key_fromdata(ECX_KEY *ecx, const OSSL_PARAM params[], int include_private); +ECX_KEY *ossl_ecx_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); ECX_KEY *ossl_evp_pkey_get1_X25519(EVP_PKEY *pkey); ECX_KEY *ossl_evp_pkey_get1_X448(EVP_PKEY *pkey); diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h index 7fca88dfe4..69fa8a4d8a 100644 --- a/include/crypto/rsa.h +++ b/include/crypto/rsa.h @@ -13,6 +13,7 @@ # include # include +# include # include "crypto/types.h" typedef struct rsa_pss_params_30_st { @@ -69,6 +70,14 @@ int ossl_rsa_pss_params_30_fromdata(RSA_PSS_PARAMS_30 *pss_params, int *defaults_set, const OSSL_PARAM params[], OSSL_LIB_CTX *libctx); +int ossl_rsa_set0_pss_params(RSA *r, RSA_PSS_PARAMS *pss); +int ossl_rsa_pss_get_param_unverified(const RSA_PSS_PARAMS *pss, + const EVP_MD **pmd, const EVP_MD **pmgf1md, + int *psaltlen, int *ptrailerField); +RSA_PSS_PARAMS *ossl_rsa_pss_decode(const X509_ALGOR *alg); +int ossl_rsa_param_decode(RSA *rsa, const X509_ALGOR *alg); +RSA *ossl_rsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); int ossl_rsa_padding_check_PKCS1_type_2_TLS(OSSL_LIB_CTX *ctx, unsigned char *to, size_t tlen, @@ -113,4 +122,5 @@ void ossl_rsa_acvp_test_free(RSA_ACVP_TEST *t); # define RSA_ACVP_TEST void # endif +RSA *evp_pkey_get1_RSA_PSS(EVP_PKEY *pkey); #endif diff --git a/include/crypto/types.h b/include/crypto/types.h index 275d1d36c1..13a5f9ce1d 100644 --- a/include/crypto/types.h +++ b/include/crypto/types.h @@ -12,6 +12,12 @@ #ifdef OPENSSL_NO_DEPRECATED_3_0 typedef struct rsa_st RSA; typedef struct rsa_meth_st RSA_METHOD; +# ifndef OPENSSL_NO_EC typedef struct ec_key_st EC_KEY; typedef struct ec_key_method_st EC_KEY_METHOD; +# endif +#endif + +#ifndef OPENSSL_NO_EC +typedef struct ecx_key_st ECX_KEY; #endif diff --git a/include/crypto/x509.h b/include/crypto/x509.h index e0997a4712..98aea5f1fd 100644 --- a/include/crypto/x509.h +++ b/include/crypto/x509.h @@ -14,7 +14,7 @@ # include "internal/refcount.h" # include # include -# include "crypto/ecx.h" +# include "crypto/types.h" /* Internal X509 structures and functions: not for application use */ diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index 74f462794a..f50fca3896 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -56,68 +56,13 @@ SET_ERR_MARK(); \ } while(0) -static int read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin, - unsigned char **data, long *len) -{ - BUF_MEM *mem = NULL; - BIO *in = ossl_bio_new_from_core_bio(provctx, cin); - int ok = (asn1_d2i_read_bio(in, &mem) >= 0); - - if (ok) { - *data = (unsigned char *)mem->data; - *len = (long)mem->length; - OPENSSL_free(mem); - } - BIO_free(in); - return ok; -} - -static int der_from_p8(unsigned char **new_der, long *new_der_len, - unsigned char *input_der, long input_der_len, - OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) -{ - const unsigned char *derp; - X509_SIG *p8 = NULL; - int ok = 0; - - if (!ossl_assert(new_der != NULL && *new_der == NULL) - || !ossl_assert(new_der_len != NULL)) - return 0; - - derp = input_der; - if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) { - char pbuf[PEM_BUFSIZE]; - size_t plen = 0; - - if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) { - ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE); - } else { - const X509_ALGOR *alg = NULL; - const ASN1_OCTET_STRING *oct = NULL; - int len = 0; - - X509_SIG_get0(p8, &alg, &oct); - if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length, - new_der, &len, 0) != NULL) - ok = 1; - *new_der_len = len; - } - } - X509_SIG_free(p8); - return ok; -} - -/* ---------------------------------------------------------------------- */ - -static OSSL_FUNC_decoder_freectx_fn der2key_freectx; -static OSSL_FUNC_decoder_decode_fn der2key_decode; -static OSSL_FUNC_decoder_export_object_fn der2key_export_object; - struct der2key_ctx_st; /* Forward declaration */ -typedef void *extract_key_fn(EVP_PKEY *); typedef int check_key_fn(void *, struct der2key_ctx_st *ctx); typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx); typedef void free_key_fn(void *); +typedef void *d2i_PKCS8_fn(void **, const unsigned char **, long, + struct der2key_ctx_st *, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg); struct keytype_desc_st { const char *keytype_name; const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */ @@ -140,13 +85,9 @@ struct keytype_desc_st { d2i_of_void *d2i_private_key; /* From type-specific DER */ d2i_of_void *d2i_public_key; /* From type-specific DER */ d2i_of_void *d2i_key_params; /* From type-specific DER */ + d2i_PKCS8_fn *d2i_PKCS8; /* Wrapped in a PKCS#8, possibly encrypted */ d2i_of_void *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */ - /* - * For PKCS#8 decoders, we use EVP_PKEY extractors, EVP_PKEY_get1_{TYPE}() - */ - extract_key_fn *extract_key; - /* * For any key, we may need to check that the key meets expectations. * This is useful when the same functions can decode several variants @@ -169,8 +110,67 @@ struct keytype_desc_st { struct der2key_ctx_st { PROV_CTX *provctx; const struct keytype_desc_st *desc; + /* Flag used to signal that a failure is fatal */ + unsigned int flag_fatal : 1; }; +static int read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin, + unsigned char **data, long *len) +{ + BUF_MEM *mem = NULL; + BIO *in = ossl_bio_new_from_core_bio(provctx, cin); + int ok = (asn1_d2i_read_bio(in, &mem) >= 0); + + if (ok) { + *data = (unsigned char *)mem->data; + *len = (long)mem->length; + OPENSSL_free(mem); + } + BIO_free(in); + return ok; +} + +typedef void *key_from_pkcs8_t(const PKCS8_PRIV_KEY_INFO *p8inf, + OSSL_LIB_CTX *libctx, const char *propq); +static void *der2key_decode_p8(const unsigned char **input_der, + long input_der_len, struct der2key_ctx_st *ctx, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg, + key_from_pkcs8_t *key_from_pkcs8) +{ + X509_SIG *p8 = NULL; + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + const X509_ALGOR *alg = NULL; + void *key = NULL; + + ctx->flag_fatal = 0; + if ((p8 = d2i_X509_SIG(NULL, input_der, input_der_len)) != NULL) { + char pbuf[PEM_BUFSIZE]; + size_t plen = 0; + + if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) + ERR_raise(ERR_LIB_PROV, PROV_R_UNABLE_TO_GET_PASSPHRASE); + else + p8inf = PKCS8_decrypt(p8, pbuf, plen); + if (p8inf == NULL) + ctx->flag_fatal = 1; + X509_SIG_free(p8); + } else { + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, input_der, input_der_len); + } + if (p8inf != NULL + && PKCS8_pkey_get0(NULL, NULL, NULL, &alg, p8inf) + && OBJ_obj2nid(alg->algorithm) == ctx->desc->evp_type) + key = key_from_pkcs8(p8inf, PROV_LIBCTX_OF(ctx->provctx), NULL); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return key; +} + +/* ---------------------------------------------------------------------- */ + +static OSSL_FUNC_decoder_freectx_fn der2key_freectx; +static OSSL_FUNC_decoder_decode_fn der2key_decode; +static OSSL_FUNC_decoder_export_object_fn der2key_export_object; + static struct der2key_ctx_st * der2key_newctx(void *provctx, const struct keytype_desc_st *desc) { @@ -262,13 +262,9 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { struct der2key_ctx_st *ctx = vctx; - void *libctx = PROV_LIBCTX_OF(ctx->provctx); unsigned char *der = NULL; const unsigned char *derp; long der_len = 0; - unsigned char *new_der = NULL; - long new_der_len; - EVP_PKEY *pkey = NULL; void *key = NULL; int orig_selection = selection; int ok = 0; @@ -292,18 +288,21 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, if (!read_der(ctx->provctx, cin, &der, &der_len)) goto next; - /* We try the typs specific functions first, if available */ - if (ctx->desc->d2i_private_key != NULL - && (selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { + if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { RESET_ERR_MARK(); derp = der; - key = ctx->desc->d2i_private_key(NULL, &derp, der_len); + if (ctx->desc->d2i_PKCS8 != NULL) { + key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx, + pw_cb, pw_cbarg); + if (ctx->flag_fatal) + goto end; + } else if (ctx->desc->d2i_private_key != NULL) { + key = ctx->desc->d2i_private_key(NULL, &derp, der_len); + } if (key == NULL && orig_selection != 0) goto next; } - if (key == NULL - && (ctx->desc->d2i_PUBKEY != NULL || ctx->desc->d2i_public_key != NULL) - && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { + if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { RESET_ERR_MARK(); derp = der; if (ctx->desc->d2i_PUBKEY != NULL) @@ -313,71 +312,15 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, if (key == NULL && orig_selection != 0) goto next; } - if (key == NULL - && ctx->desc->d2i_key_params != NULL - && (selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) { + if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_ALL_PARAMETERS) != 0) { RESET_ERR_MARK(); derp = der; - key = ctx->desc->d2i_key_params(NULL, &derp, der_len); - } - if (key == NULL - && ctx->desc->extract_key != NULL) { - /* - * There is a EVP_PKEY extractor, so we use the more generic - * EVP_PKEY functions, since they know how to unpack PKCS#8 and - * SubjectPublicKeyInfo. - */ - - if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { - /* - * Opportunistic attempt to decrypt. If it doesn't work, we try - * to decode our input unencrypted. - */ - if (der_from_p8(&new_der, &new_der_len, der, der_len, - pw_cb, pw_cbarg)) { - OPENSSL_free(der); - der = new_der; - der_len = new_der_len; - } - RESET_ERR_MARK(); - - derp = der; - pkey = evp_privatekey_from_binary(ctx->desc->evp_type, NULL, - &derp, der_len, libctx, NULL); - } - - /* - * As long as we have algos without a specific d2i__PUBKEY, - * this code must remain... - */ - if (pkey == NULL - && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { - RESET_ERR_MARK(); - derp = der; - pkey = ossl_d2i_PUBKEY_legacy(NULL, &derp, der_len); - } - - if (pkey != NULL) { - /* - * Tear out the low-level key pointer from the pkey, - * but only if it matches the expected key type. - * - * The check should be done with EVP_PKEY_is_a(), but - * as long as we still have #legacy internal keys, it's safer - * to use the type numbers inside the provider. - */ - if (EVP_PKEY_id(pkey) == ctx->desc->evp_type) - key = ctx->desc->extract_key(pkey); - - /* - * ctx->desc->extract_key() is expected to have incremented - * |key|'s reference count, so it should be safe to free |pkey| - * now. - */ - EVP_PKEY_free(pkey); - } + if (ctx->desc->d2i_key_params != NULL) + key = ctx->desc->d2i_key_params(NULL, &derp, der_len); + if (key == NULL && orig_selection != 0) + goto next; } - + RESET_ERR_MARK(); if (key != NULL && ctx->desc->check_key != NULL && !ctx->desc->check_key(key, ctx)) { @@ -453,10 +396,18 @@ static int der2key_export_object(void *vctx, #ifndef OPENSSL_NO_DH # define dh_evp_type EVP_PKEY_DH -# define dh_evp_extract (extract_key_fn *)EVP_PKEY_get1_DH # define dh_d2i_private_key NULL # define dh_d2i_public_key NULL # define dh_d2i_key_params (d2i_of_void *)d2i_DHparams + +static void *dh_d2i_PKCS8(void **key, const unsigned char **der, long der_len, + struct der2key_ctx_st *ctx, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg, + (key_from_pkcs8_t *)ossl_dh_key_from_pkcs8); +} + # define dh_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DH_PUBKEY # define dh_free (free_key_fn *)DH_free # define dh_check NULL @@ -467,10 +418,10 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx) } # define dhx_evp_type EVP_PKEY_DHX -# define dhx_evp_extract (extract_key_fn *)EVP_PKEY_get1_DH # define dhx_d2i_private_key NULL # define dhx_d2i_public_key NULL # define dhx_d2i_key_params (d2i_of_void *)d2i_DHxparams +# define dhx_d2i_PKCS8 dh_d2i_PKCS8 # define dhx_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DHx_PUBKEY # define dhx_free (free_key_fn *)DH_free # define dhx_check NULL @@ -481,10 +432,18 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx) #ifndef OPENSSL_NO_DSA # define dsa_evp_type EVP_PKEY_DSA -# define dsa_evp_extract (extract_key_fn *)EVP_PKEY_get1_DSA # define dsa_d2i_private_key (d2i_of_void *)d2i_DSAPrivateKey # define dsa_d2i_public_key (d2i_of_void *)d2i_DSAPublicKey # define dsa_d2i_key_params (d2i_of_void *)d2i_DSAparams + +static void *dsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len, + struct der2key_ctx_st *ctx, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg, + (key_from_pkcs8_t *)ossl_dsa_key_from_pkcs8); +} + # define dsa_d2i_PUBKEY (d2i_of_void *)d2i_DSA_PUBKEY # define dsa_free (free_key_fn *)DSA_free # define dsa_check NULL @@ -499,10 +458,18 @@ static void dsa_adjust(void *key, struct der2key_ctx_st *ctx) #ifndef OPENSSL_NO_EC # define ec_evp_type EVP_PKEY_EC -# define ec_evp_extract (extract_key_fn *)EVP_PKEY_get1_EC_KEY # define ec_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey # define ec_d2i_public_key NULL # define ec_d2i_key_params (d2i_of_void *)d2i_ECParameters + +static void *ec_d2i_PKCS8(void **key, const unsigned char **der, long der_len, + struct der2key_ctx_st *ctx, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg, + (key_from_pkcs8_t *)ossl_ec_key_from_pkcs8); +} + # define ec_d2i_PUBKEY (d2i_of_void *)d2i_EC_PUBKEY # define ec_free (free_key_fn *)EC_KEY_free @@ -525,46 +492,54 @@ static void ec_adjust(void *key, struct der2key_ctx_st *ctx) * so no d2i functions to be had. */ +static void *ecx_d2i_PKCS8(void **key, const unsigned char **der, long der_len, + struct der2key_ctx_st *ctx, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg, + (key_from_pkcs8_t *)ossl_ecx_key_from_pkcs8); +} + static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) { ossl_ecx_key_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx)); } # define ed25519_evp_type EVP_PKEY_ED25519 -# define ed25519_evp_extract (extract_key_fn *)ossl_evp_pkey_get1_ED25519 # define ed25519_d2i_private_key NULL # define ed25519_d2i_public_key NULL # define ed25519_d2i_key_params NULL +# define ed25519_d2i_PKCS8 ecx_d2i_PKCS8 # define ed25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED25519_PUBKEY # define ed25519_free (free_key_fn *)ossl_ecx_key_free # define ed25519_check NULL # define ed25519_adjust ecx_key_adjust # define ed448_evp_type EVP_PKEY_ED448 -# define ed448_evp_extract (extract_key_fn *)ossl_evp_pkey_get1_ED448 # define ed448_d2i_private_key NULL # define ed448_d2i_public_key NULL # define ed448_d2i_key_params NULL +# define ed448_d2i_PKCS8 ecx_d2i_PKCS8 # define ed448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED448_PUBKEY # define ed448_free (free_key_fn *)ossl_ecx_key_free # define ed448_check NULL # define ed448_adjust ecx_key_adjust # define x25519_evp_type EVP_PKEY_X25519 -# define x25519_evp_extract (extract_key_fn *)ossl_evp_pkey_get1_X25519 # define x25519_d2i_private_key NULL # define x25519_d2i_public_key NULL # define x25519_d2i_key_params NULL +# define x25519_d2i_PKCS8 ecx_d2i_PKCS8 # define x25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X25519_PUBKEY # define x25519_free (free_key_fn *)ossl_ecx_key_free # define x25519_check NULL # define x25519_adjust ecx_key_adjust # define x448_evp_type EVP_PKEY_X448 -# define x448_evp_extract (extract_key_fn *)ossl_evp_pkey_get1_X448 # define x448_d2i_private_key NULL # define x448_d2i_public_key NULL # define x448_d2i_key_params NULL +# define x448_d2i_PKCS8 ecx_d2i_PKCS8 # define x448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X448_PUBKEY # define x448_free (free_key_fn *)ossl_ecx_key_free # define x448_check NULL @@ -572,10 +547,18 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) # ifndef OPENSSL_NO_SM2 # define sm2_evp_type EVP_PKEY_SM2 -# define sm2_evp_extract (extract_key_fn *)EVP_PKEY_get1_EC_KEY # define sm2_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey # define sm2_d2i_public_key NULL # define sm2_d2i_key_params (d2i_of_void *)d2i_ECParameters + +static void *sm2_d2i_PKCS8(void **key, const unsigned char **der, long der_len, + struct der2key_ctx_st *ctx, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg, + (key_from_pkcs8_t *)ossl_ec_key_from_pkcs8); +} + # define sm2_d2i_PUBKEY (d2i_of_void *)d2i_EC_PUBKEY # define sm2_free (free_key_fn *)EC_KEY_free # define sm2_check ec_check @@ -586,10 +569,18 @@ static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) /* ---------------------------------------------------------------------- */ #define rsa_evp_type EVP_PKEY_RSA -#define rsa_evp_extract (extract_key_fn *)EVP_PKEY_get1_RSA #define rsa_d2i_private_key (d2i_of_void *)d2i_RSAPrivateKey #define rsa_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey #define rsa_d2i_key_params NULL + +static void *rsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len, + struct der2key_ctx_st *ctx, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) +{ + return der2key_decode_p8(der, der_len, ctx, pw_cb, pw_cbarg, + (key_from_pkcs8_t *)ossl_rsa_key_from_pkcs8); +} + #define rsa_d2i_PUBKEY (d2i_of_void *)d2i_RSA_PUBKEY #define rsa_free (free_key_fn *)RSA_free @@ -612,10 +603,10 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) } #define rsapss_evp_type EVP_PKEY_RSA_PSS -#define rsapss_evp_extract (extract_key_fn *)EVP_PKEY_get1_RSA #define rsapss_d2i_private_key (d2i_of_void *)d2i_RSAPrivateKey #define rsapss_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey #define rsapss_d2i_key_params NULL +#define rsapss_d2i_PKCS8 rsa_d2i_PKCS8 #define rsapss_d2i_PUBKEY (d2i_of_void *)d2i_RSA_PUBKEY #define rsapss_free (free_key_fn *)RSA_free #define rsapss_check rsa_check @@ -706,8 +697,8 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ NULL, \ NULL, \ + keytype##_d2i_PKCS8, \ NULL, \ - keytype##_evp_extract, \ keytype##_check, \ keytype##_adjust, \ keytype##_free @@ -718,8 +709,8 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) NULL, \ NULL, \ NULL, \ + NULL, \ keytype##_d2i_PUBKEY, \ - keytype##_evp_extract, \ keytype##_check, \ keytype##_adjust, \ keytype##_free -- 2.39.2