[openssl] master update

Richard Levitte levitte at openssl.org
Sun May 12 20:46:20 UTC 2019


The branch master has been updated
       via  0211740fcc47a954be19cceb65fb57a6f7deb797 (commit)
       via  1f79ddf5049ff53ad8a7cbab76e62d02d9ac099f (commit)
       via  2e49c05472ab76cee4e30c2eaa4fa576b9ae92c6 (commit)
       via  baff732dc654f8aab37953f6036399989c765604 (commit)
       via  f2182a4e6fef098014117eb4a4f35ca84cd2cf8e (commit)
      from  ffa9bff8a2024bc8e6322be2cbff7d17fb8d828d (commit)


- Log -----------------------------------------------------------------
commit 0211740fcc47a954be19cceb65fb57a6f7deb797
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed May 8 14:00:31 2019 +0200

    EVP_FETCH: remove the need to transport the legacy NID through construction
    
    Now that the legacy NID isn't used as a main index for fetched
    algorithms, the legacy NID was just transported around unnecessarily.
    This is removed, and the legacy NID is simply set by EVP_{API}_fetch()
    after the construction process is done.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8878)

commit 1f79ddf5049ff53ad8a7cbab76e62d02d9ac099f
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun May 5 11:30:38 2019 +0200

    util/find-doc-nits: Fine tune detection of POD markup in NAME section
    
    POD markup is only forbidden in the actual names, while permitted in
    the description.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8878)

commit 2e49c05472ab76cee4e30c2eaa4fa576b9ae92c6
Author: Richard Levitte <levitte at openssl.org>
Date:   Sun May 5 08:42:21 2019 +0200

    EVP_FETCH: deal with names without pre-defined NIDs
    
    We didn't deal very well with names that didn't have pre-defined NIDs,
    as the NID zero travelled through the full process and resulted in an
    inaccessible method.  By consequence, we need to refactor the method
    construction callbacks to rely more on algorithm names.
    
    We must, however, still store the legacy NID with the method, for the
    sake of other code that depend on it (for example, CMS).
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8878)

commit baff732dc654f8aab37953f6036399989c765604
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat May 4 12:56:32 2019 +0200

    Make the generic EVP fetching mechanism use the namenum map
    
    This avoids using the ASN1_OBJECT database, which is bloated for the
    purpose of a simple number <-> name database.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8878)

commit f2182a4e6fef098014117eb4a4f35ca84cd2cf8e
Author: Richard Levitte <levitte at openssl.org>
Date:   Sat May 4 12:55:32 2019 +0200

    Create internal number<->name mapping API
    
    This can be used as a general name to identity map.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/8878)

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

Summary of changes:
 crypto/build.info                           |   2 +-
 crypto/core_fetch.c                         |  17 +--
 crypto/core_namemap.c                       | 211 ++++++++++++++++++++++++++++
 crypto/evp/digest.c                         |  35 +++--
 crypto/evp/evp_enc.c                        |  36 +++--
 crypto/evp/evp_fetch.c                      |  84 +++++------
 crypto/evp/evp_locl.h                       |   5 +-
 doc/internal/man3/evp_generic_fetch.pod     |  37 ++---
 doc/internal/man3/ossl_method_construct.pod |  23 +--
 doc/internal/man3/ossl_namemap_new.pod      |  74 ++++++++++
 include/internal/core.h                     |  10 +-
 include/internal/cryptlib.h                 |   3 +-
 include/internal/namemap.h                  |  21 +++
 util/find-doc-nits                          |   3 +-
 14 files changed, 438 insertions(+), 123 deletions(-)
 create mode 100644 crypto/core_namemap.c
 create mode 100644 doc/internal/man3/ossl_namemap_new.pod
 create mode 100644 include/internal/namemap.h

diff --git a/crypto/build.info b/crypto/build.info
index fa99d61..63913f4 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -10,7 +10,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 x509v3 conf \
 LIBS=../libcrypto
 # The Core
 SOURCE[../libcrypto]=provider_core.c provider_predefined.c provider_conf.c \
-        core_fetch.c
+        core_fetch.c core_namemap.c
 
 # Central utilities
 SOURCE[../libcrypto]=\
diff --git a/crypto/core_fetch.c b/crypto/core_fetch.c
index 6c4ed6a..227f920 100644
--- a/crypto/core_fetch.c
+++ b/crypto/core_fetch.c
@@ -56,14 +56,14 @@ static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata)
              * If we haven't been told not to store,
              * add to the global store
              */
