diff options
author | Richard Levitte <levitte@openssl.org> | 2021-01-27 11:07:38 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2021-02-03 17:20:56 +0100 |
commit | 977e95b912138d02bae86d829a990d81c2bbcca0 (patch) | |
tree | 0e0c3e9a851c9676fc4b1fe81e111c77c74fb8a4 /crypto | |
parent | 60488d2434c5be15dc14e1fa2a8733f076d9ccf4 (diff) | |
download | openssl-977e95b912138d02bae86d829a990d81c2bbcca0.zip openssl-977e95b912138d02bae86d829a990d81c2bbcca0.tar.gz openssl-977e95b912138d02bae86d829a990d81c2bbcca0.tar.bz2 |
EVP: Fix evp_pkey_ctx_store_cached_data() to handle provider backed EVP_PKEY_CTX
It assumed there would always be a non-NULL ctx->pmeth, leading to a
crash when that isn't the case. Since it needs to check 'keytype'
when that one isn't -1, we also add a corresponding check for the
provider backed EVP_PKEY_CTX case.
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/13973)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/evp/p_lib.c | 95 | ||||
-rw-r--r-- | crypto/evp/pmeth_lib.c | 29 |
2 files changed, 77 insertions, 47 deletions
diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index 21ce51d..558f378 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -906,53 +906,58 @@ int EVP_PKEY_base_id(const EVP_PKEY *pkey) } #ifndef FIPS_MODULE +/* + * These hard coded cases are pure hackery to get around the fact + * that names in crypto/objects/objects.txt are a mess. There is + * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's + * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1, + * the NID of which is used for EVP_PKEY_RSA. Strangely enough, + * "DSA" is accurate... but still, better be safe and hard-code + * names that we know. + * On a similar topic, EVP_PKEY_type(EVP_PKEY_SM2) will result in + * EVP_PKEY_EC, because of aliasing. + * TODO Clean this away along with all other #legacy support. + */ +static const OSSL_ITEM standard_name2type[] = { + { EVP_PKEY_RSA, "RSA" }, + { EVP_PKEY_RSA_PSS, "RSA-PSS" }, + { EVP_PKEY_EC, "EC" }, + { EVP_PKEY_ED25519, "ED25519" }, + { EVP_PKEY_ED448, "ED448" }, + { EVP_PKEY_X25519, "X25519" }, + { EVP_PKEY_X448, "X448" }, + { EVP_PKEY_SM2, "SM2" }, + { EVP_PKEY_DH, "DH" }, + { EVP_PKEY_DHX, "X9.42 DH" }, + { EVP_PKEY_DHX, "DHX" }, + { EVP_PKEY_DSA, "DSA" }, +}; + int evp_pkey_name2type(const char *name) { - /* - * These hard coded cases are pure hackery to get around the fact - * that names in crypto/objects/objects.txt are a mess. There is - * no "EC", and "RSA" leads to the NID for 2.5.8.1.1, an OID that's - * fallen out in favor of { pkcs-1 1 }, i.e. 1.2.840.113549.1.1.1, - * the NID of which is used for EVP_PKEY_RSA. Strangely enough, - * "DSA" is accurate... but still, better be safe and hard-code - * names that we know. - * On a similar topic, EVP_PKEY_type(EVP_PKEY_SM2) will result in - * EVP_PKEY_EC, because of aliasing. - * TODO Clean this away along with all other #legacy support. - */ - int type = NID_undef; - - if (strcasecmp(name, "RSA") == 0) - type = EVP_PKEY_RSA; - else if (strcasecmp(name, "RSA-PSS") == 0) - type = EVP_PKEY_RSA_PSS; - else if (strcasecmp(name, "EC") == 0) - type = EVP_PKEY_EC; - else if (strcasecmp(name, "ED25519") == 0) - type = EVP_PKEY_ED25519; - else if (strcasecmp(name, "ED448") == 0) - type = EVP_PKEY_ED448; - else if (strcasecmp(name, "X25519") == 0) - type = EVP_PKEY_X25519; - else if (strcasecmp(name, "X448") == 0) - type = EVP_PKEY_X448; - else if (strcasecmp(name, "SM2") == 0) - type = EVP_PKEY_SM2; - else if (strcasecmp(name, "DH") == 0) - type = EVP_PKEY_DH; - else if (strcasecmp(name, "X9.42 DH") == 0) - type = EVP_PKEY_DHX; - else if (strcasecmp(name, "DHX") == 0) - type = EVP_PKEY_DHX; - else if (strcasecmp(name, "DSA") == 0) - type = EVP_PKEY_DSA; - - if (type == NID_undef) - type = EVP_PKEY_type(OBJ_sn2nid(name)); - if (type == NID_undef) - type = EVP_PKEY_type(OBJ_ln2nid(name)); - - return type; + int type; + size_t i; + + for (i = 0; i < OSSL_NELEM(standard_name2type); i++) { + if (strcasecmp(name, standard_name2type[i].ptr) == 0) + return (int)standard_name2type[i].id; + } + + if ((type = EVP_PKEY_type(OBJ_sn2nid(name))) != NID_undef) + return type; + return EVP_PKEY_type(OBJ_ln2nid(name)); +} + +const char *evp_pkey_type2name(int type) +{ + size_t i; + + for (i = 0; i < OSSL_NELEM(standard_name2type); i++) { + if (type == (int)standard_name2type[i].id) + return standard_name2type[i].ptr; + } + + return OBJ_nid2sn(type); } #endif diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index bc58ea3..91d892e 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -1684,8 +1684,33 @@ static int evp_pkey_ctx_store_cached_data(EVP_PKEY_CTX *ctx, int cmd, const char *name, const void *data, size_t data_len) { - if ((keytype != -1 && ctx->pmeth->pkey_id != keytype) - || ((optype != -1) && !(ctx->operation & optype))) { + if (keytype != -1) { + switch (evp_pkey_ctx_state(ctx)) { + case EVP_PKEY_STATE_PROVIDER: + if (ctx->keymgmt == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!EVP_KEYMGMT_is_a(ctx->keymgmt, + evp_pkey_type2name(keytype))) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return -1; + } + break; + case EVP_PKEY_STATE_UNKNOWN: + case EVP_PKEY_STATE_LEGACY: + if (ctx->pmeth == NULL) { + ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (ctx->pmeth->pkey_id != keytype) { + ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); + return -1; + } + break; + } + } + if (optype != -1 && (ctx->operation & optype) == 0) { ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_OPERATION); return -1; } |