diff options
-rw-r--r-- | crypto/core_namemap.c | 12 | ||||
-rw-r--r-- | crypto/evp/digest.c | 11 | ||||
-rw-r--r-- | crypto/evp/evp_enc.c | 10 | ||||
-rw-r--r-- | crypto/evp/evp_fetch.c | 65 | ||||
-rw-r--r-- | doc/internal/man3/ossl_namemap_new.pod | 9 | ||||
-rw-r--r-- | include/internal/namemap.h | 1 |
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, |