-            data->mcm->put(data->libctx, NULL,
-                           thismap->property_definition,
-                           method, data->mcm_data);
+            data->mcm->put(data->libctx, NULL, method,
+                           thismap->algorithm_name,
+                           thismap->property_definition, data->mcm_data);
         }
 
-        data->mcm->put(data->libctx, data->store,
-                       thismap->property_definition,
-                       method, data->mcm_data);
+        data->mcm->put(data->libctx, data->store, method,
+                       thismap->algorithm_name, thismap->property_definition,
+                       data->mcm_data);
 
         /* refcnt-- because we're dropping the reference */
         data->mcm->destruct(method, data->mcm_data);
@@ -79,7 +79,8 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
 {
     void *method = NULL;
 
-    if ((method = mcm->get(libctx, NULL, propquery, mcm_data)) == NULL) {
+    if ((method =
+         mcm->get(libctx, NULL, name, propquery, mcm_data)) == NULL) {
         struct construct_data_st cbdata;
 
         /*
@@ -97,7 +98,7 @@ void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
         ossl_provider_forall_loaded(libctx, ossl_method_construct_this,
                                     &cbdata);
 
-        method = mcm->get(libctx, cbdata.store, propquery, mcm_data);
+        method = mcm->get(libctx, cbdata.store, name, propquery, mcm_data);
         mcm->dealloc_tmp_store(cbdata.store);
     }
 
diff --git a/crypto/core_namemap.c b/crypto/core_namemap.c
new file mode 100644
index 0000000..5155a22
--- /dev/null
+++ b/crypto/core_namemap.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/namemap.h"
+#include <openssl/lhash.h>
+#include <openssl/safestack.h>
+
+/* The namemap entry */
+typedef struct {
+    int number;
+    const char *name;
+    char body[1];        /* Sized appropriately to contain the name */
+} NAMEMAP_ENTRY;
+
+DEFINE_LHASH_OF(NAMEMAP_ENTRY);
+DEFINE_STACK_OF(NAMEMAP_ENTRY)
+
+/* The namemap, which provides for bidirectional indexing */
+
+struct ossl_namemap_st {
+    /* Flags */
+    unsigned int stored:1; /* If 1, it's stored in a library context */
+
+    CRYPTO_RWLOCK *lock;
+    LHASH_OF(NAMEMAP_ENTRY) *namenum;  /* Name->number mapping */
+    STACK_OF(NAMEMAP_ENTRY) *numname;  /* Number->name mapping */
+};
+
+/* LHASH callbacks */
+
+static unsigned long namemap_hash(const NAMEMAP_ENTRY *n)
+{
+    return OPENSSL_LH_strhash(n->name);
+}
+
+static int namemap_cmp(const NAMEMAP_ENTRY *a, const NAMEMAP_ENTRY *b)
+{
+    return strcmp(a->name, b->name);
+}
+
+static void namemap_free(NAMEMAP_ENTRY *n)
+{
+    OPENSSL_free(n);
+}
+
+/* OPENSSL_CTX_METHOD functions for a namemap stored in a library context */
+
+static void *stored_namemap_new(OPENSSL_CTX *libctx)
+{
+    OSSL_NAMEMAP *namemap = ossl_namemap_new();
+
+    if (namemap != NULL)
+        namemap->stored = 1;
+
+    return namemap;
+}
+
+static void stored_namemap_free(void *vnamemap)
+{
+    OSSL_NAMEMAP *namemap = vnamemap;
+
+    /* Pretend it isn't stored, or ossl_namemap_free() will do nothing */
+    namemap->stored = 0;
+    ossl_namemap_free(namemap);
+}
+
+static const OPENSSL_CTX_METHOD stored_namemap_method = {
+    stored_namemap_new,
+    stored_namemap_free,
+};
+
+/* API functions */
+
+OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx)
+{
+    return openssl_ctx_get_data(libctx, OPENSSL_CTX_NAMEMAP_INDEX,
+                                &stored_namemap_method);
+}
+
+OSSL_NAMEMAP *ossl_namemap_new(void)
+{
+    OSSL_NAMEMAP *namemap;
+
+    if ((namemap = OPENSSL_zalloc(sizeof(*namemap))) != NULL
+        && (namemap->lock = CRYPTO_THREAD_lock_new()) != NULL
+        && (namemap->numname = sk_NAMEMAP_ENTRY_new_null()) != NULL
+        && (namemap->namenum =
+            lh_NAMEMAP_ENTRY_new(namemap_hash, namemap_cmp)) != NULL) {
+        return namemap;
+    }
+
+    ossl_namemap_free(namemap);
+    return NULL;
+}
+
+void ossl_namemap_free(OSSL_NAMEMAP *namemap)
+{
+    if (namemap == NULL || namemap->stored)
+        return;
+
+     /* The elements will be freed by sk_NAMEMAP_ENTRY_pop_free() */
+    lh_NAMEMAP_ENTRY_free(namemap->namenum);
+
+    sk_NAMEMAP_ENTRY_pop_free(namemap->numname, namemap_free);
+
+    CRYPTO_THREAD_lock_free(namemap->lock);
+    OPENSSL_free(namemap);
+}
+
+/*
+ * TODO(3.0) It isn't currently possible to have a default namemap in the
+ * FIPS module because if init and cleanup constraints, so we currently
+ * disable the code that would allow it when FIPS_MODE is defined.
+ */
+
+const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number)
+{
+    NAMEMAP_ENTRY *entry;
+
+#ifndef FIPS_MODE
+    if (namemap == NULL)
+        namemap = ossl_namemap_stored(NULL);
+#endif
+
+    if (namemap == NULL || number == 0)
+        return NULL;
+
+    CRYPTO_THREAD_read_lock(namemap->lock);
+    entry = sk_NAMEMAP_ENTRY_value(namemap->numname, number);
+    CRYPTO_THREAD_unlock(namemap->lock);
+
+    if (entry != NULL)
+        return entry->name;
+    return NULL;
+}
+
+int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name)
+{
+    NAMEMAP_ENTRY *entry, template;
+
+#ifndef FIPS_MODE
+    if (namemap == NULL)
+        namemap = ossl_namemap_stored(NULL);
+#endif
+
+    if (namemap == NULL)
+        return 0;
+
+    template.name = name;
+    CRYPTO_THREAD_read_lock(namemap->lock);
+    entry = lh_NAMEMAP_ENTRY_retrieve(namemap->namenum, &template);
+    CRYPTO_THREAD_unlock(namemap->lock);
+
+    if (entry == NULL)
+        return 0;
+
+    return entry->number;
+}
+
+int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name)
+{
+    NAMEMAP_ENTRY *entry;
+    int number;
+
+#ifndef FIPS_MODE
+    if (namemap == NULL)
+        namemap = ossl_namemap_stored(NULL);
+#endif
+
+    if (name == NULL || namemap == NULL)
+        return 0;
+
+    if ((number = ossl_namemap_number(namemap, name)) != 0)
+        return number;           /* Pretend success */
+
+    if ((entry = OPENSSL_zalloc(sizeof(*entry) + strlen(name))) == NULL)
+        goto err;
+
+    strcpy(entry->body, name);
+    entry->name = entry->body;
+
+    CRYPTO_THREAD_write_lock(namemap->lock);
+
+    entry->number = sk_NAMEMAP_ENTRY_push(namemap->numname, entry);
+
+    if (entry->number == 0)
+        goto err;
+
+    (void)lh_NAMEMAP_ENTRY_insert(namemap->namenum, entry);
+    if (lh_NAMEMAP_ENTRY_error(namemap->namenum))
+        goto err;
+
+    CRYPTO_THREAD_unlock(namemap->lock);
+
+    return entry->number;
+
+ err:
+    if (entry != NULL) {
+        if (entry->number != 0)
+            (void)sk_NAMEMAP_ENTRY_pop(namemap->numname);
+        lh_NAMEMAP_ENTRY_delete(namemap->namenum, entry);
+        CRYPTO_THREAD_unlock(namemap->lock);
+    }
+    return 0;
+}
diff --git a/crypto/evp/digest.c b/crypto/evp/digest.c
index 9b10a7f..dc50528 100644
--- a/crypto/evp/digest.c
+++ b/crypto/evp/digest.c
@@ -494,13 +494,14 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
     return 0;
 }
 
