mirror of https://github.com/openssl/openssl.git
Update our EVP_PKEY_METHODs to get low level keys via public APIs
It is possible to call built-in EVP_PKEY_METHOD functions with a provided key. For example this might occur if a custom EVP_PKEY_METHOD is in use that wraps a built-in EVP_PKEY_METHOD. Therefore our EVP_PKEY_METHOD functions should not assume that we are using a legacy key. Instead we get the low level key using EVP_PKEY_get0_RSA() or other similar functions. This "does the right thing" if the key is actually provided. Reviewed-by: Paul Dale <pauli@openssl.org> Reviewed-by: Nicola Tuveri <nic.tuv@gmail.com> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/16118)
This commit is contained in:
parent
981a5b7ce3
commit
5dc6489bb6
|
|
@ -392,7 +392,7 @@ static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
|||
/* Note: if error return, pkey is freed by parent routine */
|
||||
if (ctx->pkey != NULL && !EVP_PKEY_copy_parameters(pkey, ctx->pkey))
|
||||
return 0;
|
||||
return DH_generate_key(pkey->pkey.dh);
|
||||
return DH_generate_key((DH *)EVP_PKEY_get0_DH(pkey));
|
||||
}
|
||||
|
||||
static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
||||
|
|
@ -408,7 +408,7 @@ static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
|||
ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
|
||||
return 0;
|
||||
}
|
||||
dh = ctx->pkey->pkey.dh;
|
||||
dh = (DH *)EVP_PKEY_get0_DH(ctx->pkey);
|
||||
dhpub = EVP_PKEY_get0_DH(ctx->peerkey);
|
||||
if (dhpub == NULL) {
|
||||
ERR_raise(ERR_LIB_DH, DH_R_KEYS_NOT_SET);
|
||||
|
|
|
|||
|
|
@ -81,7 +81,12 @@ static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
|||
int ret;
|
||||
unsigned int sltmp;
|
||||
DSA_PKEY_CTX *dctx = ctx->data;
|
||||
DSA *dsa = ctx->pkey->pkey.dsa;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey);
|
||||
|
||||
if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md))
|
||||
return 0;
|
||||
|
|
@ -100,7 +105,12 @@ static int pkey_dsa_verify(EVP_PKEY_CTX *ctx,
|
|||
{
|
||||
int ret;
|
||||
DSA_PKEY_CTX *dctx = ctx->data;
|
||||
DSA *dsa = ctx->pkey->pkey.dsa;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
DSA *dsa = (DSA *)EVP_PKEY_get0_DSA(ctx->pkey);
|
||||
|
||||
if (dctx->md != NULL && tbslen != (size_t)EVP_MD_get_size(dctx->md))
|
||||
return 0;
|
||||
|
|
@ -245,7 +255,7 @@ static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
|
|||
/* Note: if error return, pkey is freed by parent routine */
|
||||
if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey))
|
||||
return 0;
|
||||
return DSA_generate_key(pkey->pkey.dsa);
|
||||
return DSA_generate_key((DSA *)EVP_PKEY_get0_DSA(pkey));
|
||||
}
|
||||
|
||||
static const EVP_PKEY_METHOD dsa_pkey_meth = {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,12 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
|
|||
int ret, type;
|
||||
unsigned int sltmp;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
|
||||
const int sig_sz = ECDSA_size(ec);
|
||||
|
||||
/* ensure cast to size_t is safe */
|
||||
|
|
@ -142,7 +147,12 @@ static int pkey_ec_verify(EVP_PKEY_CTX *ctx,
|
|||
{
|
||||
int ret, type;
|
||||
EC_PKEY_CTX *dctx = ctx->data;
|
||||
EC_KEY *ec = ctx->pkey->pkey.ec;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
EC_KEY *ec = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
|
||||
|
||||
if (dctx->md)
|
||||
type = EVP_MD_get_type(dctx->md);
|
||||
|
|
@ -174,7 +184,8 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen)
|
|||
return 0;
|
||||
}
|
||||
|
||||
eckey = dctx->co_key ? dctx->co_key : ctx->pkey->pkey.ec;
|
||||
eckey = dctx->co_key ? dctx->co_key
|
||||
: (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
|
||||
|
||||
if (!key) {
|
||||
const EC_GROUP *group;
|
||||
|
|
@ -266,14 +277,23 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
|
|||
if (dctx->cofactor_mode != -1)
|
||||
return dctx->cofactor_mode;
|
||||
else {
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ctx->pkey);
|
||||
return EC_KEY_get_flags(ec_key) & EC_FLAG_COFACTOR_ECDH ? 1 : 0;
|
||||
}
|
||||
} else if (p1 < -1 || p1 > 1)
|
||||
return -2;
|
||||
dctx->cofactor_mode = p1;
|
||||
if (p1 != -1) {
|
||||
EC_KEY *ec_key = ctx->pkey->pkey.ec;
|
||||
EC_KEY *ec_key = (EC_KEY *)EVP_PKEY_get0_EC_KEY(ctx->pkey);
|
||||
|
||||
/*
|
||||
* We discarded the "const" above. This will only work if the key is
|
||||
* a "real" legacy key, and not a cached copy of a provided key
|
||||
*/
|
||||
if (evp_pkey_is_provided(ctx->pkey)) {
|
||||
ERR_raise(ERR_LIB_EC, ERR_R_UNSUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
if (!ec_key->group)
|
||||
return -2;
|
||||
/* If cofactor is 1 cofactor mode does nothing */
|
||||
|
|
|
|||
|
|
@ -732,8 +732,8 @@ static int validate_ecx_derive(EVP_PKEY_CTX *ctx, unsigned char *key,
|
|||
ERR_raise(ERR_LIB_EC, EC_R_KEYS_NOT_SET);
|
||||
return 0;
|
||||
}
|
||||
ecxkey = ctx->pkey->pkey.ecx;
|
||||
peerkey = EVP_PKEY_get0(ctx->peerkey);
|
||||
ecxkey = evp_pkey_get_legacy(ctx->pkey);
|
||||
peerkey = evp_pkey_get_legacy(ctx->peerkey);
|
||||
if (ecxkey == NULL || ecxkey->privkey == NULL) {
|
||||
ERR_raise(ERR_LIB_EC, EC_R_INVALID_PRIVATE_KEY);
|
||||
return 0;
|
||||
|
|
@ -806,7 +806,7 @@ static int pkey_ecd_digestsign25519(EVP_MD_CTX *ctx, unsigned char *sig,
|
|||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = ED25519_SIGSIZE;
|
||||
|
|
@ -828,7 +828,7 @@ static int pkey_ecd_digestsign448(EVP_MD_CTX *ctx, unsigned char *sig,
|
|||
size_t *siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
|
||||
if (sig == NULL) {
|
||||
*siglen = ED448_SIGSIZE;
|
||||
|
|
@ -850,7 +850,7 @@ static int pkey_ecd_digestverify25519(EVP_MD_CTX *ctx, const unsigned char *sig,
|
|||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
|
||||
if (siglen != ED25519_SIGSIZE)
|
||||
return 0;
|
||||
|
|
@ -863,7 +863,7 @@ static int pkey_ecd_digestverify448(EVP_MD_CTX *ctx, const unsigned char *sig,
|
|||
size_t siglen, const unsigned char *tbs,
|
||||
size_t tbslen)
|
||||
{
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
|
||||
if (siglen != ED448_SIGSIZE)
|
||||
return 0;
|
||||
|
|
@ -1177,7 +1177,7 @@ static int s390x_pkey_ecd_digestsign25519(EVP_MD_CTX *ctx,
|
|||
} ed25519;
|
||||
unsigned long long buff[512];
|
||||
} param;
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
int rc;
|
||||
|
||||
if (sig == NULL) {
|
||||
|
|
@ -1217,7 +1217,7 @@ static int s390x_pkey_ecd_digestsign448(EVP_MD_CTX *ctx,
|
|||
} ed448;
|
||||
unsigned long long buff[512];
|
||||
} param;
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
int rc;
|
||||
|
||||
if (sig == NULL) {
|
||||
|
|
@ -1260,7 +1260,7 @@ static int s390x_pkey_ecd_digestverify25519(EVP_MD_CTX *ctx,
|
|||
} ed25519;
|
||||
unsigned long long buff[512];
|
||||
} param;
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
|
||||
if (siglen != ED25519_SIGSIZE)
|
||||
return 0;
|
||||
|
|
@ -1287,7 +1287,7 @@ static int s390x_pkey_ecd_digestverify448(EVP_MD_CTX *ctx,
|
|||
} ed448;
|
||||
unsigned long long buff[512];
|
||||
} param;
|
||||
const ECX_KEY *edkey = EVP_MD_CTX_get_pkey_ctx(ctx)->pkey->pkey.ecx;
|
||||
const ECX_KEY *edkey = evp_pkey_get_legacy(EVP_MD_CTX_get_pkey_ctx(ctx)->pkey);
|
||||
|
||||
if (siglen != ED448_SIGSIZE)
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -111,7 +111,8 @@ static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk)
|
|||
{
|
||||
if (ctx->tbuf != NULL)
|
||||
return 1;
|
||||
if ((ctx->tbuf = OPENSSL_malloc(RSA_size(pk->pkey->pkey.rsa))) == NULL) {
|
||||
if ((ctx->tbuf =
|
||||
OPENSSL_malloc(RSA_size(EVP_PKEY_get0_RSA(pk->pkey)))) == NULL) {
|
||||
ERR_raise(ERR_LIB_RSA, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -135,7 +136,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
|||
{
|
||||
int ret;
|
||||
RSA_PKEY_CTX *rctx = ctx->data;
|
||||
RSA *rsa = ctx->pkey->pkey.rsa;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey);
|
||||
|
||||
if (rctx->md) {
|
||||
if (tbslen != (size_t)EVP_MD_get_size(rctx->md)) {
|
||||
|
|
@ -147,8 +153,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
|||
unsigned int sltmp;
|
||||
if (rctx->pad_mode != RSA_PKCS1_PADDING)
|
||||
return -1;
|
||||
ret = RSA_sign_ASN1_OCTET_STRING(0,
|
||||
tbs, tbslen, sig, &sltmp, rsa);
|
||||
ret = RSA_sign_ASN1_OCTET_STRING(0, tbs, tbslen, sig, &sltmp, rsa);
|
||||
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
|
@ -187,8 +192,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig,
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa,
|
||||
rctx->pad_mode);
|
||||
ret = RSA_private_encrypt(tbslen, tbs, sig, rsa, rctx->pad_mode);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -202,13 +206,18 @@ static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
|
|||
{
|
||||
int ret;
|
||||
RSA_PKEY_CTX *rctx = ctx->data;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey);
|
||||
|
||||
if (rctx->md) {
|
||||
if (rctx->pad_mode == RSA_X931_PADDING) {
|
||||
if (!setup_tbuf(rctx, ctx))
|
||||
return -1;
|
||||
ret = RSA_public_decrypt(siglen, sig,
|
||||
rctx->tbuf, ctx->pkey->pkey.rsa,
|
||||
ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, rsa,
|
||||
RSA_X931_PADDING);
|
||||
if (ret < 1)
|
||||
return 0;
|
||||
|
|
@ -227,7 +236,7 @@ static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
|
|||
size_t sltmp;
|
||||
ret = ossl_rsa_verify(EVP_MD_get_type(rctx->md),
|
||||
NULL, 0, rout, &sltmp,
|
||||
sig, siglen, ctx->pkey->pkey.rsa);
|
||||
sig, siglen, rsa);
|
||||
if (ret <= 0)
|
||||
return 0;
|
||||
ret = sltmp;
|
||||
|
|
@ -235,8 +244,7 @@ static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx,
|
|||
return -1;
|
||||
}
|
||||
} else {
|
||||
ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa,
|
||||
rctx->pad_mode);
|
||||
ret = RSA_public_decrypt(siglen, sig, rout, rsa, rctx->pad_mode);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -249,7 +257,12 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
|
|||
const unsigned char *tbs, size_t tbslen)
|
||||
{
|
||||
RSA_PKEY_CTX *rctx = ctx->data;
|
||||
RSA *rsa = ctx->pkey->pkey.rsa;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey);
|
||||
size_t rslen;
|
||||
|
||||
if (rctx->md) {
|
||||
|
|
@ -302,9 +315,15 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
|
|||
{
|
||||
int ret;
|
||||
RSA_PKEY_CTX *rctx = ctx->data;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey);
|
||||
|
||||
if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
|
||||
int klen = RSA_size(ctx->pkey->pkey.rsa);
|
||||
int klen = RSA_size(rsa);
|
||||
if (!setup_tbuf(rctx, ctx))
|
||||
return -1;
|
||||
if (!RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, klen,
|
||||
|
|
@ -313,11 +332,9 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx,
|
|||
rctx->oaep_labellen,
|
||||
rctx->md, rctx->mgf1md))
|
||||
return -1;
|
||||
ret = RSA_public_encrypt(klen, rctx->tbuf, out,
|
||||
ctx->pkey->pkey.rsa, RSA_NO_PADDING);
|
||||
ret = RSA_public_encrypt(klen, rctx->tbuf, out, rsa, RSA_NO_PADDING);
|
||||
} else {
|
||||
ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa,
|
||||
rctx->pad_mode);
|
||||
ret = RSA_public_encrypt(inlen, in, out, rsa, rctx->pad_mode);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
@ -331,12 +348,17 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
|
|||
{
|
||||
int ret;
|
||||
RSA_PKEY_CTX *rctx = ctx->data;
|
||||
/*
|
||||
* Discard const. Its marked as const because this may be a cached copy of
|
||||
* the "real" key. These calls don't make any modifications that need to
|
||||
* be reflected back in the "original" key.
|
||||
*/
|
||||
RSA *rsa = (RSA *)EVP_PKEY_get0_RSA(ctx->pkey);
|
||||
|
||||
if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
|
||||
if (!setup_tbuf(rctx, ctx))
|
||||
return -1;
|
||||
ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
|
||||
ctx->pkey->pkey.rsa, RSA_NO_PADDING);
|
||||
ret = RSA_private_decrypt(inlen, in, rctx->tbuf, rsa, RSA_NO_PADDING);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf,
|
||||
|
|
@ -345,8 +367,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
|
|||
rctx->oaep_labellen,
|
||||
rctx->md, rctx->mgf1md);
|
||||
} else {
|
||||
ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa,
|
||||
rctx->pad_mode);
|
||||
ret = RSA_private_decrypt(inlen, in, out, rsa, rctx->pad_mode);
|
||||
}
|
||||
*outlen = constant_time_select_s(constant_time_msb_s(ret), *outlen, ret);
|
||||
ret = constant_time_select_int(constant_time_msb(ret), ret, 1);
|
||||
|
|
@ -805,7 +826,7 @@ const EVP_PKEY_METHOD *ossl_rsa_pkey_method(void)
|
|||
|
||||
static int pkey_pss_init(EVP_PKEY_CTX *ctx)
|
||||
{
|
||||
RSA *rsa;
|
||||
const RSA *rsa;
|
||||
RSA_PKEY_CTX *rctx = ctx->data;
|
||||
const EVP_MD *md;
|
||||
const EVP_MD *mgf1md;
|
||||
|
|
@ -814,7 +835,7 @@ static int pkey_pss_init(EVP_PKEY_CTX *ctx)
|
|||
/* Should never happen */
|
||||
if (!pkey_ctx_is_pss(ctx))
|
||||
return 0;
|
||||
rsa = ctx->pkey->pkey.rsa;
|
||||
rsa = EVP_PKEY_get0_RSA(ctx->pkey);
|
||||
/* If no restrictions just return */
|
||||
if (rsa->pss == NULL)
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Reference in New Issue