summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2021-03-18 10:41:53 +0100
committerRichard Levitte <levitte@openssl.org>2021-03-19 16:46:39 +0100
commitcf333799979755dd46193b49c15db0afd262c6a0 (patch)
tree77e5ab82979b1b8a9a64fcb2e0500af5361a57d0
parente0be34beee9ef8ebab49c51581f796e013600b77 (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)
-rw-r--r--crypto/dh/dh_ameth.c50
-rw-r--r--crypto/dh/dh_backend.c66
-rw-r--r--crypto/dsa/dsa_ameth.c63
-rw-r--r--crypto/dsa/dsa_backend.c73
-rw-r--r--crypto/ec/ec_ameth.c84
-rw-r--r--crypto/ec/ec_backend.c79
-rw-r--r--crypto/ec/ecx_backend.c109
-rw-r--r--crypto/ec/ecx_meth.c155
-rw-r--r--crypto/rsa/rsa_ameth.c163
-rw-r--r--crypto/rsa/rsa_backend.c155
-rw-r--r--crypto/rsa/rsa_lib.c12
-rw-r--r--include/crypto/dh.h3
-rw-r--r--include/crypto/dsa.h3
-rw-r--r--include/crypto/ec.h7
-rw-r--r--include/crypto/ecx.h16
-rw-r--r--include/crypto/rsa.h10
-rw-r--r--include/crypto/types.h6
-rw-r--r--include/crypto/x509.h2
-rw-r--r--providers/implementations/encode_decode/decode_der2key.c289
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 <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
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
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 <string.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include <openssl/ec.h>
+#include <openssl/rand.h>
#include <openssl/err.h>
#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 <stdio.h>
#include <openssl/x509.h>
#include <openssl/ec.h>
-#include <openssl/rand.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#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);