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/dsa | |
parent | e0be34beee9ef8ebab49c51581f796e013600b77 (diff) |
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/dsa')
-rw-r--r-- | crypto/dsa/dsa_ameth.c | 63 | ||||
-rw-r--r-- | crypto/dsa/dsa_backend.c | 73 |
2 files changed, 77 insertions, 59 deletions
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 <openssl/core_names.h> +#include <openssl/err.h> #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 |