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