]> git.ipfire.org Git - thirdparty/openssl.git/blobdiff - crypto/evp/evp_fetch.c
Modify ossl_method_store_add() to handle reference counting
[thirdparty/openssl.git] / crypto / evp / evp_fetch.c
index 1c9e27db87d9c363ba022eab88c57b32209db3c1..41dee721a45ab66140ca6c30300268eda71e78b8 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);
 };
@@ -99,7 +100,7 @@ static void *get_method_from_store(OPENSSL_CTX *libctx, void *store,
         return NULL;
 
     if ((namemap = ossl_namemap_stored(libctx)) == NULL
-        || (nameid = ossl_namemap_add(namemap, name)) == 0
+        || (nameid = ossl_namemap_name2num(namemap, name)) == 0
         || (methid = method_id(operation_id, nameid)) == 0)
         return NULL;
 
@@ -123,7 +124,7 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
     uint32_t methid;
 
     if ((namemap = ossl_namemap_stored(methdata->libctx)) == NULL
-        || (nameid = ossl_namemap_add(namemap, name)) == 0
+        || (nameid = ossl_namemap_add(namemap, 0, name)) == 0
         || (methid = method_id(operation_id, nameid)) == 0)
         return 0;
 
@@ -131,11 +132,9 @@ static int put_method_in_store(OPENSSL_CTX *libctx, void *store,
         && (store = get_default_method_store(libctx)) == NULL)
         return 0;
 
-    if (methdata->refcnt_up_method(method)
-        && ossl_method_store_add(store, methid, propdef, method,
-                                 methdata->destruct_method))
-        return 1;
-    return 0;
+    return ossl_method_store_add(store, methid, propdef, method,
+                                 methdata->refcnt_up_method,
+                                 methdata->destruct_method);
 }
 
 static void *construct_method(const char *name, const OSSL_DISPATCH *fns,
@@ -143,7 +142,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,9 +154,10 @@ 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 (*upref_method)(void *),
+                        int (*up_ref_method)(void *),
                         void (*free_method)(void *))
 {
     OSSL_METHOD_STORE *store = get_default_method_store(libctx);
@@ -181,7 +181,7 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
      * about 2^8) or too many names (more than about 2^24).  In that
      * case, we can't create any new method.
      */
-    if ((nameid = ossl_namemap_number(namemap, name)) != 0
+    if ((nameid = ossl_namemap_name2num(namemap, name)) != 0
         && (methid = method_id(operation_id, nameid)) == 0)
         return NULL;
 
@@ -203,23 +203,23 @@ void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id,
         mcmdata.name = name;
         mcmdata.method_from_dispatch = new_method;
         mcmdata.destruct_method = free_method;
-        mcmdata.refcnt_up_method = upref_method;
+        mcmdata.refcnt_up_method = up_ref_method;
         mcmdata.destruct_method = free_method;
         if ((method = ossl_method_construct(libctx, operation_id, name,
                                             properties, 0 /* !force_cache */,
-                                            &mcm, &mcmdata)) == NULL) {
+                                            &mcm, &mcmdata)) != NULL) {
             /*
              * If construction did create a method for us, we know that
              * there is a correct nameid and methodid, since those have
              * already been calculated in get_method_from_store() and
              * put_method_in_store() above.
              */
-            nameid = ossl_namemap_number(namemap, name);
+            nameid = ossl_namemap_name2num(namemap, name);
             methid = method_id(operation_id, nameid);
             ossl_method_store_cache_set(store, methid, properties, method);
         }
     } else {
-        upref_method(method);
+        up_ref_method(method);
     }
 
     return method;
@@ -234,3 +234,41 @@ int EVP_set_default_properties(OPENSSL_CTX *libctx, const char *propq)
     EVPerr(EVP_F_EVP_SET_DEFAULT_PROPERTIES, ERR_R_INTERNAL_ERROR);
     return 0;
 }
+
+struct do_all_data_st {
+    void (*user_fn)(void *method, void *arg);
+    void *user_arg;
+    void *(*new_method)(const char *name, const OSSL_DISPATCH *fns,
+                        OSSL_PROVIDER *prov);
+    void (*free_method)(void *);
+};
+
+static void do_one(OSSL_PROVIDER *provider, const OSSL_ALGORITHM *algo,
+                   int no_store, void *vdata)
+{
+    struct do_all_data_st *data = vdata;
+    void *method = data->new_method(algo->algorithm_name,
+                                    algo->implementation, provider);
+
+    if (method != NULL) {
+        data->user_fn(method, data->user_arg);
+        data->free_method(method);
+    }
+}
+
+void evp_generic_do_all(OPENSSL_CTX *libctx, int operation_id,
+                        void (*user_fn)(void *method, void *arg),
+                        void *user_arg,
+                        void *(*new_method)(const char *name,
+                                            const OSSL_DISPATCH *fns,
+                                            OSSL_PROVIDER *prov),
+                        void (*free_method)(void *))
+{
+    struct do_all_data_st data;
+
+    data.new_method = new_method;
+    data.free_method = free_method;
+    data.user_fn = user_fn;
+    data.user_arg = user_arg;
+    ossl_algorithm_do_all(libctx, operation_id, NULL, do_one, &data);
+}