-static void *evp_md_from_dispatch(int mdtype, const OSSL_DISPATCH *fns,
-                                    OSSL_PROVIDER *prov)
+static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
+                                  OSSL_PROVIDER *prov)
 {
     EVP_MD *md = NULL;
     int fncnt = 0;
 
-    if ((md = EVP_MD_meth_new(mdtype, NID_undef)) == NULL)
+    /* EVP_MD_fetch() will set the legacy NID if available */
+    if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL)
         return NULL;
 
     for (; fns->function_id != 0; fns++) {
@@ -587,17 +588,25 @@ static void evp_md_free(void *md)
     EVP_MD_meth_free(md);
 }
 
-static int evp_md_nid(void *vmd)
-{
-    EVP_MD *md = vmd;
-
-    return md->type;
-}
-
 EVP_MD *EVP_MD_fetch(OPENSSL_CTX *ctx, const char *algorithm,
                      const char *properties)
 {
-    return evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
-                             evp_md_from_dispatch, evp_md_upref,
-                             evp_md_free, evp_md_nid);
+    EVP_MD *md =
+        evp_generic_fetch(ctx, OSSL_OP_DIGEST, algorithm, properties,
+                          evp_md_from_dispatch, evp_md_upref,
+                          evp_md_free);
+
+#ifndef FIPS_MODE
+    /* TODO(3.x) get rid of the need for legacy NIDs */
+    if (md != NULL) {
+        /*
+         * FIPS module note: since internal fetches will be entirely
+         * provider based, we know that none of its code depends on legacy
+         * NIDs or any functionality that use them.
+         */
+        md->type = OBJ_sn2nid(algorithm);
+    }
+#endif
+
+    return md;
 }
diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index 29b707a..c05d48e 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -1044,13 +1044,17 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
     return 1;
 }
 
-static void *evp_cipher_from_dispatch(int nid, const OSSL_DISPATCH *fns,
+static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
                                       OSSL_PROVIDER *prov)
 {
     EVP_CIPHER *cipher = NULL;
     int fnciphcnt = 0, fnctxcnt = 0;
 
-    if ((cipher = EVP_CIPHER_meth_new(nid, 0, 0)) == NULL)
+    /*
+     * The legacy NID is set by EVP_CIPHER_fetch() if the name exists in
+     * the object database.
+     */
+    if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL)
         return NULL;
 
     for (; fns->function_id != 0; fns++) {
@@ -1167,17 +1171,25 @@ static void evp_cipher_free(void *cipher)
     EVP_CIPHER_meth_free(cipher);
 }
 
-static int evp_cipher_nid(void *vcipher)
-{
-    EVP_CIPHER *cipher = vcipher;
-
-    return cipher->nid;
-}
-
 EVP_CIPHER *EVP_CIPHER_fetch(OPENSSL_CTX *ctx, const char *algorithm,
                              const char *properties)
 {
-    return evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
-                             evp_cipher_from_dispatch, evp_cipher_upref,
-                             evp_cipher_free, evp_cipher_nid);
+    EVP_CIPHER *cipher =
+        evp_generic_fetch(ctx, OSSL_OP_CIPHER, algorithm, properties,
+                          evp_cipher_from_dispatch, evp_cipher_upref,
+                          evp_cipher_free);
+
+#ifndef FIPS_MODE
+    /* TODO(3.x) get rid of the need for legacy NIDs */
+    if (cipher != NULL) {
+        /*
+         * FIPS module note: since internal fetches will be entirely
+         * provider based, we know that none of its code depends on legacy
+         * NIDs or any functionality that use them.
+         */
+        cipher->nid = OBJ_sn2nid(algorithm);
+    }
+#endif
+
+    return cipher;
 }
diff --git a/crypto/evp/evp_fetch.c b/crypto/evp/evp_fetch.c
index d2c0b62..fdd6209 100644
--- a/crypto/evp/evp_fetch.c
+++ b/crypto/evp/evp_fetch.c
@@ -13,9 +13,9 @@
 #include <openssl/core.h>
 #include "internal/cryptlib.h"
 #include "internal/thread_once.h"
-#include "internal/asn1_int.h"
 #include "internal/property.h"
 #include "internal/core.h"
+#include "internal/namemap.h"
 #include "internal/evp_int.h"    /* evp_locl.h needs it */
 #include "evp_locl.h"
 
