summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/core_namemap.c12
-rw-r--r--crypto/evp/digest.c11
-rw-r--r--crypto/evp/evp_enc.c10
-rw-r--r--crypto/evp/evp_fetch.c65
-rw-r--r--doc/internal/man3/ossl_namemap_new.pod9
-rw-r--r--include/internal/namemap.h1
6 files changed, 102 insertions, 6 deletions
diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
index 71b70ff5aa..e5a17272d8 100644
--- a/crypto/core_namemap.c
+++ b/crypto/core_namemap.c
@@ -119,6 +119,18 @@ void ossl_namemap_free(OSSL_NAMEMAP *namemap)
OPENSSL_free(namemap);
}
+int ossl_namemap_empty(OSSL_NAMEMAP *namemap)
+{
+ int rv = 0;
+
+ CRYPTO_THREAD_read_lock(namemap->lock);
+ if (namemap->max_number == 0)
+ rv = 1;
+ CRYPTO_THREAD_unlock(namemap->lock);
+
+ return rv;
+}
+
typedef struct doall_names_data_st {
int number;
void (*fn)(const char *name, void *data);
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index bbe637e3ce..1609d2bf53 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -730,12 +730,19 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid)
{
int nid;
int *legacy_nid = vlegacy_nid;
+ /*
+ * We use lowest level function to get the associated method, because
+ * higher level functions such as EVP_get_digestbyname() have changed
+ * to look at providers too.
+ */
+ const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH);
if (*legacy_nid == -1) /* We found a clash already */
return;
- if ((nid = OBJ_sn2nid(name)) == NID_undef
- && (nid = OBJ_ln2nid(name)) == NID_undef)
+
+ if (legacy_method == NULL)
return;
+ nid = EVP_MD_nid(legacy_method);
if (*legacy_nid != NID_undef && *legacy_nid != nid) {
*legacy_nid = -1;
return;
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 45e1dc67c2..da6dde0c4d 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -1359,12 +1359,18 @@ static void set_legacy_nid(const char *name, void *vlegacy_nid)
{
int nid;
int *legacy_nid = vlegacy_nid;
+ /*
+ * We use lowest level function to get the associated method, because
+ * higher level functions such as EVP_get_cipherbyname() have changed
+ * to look at providers too.
+ */
+ const void *legacy_method = OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH);
if (*legacy_nid == -1) /* We found a clash already */
return;
- if ((nid = OBJ_sn2nid(name)) == NID_undef
- && (nid = OBJ_ln2nid(name)) == NID_undef)
+ if (legacy_method == NULL)
return;
+ nid = EVP_CIPHER_nid(legacy_method);
if (*legacy_nid != NID_undef && *legacy_nid != nid) {
*legacy_nid = -1;
return;
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;
diff --git a/doc/internal/man3/ossl_namemap_new.pod b/doc/internal/man3/ossl_namemap_new.pod
index 2bcf21386d..b66fd91957 100644
--- a/doc/internal/man3/ossl_namemap_new.pod
+++ b/doc/internal/man3/ossl_namemap_new.pod
@@ -2,7 +2,7 @@
=head1 NAME
-ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored,
+ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored, ossl_namemap_empty,
ossl_namemap_add, ossl_namemap_add_n,
ossl_namemap_name2num, ossl_namemap_name2num_n,
ossl_namemap_doall_names
@@ -16,6 +16,7 @@ ossl_namemap_doall_names
OSSL_NAMEMAP *ossl_namemap_new(void);
void ossl_namemap_free(OSSL_NAMEMAP *namemap);
+ int ossl_namemap_empty(OSSL_NAMEMAP *namemap);
int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name);
int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number,
@@ -40,6 +41,9 @@ new B<OSSL_NAMEMAP>.
This is suitable to use when the B<OSSL_NAMEMAP> is embedded in other
structures, or should be independent for any reason.
+ossl_namemap_empty() checks if the given B<OSSL_NAMEMAP> is empty or
+not.
+
ossl_namemap_stored() finds or auto-creates the default namemap in the
given library context.
The returned B<OSSL_NAMEMAP> can't be destructed using
@@ -72,6 +76,9 @@ pass extra data for that function to use.
ossl_namemap_new() and ossl_namemap_stored() return the pointer to a
B<OSSL_NAMEMAP>, or NULL on error.
+ossl_namemap_empty() returns 1 if the B<OSSL_NAMEMAP> is NULL or
+empty, or 0 if it's not empty.
+
ossl_namemap_add() and ossl_namemap_add_n() return the number associated
with the added string, or zero on error.
diff --git a/include/internal/namemap.h b/include/internal/namemap.h
index 73163a42cb..f977606ca6 100644
--- a/include/internal/namemap.h
+++ b/include/internal/namemap.h
@@ -15,6 +15,7 @@ OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx);
OSSL_NAMEMAP *ossl_namemap_new(void);
void ossl_namemap_free(OSSL_NAMEMAP *namemap);
+int ossl_namemap_empty(OSSL_NAMEMAP *namemap);
int ossl_namemap_add(OSSL_NAMEMAP *namemap, int number, const char *name);
int ossl_namemap_add_n(OSSL_NAMEMAP *namemap, int number,