From 05aed12f54de44df586d8912172b4ec05a8af855 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 16 Mar 2021 05:40:50 +0100 Subject: [PATCH] CORE: pre-populate the namemap with legacy OIDs too This also pre-populates the namemap with names derived from the internal EVP_PKEY_ASN1_METHODs. This requires attention, as they contain aliases that we may want (RSA == rsaEncryption), as well as aliases that we absolutely do not want (SM2 == EC). Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/14498) --- crypto/core_namemap.c | 59 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c index 89c92bdd92..daf22c3af2 100644 --- a/crypto/core_namemap.c +++ b/crypto/core_namemap.c @@ -12,6 +12,7 @@ #include #include "crypto/lhash.h" /* ossl_lh_strcasehash */ #include "internal/tsan_assist.h" +#include "internal/sizes.h" /*- * The namenum entry @@ -379,7 +380,7 @@ int ossl_namemap_add_names(OSSL_NAMEMAP *namemap, int number, /* Creates an initial namemap with names found in the legacy method db */ static void get_legacy_evp_names(const char *name, const char *desc, - void *arg) + const ASN1_OBJECT *obj, void *arg) { int num = ossl_namemap_add_name(arg, 0, name); @@ -401,6 +402,13 @@ static void get_legacy_evp_names(const char *name, const char *desc, if (desc != NULL) { (void)ossl_namemap_add_name(arg, num, desc); } + + if (obj != NULL) { + char txtoid[OSSL_MAX_NAME_SIZE]; + + if (OBJ_obj2txt(txtoid, sizeof(txtoid), obj, 1)) + (void)ossl_namemap_add_name(arg, num, txtoid); + } } static void get_legacy_cipher_names(const OBJ_NAME *on, void *arg) @@ -408,7 +416,8 @@ static void get_legacy_cipher_names(const OBJ_NAME *on, void *arg) const EVP_CIPHER *cipher = (void *)OBJ_NAME_get(on->name, on->type); int nid = EVP_CIPHER_type(cipher); - get_legacy_evp_names(OBJ_nid2sn(nid), OBJ_nid2ln(nid), arg); + get_legacy_evp_names(OBJ_nid2sn(nid), OBJ_nid2ln(nid), OBJ_nid2obj(nid), + arg); } static void get_legacy_md_names(const OBJ_NAME *on, void *arg) @@ -416,7 +425,45 @@ static void get_legacy_md_names(const OBJ_NAME *on, void *arg) const EVP_MD *md = (void *)OBJ_NAME_get(on->name, on->type); int nid = EVP_MD_type(md); - get_legacy_evp_names(OBJ_nid2sn(nid), OBJ_nid2ln(nid), arg); + get_legacy_evp_names(OBJ_nid2sn(nid), OBJ_nid2ln(nid), OBJ_nid2obj(nid), + arg); +} + +static void get_legacy_pkey_meth_names(const EVP_PKEY_ASN1_METHOD *ameth, + void *arg) +{ + int nid = 0, base_nid = 0, flags = 0; + + EVP_PKEY_asn1_get0_info(&nid, &base_nid, &flags, NULL, NULL, ameth); + if (nid != NID_undef) { + if ((flags & ASN1_PKEY_ALIAS) == 0) { + get_legacy_evp_names(OBJ_nid2sn(nid), OBJ_nid2ln(nid), + OBJ_nid2obj(nid), arg); + } else { + /* + * Treat aliases carefully, some of them are undesirable, or + * should not be treated as such for providers. + */ + + switch (nid) { + case EVP_PKEY_SM2: + case EVP_PKEY_DHX: + /* + * SM2 is a separate keytype with providers, not an alias for + * EC. + * DHX is a separate keytype with providers, not an alias for + * DH. + */ + get_legacy_evp_names(OBJ_nid2sn(nid), OBJ_nid2ln(nid), + OBJ_nid2obj(nid), arg); + break; + default: + /* Use the short name of the base nid as the common reference */ + get_legacy_evp_names(OBJ_nid2sn(base_nid), OBJ_nid2ln(nid), + OBJ_nid2obj(nid), arg); + } + } + } } #endif @@ -447,6 +494,8 @@ OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx) return NULL; } if (nms == 1) { + int i, end; + /* Before pilfering, we make sure the legacy database is populated */ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL); @@ -455,6 +504,10 @@ OSSL_NAMEMAP *ossl_namemap_stored(OSSL_LIB_CTX *libctx) get_legacy_cipher_names, namemap); OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, get_legacy_md_names, namemap); + + /* We also pilfer data from the legacy EVP_PKEY_ASN1_METHODs */ + for (i = 0, end = EVP_PKEY_asn1_get_count(); i < end; i++) + get_legacy_pkey_meth_names(EVP_PKEY_asn1_get0(i), namemap); } #endif -- 2.39.5