Add a mechnism to save the name of fetched methods
authorRichard Levitte <levitte@openssl.org>
Wed, 10 Jul 2019 20:22:16 +0000 (22:22 +0200)
committerRichard Levitte <levitte@openssl.org>
Tue, 23 Jul 2019 04:34:09 +0000 (06:34 +0200)
This will be useful for information display, as well as for code that
want to check the name of an algorithm.  This can eventually replace
all NID checks.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/9356)

crypto/evp/cmeth_lib.c
crypto/evp/digest.c
crypto/evp/evp_enc.c
crypto/evp/evp_fetch.c
crypto/evp/evp_lib.c
crypto/evp/evp_locl.h
crypto/evp/exchange.c
crypto/evp/keymgmt_meth.c
crypto/include/internal/evp_int.h

index 40aca34..51c9b6e 100644 (file)
@@ -55,6 +55,7 @@ void EVP_CIPHER_meth_free(EVP_CIPHER *cipher)
         if (i > 0)
             return;
         ossl_provider_free(cipher->prov);
+        OPENSSL_free(cipher->name);
         CRYPTO_THREAD_lock_free(cipher->lock);
         OPENSSL_free(cipher);
     }
index 65b12e3..27f9d12 100644 (file)
@@ -577,15 +577,19 @@ int EVP_MD_CTX_ctrl(EVP_MD_CTX *ctx, int cmd, int p1, void *p2)
     return 0;
 }
 
