Move wp_asm_src file information to build.info files
[openssl.git] / crypto / core_fetch.c
1 /*
2  * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stddef.h>
11
12 #include <openssl/core.h>
13 #include "internal/cryptlib.h"
14 #include "internal/core.h"
15 #include "internal/property.h"
16 #include "internal/provider.h"
17
18 struct construct_data_st {
19     OPENSSL_CTX *libctx;
20     OSSL_METHOD_STORE *store;
21     int operation_id;
22     int force_store;
23     OSSL_METHOD_CONSTRUCT_METHOD *mcm;
24     void *mcm_data;
25 };
26
27 static int ossl_method_construct_this(OSSL_PROVIDER *provider, void *cbdata)
28 {
29     struct construct_data_st *data = cbdata;
30     int no_store = 0;    /* Assume caching is ok */
31     const OSSL_ALGORITHM *map =
32         ossl_provider_query_operation(provider, data->operation_id, &no_store);
33
34     if (map == NULL)
35         return 0;
36
37     while (map->algorithm_name != NULL) {
38         const OSSL_ALGORITHM *thismap = map++;
39         void *method = NULL;
40
41         if ((method = data->mcm->construct(thismap->algorithm_name,
42                                            thismap->implementation, provider,
43                                            data->mcm_data)) == NULL)
44             continue;
45
46         /*
47          * Note regarding putting the method in stores:
48          *
49          * we don't need to care if it actually got in or not here.
50          * If it didn't get in, it will simply not be available when
51          * ossl_method_construct() tries to get it from the store.
52          *
53          * It is *expected* that the put function increments the refcnt
54          * of the passed method.
55          */
56
57         if (data->force_store || !no_store) {
58             /*
59              * If we haven't been told not to store,
60              * add to the global store
61              */
62             data->mcm->put(data->libctx, NULL, method, data->operation_id,
63                            thismap->algorithm_name,
64                            thismap->property_definition, data->mcm_data);
65         }
66
67         data->mcm->put(data->libctx, data->store, method, data->operation_id,
68                        thismap->algorithm_name, thismap->property_definition,
69                        data->mcm_data);
70
71         /* refcnt-- because we're dropping the reference */
72         data->mcm->destruct(method, data->mcm_data);
73     }
74
75     return 1;
76 }
77
78 void *ossl_method_construct(OPENSSL_CTX *libctx, int operation_id,
79                             const char *name, const char *propquery,
80                             int force_store,
81                             OSSL_METHOD_CONSTRUCT_METHOD *mcm, void *mcm_data)
82 {
83     void *method = NULL;
84
85     if ((method =
86          mcm->get(libctx, NULL, operation_id, name, propquery, mcm_data))
87         == NULL) {
88         struct construct_data_st cbdata;
89
90         /*
91          * We have a temporary store to be able to easily search among new
92          * items, or items that should find themselves in the global store.
93          */
94         if ((cbdata.store = mcm->alloc_tmp_store(libctx)) == NULL)
95             goto fin;
96
97         cbdata.libctx = libctx;
98         cbdata.operation_id = operation_id;
99         cbdata.force_store = force_store;
100         cbdata.mcm = mcm;
101         cbdata.mcm_data = mcm_data;
102         ossl_provider_forall_loaded(libctx, ossl_method_construct_this,
103                                     &cbdata);
104
105         method = mcm->get(libctx, cbdata.store, operation_id, name,
106                           propquery, mcm_data);
107         mcm->dealloc_tmp_store(cbdata.store);
108     }
109
110  fin:
111     return method;
112 }