]>
Commit | Line | Data |
---|---|---|
b1322259 | 1 | /* |
e39e295e | 2 | * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. |
b6d1e52d | 3 | * |
3c120f91 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
b1322259 RS |
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 | |
b6d1e52d GT |
8 | */ |
9 | ||
e4468e6d P |
10 | /* We need to use some engine deprecated APIs */ |
11 | #define OPENSSL_SUPPRESS_DEPRECATED | |
12 | ||
677963e5 | 13 | #include "e_os.h" |
706457b7 | 14 | #include "eng_local.h" |
b6d1e52d | 15 | |
0f113f3e MC |
16 | /* |
17 | * Initialise a engine type for use (or up its functional reference count if | |
18 | * it's already in use). This version is only used internally. | |
19 | */ | |
b6d1e52d | 20 | int engine_unlocked_init(ENGINE *e) |
0f113f3e MC |
21 | { |
22 | int to_return = 1; | |
b6d1e52d | 23 | |
0f113f3e MC |
24 | if ((e->funct_ref == 0) && e->init) |
25 | /* | |
26 | * This is the first functional reference and the engine requires | |
27 | * initialisation so we do it now. | |
28 | */ | |
29 | to_return = e->init(e); | |
30 | if (to_return) { | |
31 | /* | |
32 | * OK, we return a functional reference which is also a structural | |
33 | * reference. | |
34 | */ | |
35 | e->struct_ref++; | |
36 | e->funct_ref++; | |
43d6702d F |
37 | engine_ref_debug(e, 0, 1); |
38 | engine_ref_debug(e, 1, 1); | |
0f113f3e MC |
39 | } |
40 | return to_return; | |
41 | } | |
b6d1e52d | 42 | |
0f113f3e MC |
43 | /* |
44 | * Free a functional reference to a engine type. This version is only used | |
45 | * internally. | |
46 | */ | |
b6d1e52d | 47 | int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) |
0f113f3e MC |
48 | { |
49 | int to_return = 1; | |
b6d1e52d | 50 | |
0f113f3e MC |
51 | /* |
52 | * Reduce the functional reference count here so if it's the terminating | |
53 | * case, we can release the lock safely and call the finish() handler | |
54 | * without risk of a race. We get a race if we leave the count until | |
55 | * after and something else is calling "finish" at the same time - | |
56 | * there's a chance that both threads will together take the count from 2 | |
57 | * to 0 without either calling finish(). | |
58 | */ | |
59 | e->funct_ref--; | |
60 | engine_ref_debug(e, 1, -1); | |
61 | if ((e->funct_ref == 0) && e->finish) { | |
62 | if (unlock_for_handlers) | |
40e068d5 | 63 | CRYPTO_THREAD_unlock(global_engine_lock); |
0f113f3e MC |
64 | to_return = e->finish(e); |
65 | if (unlock_for_handlers) | |
40e068d5 | 66 | CRYPTO_THREAD_write_lock(global_engine_lock); |
0f113f3e MC |
67 | if (!to_return) |
68 | return 0; | |
69 | } | |
f3f1cf84 | 70 | REF_ASSERT_ISNT(e->funct_ref < 0); |
0f113f3e MC |
71 | /* Release the structural reference too */ |
72 | if (!engine_free_util(e, 0)) { | |
9311d0c4 | 73 | ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED); |
0f113f3e MC |
74 | return 0; |
75 | } | |
76 | return to_return; | |
77 | } | |
b6d1e52d GT |
78 | |
79 | /* The API (locked) version of "init" */ | |
80 | int ENGINE_init(ENGINE *e) | |
0f113f3e MC |
81 | { |
82 | int ret; | |
83 | if (e == NULL) { | |
9311d0c4 | 84 | ERR_raise(ERR_LIB_ENGINE, ERR_R_PASSED_NULL_PARAMETER); |
0f113f3e MC |
85 | return 0; |
86 | } | |
c2e4e5d2 | 87 | if (!RUN_ONCE(&engine_lock_init, do_engine_lock_init)) { |
9311d0c4 | 88 | ERR_raise(ERR_LIB_ENGINE, ERR_R_MALLOC_FAILURE); |
c2e4e5d2 RL |
89 | return 0; |
90 | } | |
40e068d5 | 91 | CRYPTO_THREAD_write_lock(global_engine_lock); |
0f113f3e | 92 | ret = engine_unlocked_init(e); |
40e068d5 | 93 | CRYPTO_THREAD_unlock(global_engine_lock); |
0f113f3e MC |
94 | return ret; |
95 | } | |
b6d1e52d GT |
96 | |
97 | /* The API (locked) version of "finish" */ | |
98 | int ENGINE_finish(ENGINE *e) | |
0f113f3e MC |
99 | { |
100 | int to_return = 1; | |
b6d1e52d | 101 | |
7c96dbcd RS |
102 | if (e == NULL) |
103 | return 1; | |
40e068d5 | 104 | CRYPTO_THREAD_write_lock(global_engine_lock); |
0f113f3e | 105 | to_return = engine_unlocked_finish(e, 1); |
40e068d5 | 106 | CRYPTO_THREAD_unlock(global_engine_lock); |
0f113f3e | 107 | if (!to_return) { |
9311d0c4 | 108 | ERR_raise(ERR_LIB_ENGINE, ENGINE_R_FINISH_FAILED); |
0f113f3e MC |
109 | return 0; |
110 | } | |
111 | return to_return; | |
112 | } |