-static void *evp_md_from_dispatch(const OSSL_DISPATCH *fns,
+static void *evp_md_from_dispatch(const char *name, const OSSL_DISPATCH *fns,
                                   OSSL_PROVIDER *prov)
 {
     EVP_MD *md = NULL;
     int fncnt = 0;
 
     /* EVP_MD_fetch() will set the legacy NID if available */
-    if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL)
+    if ((md = EVP_MD_meth_new(NID_undef, NID_undef)) == NULL
+        || (md->name = OPENSSL_strdup(name)) == NULL) {
+        EVP_MD_meth_free(md);
+        EVPerr(0, ERR_R_MALLOC_FAILURE);
         return NULL;
+    }
 
     for (; fns->function_id != 0; fns++) {
         switch (fns->function_id) {
index c1f7e77..bfdd581 100644 (file)
@@ -1127,7 +1127,8 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
     return 1;
 }
 
-static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
+static void *evp_cipher_from_dispatch(const char *name,
+                                      const OSSL_DISPATCH *fns,
                                       OSSL_PROVIDER *prov)
 {
     EVP_CIPHER *cipher = NULL;
@@ -1137,8 +1138,12 @@ static void *evp_cipher_from_dispatch(const OSSL_DISPATCH *fns,
      * 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)
+    if ((cipher = EVP_CIPHER_meth_new(0, 0, 0)) == NULL
+        || (cipher->name = OPENSSL_strdup(name)) == NULL) {
+        EVP_CIPHER_meth_free(cipher);
+        EVPerr(0, ERR_R_MALLOC_FAILURE);
         return NULL;
+    }
 
     for (; fns->function_id != 0; fns++) {
         switch (fns->function_id) {
index 0c25f0d..82f6e5d 100644 (file)
@@ -40,7 +40,8 @@ struct method_data_st {
     OPENSSL_CTX *libctx;
     const char *name;
     OSSL_METHOD_CONSTRUCT_METHOD *mcm;
-    void *(*method_from_dispatch)(const OSSL_DISPATCH *, OSSL_PROVIDER *);
+    void *(*method_from_dispatch)(const char *, const OSSL_DISPATCH *,
+                                  OSSL_PROVIDER *);
     int (*refcnt_up_method)(void *method);
     void (*destruct_method)(void *method);
 };
@@ -143,7 +144,7 @@ static void *construct_method(const char *name, const OSSL_DISPATCH *fns,
 {
     struct method_data_st *methdata = data;
 
-    return methdata->method_from_dispatch(fns, prov);
+    return methdata->method_from_dispatch(name, fns, prov);
 }
 
 static void destruct_method(void *method, void *data)
@@ -155,7 +156,8 @@ static void destruct_method(void *method, void *data)
 
 void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
                         const char *name, const char *properties,
-                        void *(*new_method)(const OSSL_DISPATCH *fns,
+                        void *(*new_method)(const char *name,
+                                            const OSSL_DISPATCH *fns,
                                             OSSL_PROVIDER *prov),
                         int (*up_ref_method)(void *),
                         void (*free_method)(void *))
index 47bbb2b..24441ef 100644 (file)
@@ -513,6 +513,7 @@ void EVP_MD_meth_free(EVP_MD *md)
         if (i > 0)
             return;
         ossl_provider_free(md->prov);
+        OPENSSL_free(md->name);
         CRYPTO_THREAD_lock_free(md->lock);
         OPENSSL_free(md);
     }
index 740c159..d557e9c 100644 (file)
@@ -65,7 +65,7 @@ struct evp_kdf_ctx_st {
 struct evp_keymgmt_st {
     int id;                      /* libcrypto internal */
 
-    const char *name;
+    char *name;
     OSSL_PROVIDER *prov;
     CRYPTO_REF_COUNT refcnt;
     CRYPTO_RWLOCK *lock;
@@ -89,6 +89,7 @@ struct evp_keymgmt_st {
 } /* EVP_KEYMGMT */ ;
 
 struct evp_keyexch_st {
+    char *name;
     OSSL_PROVIDER *prov;
     CRYPTO_REF_COUNT refcnt;
     CRYPTO_RWLOCK *lock;
@@ -133,7 +134,8 @@ 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)(const OSSL_DISPATCH *fns,
+                        void *(*new_method)(const char *name,
+                                            const OSSL_DISPATCH *fns,
                                             OSSL_PROVIDER *prov),
                         int (*up_ref_method)(void *),
                         void (*free_method)(void *));
index 208bb98..d8afcbd 100644 (file)
@@ -31,14 +31,19 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
     return exchange;
 }
 
-static void *evp_keyexch_from_dispatch(const OSSL_DISPATCH *fns,
+static void *evp_keyexch_from_dispatch(const char *name,
+                                       const OSSL_DISPATCH *fns,
                                        OSSL_PROVIDER *prov)
 {
     EVP_KEYEXCH *exchange = NULL;
     int fncnt = 0;
 
-    if ((exchange = evp_keyexch_new(prov)) == NULL)
+    if ((exchange = evp_keyexch_new(prov)) == NULL
+        || (exchange->name = OPENSSL_strdup(name)) == NULL) {
+        EVP_KEYEXCH_free(exchange);
+        EVPerr(0, ERR_R_MALLOC_FAILURE);
         return NULL;
+    }
 
     for (; fns->function_id != 0; fns++) {
         switch (fns->function_id) {
@@ -108,6 +113,7 @@ void EVP_KEYEXCH_free(EVP_KEYEXCH *exchange)
         if (i > 0)
             return;
         ossl_provider_free(exchange->prov);
+        OPENSSL_free(exchange->name);
         CRYPTO_THREAD_lock_free(exchange->lock);
         OPENSSL_free(exchange);
     }
index 9723820..67c33eb 100644 (file)
@@ -24,6 +24,7 @@ static void *keymgmt_new(void)
     if ((keymgmt = OPENSSL_zalloc(sizeof(*keymgmt))) == NULL
         || (keymgmt->lock = CRYPTO_THREAD_lock_new()) == NULL) {
         EVP_KEYMGMT_free(keymgmt);
+        EVPerr(0, ERR_R_MALLOC_FAILURE);
         return NULL;
     }
 
@@ -32,13 +33,16 @@ static void *keymgmt_new(void)
     return keymgmt;
 }
 
-static void *keymgmt_from_dispatch(const OSSL_DISPATCH *fns,
+static void *keymgmt_from_dispatch(const char *name, const OSSL_DISPATCH *fns,
                                    OSSL_PROVIDER *prov)
 {
     EVP_KEYMGMT *keymgmt = NULL;
 
-    if ((keymgmt = keymgmt_new()) == NULL)
+    if ((keymgmt = keymgmt_new()) == NULL
+        || (keymgmt->name = OPENSSL_strdup(name)) == NULL) {
+        EVP_KEYMGMT_free(keymgmt);
         return NULL;
+    }
 
     for (; fns->function_id != 0; fns++) {
         switch (fns->function_id) {
@@ -178,6 +182,7 @@ void EVP_KEYMGMT_free(EVP_KEYMGMT *keymgmt)
     if (ref > 0)
         return;
     ossl_provider_free(keymgmt->prov);
+    OPENSSL_free(keymgmt->name);
     CRYPTO_THREAD_lock_free(keymgmt->lock);
     OPENSSL_free(keymgmt);
 }
index 50ed933..9d87898 100644 (file)
@@ -201,6 +201,7 @@ struct evp_md_st {
 
     /* New structure members */
     /* TODO(3.0): Remove above comment when legacy has gone */
+    char *name;
     OSSL_PROVIDER *prov;
     CRYPTO_REF_COUNT refcnt;
     CRYPTO_RWLOCK *lock;
@@ -251,6 +252,7 @@ struct evp_cipher_st {
 
     /* New structure members */
     /* TODO(3.0): Remove above comment when legacy has gone */
+    char *name;
     OSSL_PROVIDER *prov;
     CRYPTO_REF_COUNT refcnt;
     CRYPTO_RWLOCK *lock;