@@ -37,14 +37,13 @@ static const OPENSSL_CTX_METHOD default_method_store_method = {
 
 /* Data to be passed through ossl_method_construct() */
 struct method_data_st {
+    OPENSSL_CTX *libctx;
     const char *name;
-    int nid;
+    int id;
     OSSL_METHOD_CONSTRUCT_METHOD *mcm;
-    void *(*method_from_dispatch)(int nid, const OSSL_DISPATCH *,
-                                  OSSL_PROVIDER *);
+    void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *);
     int (*refcnt_up_method)(void *method);
     void (*destruct_method)(void *method);
-    int (*nid_method)(void *method);
 };
 
 /*
@@ -68,16 +67,23 @@ static OSSL_METHOD_STORE *get_default_method_store(OPENSSL_CTX *libctx)
 }
 
 static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
-                                   const char *propquery, void *data)
+                                   const char *name, const char *propquery,
+                                   void *data)
 {
     struct method_data_st *methdata = data;
     void *method = NULL;
+    OSSL_NAMEMAP *namemap;
+    int id;
 
     if (store == NULL
         && (store = get_default_method_store(libctx)) == NULL)
         return NULL;
 
-    (void)ossl_method_store_fetch(store, methdata->nid, propquery, &method);
+    if ((namemap = ossl_namemap_stored(libctx)) == NULL
+        || (id = ossl_namemap_add(namemap, name)) == 0)
+        return NULL;
+
+    (void)ossl_method_store_fetch(store, id, propquery, &method);
 
     if (method != NULL
         && !methdata->refcnt_up_method(method)) {
@@ -87,13 +93,15 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
 }
 
 static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
-                               const char *propdef,
-                               void *method, void *data)
+                               void *method, const char *name,
+                               const char *propdef, void *data)
 {
     struct method_data_st *methdata = data;
-    int nid = methdata->nid_method(method);
+    OSSL_NAMEMAP *namemap;
+    int id;
 
-    if (nid == NID_undef)
+    if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
+        || (id = ossl_namemap_add(namemap, name)) == 0)
         return 0;
 
     if (store == NULL
@@ -101,41 +109,18 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
         return 0;
 
     if (methdata->refcnt_up_method(method)
-        && ossl_method_store_add(store, nid, propdef, method,
+        && ossl_method_store_add(store, id, propdef, method,
                                  methdata->destruct_method))
         return 1;
     return 0;
 }
 
-static void *construct_method(const char *algorithm_name,
-                              const OSSL_DISPATCH *fns, OSSL_PROVIDER *prov,
-                              void *data)
+static void *construct_method(const char *name, const OSSL_DISPATCH *fns,
+                              OSSL_PROVIDER *prov, void *data)
 {
     struct method_data_st *methdata = data;
-    void *method = NULL;
-    int nid = OBJ_sn2nid(algorithm_name);
 
-    if (nid == NID_undef) {
-        /* Create a new NID for that name on the fly */
-        ASN1_OBJECT tmpobj;
-
-        /* This is the same as OBJ_create() but without requiring a OID */
-        tmpobj.nid = OBJ_new_nid(1);
-        tmpobj.sn = tmpobj.ln = methdata->name;
-        tmpobj.flags = ASN1_OBJECT_FLAG_DYNAMIC;
-        tmpobj.length = 0;
-        tmpobj.data = NULL;
-
-        nid = OBJ_add_object(&tmpobj);
-    }
-
-    if (nid == NID_undef)
-        return NULL;
-
-    method = methdata->method_from_dispatch(nid, fns, prov);
-    if (method == NULL)
-        return NULL;
-    return method;
+    return methdata->method_from_dispatch(fns, prov);
 }
 
 static void destruct_method(void *method, void *data)
@@ -146,22 +131,22 @@ static void destruct_method(void *method, void *data)
 }
 
 void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
-                        const char *algorithm, const char *properties,
-                        void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
+                        const char *name, const char *properties,
+                        void *(*new_method)(const OSSL_DISPATCH *fns,
                                             OSSL_PROVIDER *prov),
                         int (*upref_method)(void *),
