[openssl] master update

Richard Levitte levitte at openssl.org
Wed Nov 20 13:22:41 UTC 2019


The branch master has been updated
       via  6a835fcfb10ba004498f9e39873db3d2b9011609 (commit)
      from  9ce91035bcf7d74fe15c94650f3bc1f89b7c0f07 (commit)


- Log -----------------------------------------------------------------
commit 6a835fcfb10ba004498f9e39873db3d2b9011609
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu May 23 03:27:37 2019 +0200

    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 at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8984)

-----------------------------------------------------------------------

Summary of changes:
 crypto/core_namemap.c                  | 12 +++++++
 crypto/evp/digest.c                    | 11 ++++--
 crypto/evp/evp_enc.c                   | 10 ++++--
 crypto/evp/evp_fetch.c                 | 65 +++++++++++++++++++++++++++++++++-
 doc/internal/man3/ossl_namemap_new.pod |  9 ++++-
 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,


More information about the openssl-commits mailing list