File: | out/../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c |
Warning: | line 310, column 17 Value stored to 'input_structure' during its initialization is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* |
2 | * Copyright 2020-2022 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 <openssl/core_names.h> |
11 | #include <openssl/core_object.h> |
12 | #include <openssl/provider.h> |
13 | #include <openssl/evp.h> |
14 | #include <openssl/ui.h> |
15 | #include <openssl/decoder.h> |
16 | #include <openssl/safestack.h> |
17 | #include <openssl/trace.h> |
18 | #include "crypto/evp.h" |
19 | #include "crypto/decoder.h" |
20 | #include "encoder_local.h" |
21 | |
22 | int OSSL_DECODER_CTX_set_passphrase(OSSL_DECODER_CTX *ctx, |
23 | const unsigned char *kstr, |
24 | size_t klen) |
25 | { |
26 | return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen); |
27 | } |
28 | |
29 | int OSSL_DECODER_CTX_set_passphrase_ui(OSSL_DECODER_CTX *ctx, |
30 | const UI_METHOD *ui_method, |
31 | void *ui_data) |
32 | { |
33 | return ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); |
34 | } |
35 | |
36 | int OSSL_DECODER_CTX_set_pem_password_cb(OSSL_DECODER_CTX *ctx, |
37 | pem_password_cb *cb, void *cbarg) |
38 | { |
39 | return ossl_pw_set_pem_password_cb(&ctx->pwdata, cb, cbarg); |
40 | } |
41 | |
42 | int OSSL_DECODER_CTX_set_passphrase_cb(OSSL_DECODER_CTX *ctx, |
43 | OSSL_PASSPHRASE_CALLBACK *cb, |
44 | void *cbarg) |
45 | { |
46 | return ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg); |
47 | } |
48 | |
49 | /* |
50 | * Support for OSSL_DECODER_CTX_new_for_pkey: |
51 | * The construct data, and collecting keymgmt information for it |
52 | */ |
53 | |
54 | DEFINE_STACK_OF(EVP_KEYMGMT)struct stack_st_EVP_KEYMGMT; typedef int (*sk_EVP_KEYMGMT_compfunc )(const EVP_KEYMGMT * const *a, const EVP_KEYMGMT *const *b); typedef void (*sk_EVP_KEYMGMT_freefunc)(EVP_KEYMGMT *a); typedef EVP_KEYMGMT * (*sk_EVP_KEYMGMT_copyfunc)(const EVP_KEYMGMT * a); static __attribute__((unused)) inline int sk_EVP_KEYMGMT_num (const struct stack_st_EVP_KEYMGMT *sk) { return OPENSSL_sk_num ((const OPENSSL_STACK *)sk); } static __attribute__((unused)) inline EVP_KEYMGMT *sk_EVP_KEYMGMT_value(const struct stack_st_EVP_KEYMGMT *sk, int idx) { return (EVP_KEYMGMT *)OPENSSL_sk_value((const OPENSSL_STACK *)sk, idx); } static __attribute__((unused)) inline struct stack_st_EVP_KEYMGMT *sk_EVP_KEYMGMT_new(sk_EVP_KEYMGMT_compfunc compare) { return (struct stack_st_EVP_KEYMGMT *)OPENSSL_sk_new ((OPENSSL_sk_compfunc)compare); } static __attribute__((unused )) inline struct stack_st_EVP_KEYMGMT *sk_EVP_KEYMGMT_new_null (void) { return (struct stack_st_EVP_KEYMGMT *)OPENSSL_sk_new_null (); } static __attribute__((unused)) inline struct stack_st_EVP_KEYMGMT *sk_EVP_KEYMGMT_new_reserve(sk_EVP_KEYMGMT_compfunc compare, int n) { return (struct stack_st_EVP_KEYMGMT *)OPENSSL_sk_new_reserve ((OPENSSL_sk_compfunc)compare, n); } static __attribute__((unused )) inline int sk_EVP_KEYMGMT_reserve(struct stack_st_EVP_KEYMGMT *sk, int n) { return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); } static __attribute__((unused)) inline void sk_EVP_KEYMGMT_free (struct stack_st_EVP_KEYMGMT *sk) { OPENSSL_sk_free((OPENSSL_STACK *)sk); } static __attribute__((unused)) inline void sk_EVP_KEYMGMT_zero (struct stack_st_EVP_KEYMGMT *sk) { OPENSSL_sk_zero((OPENSSL_STACK *)sk); } static __attribute__((unused)) inline EVP_KEYMGMT * sk_EVP_KEYMGMT_delete(struct stack_st_EVP_KEYMGMT *sk, int i) { return (EVP_KEYMGMT *)OPENSSL_sk_delete((OPENSSL_STACK *)sk , i); } static __attribute__((unused)) inline EVP_KEYMGMT *sk_EVP_KEYMGMT_delete_ptr (struct stack_st_EVP_KEYMGMT *sk, EVP_KEYMGMT *ptr) { return ( EVP_KEYMGMT *)OPENSSL_sk_delete_ptr((OPENSSL_STACK *)sk, (const void *)ptr); } static __attribute__((unused)) inline int sk_EVP_KEYMGMT_push (struct stack_st_EVP_KEYMGMT *sk, EVP_KEYMGMT *ptr) { return OPENSSL_sk_push ((OPENSSL_STACK *)sk, (const void *)ptr); } static __attribute__ ((unused)) inline int sk_EVP_KEYMGMT_unshift(struct stack_st_EVP_KEYMGMT *sk, EVP_KEYMGMT *ptr) { return OPENSSL_sk_unshift((OPENSSL_STACK *)sk, (const void *)ptr); } static __attribute__((unused)) inline EVP_KEYMGMT *sk_EVP_KEYMGMT_pop(struct stack_st_EVP_KEYMGMT * sk) { return (EVP_KEYMGMT *)OPENSSL_sk_pop((OPENSSL_STACK *)sk ); } static __attribute__((unused)) inline EVP_KEYMGMT *sk_EVP_KEYMGMT_shift (struct stack_st_EVP_KEYMGMT *sk) { return (EVP_KEYMGMT *)OPENSSL_sk_shift ((OPENSSL_STACK *)sk); } static __attribute__((unused)) inline void sk_EVP_KEYMGMT_pop_free(struct stack_st_EVP_KEYMGMT *sk , sk_EVP_KEYMGMT_freefunc freefunc) { OPENSSL_sk_pop_free((OPENSSL_STACK *)sk, (OPENSSL_sk_freefunc)freefunc); } static __attribute__ ((unused)) inline int sk_EVP_KEYMGMT_insert(struct stack_st_EVP_KEYMGMT *sk, EVP_KEYMGMT *ptr, int idx) { return OPENSSL_sk_insert(( OPENSSL_STACK *)sk, (const void *)ptr, idx); } static __attribute__ ((unused)) inline EVP_KEYMGMT *sk_EVP_KEYMGMT_set(struct stack_st_EVP_KEYMGMT *sk, int idx, EVP_KEYMGMT *ptr) { return (EVP_KEYMGMT *)OPENSSL_sk_set ((OPENSSL_STACK *)sk, idx, (const void *)ptr); } static __attribute__ ((unused)) inline int sk_EVP_KEYMGMT_find(struct stack_st_EVP_KEYMGMT *sk, EVP_KEYMGMT *ptr) { return OPENSSL_sk_find((OPENSSL_STACK *)sk, (const void *)ptr); } static __attribute__((unused)) inline int sk_EVP_KEYMGMT_find_ex(struct stack_st_EVP_KEYMGMT *sk, EVP_KEYMGMT *ptr) { return OPENSSL_sk_find_ex((OPENSSL_STACK *)sk, (const void *)ptr); } static __attribute__((unused)) inline int sk_EVP_KEYMGMT_find_all (struct stack_st_EVP_KEYMGMT *sk, EVP_KEYMGMT *ptr, int *pnum ) { return OPENSSL_sk_find_all((OPENSSL_STACK *)sk, (const void *)ptr, pnum); } static __attribute__((unused)) inline void sk_EVP_KEYMGMT_sort (struct stack_st_EVP_KEYMGMT *sk) { OPENSSL_sk_sort((OPENSSL_STACK *)sk); } static __attribute__((unused)) inline int sk_EVP_KEYMGMT_is_sorted (const struct stack_st_EVP_KEYMGMT *sk) { return OPENSSL_sk_is_sorted ((const OPENSSL_STACK *)sk); } static __attribute__((unused)) inline struct stack_st_EVP_KEYMGMT * sk_EVP_KEYMGMT_dup(const struct stack_st_EVP_KEYMGMT *sk) { return (struct stack_st_EVP_KEYMGMT *)OPENSSL_sk_dup((const OPENSSL_STACK *)sk); } static __attribute__ ((unused)) inline struct stack_st_EVP_KEYMGMT *sk_EVP_KEYMGMT_deep_copy (const struct stack_st_EVP_KEYMGMT *sk, sk_EVP_KEYMGMT_copyfunc copyfunc, sk_EVP_KEYMGMT_freefunc freefunc) { return (struct stack_st_EVP_KEYMGMT *)OPENSSL_sk_deep_copy((const OPENSSL_STACK *)sk, (OPENSSL_sk_copyfunc)copyfunc, (OPENSSL_sk_freefunc)freefunc ); } static __attribute__((unused)) inline sk_EVP_KEYMGMT_compfunc sk_EVP_KEYMGMT_set_cmp_func(struct stack_st_EVP_KEYMGMT *sk, sk_EVP_KEYMGMT_compfunc compare) { return (sk_EVP_KEYMGMT_compfunc )OPENSSL_sk_set_cmp_func((OPENSSL_STACK *)sk, (OPENSSL_sk_compfunc )compare); } |
55 | |
56 | struct decoder_pkey_data_st { |
57 | OSSL_LIB_CTX *libctx; |
58 | char *propq; |
59 | int selection; |
60 | |
61 | STACK_OF(EVP_KEYMGMT)struct stack_st_EVP_KEYMGMT *keymgmts; |
62 | char *object_type; /* recorded object data type, may be NULL */ |
63 | void **object; /* Where the result should end up */ |
64 | }; |
65 | |
66 | static int decoder_construct_pkey(OSSL_DECODER_INSTANCE *decoder_inst, |
67 | const OSSL_PARAM *params, |
68 | void *construct_data) |
69 | { |
70 | struct decoder_pkey_data_st *data = construct_data; |
71 | OSSL_DECODER *decoder = OSSL_DECODER_INSTANCE_get_decoder(decoder_inst); |
72 | void *decoderctx = OSSL_DECODER_INSTANCE_get_decoder_ctx(decoder_inst); |
73 | const OSSL_PROVIDER *decoder_prov = OSSL_DECODER_get0_provider(decoder); |
74 | EVP_KEYMGMT *keymgmt = NULL((void*)0); |
75 | const OSSL_PROVIDER *keymgmt_prov = NULL((void*)0); |
76 | int i, end; |
77 | /* |
78 | * |object_ref| points to a provider reference to an object, its exact |
79 | * contents entirely opaque to us, but may be passed to any provider |
80 | * function that expects this (such as OSSL_FUNC_keymgmt_load(). |
81 | * |
82 | * This pointer is considered volatile, i.e. whatever it points at |
83 | * is assumed to be freed as soon as this function returns. |
84 | */ |
85 | void *object_ref = NULL((void*)0); |
86 | size_t object_ref_sz = 0; |
87 | const OSSL_PARAM *p; |
88 | |
89 | p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_TYPE"data-type"); |
90 | if (p != NULL((void*)0)) { |
91 | char *object_type = NULL((void*)0); |
92 | |
93 | if (!OSSL_PARAM_get_utf8_string(p, &object_type, 0)) |
94 | return 0; |
95 | OPENSSL_free(data->object_type)CRYPTO_free(data->object_type, "../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" , 95); |
96 | data->object_type = object_type; |
97 | } |
98 | |
99 | /* |
100 | * For stuff that should end up in an EVP_PKEY, we only accept an object |
101 | * reference for the moment. This enforces that the key data itself |
102 | * remains with the provider. |
103 | */ |
104 | p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_REFERENCE"reference"); |
105 | if (p == NULL((void*)0) || p->data_type != OSSL_PARAM_OCTET_STRING5) |
106 | return 0; |
107 | object_ref = p->data; |
108 | object_ref_sz = p->data_size; |
109 | |
110 | /* |
111 | * First, we try to find a keymgmt that comes from the same provider as |
112 | * the decoder that passed the params. |
113 | */ |
114 | end = sk_EVP_KEYMGMT_num(data->keymgmts); |
115 | for (i = 0; i < end; i++) { |
116 | keymgmt = sk_EVP_KEYMGMT_value(data->keymgmts, i); |
117 | keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt); |
118 | |
119 | if (keymgmt_prov == decoder_prov |
120 | && evp_keymgmt_has_load(keymgmt) |
121 | && EVP_KEYMGMT_is_a(keymgmt, data->object_type)) |
122 | break; |
123 | } |
124 | if (i < end) { |
125 | /* To allow it to be freed further down */ |
126 | if (!EVP_KEYMGMT_up_ref(keymgmt)) |
127 | return 0; |
128 | } else if ((keymgmt = EVP_KEYMGMT_fetch(data->libctx, |
129 | data->object_type, |
130 | data->propq)) != NULL((void*)0)) { |
131 | keymgmt_prov = EVP_KEYMGMT_get0_provider(keymgmt); |
132 | } |
133 | |
134 | if (keymgmt != NULL((void*)0)) { |
135 | EVP_PKEY *pkey = NULL((void*)0); |
136 | void *keydata = NULL((void*)0); |
137 | |
138 | /* |
139 | * If the EVP_KEYMGMT and the OSSL_DECODER are from the |
140 | * same provider, we assume that the KEYMGMT has a key loading |
141 | * function that can handle the provider reference we hold. |
142 | * |
143 | * Otherwise, we export from the decoder and import the |
144 | * result in the keymgmt. |
145 | */ |
146 | if (keymgmt_prov == decoder_prov) { |
147 | keydata = evp_keymgmt_load(keymgmt, object_ref, object_ref_sz); |
148 | } else { |
149 | struct evp_keymgmt_util_try_import_data_st import_data; |
150 | |
151 | import_data.keymgmt = keymgmt; |
152 | import_data.keydata = NULL((void*)0); |
153 | import_data.selection = data->selection; |
154 | |
155 | /* |
156 | * No need to check for errors here, the value of |
157 | * |import_data.keydata| is as much an indicator. |
158 | */ |
159 | (void)decoder->export_object(decoderctx, |
160 | object_ref, object_ref_sz, |
161 | &evp_keymgmt_util_try_import, |
162 | &import_data); |
163 | keydata = import_data.keydata; |
164 | import_data.keydata = NULL((void*)0); |
165 | } |
166 | |
167 | if (keydata != NULL((void*)0) |
168 | && (pkey = evp_keymgmt_util_make_pkey(keymgmt, keydata)) == NULL((void*)0)) |
169 | evp_keymgmt_freedata(keymgmt, keydata); |
170 | |
171 | *data->object = pkey; |
172 | |
173 | /* |
174 | * evp_keymgmt_util_make_pkey() increments the reference count when |
175 | * assigning the EVP_PKEY, so we can free the keymgmt here. |
176 | */ |
177 | EVP_KEYMGMT_free(keymgmt); |
178 | } |
179 | /* |
180 | * We successfully looked through, |*ctx->object| determines if we |
181 | * actually found something. |
182 | */ |
183 | return (*data->object != NULL((void*)0)); |
184 | } |
185 | |
186 | static void decoder_clean_pkey_construct_arg(void *construct_data) |
187 | { |
188 | struct decoder_pkey_data_st *data = construct_data; |
189 | |
190 | if (data != NULL((void*)0)) { |
191 | sk_EVP_KEYMGMT_pop_free(data->keymgmts, EVP_KEYMGMT_free); |
192 | OPENSSL_free(data->propq)CRYPTO_free(data->propq, "../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" , 192); |
193 | OPENSSL_free(data->object_type)CRYPTO_free(data->object_type, "../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" , 193); |
194 | OPENSSL_free(data)CRYPTO_free(data, "../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" , 194); |
195 | } |
196 | } |
197 | |
198 | static void collect_name(const char *name, void *arg) |
199 | { |
200 | STACK_OF(OPENSSL_CSTRING)struct stack_st_OPENSSL_CSTRING *names = arg; |
201 | |
202 | sk_OPENSSL_CSTRING_push(names, name)OPENSSL_sk_push(ossl_check_OPENSSL_CSTRING_sk_type(names), ossl_check_OPENSSL_CSTRING_type (name)); |
203 | } |
204 | |
205 | static void collect_keymgmt(EVP_KEYMGMT *keymgmt, void *arg) |
206 | { |
207 | STACK_OF(EVP_KEYMGMT)struct stack_st_EVP_KEYMGMT *keymgmts = arg; |
208 | |
209 | if (!EVP_KEYMGMT_up_ref(keymgmt) /* ref++ */) |
210 | return; |
211 | if (sk_EVP_KEYMGMT_push(keymgmts, keymgmt) <= 0) { |
212 | EVP_KEYMGMT_free(keymgmt); /* ref-- */ |
213 | return; |
214 | } |
215 | } |
216 | |
217 | struct collect_decoder_data_st { |
218 | STACK_OF(OPENSSL_CSTRING)struct stack_st_OPENSSL_CSTRING *names; |
219 | OSSL_DECODER_CTX *ctx; |
220 | |
221 | int total; |
222 | unsigned int error_occurred:1; |
223 | }; |
224 | |
225 | static void collect_decoder(OSSL_DECODER *decoder, void *arg) |
226 | { |
227 | struct collect_decoder_data_st *data = arg; |
228 | size_t i, end_i; |
229 | const OSSL_PROVIDER *prov = OSSL_DECODER_get0_provider(decoder); |
230 | void *provctx = OSSL_PROVIDER_get0_provider_ctx(prov); |
231 | |
232 | if (data->error_occurred) |
233 | return; |
234 | |
235 | if (data->names == NULL((void*)0)) { |
236 | data->error_occurred = 1; |
237 | return; |
238 | } |
239 | |
240 | /* |
241 | * Either the caller didn't give a selection, or if they did, |
242 | * the decoder must tell us if it supports that selection to |
243 | * be accepted. If the decoder doesn't have |does_selection|, |
244 | * it's seen as taking anything. |
245 | */ |
246 | if (decoder->does_selection != NULL((void*)0) |
247 | && !decoder->does_selection(provctx, data->ctx->selection)) |
248 | return; |
249 | |
250 | OSSL_TRACE_BEGIN(DECODER)do { BIO *trc_out = ((void*)0); if (0) { |
251 | BIO_printf(trc_out, |
252 | "(ctx %p) Checking out decoder %p:\n" |
253 | " %s with %s\n", |
254 | (void *)data->ctx, (void *)decoder, |
255 | OSSL_DECODER_get0_name(decoder), |
256 | OSSL_DECODER_get0_properties(decoder)); |
257 | } OSSL_TRACE_END(DECODER)} while(0); |
258 | |
259 | end_i = sk_OPENSSL_CSTRING_num(data->names)OPENSSL_sk_num(ossl_check_const_OPENSSL_CSTRING_sk_type(data-> names)); |
260 | for (i = 0; i < end_i; i++) { |
261 | const char *name = sk_OPENSSL_CSTRING_value(data->names, i)((const char *)OPENSSL_sk_value(ossl_check_const_OPENSSL_CSTRING_sk_type (data->names), (i))); |
262 | |
263 | if (OSSL_DECODER_is_a(decoder, name)) { |
264 | void *decoderctx = NULL((void*)0); |
265 | OSSL_DECODER_INSTANCE *di = NULL((void*)0); |
266 | |
267 | if ((decoderctx = decoder->newctx(provctx)) == NULL((void*)0)) { |
268 | data->error_occurred = 1; |
269 | return; |
270 | } |
271 | if ((di = ossl_decoder_instance_new(decoder, decoderctx)) == NULL((void*)0)) { |
272 | decoder->freectx(decoderctx); |
273 | data->error_occurred = 1; |
274 | return; |
275 | } |
276 | |
277 | OSSL_TRACE_BEGIN(DECODER)do { BIO *trc_out = ((void*)0); if (0) { |
278 | BIO_printf(trc_out, |
279 | "(ctx %p) Checking out decoder %p:\n" |
280 | " %s with %s\n", |
281 | (void *)data->ctx, (void *)decoder, |
282 | OSSL_DECODER_get0_name(decoder), |
283 | OSSL_DECODER_get0_properties(decoder)); |
284 | } OSSL_TRACE_END(DECODER)} while(0); |
285 | |
286 | if (!ossl_decoder_ctx_add_decoder_inst(data->ctx, di)) { |
287 | ossl_decoder_instance_free(di); |
288 | data->error_occurred = 1; |
289 | return; |
290 | } |
291 | data->total++; |
292 | |
293 | /* Success */ |
294 | return; |
295 | } |
296 | } |
297 | |
298 | /* Decoder not suitable - but not a fatal error */ |
299 | data->error_occurred = 0; |
300 | } |
301 | |
302 | int ossl_decoder_ctx_setup_for_pkey(OSSL_DECODER_CTX *ctx, |
303 | EVP_PKEY **pkey, const char *keytype, |
304 | OSSL_LIB_CTX *libctx, |
305 | const char *propquery) |
306 | { |
307 | struct decoder_pkey_data_st *process_data = NULL((void*)0); |
308 | STACK_OF(OPENSSL_CSTRING)struct stack_st_OPENSSL_CSTRING *names = NULL((void*)0); |
309 | const char *input_type = ctx->start_input_type; |
310 | const char *input_structure = ctx->input_structure; |
Value stored to 'input_structure' during its initialization is never read | |
311 | int ok = 0; |
312 | int isecoid = 0; |
313 | int i, end; |
314 | |
315 | if (keytype != NULL((void*)0) |
316 | && (strcmp(keytype, "id-ecPublicKey") == 0 |
317 | || strcmp(keytype, "1.2.840.10045.2.1") == 0)) |
318 | isecoid = 1; |
319 | |
320 | OSSL_TRACE_BEGIN(DECODER)do { BIO *trc_out = ((void*)0); if (0) { |
321 | BIO_printf(trc_out, |
322 | "(ctx %p) Looking for decoders producing %s%s%s%s%s%s\n", |
323 | (void *)ctx, |
324 | keytype != NULL((void*)0) ? keytype : "", |
325 | keytype != NULL((void*)0) ? " keys" : "keys of any type", |
326 | input_type != NULL((void*)0) ? " from " : "", |
327 | input_type != NULL((void*)0) ? input_type : "", |
328 | input_structure != NULL((void*)0) ? " with " : "", |
329 | input_structure != NULL((void*)0) ? input_structure : ""); |
330 | } OSSL_TRACE_END(DECODER)} while(0); |
331 | |
332 | if ((process_data = OPENSSL_zalloc(sizeof(*process_data))CRYPTO_zalloc(sizeof(*process_data), "../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" , 332)) == NULL((void*)0) |
333 | || (propquery != NULL((void*)0) |
334 | && (process_data->propq = OPENSSL_strdup(propquery)CRYPTO_strdup(propquery, "../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" , 334)) == NULL((void*)0)) |
335 | || (process_data->keymgmts = sk_EVP_KEYMGMT_new_null()) == NULL((void*)0) |
336 | || (names = sk_OPENSSL_CSTRING_new_null()((struct stack_st_OPENSSL_CSTRING *)OPENSSL_sk_new_null())) == NULL((void*)0)) { |
337 | ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" ,337,__func__), ERR_set_error)((60),((256|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); |
338 | goto err; |
339 | } |
340 | |
341 | process_data->object = (void **)pkey; |
342 | process_data->libctx = libctx; |
343 | process_data->selection = ctx->selection; |
344 | |
345 | /* First, find all keymgmts to form goals */ |
346 | EVP_KEYMGMT_do_all_provided(libctx, collect_keymgmt, |
347 | process_data->keymgmts); |
348 | |
349 | /* Then, we collect all the keymgmt names */ |
350 | end = sk_EVP_KEYMGMT_num(process_data->keymgmts); |
351 | for (i = 0; i < end; i++) { |
352 | EVP_KEYMGMT *keymgmt = sk_EVP_KEYMGMT_value(process_data->keymgmts, i); |
353 | |
354 | /* |
355 | * If the key type is given by the caller, we only use the matching |
356 | * KEYMGMTs, otherwise we use them all. |
357 | * We have to special case SM2 here because of its abuse of the EC OID. |
358 | * The EC OID can be used to identify an EC key or an SM2 key - so if |
359 | * we have seen that OID we try both key types |
360 | */ |
361 | if (keytype == NULL((void*)0) |
362 | || EVP_KEYMGMT_is_a(keymgmt, keytype) |
363 | || (isecoid && EVP_KEYMGMT_is_a(keymgmt, "SM2"))) { |
364 | if (!EVP_KEYMGMT_names_do_all(keymgmt, collect_name, names)) { |
365 | ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_INTERNAL_ERROR)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" ,365,__func__), ERR_set_error)((60),((259|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); |
366 | goto err; |
367 | } |
368 | } |
369 | } |
370 | |
371 | OSSL_TRACE_BEGIN(DECODER)do { BIO *trc_out = ((void*)0); if (0) { |
372 | end = sk_OPENSSL_CSTRING_num(names)OPENSSL_sk_num(ossl_check_const_OPENSSL_CSTRING_sk_type(names )); |
373 | BIO_printf(trc_out, |
374 | " Found %d keytypes (possibly with duplicates)", |
375 | end); |
376 | for (i = 0; i < end; i++) |
377 | BIO_printf(trc_out, "%s%s", |
378 | i == 0 ? ": " : ", ", |
379 | sk_OPENSSL_CSTRING_value(names, i)((const char *)OPENSSL_sk_value(ossl_check_const_OPENSSL_CSTRING_sk_type (names), (i)))); |
380 | BIO_printf(trc_out, "\n"); |
381 | } OSSL_TRACE_END(DECODER)} while(0); |
382 | |
383 | /* |
384 | * Finally, find all decoders that have any keymgmt of the collected |
385 | * keymgmt names |
386 | */ |
387 | { |
388 | struct collect_decoder_data_st collect_decoder_data = { NULL((void*)0), }; |
389 | |
390 | collect_decoder_data.names = names; |
391 | collect_decoder_data.ctx = ctx; |
392 | OSSL_DECODER_do_all_provided(libctx, |
393 | collect_decoder, &collect_decoder_data); |
394 | sk_OPENSSL_CSTRING_free(names)OPENSSL_sk_free(ossl_check_OPENSSL_CSTRING_sk_type(names)); |
395 | names = NULL((void*)0); |
396 | |
397 | if (collect_decoder_data.error_occurred) |
398 | goto err; |
399 | |
400 | OSSL_TRACE_BEGIN(DECODER)do { BIO *trc_out = ((void*)0); if (0) { |
401 | BIO_printf(trc_out, |
402 | "(ctx %p) Got %d decoders producing keys\n", |
403 | (void *)ctx, collect_decoder_data.total); |
404 | } OSSL_TRACE_END(DECODER)} while(0); |
405 | } |
406 | |
407 | if (OSSL_DECODER_CTX_get_num_decoders(ctx) != 0) { |
408 | if (!OSSL_DECODER_CTX_set_construct(ctx, decoder_construct_pkey) |
409 | || !OSSL_DECODER_CTX_set_construct_data(ctx, process_data) |
410 | || !OSSL_DECODER_CTX_set_cleanup(ctx, |
411 | decoder_clean_pkey_construct_arg)) |
412 | goto err; |
413 | |
414 | process_data = NULL((void*)0); /* Avoid it being freed */ |
415 | } |
416 | |
417 | ok = 1; |
418 | err: |
419 | decoder_clean_pkey_construct_arg(process_data); |
420 | sk_OPENSSL_CSTRING_free(names)OPENSSL_sk_free(ossl_check_OPENSSL_CSTRING_sk_type(names)); |
421 | |
422 | return ok; |
423 | } |
424 | |
425 | OSSL_DECODER_CTX * |
426 | OSSL_DECODER_CTX_new_for_pkey(EVP_PKEY **pkey, |
427 | const char *input_type, |
428 | const char *input_structure, |
429 | const char *keytype, int selection, |
430 | OSSL_LIB_CTX *libctx, const char *propquery) |
431 | { |
432 | OSSL_DECODER_CTX *ctx = NULL((void*)0); |
433 | |
434 | if ((ctx = OSSL_DECODER_CTX_new()) == NULL((void*)0)) { |
435 | ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE)(ERR_new(), ERR_set_debug("../deps/openssl/openssl/crypto/encode_decode/decoder_pkey.c" ,435,__func__), ERR_set_error)((60),((256|((0x1 << 18L) |(0x2 << 18L)))),((void*)0)); |
436 | return NULL((void*)0); |
437 | } |
438 | |
439 | OSSL_TRACE_BEGIN(DECODER)do { BIO *trc_out = ((void*)0); if (0) { |
440 | BIO_printf(trc_out, |
441 | "(ctx %p) Looking for %s decoders with selection %d\n", |
442 | (void *)ctx, keytype, selection); |
443 | BIO_printf(trc_out, " input type: %s, input structure: %s\n", |
444 | input_type, input_structure); |
445 | } OSSL_TRACE_END(DECODER)} while(0); |
446 | |
447 | if (OSSL_DECODER_CTX_set_input_type(ctx, input_type) |
448 | && OSSL_DECODER_CTX_set_input_structure(ctx, input_structure) |
449 | && OSSL_DECODER_CTX_set_selection(ctx, selection) |
450 | && ossl_decoder_ctx_setup_for_pkey(ctx, pkey, keytype, |
451 | libctx, propquery) |
452 | && OSSL_DECODER_CTX_add_extra(ctx, libctx, propquery)) { |
453 | OSSL_TRACE_BEGIN(DECODER)do { BIO *trc_out = ((void*)0); if (0) { |
454 | BIO_printf(trc_out, "(ctx %p) Got %d decoders\n", |
455 | (void *)ctx, OSSL_DECODER_CTX_get_num_decoders(ctx)); |
456 | } OSSL_TRACE_END(DECODER)} while(0); |
457 | return ctx; |
458 | } |
459 | |
460 | OSSL_DECODER_CTX_free(ctx); |
461 | return NULL((void*)0); |
462 | } |