-                        void (*free_method)(void *),
-                        int (*nid_method)(void *))
+                        void (*free_method)(void *))
 {
     OSSL_METHOD_STORE *store = get_default_method_store(libctx);
-    int nid = OBJ_sn2nid(algorithm);
+    OSSL_NAMEMAP *namemap = ossl_namemap_stored(libctx);
+    int id;
     void *method = NULL;
 
-    if (store == NULL)
+    if (store == NULL || namemap == NULL)
         return NULL;
 
-    if (nid == NID_undef
-        || !ossl_method_store_cache_get(store, nid, properties, &method)) {
+    if ((id = ossl_namemap_number(namemap, name)) == 0
+        || !ossl_method_store_cache_get(store, id, properties, &method)) {
         OSSL_METHOD_CONSTRUCT_METHOD mcm = {
             alloc_tmp_method_store,
             dealloc_tmp_method_store,
@@ -172,17 +157,16 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
         };
         struct method_data_st mcmdata;
 
-        mcmdata.nid = nid;
         mcmdata.mcm = &mcm;
+        mcmdata.libctx = libctx;
         mcmdata.method_from_dispatch = new_method;
         mcmdata.destruct_method = free_method;
         mcmdata.refcnt_up_method = upref_method;
         mcmdata.destruct_method = free_method;
-        mcmdata.nid_method = nid_method;
-        method = ossl_method_construct(libctx, operation_id, algorithm,
+        method = ossl_method_construct(libctx, operation_id, name,
                                        properties, 0 /* !force_cache */,
                                        &mcm, &mcmdata);
-        ossl_method_store_cache_set(store, nid, properties, method);
+        ossl_method_store_cache_set(store, id, properties, method);
     } else {
         upref_method(method);
     }
diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
index 0bb6d15..8876b06 100644
--- a/crypto/evp/evp_locl.h
+++ b/crypto/evp/evp_locl.h
@@ -91,8 +91,7 @@ int is_partially_overlapping(const void *ptr1, const void *ptr2, int len);
 
 void *evp_generic_fetch(OPENSSL_CTX *ctx, int operation_id,
                         const char *algorithm, const char *properties,
-                        void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
+                        void *(*new_method)(const OSSL_DISPATCH *fns,
                                             OSSL_PROVIDER *prov),
                         int (*upref_method)(void *),
-                        void (*free_method)(void *),
-                        int (*nid_method)(void *));
+                        void (*free_method)(void *));
diff --git a/doc/internal/man3/evp_generic_fetch.pod b/doc/internal/man3/evp_generic_fetch.pod
index 881aaf9..2679a7e 100644
--- a/doc/internal/man3/evp_generic_fetch.pod
+++ b/doc/internal/man3/evp_generic_fetch.pod
@@ -10,17 +10,16 @@ evp_generic_fetch - generic algorithm fetcher and method creator for EVP
  #include "evp_locl.h"
 
  void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
-                         const char *algorithm, const char *properties,
-                         void *(*new_method)(int nid, const OSSL_DISPATCH *fns,
+                         const char *name, const char *properties,
+                         void *(*new_method)(const OSSL_DISPATCH *fns,
                                              OSSL_PROVIDER *prov),
                          int (*upref_method)(void *),
-                         void (*free_method)(void *),
-                         int (*nid_method)(void *));
+                         void (*free_method)(void *));
 
 =head1 DESCRIPTION
 
 evp_generic_fetch() calls ossl_method_construct() with the given
-C<libctx>, C<operation_id>, C<algorithm>, and C<properties> and uses
+C<libctx>, C<operation_id>, C<name>, and C<properties> and uses
 it to create an EVP method with the help of the functions
 C<new_method>, C<upref_method>, and C<free_method>.
 
@@ -42,10 +41,6 @@ one.
 
 frees the given method.
 
-=item nid_method()
-
-returns the nid associated with the given method.
-
 =back
 
 =head1 RETURN VALUES
@@ -80,7 +75,6 @@ And here's the implementation of the FOO method fetcher:
     /* typedef struct evp_foo_st EVP_FOO */
     struct evp_foo_st {
         OSSL_PROVIDER *prov;
-        int nid;
 	CRYPTO_REF_COUNT refcnt;
         OSSL_OP_foo_newctx_fn *newctx;
         OSSL_OP_foo_init_fn *init;
@@ -93,7 +87,7 @@ And here's the implementation of the FOO method fetcher:
      * In this example, we have a public method creator and destructor.
      * It's not absolutely necessary, but is in the spirit of OpenSSL.
      */
-    EVP_FOO *EVP_FOO_meth_from_dispatch(int foo_type, const OSSL_DISPATCH *fns,
+    EVP_FOO *EVP_FOO_meth_from_dispatch(const OSSL_DISPATCH *fns,
                                         OSSL_PROVIDER *prov)
     {
         EVP_FOO *foo = NULL;
@@ -120,7 +114,6 @@ And here's the implementation of the FOO method fetcher:
                 break;
             }
         }
-        foo->nid = foo_type;
         foo->prov = prov;
         if (prov)
             ossl_provider_upref(prov);
@@ -138,10 +131,10 @@ And here's the implementation of the FOO method fetcher:
         }
     }
 
-    static void *foo_from_dispatch(int nid, const OSSL_DISPATCH *fns,
+    static void *foo_from_dispatch(const OSSL_DISPATCH *fns,
                                    OSSL_PROVIDER *prov)
     {
-        return EVP_FOO_meth_from_dispatch(nid, fns, prov);
+        return EVP_FOO_meth_from_dispatch(fns, prov);
     }
 
     static int foo_upref(void *vfoo)
@@ -159,11 +152,21 @@ And here's the implementation of the FOO method fetcher:
     }
 
     EVP_FOO *EVP_FOO_fetch(OPENSSL_CTX *ctx,
-                           const char *algorithm,
+                           const char *name,
                            const char *properties)
     {
-        return evp_generic_fetch(ctx, OSSL_OP_FOO, algorithm, properties,
-                                 foo_from_dispatch, foo_upref, foo_free);
+        EVP_FOO *foo =
+            evp_generic_fetch(ctx, OSSL_OP_FOO, name, properties,
+                              foo_from_dispatch, foo_upref, foo_free);
+
+        /*
+         * If this method exists in legacy form, with a constant NID for the
+         * given |name|, this is the spot to find that NID and set it in
+         * the newly constructed EVP_FOO instance.
+         */
+
+        return foo;
+
     }
 
 And finally, the library functions:
