]>
Commit | Line | Data |
---|---|---|
71a5516d | 1 | /* |
33388b44 | 2 | * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved. |
71a5516d | 3 | * |
5c0d0c86 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
71a5516d RL |
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 <stdlib.h> | |
11 | #include <string.h> | |
072bfcc9 | 12 | #include <assert.h> |
34b80d06 | 13 | |
a1447076 RL |
14 | /* We need to use some STORE deprecated APIs */ |
15 | #define OPENSSL_SUPPRESS_DEPRECATED | |
16 | ||
34b80d06 RL |
17 | #include "e_os.h" |
18 | ||
71a5516d RL |
19 | #include <openssl/crypto.h> |
20 | #include <openssl/err.h> | |
2897b009 | 21 | #include <openssl/trace.h> |
34b80d06 RL |
22 | #include <openssl/core_names.h> |
23 | #include <openssl/provider.h> | |
24 | #include <openssl/param_build.h> | |
71a5516d RL |
25 | #include <openssl/store.h> |
26 | #include "internal/thread_once.h" | |
34b80d06 RL |
27 | #include "internal/cryptlib.h" |
28 | #include "internal/provider.h" | |
25f2138b | 29 | #include "crypto/store.h" |
706457b7 | 30 | #include "store_local.h" |
71a5516d | 31 | |
34b80d06 | 32 | static int ossl_store_close_it(OSSL_STORE_CTX *ctx); |
71a5516d | 33 | |
34b80d06 RL |
34 | OSSL_STORE_CTX * |
35 | OSSL_STORE_open_with_libctx(const char *uri, | |
36 | OPENSSL_CTX *libctx, const char *propq, | |
37 | const UI_METHOD *ui_method, void *ui_data, | |
38 | OSSL_STORE_post_process_info_fn post_process, | |
39 | void *post_process_data) | |
71a5516d | 40 | { |
ae9c39d8 | 41 | const OSSL_STORE_LOADER *loader = NULL; |
34b80d06 | 42 | OSSL_STORE_LOADER *fetched_loader = NULL; |
71a5516d RL |
43 | OSSL_STORE_LOADER_CTX *loader_ctx = NULL; |
44 | OSSL_STORE_CTX *ctx = NULL; | |
34b80d06 | 45 | char *propq_copy = NULL; |
ae9c39d8 RL |
46 | char scheme_copy[256], *p, *schemes[2]; |
47 | size_t schemes_n = 0; | |
48 | size_t i; | |
49 | ||
50 | /* | |
51 | * Put the file scheme first. If the uri does represent an existing file, | |
52 | * possible device name and all, then it should be loaded. Only a failed | |
53 | * attempt at loading a local file should have us try something else. | |
54 | */ | |
55 | schemes[schemes_n++] = "file"; | |
71a5516d | 56 | |
ae9c39d8 RL |
57 | /* |
58 | * Now, check if we have something that looks like a scheme, and add it | |
59 | * as a second scheme. However, also check if there's an authority start | |
60 | * (://), because that will invalidate the previous file scheme. Also, | |
61 | * check that this isn't actually the file scheme, as there's no point | |
62 | * going through that one twice! | |
63 | */ | |
71a5516d RL |
64 | OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy)); |
65 | if ((p = strchr(scheme_copy, ':')) != NULL) { | |
ae9c39d8 RL |
66 | *p++ = '\0'; |
67 | if (strcasecmp(scheme_copy, "file") != 0) { | |
68 | if (strncmp(p, "//", 2) == 0) | |
69 | schemes_n--; /* Invalidate the file scheme */ | |
70 | schemes[schemes_n++] = scheme_copy; | |
71 | } | |
71a5516d RL |
72 | } |
73 | ||
140dab3d RL |
74 | ERR_set_mark(); |
75 | ||
34b80d06 RL |
76 | /* |
77 | * Try each scheme until we find one that could open the URI. | |
78 | * | |
79 | * For each scheme, we look for the engine implementation first, and | |
80 | * failing that, we then try to fetch a provided implementation. | |
81 | * This is consistent with how we handle legacy / engine implementations | |
82 | * elsewhere. | |
83 | */ | |
ae9c39d8 | 84 | for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { |
2897b009 | 85 | OSSL_TRACE1(STORE, "Looking up scheme %s\n", schemes[i]); |
a1447076 | 86 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
2897b009 | 87 | if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) { |
6725682d SL |
88 | if (loader->open_with_libctx != NULL) |
89 | loader_ctx = loader->open_with_libctx(loader, uri, libctx, propq, | |
90 | ui_method, ui_data); | |
91 | else | |
92 | loader_ctx = loader->open(loader, uri, ui_method, ui_data); | |
34b80d06 | 93 | } |
a1447076 | 94 | #endif |
34b80d06 RL |
95 | if (loader == NULL |
96 | && (fetched_loader = | |
97 | OSSL_STORE_LOADER_fetch(schemes[i], libctx, propq)) != NULL) { | |
98 | const OSSL_PROVIDER *provider = | |
99 | OSSL_STORE_LOADER_provider(fetched_loader); | |
100 | void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); | |
101 | ||
102 | loader_ctx = fetched_loader->p_open(provctx, uri); | |
103 | if (loader_ctx == NULL) { | |
104 | OSSL_STORE_LOADER_free(fetched_loader); | |
105 | fetched_loader = NULL; | |
106 | } else if (propq != NULL) { | |
107 | OSSL_PARAM params[] = { | |
108 | OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, | |
109 | NULL, 0), | |
110 | OSSL_PARAM_END | |
111 | }; | |
112 | ||
113 | params[0].data = (void *)propq; | |
114 | if (!fetched_loader->p_set_ctx_params(loader_ctx, params)) { | |
115 | (void)fetched_loader->p_close(loader_ctx); | |
116 | OSSL_STORE_LOADER_free(fetched_loader); | |
117 | fetched_loader = NULL; | |
118 | } | |
119 | } | |
120 | loader = fetched_loader; | |
2897b009 | 121 | } |
ae9c39d8 | 122 | } |
2897b009 | 123 | |
34b80d06 RL |
124 | if (loader != NULL) |
125 | OSSL_TRACE1(STORE, "Found loader for scheme %s\n", schemes[i]); | |
126 | ||
ae9c39d8 | 127 | if (loader_ctx == NULL) |
140dab3d | 128 | goto err; |
ae9c39d8 | 129 | |
34b80d06 RL |
130 | OSSL_TRACE2(STORE, "Opened %s => %p\n", uri, (void *)loader_ctx); |
131 | ||
132 | if ((propq != NULL && (propq_copy = OPENSSL_strdup(propq)) == NULL) | |
133 | || (ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { | |
a8b7ea82 | 134 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
140dab3d | 135 | goto err; |
71a5516d RL |
136 | } |
137 | ||
34b80d06 RL |
138 | if ((ui_method != NULL |
139 | && !ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data)) | |
140 | || !ossl_pw_enable_passphrase_caching(&ctx->pwdata)) { | |
141 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_CRYPTO_LIB); | |
142 | goto err; | |
143 | } | |
144 | ctx->properties = propq_copy; | |
145 | ctx->fetched_loader = fetched_loader; | |
71a5516d RL |
146 | ctx->loader = loader; |
147 | ctx->loader_ctx = loader_ctx; | |
71a5516d RL |
148 | ctx->post_process = post_process; |
149 | ctx->post_process_data = post_process_data; | |
150 | ||
140dab3d RL |
151 | /* |
152 | * If the attempt to open with the 'file' scheme loader failed and the | |
153 | * other scheme loader succeeded, the failure to open with the 'file' | |
154 | * scheme loader leaves an error on the error stack. Let's remove it. | |
155 | */ | |
156 | ERR_pop_to_mark(); | |
157 | ||
158 | return ctx; | |
159 | ||
160 | err: | |
161 | ERR_clear_last_mark(); | |
71a5516d | 162 | if (loader_ctx != NULL) { |
34b80d06 RL |
163 | /* |
164 | * Temporary structure so OSSL_STORE_close() can work even when | |
165 | * |ctx| couldn't be allocated properly | |
166 | */ | |
167 | OSSL_STORE_CTX tmpctx = { NULL, }; | |
168 | ||
169 | tmpctx.fetched_loader = fetched_loader; | |
170 | tmpctx.loader = loader; | |
171 | tmpctx.loader_ctx = loader_ctx; | |
172 | ||
71a5516d RL |
173 | /* |
174 | * We ignore a returned error because we will return NULL anyway in | |
175 | * this case, so if something goes wrong when closing, that'll simply | |
176 | * just add another entry on the error stack. | |
177 | */ | |
34b80d06 | 178 | (void)ossl_store_close_it(&tmpctx); |
71a5516d | 179 | } |
34b80d06 RL |
180 | OSSL_STORE_LOADER_free(fetched_loader); |
181 | OPENSSL_free(propq_copy); | |
140dab3d | 182 | return NULL; |
71a5516d RL |
183 | } |
184 | ||
6725682d SL |
185 | OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, |
186 | const UI_METHOD *ui_method, void *ui_data, | |
187 | OSSL_STORE_post_process_info_fn post_process, | |
188 | void *post_process_data) | |
189 | { | |
190 | return OSSL_STORE_open_with_libctx(uri, NULL, NULL, ui_method, ui_data, | |
191 | post_process, post_process_data); | |
192 | } | |
193 | ||
a1447076 | 194 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
71a5516d RL |
195 | int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) |
196 | { | |
197 | va_list args; | |
4fd39122 | 198 | int ret; |
71a5516d RL |
199 | |
200 | va_start(args, cmd); | |
4fd39122 | 201 | ret = OSSL_STORE_vctrl(ctx, cmd, args); |
71a5516d RL |
202 | va_end(args); |
203 | ||
204 | return ret; | |
205 | } | |
206 | ||
4fd39122 RL |
207 | int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args) |
208 | { | |
34b80d06 RL |
209 | if (ctx->fetched_loader != NULL) { |
210 | if (ctx->fetched_loader->p_set_ctx_params != NULL) { | |
211 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | |
212 | ||
213 | switch (cmd) { | |
214 | case OSSL_STORE_C_USE_SECMEM: | |
215 | { | |
216 | int on = *(va_arg(args, int *)); | |
217 | ||
218 | params[0] = OSSL_PARAM_construct_int("use_secmem", &on); | |
219 | } | |
220 | break; | |
221 | default: | |
222 | break; | |
223 | } | |
224 | ||
225 | return ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, | |
226 | params); | |
227 | } | |
228 | } else if (ctx->loader->ctrl != NULL) { | |
4fd39122 | 229 | return ctx->loader->ctrl(ctx->loader_ctx, cmd, args); |
34b80d06 RL |
230 | } |
231 | ||
232 | /* | |
233 | * If the fetched loader doesn't have a set_ctx_params or a ctrl, it's as | |
234 | * if there was one that ignored our params, which usually returns 1. | |
235 | */ | |
236 | return 1; | |
4fd39122 | 237 | } |
a1447076 | 238 | #endif |
4fd39122 | 239 | |
072bfcc9 RL |
240 | int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) |
241 | { | |
34b80d06 RL |
242 | int ret = 1; |
243 | ||
072bfcc9 | 244 | if (ctx->loading) { |
a8b7ea82 | 245 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); |
072bfcc9 RL |
246 | return 0; |
247 | } | |
248 | ||
249 | ctx->expected_type = expected_type; | |
34b80d06 RL |
250 | if (ctx->fetched_loader != NULL |
251 | && ctx->fetched_loader->p_set_ctx_params != NULL) { | |
252 | OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END }; | |
253 | ||
254 | params[0] = | |
255 | OSSL_PARAM_construct_int(OSSL_STORE_PARAM_EXPECT, &expected_type); | |
256 | ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, params); | |
257 | } | |
258 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | |
259 | if (ctx->fetched_loader == NULL | |
260 | && ctx->loader->expect != NULL) { | |
261 | ret = ctx->loader->expect(ctx->loader_ctx, expected_type); | |
262 | } | |
263 | #endif | |
264 | return ret; | |
072bfcc9 RL |
265 | } |
266 | ||
e3c4ad28 | 267 | int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) |
fac8673b | 268 | { |
34b80d06 RL |
269 | int ret = 1; |
270 | ||
fac8673b | 271 | if (ctx->loading) { |
a8b7ea82 | 272 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_LOADING_STARTED); |
fac8673b RL |
273 | return 0; |
274 | } | |
34b80d06 RL |
275 | |
276 | if (ctx->fetched_loader != NULL) { | |
277 | OSSL_PARAM_BLD *bld; | |
278 | OSSL_PARAM *params; | |
279 | /* OSSL_STORE_SEARCH_BY_NAME, OSSL_STORE_SEARCH_BY_ISSUER_SERIAL*/ | |
280 | void *name_der = NULL; | |
281 | int name_der_sz; | |
282 | /* OSSL_STORE_SEARCH_BY_ISSUER_SERIAL */ | |
283 | BIGNUM *number = NULL; | |
284 | ||
285 | if (ctx->fetched_loader->p_set_ctx_params == NULL) { | |
a8b7ea82 | 286 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); |
34b80d06 RL |
287 | return 0; |
288 | } | |
289 | ||
290 | if ((bld = OSSL_PARAM_BLD_new()) == NULL) { | |
a8b7ea82 | 291 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
34b80d06 RL |
292 | return 0; |
293 | } | |
294 | ||
295 | ret = 0; /* Assume the worst */ | |
296 | ||
297 | switch (search->search_type) { | |
298 | case OSSL_STORE_SEARCH_BY_NAME: | |
299 | if ((name_der_sz = i2d_X509_NAME(search->name, | |
300 | (unsigned char **)&name_der)) > 0 | |
301 | && OSSL_PARAM_BLD_push_octet_string(bld, | |
302 | OSSL_STORE_PARAM_SUBJECT, | |
303 | name_der, name_der_sz)) | |
304 | ret = 1; | |
305 | break; | |
306 | case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: | |
307 | if ((name_der_sz = i2d_X509_NAME(search->name, | |
308 | (unsigned char **)&name_der)) > 0 | |
309 | && (number = ASN1_INTEGER_to_BN(search->serial, NULL)) != NULL | |
310 | && OSSL_PARAM_BLD_push_octet_string(bld, | |
311 | OSSL_STORE_PARAM_ISSUER, | |
312 | name_der, name_der_sz) | |
313 | && OSSL_PARAM_BLD_push_BN(bld, OSSL_STORE_PARAM_SERIAL, | |
314 | number)) | |
315 | ret = 1; | |
316 | break; | |
317 | case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: | |
318 | if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_DIGEST, | |
319 | EVP_MD_name(search->digest), 0) | |
320 | && OSSL_PARAM_BLD_push_octet_string(bld, | |
321 | OSSL_STORE_PARAM_FINGERPRINT, | |
322 | search->string, | |
323 | search->stringlength)) | |
324 | ret = 1; | |
325 | break; | |
326 | case OSSL_STORE_SEARCH_BY_ALIAS: | |
327 | if (OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_STORE_PARAM_ALIAS, | |
328 | (char *)search->string, | |
329 | search->stringlength)) | |
330 | ret = 1; | |
331 | break; | |
332 | } | |
333 | if (ret) { | |
334 | params = OSSL_PARAM_BLD_to_param(bld); | |
335 | ret = ctx->fetched_loader->p_set_ctx_params(ctx->loader_ctx, | |
336 | params); | |
337 | OSSL_PARAM_BLD_free_params(params); | |
338 | } | |
339 | OSSL_PARAM_BLD_free(bld); | |
340 | OPENSSL_free(name_der); | |
341 | BN_free(number); | |
342 | } else { | |
a1447076 | 343 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
34b80d06 RL |
344 | /* legacy loader section */ |
345 | if (ctx->loader->find == NULL) { | |
a8b7ea82 | 346 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_UNSUPPORTED_OPERATION); |
34b80d06 RL |
347 | return 0; |
348 | } | |
349 | ret = ctx->loader->find(ctx->loader_ctx, search); | |
a1447076 | 350 | #endif |
fac8673b RL |
351 | } |
352 | ||
34b80d06 | 353 | return ret; |
fac8673b RL |
354 | } |
355 | ||
71a5516d RL |
356 | OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) |
357 | { | |
358 | OSSL_STORE_INFO *v = NULL; | |
359 | ||
4eefdbda | 360 | ctx->loading = 1; |
71a5516d | 361 | again: |
6e2f49b3 RL |
362 | if (OSSL_STORE_eof(ctx)) |
363 | return NULL; | |
364 | ||
34b80d06 RL |
365 | if (ctx->loader != NULL) |
366 | OSSL_TRACE(STORE, "Loading next object\n"); | |
367 | ||
368 | if (ctx->cached_info != NULL | |
369 | && sk_OSSL_STORE_INFO_num(ctx->cached_info) == 0) { | |
370 | sk_OSSL_STORE_INFO_free(ctx->cached_info); | |
371 | ctx->cached_info = NULL; | |
372 | } | |
373 | ||
374 | if (ctx->cached_info != NULL) { | |
375 | v = sk_OSSL_STORE_INFO_shift(ctx->cached_info); | |
376 | } else { | |
377 | if (ctx->fetched_loader != NULL) { | |
378 | struct ossl_load_result_data_st load_data; | |
379 | ||
380 | load_data.v = NULL; | |
381 | load_data.ctx = ctx; | |
382 | ||
383 | if (!ctx->fetched_loader->p_load(ctx->loader_ctx, | |
384 | ossl_store_handle_load_result, | |
385 | &load_data, | |
386 | ossl_pw_passphrase_callback_dec, | |
387 | &ctx->pwdata)) { | |
388 | if (!OSSL_STORE_eof(ctx)) | |
389 | ctx->error_flag = 1; | |
390 | return NULL; | |
391 | } | |
392 | v = load_data.v; | |
393 | } | |
a1447076 | 394 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
34b80d06 RL |
395 | if (ctx->fetched_loader == NULL) |
396 | v = ctx->loader->load(ctx->loader_ctx, | |
397 | ctx->pwdata._.ui_method.ui_method, | |
398 | ctx->pwdata._.ui_method.ui_method_data); | |
a1447076 | 399 | #endif |
34b80d06 | 400 | } |
71a5516d RL |
401 | |
402 | if (ctx->post_process != NULL && v != NULL) { | |
403 | v = ctx->post_process(v, ctx->post_process_data); | |
404 | ||
405 | /* | |
406 | * By returning NULL, the callback decides that this object should | |
407 | * be ignored. | |
408 | */ | |
409 | if (v == NULL) | |
410 | goto again; | |
411 | } | |
412 | ||
072bfcc9 RL |
413 | if (v != NULL && ctx->expected_type != 0) { |
414 | int returned_type = OSSL_STORE_INFO_get_type(v); | |
415 | ||
416 | if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) { | |
072bfcc9 RL |
417 | if (ctx->expected_type != returned_type) { |
418 | OSSL_STORE_INFO_free(v); | |
419 | goto again; | |
420 | } | |
421 | } | |
422 | } | |
423 | ||
34b80d06 | 424 | ossl_pw_clear_passphrase_cache(&ctx->pwdata); |
2897b009 RL |
425 | if (v != NULL) |
426 | OSSL_TRACE1(STORE, "Got a %s\n", | |
427 | OSSL_STORE_INFO_type_string(OSSL_STORE_INFO_get_type(v))); | |
428 | ||
71a5516d RL |
429 | return v; |
430 | } | |
431 | ||
432 | int OSSL_STORE_error(OSSL_STORE_CTX *ctx) | |
433 | { | |
34b80d06 RL |
434 | int ret = 1; |
435 | ||
436 | if (ctx->fetched_loader != NULL) | |
437 | ret = ctx->error_flag; | |
a1447076 | 438 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
34b80d06 RL |
439 | if (ctx->fetched_loader == NULL) |
440 | ret = ctx->loader->error(ctx->loader_ctx); | |
a1447076 | 441 | #endif |
34b80d06 | 442 | return ret; |
71a5516d RL |
443 | } |
444 | ||
445 | int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) | |
446 | { | |
34b80d06 RL |
447 | int ret = 1; |
448 | ||
449 | if (ctx->fetched_loader != NULL) | |
450 | ret = ctx->loader->p_eof(ctx->loader_ctx); | |
a1447076 | 451 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
34b80d06 RL |
452 | if (ctx->fetched_loader == NULL) |
453 | ret = ctx->loader->eof(ctx->loader_ctx); | |
a1447076 | 454 | #endif |
34b80d06 | 455 | return ret; |
71a5516d RL |
456 | } |
457 | ||
34b80d06 | 458 | static int ossl_store_close_it(OSSL_STORE_CTX *ctx) |
71a5516d | 459 | { |
34b80d06 | 460 | int ret = 0; |
2897b009 | 461 | |
6d382c74 DDO |
462 | if (ctx == NULL) |
463 | return 1; | |
2897b009 | 464 | OSSL_TRACE1(STORE, "Closing %p\n", (void *)ctx->loader_ctx); |
34b80d06 RL |
465 | |
466 | if (ctx->fetched_loader != NULL) | |
467 | ret = ctx->loader->p_close(ctx->loader_ctx); | |
a1447076 | 468 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
34b80d06 RL |
469 | if (ctx->fetched_loader == NULL) |
470 | ret = ctx->loader->close(ctx->loader_ctx); | |
a1447076 | 471 | #endif |
34b80d06 RL |
472 | |
473 | sk_OSSL_STORE_INFO_pop_free(ctx->cached_info, OSSL_STORE_INFO_free); | |
474 | OSSL_STORE_LOADER_free(ctx->fetched_loader); | |
475 | OPENSSL_free(ctx->properties); | |
476 | return ret; | |
477 | } | |
478 | ||
479 | int OSSL_STORE_close(OSSL_STORE_CTX *ctx) | |
480 | { | |
481 | int ret = ossl_store_close_it(ctx); | |
71a5516d RL |
482 | |
483 | OPENSSL_free(ctx); | |
34b80d06 | 484 | return ret; |
71a5516d RL |
485 | } |
486 | ||
487 | /* | |
488 | * Functions to generate OSSL_STORE_INFOs, one function for each type we | |
baa77e07 | 489 | * support having in them as well as a generic constructor. |
71a5516d | 490 | * |
68756b12 | 491 | * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO |
71a5516d RL |
492 | * and will therefore be freed when the OSSL_STORE_INFO is freed. |
493 | */ | |
16feca71 | 494 | OSSL_STORE_INFO *OSSL_STORE_INFO_new(int type, void *data) |
71a5516d RL |
495 | { |
496 | OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info)); | |
497 | ||
498 | if (info == NULL) | |
499 | return NULL; | |
500 | ||
501 | info->type = type; | |
502 | info->_.data = data; | |
503 | return info; | |
504 | } | |
505 | ||
506 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) | |
507 | { | |
16feca71 | 508 | OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_NAME, NULL); |
71a5516d RL |
509 | |
510 | if (info == NULL) { | |
a8b7ea82 | 511 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
71a5516d RL |
512 | return NULL; |
513 | } | |
514 | ||
515 | info->_.name.name = name; | |
516 | info->_.name.desc = NULL; | |
517 | ||
518 | return info; | |
519 | } | |
520 | ||
521 | int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) | |
522 | { | |
523 | if (info->type != OSSL_STORE_INFO_NAME) { | |
a8b7ea82 | 524 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_PASSED_INVALID_ARGUMENT); |
71a5516d RL |
525 | return 0; |
526 | } | |
527 | ||
528 | info->_.name.desc = desc; | |
529 | ||
530 | return 1; | |
531 | } | |
532 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) | |
533 | { | |
16feca71 | 534 | OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PARAMS, params); |
71a5516d RL |
535 | |
536 | if (info == NULL) | |
a8b7ea82 | 537 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
71a5516d RL |
538 | return info; |
539 | } | |
540 | ||
2274d22d RL |
541 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PUBKEY(EVP_PKEY *pkey) |
542 | { | |
16feca71 | 543 | OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PUBKEY, pkey); |
2274d22d RL |
544 | |
545 | if (info == NULL) | |
546 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); | |
547 | return info; | |
548 | } | |
549 | ||
71a5516d RL |
550 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) |
551 | { | |
16feca71 | 552 | OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_PKEY, pkey); |
71a5516d RL |
553 | |
554 | if (info == NULL) | |
a8b7ea82 | 555 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
71a5516d RL |
556 | return info; |
557 | } | |
558 | ||
559 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) | |
560 | { | |
16feca71 | 561 | OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CERT, x509); |
71a5516d RL |
562 | |
563 | if (info == NULL) | |
a8b7ea82 | 564 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
71a5516d RL |
565 | return info; |
566 | } | |
567 | ||
568 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) | |
569 | { | |
16feca71 | 570 | OSSL_STORE_INFO *info = OSSL_STORE_INFO_new(OSSL_STORE_INFO_CRL, crl); |
71a5516d RL |
571 | |
572 | if (info == NULL) | |
a8b7ea82 | 573 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
71a5516d RL |
574 | return info; |
575 | } | |
576 | ||
577 | /* | |
578 | * Functions to try to extract data from a OSSL_STORE_INFO. | |
579 | */ | |
580 | int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info) | |
581 | { | |
582 | return info->type; | |
583 | } | |
584 | ||
16feca71 RL |
585 | void *OSSL_STORE_INFO_get0_data(int type, const OSSL_STORE_INFO *info) |
586 | { | |
587 | if (info->type == type) | |
588 | return info->_.data; | |
589 | return NULL; | |
590 | } | |
591 | ||
71a5516d RL |
592 | const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) |
593 | { | |
594 | if (info->type == OSSL_STORE_INFO_NAME) | |
595 | return info->_.name.name; | |
596 | return NULL; | |
597 | } | |
598 | ||
599 | char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) | |
600 | { | |
601 | if (info->type == OSSL_STORE_INFO_NAME) { | |
602 | char *ret = OPENSSL_strdup(info->_.name.name); | |
603 | ||
604 | if (ret == NULL) | |
a8b7ea82 | 605 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
71a5516d RL |
606 | return ret; |
607 | } | |
a8b7ea82 | 608 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); |
71a5516d RL |
609 | return NULL; |
610 | } | |
611 | ||
612 | const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info) | |
613 | { | |
614 | if (info->type == OSSL_STORE_INFO_NAME) | |
615 | return info->_.name.desc; | |
616 | return NULL; | |
617 | } | |
618 | ||
619 | char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) | |
620 | { | |
621 | if (info->type == OSSL_STORE_INFO_NAME) { | |
622 | char *ret = OPENSSL_strdup(info->_.name.desc | |
623 | ? info->_.name.desc : ""); | |
624 | ||
625 | if (ret == NULL) | |
a8b7ea82 | 626 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
71a5516d RL |
627 | return ret; |
628 | } | |
a8b7ea82 | 629 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_NAME); |
71a5516d RL |
630 | return NULL; |
631 | } | |
632 | ||
633 | EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info) | |
634 | { | |
635 | if (info->type == OSSL_STORE_INFO_PARAMS) | |
636 | return info->_.params; | |
637 | return NULL; | |
638 | } | |
639 | ||
640 | EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info) | |
641 | { | |
642 | if (info->type == OSSL_STORE_INFO_PARAMS) { | |
643 | EVP_PKEY_up_ref(info->_.params); | |
644 | return info->_.params; | |
645 | } | |
a8b7ea82 | 646 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS); |
71a5516d RL |
647 | return NULL; |
648 | } | |
649 | ||
2274d22d RL |
650 | EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info) |
651 | { | |
652 | if (info->type == OSSL_STORE_INFO_PUBKEY) | |
653 | return info->_.pubkey; | |
654 | return NULL; | |
655 | } | |
656 | ||
657 | EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info) | |
658 | { | |
659 | if (info->type == OSSL_STORE_INFO_PUBKEY) { | |
660 | EVP_PKEY_up_ref(info->_.pubkey); | |
661 | return info->_.pubkey; | |
662 | } | |
663 | OSSL_STOREerr(0, OSSL_STORE_R_NOT_A_PUBLIC_KEY); | |
664 | return NULL; | |
665 | } | |
666 | ||
71a5516d RL |
667 | EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info) |
668 | { | |
669 | if (info->type == OSSL_STORE_INFO_PKEY) | |
670 | return info->_.pkey; | |
671 | return NULL; | |
672 | } | |
673 | ||
674 | EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info) | |
675 | { | |
676 | if (info->type == OSSL_STORE_INFO_PKEY) { | |
677 | EVP_PKEY_up_ref(info->_.pkey); | |
678 | return info->_.pkey; | |
679 | } | |
a8b7ea82 | 680 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY); |
71a5516d RL |
681 | return NULL; |
682 | } | |
683 | ||
684 | X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info) | |
685 | { | |
686 | if (info->type == OSSL_STORE_INFO_CERT) | |
687 | return info->_.x509; | |
688 | return NULL; | |
689 | } | |
690 | ||
691 | X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info) | |
692 | { | |
693 | if (info->type == OSSL_STORE_INFO_CERT) { | |
694 | X509_up_ref(info->_.x509); | |
695 | return info->_.x509; | |
696 | } | |
a8b7ea82 | 697 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE); |
71a5516d RL |
698 | return NULL; |
699 | } | |
700 | ||
701 | X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info) | |
702 | { | |
703 | if (info->type == OSSL_STORE_INFO_CRL) | |
704 | return info->_.crl; | |
705 | return NULL; | |
706 | } | |
707 | ||
708 | X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info) | |
709 | { | |
710 | if (info->type == OSSL_STORE_INFO_CRL) { | |
711 | X509_CRL_up_ref(info->_.crl); | |
712 | return info->_.crl; | |
713 | } | |
a8b7ea82 | 714 | ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL); |
71a5516d RL |
715 | return NULL; |
716 | } | |
717 | ||
718 | /* | |
719 | * Free the OSSL_STORE_INFO | |
720 | */ | |
721 | void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) | |
722 | { | |
723 | if (info != NULL) { | |
724 | switch (info->type) { | |
725 | case OSSL_STORE_INFO_NAME: | |
726 | OPENSSL_free(info->_.name.name); | |
727 | OPENSSL_free(info->_.name.desc); | |
728 | break; | |
729 | case OSSL_STORE_INFO_PARAMS: | |
730 | EVP_PKEY_free(info->_.params); | |
731 | break; | |
2274d22d RL |
732 | case OSSL_STORE_INFO_PUBKEY: |
733 | EVP_PKEY_free(info->_.pubkey); | |
734 | break; | |
71a5516d RL |
735 | case OSSL_STORE_INFO_PKEY: |
736 | EVP_PKEY_free(info->_.pkey); | |
737 | break; | |
738 | case OSSL_STORE_INFO_CERT: | |
739 | X509_free(info->_.x509); | |
740 | break; | |
741 | case OSSL_STORE_INFO_CRL: | |
742 | X509_CRL_free(info->_.crl); | |
743 | break; | |
744 | } | |
745 | OPENSSL_free(info); | |
746 | } | |
747 | } | |
748 | ||
fac8673b RL |
749 | int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type) |
750 | { | |
34b80d06 RL |
751 | int ret = 0; |
752 | ||
753 | if (ctx->fetched_loader != NULL) { | |
754 | void *provctx = | |
755 | ossl_provider_ctx(OSSL_STORE_LOADER_provider(ctx->fetched_loader)); | |
756 | const OSSL_PARAM *params; | |
757 | const OSSL_PARAM *p_subject = NULL; | |
758 | const OSSL_PARAM *p_issuer = NULL; | |
759 | const OSSL_PARAM *p_serial = NULL; | |
760 | const OSSL_PARAM *p_fingerprint = NULL; | |
761 | const OSSL_PARAM *p_alias = NULL; | |
762 | ||
763 | if (ctx->fetched_loader->p_settable_ctx_params == NULL) | |
764 | return 0; | |
765 | ||
766 | params = ctx->fetched_loader->p_settable_ctx_params(provctx); | |
767 | p_subject = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT); | |
768 | p_issuer = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ISSUER); | |
769 | p_serial = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SERIAL); | |
770 | p_fingerprint = | |
771 | OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_FINGERPRINT); | |
772 | p_alias = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_ALIAS); | |
773 | ||
774 | switch (search_type) { | |
775 | case OSSL_STORE_SEARCH_BY_NAME: | |
776 | ret = (p_subject != NULL); | |
777 | break; | |
778 | case OSSL_STORE_SEARCH_BY_ISSUER_SERIAL: | |
779 | ret = (p_issuer != NULL && p_serial != NULL); | |
780 | break; | |
781 | case OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT: | |
782 | ret = (p_fingerprint != NULL); | |
783 | break; | |
784 | case OSSL_STORE_SEARCH_BY_ALIAS: | |
785 | ret = (p_alias != NULL); | |
786 | break; | |
787 | } | |
788 | } | |
a1447076 | 789 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
34b80d06 RL |
790 | if (ctx->fetched_loader == NULL) { |
791 | OSSL_STORE_SEARCH tmp_search; | |
fac8673b | 792 | |
34b80d06 RL |
793 | if (ctx->loader->find == NULL) |
794 | return 0; | |
795 | tmp_search.search_type = search_type; | |
796 | ret = ctx->loader->find(NULL, &tmp_search); | |
797 | } | |
a1447076 | 798 | #endif |
34b80d06 | 799 | return ret; |
fac8673b RL |
800 | } |
801 | ||
802 | /* Search term constructors */ | |
803 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) | |
804 | { | |
805 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | |
806 | ||
807 | if (search == NULL) { | |
a8b7ea82 | 808 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
fac8673b RL |
809 | return NULL; |
810 | } | |
811 | ||
812 | search->search_type = OSSL_STORE_SEARCH_BY_NAME; | |
813 | search->name = name; | |
814 | return search; | |
815 | } | |
816 | ||
817 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, | |
8cc86b81 | 818 | const ASN1_INTEGER *serial) |
fac8673b RL |
819 | { |
820 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | |
821 | ||
822 | if (search == NULL) { | |
a8b7ea82 | 823 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
fac8673b RL |
824 | return NULL; |
825 | } | |
826 | ||
827 | search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; | |
828 | search->name = name; | |
829 | search->serial = serial; | |
830 | return search; | |
831 | } | |
832 | ||
833 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, | |
834 | const unsigned char | |
835 | *bytes, size_t len) | |
836 | { | |
837 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | |
838 | ||
839 | if (search == NULL) { | |
a8b7ea82 | 840 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
fac8673b RL |
841 | return NULL; |
842 | } | |
843 | ||
844 | if (digest != NULL && len != (size_t)EVP_MD_size(digest)) { | |
a8b7ea82 RL |
845 | ERR_raise_data(ERR_LIB_OSSL_STORE, |
846 | OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST, | |
847 | "%s size is %d, fingerprint size is %zu", | |
848 | EVP_MD_name(digest), EVP_MD_size(digest), len); | |
849 | return NULL; | |
fac8673b RL |
850 | } |
851 | ||
852 | search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; | |
853 | search->digest = digest; | |
854 | search->string = bytes; | |
855 | search->stringlength = len; | |
856 | return search; | |
857 | } | |
858 | ||
859 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) | |
860 | { | |
861 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); | |
862 | ||
863 | if (search == NULL) { | |
a8b7ea82 | 864 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
fac8673b RL |
865 | return NULL; |
866 | } | |
867 | ||
868 | search->search_type = OSSL_STORE_SEARCH_BY_ALIAS; | |
869 | search->string = (const unsigned char *)alias; | |
870 | search->stringlength = strlen(alias); | |
871 | return search; | |
872 | } | |
873 | ||
874 | /* Search term destructor */ | |
875 | void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search) | |
876 | { | |
877 | OPENSSL_free(search); | |
878 | } | |
879 | ||
880 | /* Search term accessors */ | |
881 | int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion) | |
882 | { | |
883 | return criterion->search_type; | |
884 | } | |
885 | ||
e3c4ad28 | 886 | X509_NAME *OSSL_STORE_SEARCH_get0_name(const OSSL_STORE_SEARCH *criterion) |
fac8673b RL |
887 | { |
888 | return criterion->name; | |
889 | } | |
890 | ||
891 | const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH | |
8cc86b81 | 892 | *criterion) |
fac8673b RL |
893 | { |
894 | return criterion->serial; | |
895 | } | |
896 | ||
897 | const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH | |
898 | *criterion, size_t *length) | |
899 | { | |
900 | *length = criterion->stringlength; | |
901 | return criterion->string; | |
902 | } | |
903 | ||
904 | const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion) | |
905 | { | |
906 | return (const char *)criterion->string; | |
907 | } | |
908 | ||
909 | const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion) | |
910 | { | |
911 | return criterion->digest; | |
912 | } | |
913 | ||
6725682d SL |
914 | OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme, |
915 | OPENSSL_CTX *libctx, const char *propq, | |
6ab6ecfd RL |
916 | const UI_METHOD *ui_method, void *ui_data, |
917 | OSSL_STORE_post_process_info_fn post_process, | |
918 | void *post_process_data) | |
4c17819c | 919 | { |
4c17819c | 920 | const OSSL_STORE_LOADER *loader = NULL; |
34b80d06 | 921 | OSSL_STORE_LOADER *fetched_loader = NULL; |
4c17819c | 922 | OSSL_STORE_LOADER_CTX *loader_ctx = NULL; |
34b80d06 | 923 | OSSL_STORE_CTX *ctx = NULL; |
4c17819c | 924 | |
34b80d06 RL |
925 | if (scheme == NULL) |
926 | scheme = "file"; | |
927 | ||
928 | OSSL_TRACE1(STORE, "Looking up scheme %s\n", scheme); | |
a1447076 | 929 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
34b80d06 RL |
930 | if ((loader = ossl_store_get0_loader_int(scheme)) != NULL) |
931 | loader_ctx = loader->attach(loader, bp, libctx, propq, | |
932 | ui_method, ui_data); | |
a1447076 | 933 | #endif |
34b80d06 RL |
934 | if (loader == NULL |
935 | && (fetched_loader = | |
936 | OSSL_STORE_LOADER_fetch(scheme, libctx, propq)) != NULL) { | |
937 | const OSSL_PROVIDER *provider = | |
938 | OSSL_STORE_LOADER_provider(fetched_loader); | |
939 | void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider); | |
940 | ||
941 | if ((loader_ctx = | |
942 | fetched_loader->p_attach(provctx, (OSSL_CORE_BIO *)bp)) == NULL) { | |
943 | OSSL_STORE_LOADER_free(fetched_loader); | |
944 | fetched_loader = NULL; | |
945 | } else if (propq != NULL) { | |
946 | OSSL_PARAM params[] = { | |
947 | OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, | |
948 | NULL, 0), | |
949 | OSSL_PARAM_END | |
950 | }; | |
951 | ||
952 | params[0].data = (void *)propq; | |
953 | if (!fetched_loader->p_set_ctx_params(loader_ctx, params)) { | |
954 | (void)fetched_loader->p_close(loader_ctx); | |
955 | OSSL_STORE_LOADER_free(fetched_loader); | |
956 | fetched_loader = NULL; | |
957 | } | |
958 | } | |
959 | loader = fetched_loader; | |
960 | } | |
961 | ||
962 | if (loader_ctx == NULL) | |
6ab6ecfd RL |
963 | return NULL; |
964 | ||
4c17819c | 965 | if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { |
a8b7ea82 | 966 | ERR_raise(ERR_LIB_OSSL_STORE, ERR_R_MALLOC_FAILURE); |
6ab6ecfd | 967 | return NULL; |
4c17819c RL |
968 | } |
969 | ||
34b80d06 RL |
970 | (void)ossl_pw_set_ui_method(&ctx->pwdata, ui_method, ui_data); |
971 | ctx->fetched_loader = fetched_loader; | |
4c17819c RL |
972 | ctx->loader = loader; |
973 | ctx->loader_ctx = loader_ctx; | |
6ab6ecfd RL |
974 | ctx->post_process = post_process; |
975 | ctx->post_process_data = post_process_data; | |
4c17819c | 976 | |
4c17819c RL |
977 | return ctx; |
978 | } |