summaryrefslogtreecommitdiffstats
path: root/crypto/evp/evp_fetch.c
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-05-23 03:27:37 +0200
committerRichard Levitte <levitte@openssl.org>2019-11-20 14:22:35 +0100
commit6a835fcfb10ba004498f9e39873db3d2b9011609 (patch)
tree5188724c2854ee6bb4997ef21a4810f6393fdd9f /crypto/evp/evp_fetch.c
parent9ce91035bcf7d74fe15c94650f3bc1f89b7c0f07 (diff)
Replumbing: pre-populate the EVP namemap with commonly known names
This adds ossl_namemap_empty(), to detect if a namemap is empty and can thereby be pre-populated. This also affects the way legacy NIDs are looked up in evp_cipher_from_dispatch() and evp_md_from_dispatch(). Instead of trying to find the NID directly, look up the legacy method structure and grab the NID from there. The reason is that NIDs can be aliases for other NIDs, which looks like a clash even if wasn't really one. Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/8984)
Diffstat (limited to 'crypto/evp/evp_fetch.c')
-rw-r--r--crypto/evp/evp_fetch.c65
1 files changed, 64 insertions, 1 deletions
diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c
index 24a748c716..69ca6a0300 100644
--- a/crypto/evp/evp_fetch.c
+++ b/crypto/evp/evp_fetch.c
@@ -115,6 +115,69 @@ static int add_names_to_namemap(OSSL_NAMEMAP *namemap,
return id;
}
+#ifndef FIPS_MODE
+/* Creates an initial namemap with names found in the legacy method db */
+static void get_legacy_evp_names(const char *main_name, const char *alias,
+ void *arg)
+{
+ int main_id = ossl_namemap_add(arg, 0, main_name);
+
+ /*
+ * We could check that the returned value is the same as main_id,
+ * but since this is a void function, there's no sane way to report
+ * the error. The best we can do is trust ourselve to keep the legacy
+ * method database conflict free.
+ *
+ * This registers any alias with the same number as the main name.
+ * Should it be that the current |on| *has* the main name, this is
+ * simply a no-op.
+ */
+ if (alias != NULL)
+ (void)ossl_namemap_add(arg, main_id, alias);
+}
+
+static void get_legacy_cipher_names(const OBJ_NAME *on, void *arg)
+{
+ const EVP_CIPHER *cipher = (void *)OBJ_NAME_get(on->name, on->type);
+
+ get_legacy_evp_names(EVP_CIPHER_name(cipher), on->name, arg);
+}
+
+static void get_legacy_md_names(const OBJ_NAME *on, void *arg)
+{
+ const EVP_MD *md = (void *)OBJ_NAME_get(on->name, on->type);
+ /* We don't want the pkey_type names, so we need some extra care */
+ int snid, lnid;
+
+ snid = OBJ_sn2nid(on->name);
+ lnid = OBJ_ln2nid(on->name);
+ if (snid != EVP_MD_pkey_type(md) && lnid != EVP_MD_pkey_type(md))
+ get_legacy_evp_names(EVP_MD_name(md), on->name, arg);
+ else
+ get_legacy_evp_names(EVP_MD_name(md), NULL, arg);
+}
+#endif
+
+static OSSL_NAMEMAP *get_prepopulated_namemap(OPENSSL_CTX *libctx)
+{
+ OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+
+#ifndef FIPS_MODE
+ if (namemap != NULL && ossl_namemap_empty(namemap)) {
+ /* Before pilfering, we make sure the legacy database is populated */
+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
+ |OPENSSL_INIT_ADD_ALL_DIGESTS, NULL);
+
+ OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH,
+ get_legacy_cipher_names, namemap);
+ OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH,
+ get_legacy_md_names, namemap);
+ }
+#endif
+
+ return namemap;
+}
+
/*
* Generic routines to fetch / create EVP methods with ossl_method_construct()
*/
@@ -270,7 +333,7 @@ inner_evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
void (*free_method)(void *))
{
OSSL_METHOD_STORE *store = get_evp_method_store(libctx);
- OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+ OSSL_NAMEMAP *namemap = get_prepopulated_namemap(libctx);
uint32_t meth_id = 0;
void *method = NULL;