Convert all {NAME}err() in crypto/ to their corresponding ERR_raise() call
[openssl.git] / crypto / engine / eng_list.c
1 /*
2  * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved.
3  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
4  *
5  * Licensed under the Apache License 2.0 (the "License").  You may not use
6  * this file except in compliance with the License.  You can obtain a copy
7  * in the file LICENSE in the source distribution or at
8  * https://www.openssl.org/source/license.html
9  */
10
11 /* We need to use some engine deprecated APIs */
12 #define OPENSSL_SUPPRESS_DEPRECATED
13
14 #include "eng_local.h"
15
16 /*
17  * The linked-list of pointers to engine types. engine_list_head incorporates
18  * an implicit structural reference but engine_list_tail does not - the
19  * latter is a computational optimization and only points to something that
20  * is already pointed to by its predecessor in the list (or engine_list_head
21  * itself). In the same way, the use of the "prev" pointer in each ENGINE is
22  * to save excessive list iteration, it doesn't correspond to an extra
23  * structural reference. Hence, engine_list_head, and each non-null "next"
24  * pointer account for the list itself assuming exactly 1 structural
25  * reference on each list member.
26  */
27 static ENGINE *engine_list_head = NULL;
28 static ENGINE *engine_list_tail = NULL;
29
30 /*
31  * This cleanup function is only needed internally. If it should be called,
32  * we register it with the "engine_cleanup_int()" stack to be called during
33  * cleanup.
34  */
35
36 static void engine_list_cleanup(void)
37 {
38     ENGINE *iterator = engine_list_head;
39
40     while (iterator != NULL) {
41         ENGINE_remove(iterator);
42         iterator = engine_list_head;
43     }
44     return;
45 }
46
47 /*
48  * These static functions starting with a lower case "engine_" always take
49  * place when global_engine_lock has been locked up.
50  */
51 static int engine_list_add(ENGINE *e)
52 {
53     int conflict = 0;
54     ENGINE *iterator = NULL;
55
56     if (e == NULL) {
57         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
58         return 0;
59     }
60     iterator = engine_list_head;
61     while (iterator && !conflict) {
62         conflict = (strcmp(iterator->id, e->id) == 0);
63         iterator = iterator->next;
64     }
65     if (conflict) {
66         ERR_raise(ERR_LIB_ENGINE, ENGINE_R_CONFLICTING_ENGINE_ID);
67         return 0;
68     }
69     if (engine_list_head == NULL) {
70         /* We are adding to an empty list. */
71         if (engine_list_tail) {
72             ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
73             return 0;
74         }
75         engine_list_head = e;
76         e->prev = NULL;
77         /*
78          * The first time the list allocates, we should register the cleanup.
79          */
80         engine_cleanup_add_last(engine_list_cleanup);
81     } else {
82         /* We are adding to the tail of an existing list. */
83         if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) {
84             ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
85             return 0;
86         }
87         engine_list_tail->next = e;
88         e->prev = engine_list_tail;
89     }
90     /*
91      * Having the engine in the list assumes a structural reference.
92      */
93     e->struct_ref++;
94     engine_ref_debug(e, 0, 1);
95     /* However it came to be, e is the last item in the list. */
96     engine_list_tail = e;
97     e->next = NULL;
98     return 1;
99 }
100
101 static int engine_list_remove(ENGINE *e)
102 {
103     ENGINE *iterator;
104
105     if (e == NULL) {
106         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
107         return 0;
108     }
109     /* We need to check that e is in our linked list! */
110     iterator = engine_list_head;
111     while (iterator && (iterator != e))
112         iterator = iterator->next;
113     if (iterator == NULL) {
114         ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ENGINE_IS_NOT_IN_LIST);
115         return 0;
116     }
117     /* un-link e from the chain. */
118     if (e->next)
119         e->next->prev = e->prev;
120     if (e->prev)
121         e->prev->next = e->next;
122     /* Correct our head/tail if necessary. */
123     if (engine_list_head == e)
124         engine_list_head = e->next;
125     if (engine_list_tail == e)
126         engine_list_tail = e->prev;
127     engine_free_util(e, 0);
128     return 1;
129 }
130
131 /* Get the first/last "ENGINE" type available. */
132 ENGINE *ENGINE_get_first(void)
133 {
134     ENGINE *ret;
135
136     if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
137         ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
138         return NULL;
139     }
140
141     CRYPTO_THREAD_write_lock(global_engine_lock);
142     ret = engine_list_head;
143     if (ret) {
144         ret->struct_ref++;
145         engine_ref_debug(ret, 0, 1);
146     }
147     CRYPTO_THREAD_unlock(global_engine_lock);
148     return ret;
149 }
150
151 ENGINE *ENGINE_get_last(void)
152 {
153     ENGINE *ret;
154
155     if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
156         ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
157         return NULL;
158     }
159
160     CRYPTO_THREAD_write_lock(global_engine_lock);
161     ret = engine_list_tail;
162     if (ret) {
163         ret->struct_ref++;
164         engine_ref_debug(ret, 0, 1);
165     }
166     CRYPTO_THREAD_unlock(global_engine_lock);
167     return ret;
168 }
169
170 /* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */
171 ENGINE *ENGINE_get_next(ENGINE *e)
172 {
173     ENGINE *ret = NULL;
174     if (e == NULL) {
175         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
176         return 0;
177     }
178     CRYPTO_THREAD_write_lock(global_engine_lock);
179     ret = e->next;
180     if (ret) {
181         /* Return a valid structural reference to the next ENGINE */
182         ret->struct_ref++;
183         engine_ref_debug(ret, 0, 1);
184     }
185     CRYPTO_THREAD_unlock(global_engine_lock);
186     /* Release the structural reference to the previous ENGINE */
187     ENGINE_free(e);
188     return ret;
189 }
190
191 ENGINE *ENGINE_get_prev(ENGINE *e)
192 {
193     ENGINE *ret = NULL;
194     if (e == NULL) {
195         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
196         return 0;
197     }
198     CRYPTO_THREAD_write_lock(global_engine_lock);
199     ret = e->prev;
200     if (ret) {
201         /* Return a valid structural reference to the next ENGINE */
202         ret->struct_ref++;
203         engine_ref_debug(ret, 0, 1);
204     }
205     CRYPTO_THREAD_unlock(global_engine_lock);
206     /* Release the structural reference to the previous ENGINE */
207     ENGINE_free(e);
208     return ret;
209 }
210
211 /* Add another "ENGINE" type into the list. */
212 int ENGINE_add(ENGINE *e)
213 {
214     int to_return = 1;
215     if (e == NULL) {
216         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
217         return 0;
218     }
219     if ((e->id == NULL) || (e->name == NULL)) {
220         ERR_raise(ERR_LIB_ENGINE, ENGINE_R_ID_OR_NAME_MISSING);
221         return 0;
222     }
223     CRYPTO_THREAD_write_lock(global_engine_lock);
224     if (!engine_list_add(e)) {
225         ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
226         to_return = 0;
227     }
228     CRYPTO_THREAD_unlock(global_engine_lock);
229     return to_return;
230 }
231
232 /* Remove an existing "ENGINE" type from the array. */
233 int ENGINE_remove(ENGINE *e)
234 {
235     int to_return = 1;
236     if (e == NULL) {
237         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
238         return 0;
239     }
240     CRYPTO_THREAD_write_lock(global_engine_lock);
241     if (!engine_list_remove(e)) {
242         ERR_raise(ERR_LIB_ENGINE, ENGINE_R_INTERNAL_LIST_ERROR);
243         to_return = 0;
244     }
245     CRYPTO_THREAD_unlock(global_engine_lock);
246     return to_return;
247 }
248
249 static void engine_cpy(ENGINE *dest, const ENGINE *src)
250 {
251     dest->id = src->id;
252     dest->name = src->name;
253 #ifndef OPENSSL_NO_RSA
254     dest->rsa_meth = src->rsa_meth;
255 #endif
256 #ifndef OPENSSL_NO_DSA
257     dest->dsa_meth = src->dsa_meth;
258 #endif
259 #ifndef OPENSSL_NO_DH
260     dest->dh_meth = src->dh_meth;
261 #endif
262 #ifndef OPENSSL_NO_EC
263     dest->ec_meth = src->ec_meth;
264 #endif
265     dest->rand_meth = src->rand_meth;
266     dest->ciphers = src->ciphers;
267     dest->digests = src->digests;
268     dest->pkey_meths = src->pkey_meths;
269     dest->destroy = src->destroy;
270     dest->init = src->init;
271     dest->finish = src->finish;
272     dest->ctrl = src->ctrl;
273     dest->load_privkey = src->load_privkey;
274     dest->load_pubkey = src->load_pubkey;
275     dest->cmd_defns = src->cmd_defns;
276     dest->flags = src->flags;
277 }
278
279 ENGINE *ENGINE_by_id(const char *id)
280 {
281     ENGINE *iterator;
282     char *load_dir = NULL;
283     if (id == NULL) {
284         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
285         return NULL;
286     }
287     ENGINE_load_builtin_engines();
288
289     if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) {
290         ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE);
291         return NULL;
292     }
293
294     CRYPTO_THREAD_write_lock(global_engine_lock);
295     iterator = engine_list_head;
296     while (iterator && (strcmp(id, iterator->id) != 0))
297         iterator = iterator->next;
298     if (iterator != NULL) {
299         /*
300          * We need to return a structural reference. If this is an ENGINE
301          * type that returns copies, make a duplicate - otherwise increment
302          * the existing ENGINE's reference count.
303          */
304         if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) {
305             ENGINE *cp = ENGINE_new();
306             if (cp == NULL)
307                 iterator = NULL;
308             else {
309                 engine_cpy(cp, iterator);
310                 iterator = cp;
311             }
312         } else {
313             iterator->struct_ref++;
314             engine_ref_debug(iterator, 0, 1);
315         }
316     }
317     CRYPTO_THREAD_unlock(global_engine_lock);
318     if (iterator != NULL)
319         return iterator;
320     /*
321      * Prevent infinite recursion if we're looking for the dynamic engine.
322      */
323     if (strcmp(id, "dynamic")) {
324         if ((load_dir = ossl_safe_getenv("OPENSSL_ENGINES")) == NULL)
325             load_dir = ENGINESDIR;
326         iterator = ENGINE_by_id("dynamic");
327         if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) ||
328             !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) ||
329             !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
330                                     load_dir, 0) ||
331             !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) ||
332             !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
333             goto notfound;
334         return iterator;
335     }
336  notfound:
337     ENGINE_free(iterator);
338     ERR_raise(ERR_LIB_ENGINE, ENGINE_R_NO_SUCH_ENGINE);
339     ERR_add_error_data(2, "id=", id);
340     return NULL;
341     /* EEK! Experimental code ends */
342 }
343
344 int ENGINE_up_ref(ENGINE *e)
345 {
346     int i;
347     if (e == NULL) {
348         ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER);
349         return 0;
350     }
351     CRYPTO_UP_REF(&e->struct_ref, &i, global_engine_lock);
352     return 1;
353 }