diff options
author | Richard Levitte <levitte@openssl.org> | 2021-03-18 10:41:53 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2021-03-19 16:46:39 +0100 |
commit | cf333799979755dd46193b49c15db0afd262c6a0 (patch) | |
tree | 77e5ab82979b1b8a9a64fcb2e0500af5361a57d0 /crypto/dh | |
parent | PROV: Add RSA-PSS specific OSSL_FUNC_KEYMGMT_LOAD function (diff) | |
download | openssl-cf333799979755dd46193b49c15db0afd262c6a0.tar.xz openssl-cf333799979755dd46193b49c15db0afd262c6a0.zip |
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 <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14314)
Diffstat (limited to 'crypto/dh')
-rw-r--r-- | crypto/dh/dh_ameth.c | 50 | ||||
-rw-r--r-- | crypto/dh/dh_backend.c | 66 |
2 files changed, 72 insertions, 44 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 <openssl/err.h> #include <openssl/core_names.h> #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 |