diff --git a/doc/internal/man3/ossl_method_construct.pod b/doc/internal/man3/ossl_method_construct.pod
index 47f4a24..60de260 100644
--- a/doc/internal/man3/ossl_method_construct.pod
+++ b/doc/internal/man3/ossl_method_construct.pod
@@ -15,13 +15,13 @@ OSSL_METHOD_CONSTRUCT_METHOD, ossl_method_construct
      /* Remove a store */
      void (*dealloc_tmp_store)(void *store);
      /* Get an already existing method from a store */
-     void *(*get)(OPENSSL_CTX *libctx, void *store, const char *propquery,
-                  void *data);
+     void *(*get)(OPENSSL_CTX *libctx, void *store, const char *name,
+                  const char *propquery, void *data);
      /* Store a method in a store */
-     int (*put)(OPENSSL_CTX *libctx, void *store, const char *propdef,
-                void *method, void *data);
+     int (*put)(OPENSSL_CTX *libctx, void *store, void *method,
+                const char *name, const char *propdef, void *data);
      /* Construct a new method */
-     void *(*construct)(const char *algorithm_name, const OSSL_DISPATCH *fns,
+     void *(*construct)(const char *name, const OSSL_DISPATCH *fns,
                         OSSL_PROVIDER *prov, void *data);
      /* Destruct a method */
      void (*destruct)(void *method);
@@ -77,14 +77,15 @@ Remove a temporary store.
 
 =item get()
 
-Look up an already existing method from a store.
+Look up an already existing method from a store by name.
 
 The store may be given with C<store>.
 B<NULL> is a valid value and means that a sub-system default store
 must be used.
 This default store should be stored in the library context C<libctx>.
 
-The method to be looked up should be identified with data from C<data>
+The method to be looked up should be identified with the given C<name> and
+data from C<data>
 (which is the C<mcm_data> that was passed to ossl_construct_method())
 and the provided property query C<propquery>.
 
@@ -100,15 +101,15 @@ B<NULL> is a valid value and means that a sub-system default store
 must be used.
 This default store should be stored in the library context C<libctx>.
 
-The method should be associated with the given property definition
-C<propdef> and any identification data given through C<data> (which is
+The method should be associated with the given C<name> and property definition
+C<propdef> as well as any identification data given through C<data> (which is
 the C<mcm_data> that was passed to ossl_construct_method()).
 
 This function is expected to increment the C<method>'s reference count.
 
 =item construct()
 
-Constructs a sub-system method for the given C<algorithm_name> and the given
+Constructs a sub-system method for the given C<name> and the given
 dispatch table C<fns>.
 
 The associated I<provider object> C<prov> is passed as well, to make
@@ -133,7 +134,7 @@ B<NULL> on error.
 
 =head1 HISTORY
 
-This functionality was added to OpenSSL 3.0.0.
+This functionality was added to OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
diff --git a/doc/internal/man3/ossl_namemap_new.pod b/doc/internal/man3/ossl_namemap_new.pod
new file mode 100644
index 0000000..07dc914
--- /dev/null
+++ b/doc/internal/man3/ossl_namemap_new.pod
@@ -0,0 +1,74 @@
+=pod
+
+=head1 NAME
+
+ossl_namemap_new, ossl_namemap_free, ossl_namemap_stored,
+ossl_namemap_add, ossl_namemap_name, ossl_namemap_number
+- internal number E<lt>-E<gt> name map
+
+=head1 SYNOPSIS
+
+ #include "internal/cryptlib.h"
+
+ OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx);
+
+ OSSL_NAMEMAP *ossl_namemap_new(void);
+ void ossl_namemap_free(OSSL_NAMEMAP *namemap);
+
+ int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name);
+ const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number);
+ int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name);
+
+=head1 DESCRIPTION
+
+A B<OSSL_NAMEMAP> is a simple number E<lt>-E<gt> name map, which can
+be used to give any arbitrary name (any string) a unique dynamic
+identity that is valid throughout the lifetime of the associated
+library context.
+
+ossl_namemap_new() and ossl_namemap_free() construct and destruct a
+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_stored() finds or auto-creates the default namemap in the
+given library context.
+The returned B<OSSL_NAMEMAP> can't be destructed using
+ossl_namemap_free().
+
+ossl_namemap_add() adds a new name to the namemap if it's not already
+present.
+
+ossl_namemap_name() finds the name corresponding to the given number.
+
+ossl_namemap_number() finds the number corresponding to the given
+name.
+
+=head1 RETURN VALUES
+
+ossl_namemap_new() and ossl_namemap_stored() return the pointer to a
+B<OSSL_NAMEMAP>, or NULL on error.
+
+ossl_namemap_add() returns the number associated with the added
+string, or zero on error.
+
+ossl_namemap_name() returns a pointer to the name corresponding to the
+given number, or NULL if it's undefined in the given B<OSSL_NAMEMAP>.
+
+ossl_namemap_number() returns the number corresponding to the given
+name, or 0 if it's undefined in the given B<OSSL_NAMEMAP>.
+
+=head1 HISTORY
+
+The functions described here were all added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License").  You may not use
+this file except in compliance with the License.  You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/include/internal/core.h b/include/internal/core.h
index ddafaee..64547dc 100644
--- a/include/internal/core.h
+++ b/include/internal/core.h
@@ -32,13 +32,13 @@ typedef struct ossl_method_construct_method_st {
     /* Remove a store */
     void (*dealloc_tmp_store)(void *store);
     /* Get an already existing method from a store */
-    void *(*get)(OPENSSL_CTX *libctx, void *store, const char *propquery,
-                 void *data);
+    void *(*get)(OPENSSL_CTX *libctx, void *store, const char *name,
+                 const char *propquery, void *data);
     /* Store a method in a store */
-    int (*put)(OPENSSL_CTX *libctx, void *store, const char *propdef,
-               void *method, void *data);
+    int (*put)(OPENSSL_CTX *libctx, void *store, void *method,
+               const char *name, const char *propdef, void *data);
     /* Construct a new method */
-    void *(*construct)(const char *algorithm_name, const OSSL_DISPATCH *fns,
+    void *(*construct)(const char *name, const OSSL_DISPATCH *fns,
                        OSSL_PROVIDER *prov, void *data);
     /* Destruct a method */
     void (*destruct)(void *method, void *data);
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index 46b5d34..1ce822d 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -145,7 +145,8 @@ typedef struct ossl_ex_data_global_st {
 # define OPENSSL_CTX_PROVIDER_STORE_INDEX           1
 # define OPENSSL_CTX_PROPERTY_DEFN_INDEX            2
 # define OPENSSL_CTX_PROPERTY_STRING_INDEX          3
-# define OPENSSL_CTX_MAX_INDEXES                    4
+# define OPENSSL_CTX_NAMEMAP_INDEX                  4
+# define OPENSSL_CTX_MAX_INDEXES                    5
 
 typedef struct openssl_ctx_method {
     void *(*new_func)(OPENSSL_CTX *ctx);
diff --git a/include/internal/namemap.h b/include/internal/namemap.h
new file mode 100644
index 0000000..3002818
--- /dev/null
+++ b/include/internal/namemap.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "internal/cryptlib.h"
+
+typedef struct ossl_namemap_st OSSL_NAMEMAP;
+
+OSSL_NAMEMAP *ossl_namemap_stored(OPENSSL_CTX *libctx);
+
+OSSL_NAMEMAP *ossl_namemap_new(void);
+void ossl_namemap_free(OSSL_NAMEMAP *namemap);
+
+int ossl_namemap_add(OSSL_NAMEMAP *namemap, const char *name);
+const char *ossl_namemap_name(const OSSL_NAMEMAP *namemap, int number);
+int ossl_namemap_number(const OSSL_NAMEMAP *namemap, const char *name);
diff --git a/util/find-doc-nits b/util/find-doc-nits
index 66966eb..25f3d5e 100755
--- a/util/find-doc-nits
+++ b/util/find-doc-nits
@@ -66,6 +66,7 @@ sub name_synopsis()
     $tmp =~ tr/\n/ /;
     print "$id trailing comma before - in NAME\n" if $tmp =~ /, *-/;
     $tmp =~ s/ -.*//g;
+    print "$id POD markup among the names in NAME\n" if $tmp =~ /[<>]/;
     $tmp =~ s/  */ /g;
     print "$id missing comma in NAME\n" if $tmp =~ /[^,] /;
 
@@ -198,8 +199,6 @@ sub check()
         if $contents =~ /=head\d\s\s+/;
     print "$id period in NAME section\n"
         if $contents =~ /=head1 NAME.*\.\n.*=head1 SYNOPSIS/ms;
-    print "$id POD markup in NAME section\n"
-        if $contents =~ /=head1 NAME.*[<>].*=head1 SYNOPSIS/ms;
     print "$id Duplicate $1 in L<>\n"
         if $contents =~ /L<([^>]*)\|([^>]*)>/ && $1 eq $2;
     print "$id Bad =over $1\n"


More information about the openssl-commits mailing list