fetch: convert a NULL property query to ""
authorPauli <pauli@openssl.org>
Fri, 25 Feb 2022 02:37:08 +0000 (13:37 +1100)
committerPauli <pauli@openssl.org>
Mon, 28 Feb 2022 05:20:33 +0000 (16:20 +1100)
Previously, a NULL property query was never cached and this lead to a
performance degregation.  Now, such a query is converted to an empty string
and cached.

Fixes #17752
Fixes https://github.openssl.org/openssl/openssl/issues/26

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17769)

crypto/encode_decode/decoder_meth.c
crypto/encode_decode/encoder_meth.c
crypto/evp/evp_fetch.c
crypto/property/property.c
crypto/store/store_meth.c
doc/internal/man3/OSSL_METHOD_STORE.pod

index 25407b8999e84bd4c506b1ad3edc1f38aa0acf72..2bed9e1bb3b05718e7f4add8bf498ff7b0401259 100644 (file)
@@ -339,6 +339,7 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata, int id,
 {
     OSSL_METHOD_STORE *store = get_decoder_store(methdata->libctx);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
+    const char *const propq = properties != NULL ? properties : "";
     void *method = NULL;
     int unsupported = 0;
 
@@ -367,7 +368,7 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata, int id,
         unsupported = 1;
 
     if (id == 0
-        || !ossl_method_store_cache_get(store, NULL, id, properties, &method)) {
+        || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) {
         OSSL_METHOD_CONSTRUCT_METHOD mcm = {
             get_tmp_decoder_store,
             get_decoder_from_store,
@@ -379,7 +380,7 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata, int id,
 
         methdata->id = id;
         methdata->names = name;
-        methdata->propquery = properties;
+        methdata->propquery = propq;
         methdata->flag_construct_error_occurred = 0;
         if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_DECODER,
                                             &prov, 0 /* !force_cache */,
@@ -393,7 +394,7 @@ inner_ossl_decoder_fetch(struct decoder_data_st *methdata, int id,
             if (id == 0 && name != NULL)
                 id = ossl_namemap_name2num(namemap, name);
             if (id != 0)
-                ossl_method_store_cache_set(store, prov, id, properties, method,
+                ossl_method_store_cache_set(store, prov, id, propq, method,
                                             up_ref_decoder, free_decoder);
         }
 
index 43eca755ac5bf29b9ceedb4eedb7ec4da7893036..57b2f998e237de24b61fec24c73187920cacc3c6 100644 (file)
@@ -349,6 +349,7 @@ inner_ossl_encoder_fetch(struct encoder_data_st *methdata, int id,
 {
     OSSL_METHOD_STORE *store = get_encoder_store(methdata->libctx);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
+    const char *const propq = properties != NULL ? properties : "";
     void *method = NULL;
     int unsupported = 0;
 
@@ -377,7 +378,7 @@ inner_ossl_encoder_fetch(struct encoder_data_st *methdata, int id,
         unsupported = 1;
 
     if (id == 0
-        || !ossl_method_store_cache_get(store, NULL, id, properties, &method)) {
+        || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) {
         OSSL_METHOD_CONSTRUCT_METHOD mcm = {
             get_tmp_encoder_store,
             get_encoder_from_store,
@@ -389,7 +390,7 @@ inner_ossl_encoder_fetch(struct encoder_data_st *methdata, int id,
 
         methdata->id = id;
         methdata->names = name;
-        methdata->propquery = properties;
+        methdata->propquery = propq;
         methdata->flag_construct_error_occurred = 0;
         if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_ENCODER,
                                             &prov, 0 /* !force_cache */,
@@ -402,7 +403,7 @@ inner_ossl_encoder_fetch(struct encoder_data_st *methdata, int id,
              */
             if (id == 0)
                 id = ossl_namemap_name2num(namemap, name);
-            ossl_method_store_cache_set(store, prov, id, properties, method,
+            ossl_method_store_cache_set(store, prov, id, propq, method,
                                         up_ref_encoder, free_encoder);
         }
 
index 80da3fa4bf8e345c52f2bcf9a6aa2909da77cd9a..ea32cd5dd2380a7823bd5e70b57f6f658dd56ca4 100644 (file)
@@ -247,6 +247,7 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
 {
     OSSL_METHOD_STORE *store = get_evp_method_store(methdata->libctx);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
+    const char *const propq = properties != NULL ? properties : "";
     uint32_t meth_id = 0;
     void *method = NULL;
     int unsupported = 0;
@@ -299,8 +300,7 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
         unsupported = 1;
 
     if (meth_id == 0
-        || !ossl_method_store_cache_get(store, prov, meth_id, properties,
-                                        &method)) {
+        || !ossl_method_store_cache_get(store, prov, meth_id, propq, &method)) {
         OSSL_METHOD_CONSTRUCT_METHOD mcm = {
             get_tmp_evp_method_store,
             get_evp_method_from_store,
@@ -312,7 +312,7 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
         methdata->operation_id = operation_id;
         methdata->name_id = name_id;
         methdata->names = name;
-        methdata->propquery = properties;
+        methdata->propquery = propq;
         methdata->method_from_algorithm = new_method;
         methdata->refcnt_up_method = up_ref_method;
         methdata->destruct_method = free_method;
@@ -330,7 +330,7 @@ inner_evp_generic_fetch(struct evp_method_data_st *methdata,
                 name_id = ossl_namemap_name2num(namemap, name);
             meth_id = evp_method_id(name_id, operation_id);
             if (name_id != 0)
-                ossl_method_store_cache_set(store, prov, meth_id, properties,
+                ossl_method_store_cache_set(store, prov, meth_id, propq,
                                             method, up_ref_method, free_method);
         }
 
index c087e741edc7f3491f58e0d22342b3c6ab7225f9..2967b80a0918531aefc400c17a30f86586bb813f 100644 (file)
@@ -596,7 +596,7 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
     QUERY elem, *r;
     int res = 0;
 
-    if (nid <= 0 || store == NULL)
+    if (nid <= 0 || store == NULL || prop_query == NULL)
         return 0;
 
     if (!ossl_property_read_lock(store))
@@ -605,7 +605,7 @@ int ossl_method_store_cache_get(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
     if (alg == NULL)
         goto err;
 
-    elem.query = prop_query != NULL ? prop_query : "";
+    elem.query = prop_query;
     elem.provider = prov;
     r = lh_QUERY_retrieve(alg->cache, &elem);
     if (r == NULL)
@@ -629,10 +629,8 @@ int ossl_method_store_cache_set(OSSL_METHOD_STORE *store, OSSL_PROVIDER *prov,
     size_t len;
     int res = 1;
 
-    if (nid <= 0 || store == NULL)
+    if (nid <= 0 || store == NULL || prop_query == NULL)
         return 0;
-    if (prop_query == NULL)
-        return 1;
 
     if (!ossl_assert(prov != NULL))
         return 0;
index 10b56bc685751b53a9b2ec12593dbb399fa2591c..4d18645b21ce6baa9e58559cdc5891e89e725be8 100644 (file)
@@ -280,6 +280,7 @@ inner_loader_fetch(struct loader_data_st *methdata, int id,
 {
     OSSL_METHOD_STORE *store = get_loader_store(methdata->libctx);
     OSSL_NAMEMAP *namemap = ossl_namemap_stored(methdata->libctx);
+    const char *const propq = properties != NULL ? properties : "";
     void *method = NULL;
     int unsupported = 0;
 
@@ -309,7 +310,7 @@ inner_loader_fetch(struct loader_data_st *methdata, int id,
         unsupported = 1;
 
     if (id == 0
-        || !ossl_method_store_cache_get(store, NULL, id, properties, &method)) {
+        || !ossl_method_store_cache_get(store, NULL, id, propq, &method)) {
         OSSL_METHOD_CONSTRUCT_METHOD mcm = {
             get_tmp_loader_store,
             get_loader_from_store,
@@ -321,7 +322,7 @@ inner_loader_fetch(struct loader_data_st *methdata, int id,
 
         methdata->scheme_id = id;
         methdata->scheme = scheme;
-        methdata->propquery = properties;
+        methdata->propquery = propq;
         methdata->flag_construct_error_occurred = 0;
         if ((method = ossl_method_construct(methdata->libctx, OSSL_OP_STORE,
                                             &prov, 0 /* !force_cache */,
@@ -333,7 +334,7 @@ inner_loader_fetch(struct loader_data_st *methdata, int id,
              */
             if (id == 0)
                 id = ossl_namemap_name2num(namemap, scheme);
-            ossl_method_store_cache_set(store, prov, id, properties, method,
+            ossl_method_store_cache_set(store, prov, id, propq, method,
                                         up_ref_loader, free_loader);
         }
 
index 5d9219fd0e98c1fec9de5a0cf23203e45f067b7d..e0536edff31993c38f5509b43f42deef3b551ab9 100644 (file)
@@ -102,6 +102,12 @@ The I<method_up_ref> function is called to increment the
 reference count of the method and the I<method_destruct> function is called
 to decrement it.
 
+=head1 NOTES
+
+The I<prop_query> argument to ossl_method_store_cache_get() and
+ossl_method_store_cache_set() is not allowed to be NULL.  Use "" for an
+empty property definition or query.
+
 =head1 RETURN VALUES
 
 ossl_method_store_new() returns a new method store object or NULL on failure.