aboutsummaryrefslogtreecommitdiff
path: root/crypto
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2021-01-27 11:07:38 +0100
committerRichard Levitte <levitte@openssl.org>2021-02-03 17:20:56 +0100
commit977e95b912138d02bae86d829a990d81c2bbcca0 (patch)
tree0e0c3e9a851c9676fc4b1fe81e111c77c74fb8a4 /crypto
parent60488d2434c5be15dc14e1fa2a8733f076d9ccf4 (diff)
downloadopenssl-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.c95
-rw-r--r--crypto/evp/pmeth_lib.c29
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;
}