mirror of
https://github.com/openssl/openssl.git
synced 2025-03-19 19:50:42 +08:00
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)
This commit is contained in:
parent
e0be34beee
commit
cf33379997
@ -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;
|
||||
int ret = 0;
|
||||
DH *dh = ossl_dh_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 (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;
|
||||
|
||||
/* 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)
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
if (dsa != NULL) {
|
||||
ret = 1;
|
||||
EVP_PKEY_assign_DSA(pkey, dsa);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
int ret = 0;
|
||||
EC_KEY *eckey = ossl_ec_key_from_pkcs8(p8, libctx, propq);
|
||||
|
||||
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;
|
||||
|
||||
/* 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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
int ret = 0;
|
||||
ECX_KEY *ecx = ossl_ecx_key_from_pkcs8(p8, libctx, propq);
|
||||
|
||||
if (!PKCS8_pkey_get0(NULL, &p, &plen, &palg, p8))
|
||||
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);
|
||||
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,
|
||||
|
@ -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 != NULL) {
|
||||
ret = 1;
|
||||
EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, rsa);
|
||||
}
|
||||
if (!rsa_param_decode(rsa, alg)) {
|
||||
RSA_free(rsa);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -16,9 +16,11 @@
|
||||
#include <string.h>
|
||||
#include <openssl/core_names.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#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
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
# include <openssl/core.h>
|
||||
# include <openssl/params.h>
|
||||
# include <openssl/dh.h>
|
||||
# include <openssl/x509.h>
|
||||
# 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);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
# include <openssl/core.h>
|
||||
# include <openssl/dsa.h>
|
||||
# include <openssl/x509.h>
|
||||
# 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);
|
||||
|
@ -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 <openssl/core.h>
|
||||
# include <openssl/ec.h>
|
||||
# include <openssl/x509.h>
|
||||
# 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);
|
||||
|
@ -20,7 +20,9 @@
|
||||
# include <openssl/core.h>
|
||||
# include <openssl/e_os2.h>
|
||||
# include <openssl/crypto.h>
|
||||
# include <openssl/x509.h>
|
||||
# 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);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
# include <openssl/core.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include <openssl/x509.h>
|
||||
# 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
|
||||
|
@ -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
|
||||
|
@ -14,7 +14,7 @@
|
||||
# include "internal/refcount.h"
|
||||
# include <openssl/asn1.h>
|
||||
# include <openssl/x509.h>
|
||||
# include "crypto/ecx.h"
|
||||
# include "crypto/types.h"
|
||||
|
||||
/* Internal X509 structures and functions: not for application use */
|
||||
|
||||
|
@ -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 (ctx->desc->d2i_key_params != NULL)
|
||||
key = ctx->desc->d2i_key_params(NULL, &derp, der_len);
|
||||
if (key == NULL && orig_selection != 0)
|
||||
goto next;
|
||||
}
|
||||
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_<TYPE>_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);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user