1 | /* |
2 | * Copyright 2016-2018 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 "e_os.h" |
11 | #include <stdlib.h> |
12 | #include <string.h> |
13 | #include <assert.h> |
14 | |
15 | #include "e_os.h" |
16 | |
17 | #include <openssl/crypto.h> |
18 | #include <openssl/err.h> |
19 | #include <openssl/trace.h> |
20 | #include <openssl/store.h> |
21 | #include "internal/thread_once.h" |
22 | #include "crypto/store.h" |
23 | #include "store_local.h" |
24 | |
25 | struct ossl_store_ctx_st { |
26 | const OSSL_STORE_LOADER *loader; |
27 | OSSL_STORE_LOADER_CTX *loader_ctx; |
28 | const UI_METHOD *ui_method; |
29 | void *ui_data; |
30 | OSSL_STORE_post_process_info_fn post_process; |
31 | void *post_process_data; |
32 | int expected_type; |
33 | |
34 | /* 0 before the first STORE_load(), 1 otherwise */ |
35 | int loading; |
36 | }; |
37 | |
38 | OSSL_STORE_CTX *OSSL_STORE_open(const char *uri, const UI_METHOD *ui_method, |
39 | void *ui_data, |
40 | OSSL_STORE_post_process_info_fn post_process, |
41 | void *post_process_data) |
42 | { |
43 | const OSSL_STORE_LOADER *loader = NULL; |
44 | OSSL_STORE_LOADER_CTX *loader_ctx = NULL; |
45 | OSSL_STORE_CTX *ctx = NULL; |
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" ; |
56 | |
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 | */ |
64 | OPENSSL_strlcpy(scheme_copy, uri, sizeof(scheme_copy)); |
65 | if ((p = strchr(scheme_copy, ':')) != NULL) { |
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 | } |
72 | } |
73 | |
74 | ERR_set_mark(); |
75 | |
76 | /* Try each scheme until we find one that could open the URI */ |
77 | for (i = 0; loader_ctx == NULL && i < schemes_n; i++) { |
78 | OSSL_TRACE1(STORE, "Looking up scheme %s\n" , schemes[i]); |
79 | if ((loader = ossl_store_get0_loader_int(schemes[i])) != NULL) { |
80 | OSSL_TRACE1(STORE, "Found loader for scheme %s\n" , schemes[i]); |
81 | loader_ctx = loader->open(loader, uri, ui_method, ui_data); |
82 | OSSL_TRACE2(STORE, "Opened %s => %p\n" , uri, (void *)loader_ctx); |
83 | } |
84 | } |
85 | |
86 | if (loader_ctx == NULL) |
87 | goto err; |
88 | |
89 | if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { |
90 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_OPEN, ERR_R_MALLOC_FAILURE); |
91 | goto err; |
92 | } |
93 | |
94 | ctx->loader = loader; |
95 | ctx->loader_ctx = loader_ctx; |
96 | ctx->ui_method = ui_method; |
97 | ctx->ui_data = ui_data; |
98 | ctx->post_process = post_process; |
99 | ctx->post_process_data = post_process_data; |
100 | |
101 | /* |
102 | * If the attempt to open with the 'file' scheme loader failed and the |
103 | * other scheme loader succeeded, the failure to open with the 'file' |
104 | * scheme loader leaves an error on the error stack. Let's remove it. |
105 | */ |
106 | ERR_pop_to_mark(); |
107 | |
108 | return ctx; |
109 | |
110 | err: |
111 | ERR_clear_last_mark(); |
112 | if (loader_ctx != NULL) { |
113 | /* |
114 | * We ignore a returned error because we will return NULL anyway in |
115 | * this case, so if something goes wrong when closing, that'll simply |
116 | * just add another entry on the error stack. |
117 | */ |
118 | (void)loader->close(loader_ctx); |
119 | } |
120 | return NULL; |
121 | } |
122 | |
123 | int OSSL_STORE_ctrl(OSSL_STORE_CTX *ctx, int cmd, ...) |
124 | { |
125 | va_list args; |
126 | int ret; |
127 | |
128 | va_start(args, cmd); |
129 | ret = OSSL_STORE_vctrl(ctx, cmd, args); |
130 | va_end(args); |
131 | |
132 | return ret; |
133 | } |
134 | |
135 | int OSSL_STORE_vctrl(OSSL_STORE_CTX *ctx, int cmd, va_list args) |
136 | { |
137 | if (ctx->loader->ctrl != NULL) |
138 | return ctx->loader->ctrl(ctx->loader_ctx, cmd, args); |
139 | return 0; |
140 | } |
141 | |
142 | int OSSL_STORE_expect(OSSL_STORE_CTX *ctx, int expected_type) |
143 | { |
144 | if (ctx->loading) { |
145 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_EXPECT, |
146 | OSSL_STORE_R_LOADING_STARTED); |
147 | return 0; |
148 | } |
149 | |
150 | ctx->expected_type = expected_type; |
151 | if (ctx->loader->expect != NULL) |
152 | return ctx->loader->expect(ctx->loader_ctx, expected_type); |
153 | return 1; |
154 | } |
155 | |
156 | int OSSL_STORE_find(OSSL_STORE_CTX *ctx, const OSSL_STORE_SEARCH *search) |
157 | { |
158 | if (ctx->loading) { |
159 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, |
160 | OSSL_STORE_R_LOADING_STARTED); |
161 | return 0; |
162 | } |
163 | if (ctx->loader->find == NULL) { |
164 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FIND, |
165 | OSSL_STORE_R_UNSUPPORTED_OPERATION); |
166 | return 0; |
167 | } |
168 | |
169 | return ctx->loader->find(ctx->loader_ctx, search); |
170 | } |
171 | |
172 | OSSL_STORE_INFO *OSSL_STORE_load(OSSL_STORE_CTX *ctx) |
173 | { |
174 | OSSL_STORE_INFO *v = NULL; |
175 | |
176 | ctx->loading = 1; |
177 | again: |
178 | if (OSSL_STORE_eof(ctx)) |
179 | return NULL; |
180 | |
181 | OSSL_TRACE(STORE, "Loading next object\n" ); |
182 | v = ctx->loader->load(ctx->loader_ctx, ctx->ui_method, ctx->ui_data); |
183 | |
184 | if (ctx->post_process != NULL && v != NULL) { |
185 | v = ctx->post_process(v, ctx->post_process_data); |
186 | |
187 | /* |
188 | * By returning NULL, the callback decides that this object should |
189 | * be ignored. |
190 | */ |
191 | if (v == NULL) |
192 | goto again; |
193 | } |
194 | |
195 | if (v != NULL && ctx->expected_type != 0) { |
196 | int returned_type = OSSL_STORE_INFO_get_type(v); |
197 | |
198 | if (returned_type != OSSL_STORE_INFO_NAME && returned_type != 0) { |
199 | /* |
200 | * Soft assert here so those who want to harsly weed out faulty |
201 | * loaders can do so using a debugging version of libcrypto. |
202 | */ |
203 | if (ctx->loader->expect != NULL) |
204 | assert(ctx->expected_type == returned_type); |
205 | |
206 | if (ctx->expected_type != returned_type) { |
207 | OSSL_STORE_INFO_free(v); |
208 | goto again; |
209 | } |
210 | } |
211 | } |
212 | |
213 | if (v != NULL) |
214 | OSSL_TRACE1(STORE, "Got a %s\n" , |
215 | OSSL_STORE_INFO_type_string(OSSL_STORE_INFO_get_type(v))); |
216 | |
217 | return v; |
218 | } |
219 | |
220 | int OSSL_STORE_error(OSSL_STORE_CTX *ctx) |
221 | { |
222 | return ctx->loader->error(ctx->loader_ctx); |
223 | } |
224 | |
225 | int OSSL_STORE_eof(OSSL_STORE_CTX *ctx) |
226 | { |
227 | return ctx->loader->eof(ctx->loader_ctx); |
228 | } |
229 | |
230 | int OSSL_STORE_close(OSSL_STORE_CTX *ctx) |
231 | { |
232 | int loader_ret; |
233 | |
234 | OSSL_TRACE1(STORE, "Closing %p\n" , (void *)ctx->loader_ctx); |
235 | loader_ret = ctx->loader->close(ctx->loader_ctx); |
236 | |
237 | OPENSSL_free(ctx); |
238 | return loader_ret; |
239 | } |
240 | |
241 | /* |
242 | * Functions to generate OSSL_STORE_INFOs, one function for each type we |
243 | * support having in them as well as a generic constructor. |
244 | * |
245 | * In all cases, ownership of the object is transferred to the OSSL_STORE_INFO |
246 | * and will therefore be freed when the OSSL_STORE_INFO is freed. |
247 | */ |
248 | static OSSL_STORE_INFO *store_info_new(int type, void *data) |
249 | { |
250 | OSSL_STORE_INFO *info = OPENSSL_zalloc(sizeof(*info)); |
251 | |
252 | if (info == NULL) |
253 | return NULL; |
254 | |
255 | info->type = type; |
256 | info->_.data = data; |
257 | return info; |
258 | } |
259 | |
260 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_NAME(char *name) |
261 | { |
262 | OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_NAME, NULL); |
263 | |
264 | if (info == NULL) { |
265 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_NAME, |
266 | ERR_R_MALLOC_FAILURE); |
267 | return NULL; |
268 | } |
269 | |
270 | info->_.name.name = name; |
271 | info->_.name.desc = NULL; |
272 | |
273 | return info; |
274 | } |
275 | |
276 | int OSSL_STORE_INFO_set0_NAME_description(OSSL_STORE_INFO *info, char *desc) |
277 | { |
278 | if (info->type != OSSL_STORE_INFO_NAME) { |
279 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_SET0_NAME_DESCRIPTION, |
280 | ERR_R_PASSED_INVALID_ARGUMENT); |
281 | return 0; |
282 | } |
283 | |
284 | info->_.name.desc = desc; |
285 | |
286 | return 1; |
287 | } |
288 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PARAMS(EVP_PKEY *params) |
289 | { |
290 | OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PARAMS, params); |
291 | |
292 | if (info == NULL) |
293 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PARAMS, |
294 | ERR_R_MALLOC_FAILURE); |
295 | return info; |
296 | } |
297 | |
298 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_PKEY(EVP_PKEY *pkey) |
299 | { |
300 | OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_PKEY, pkey); |
301 | |
302 | if (info == NULL) |
303 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_PKEY, |
304 | ERR_R_MALLOC_FAILURE); |
305 | return info; |
306 | } |
307 | |
308 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_CERT(X509 *x509) |
309 | { |
310 | OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CERT, x509); |
311 | |
312 | if (info == NULL) |
313 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CERT, |
314 | ERR_R_MALLOC_FAILURE); |
315 | return info; |
316 | } |
317 | |
318 | OSSL_STORE_INFO *OSSL_STORE_INFO_new_CRL(X509_CRL *crl) |
319 | { |
320 | OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_CRL, crl); |
321 | |
322 | if (info == NULL) |
323 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_CRL, |
324 | ERR_R_MALLOC_FAILURE); |
325 | return info; |
326 | } |
327 | |
328 | /* |
329 | * Functions to try to extract data from a OSSL_STORE_INFO. |
330 | */ |
331 | int OSSL_STORE_INFO_get_type(const OSSL_STORE_INFO *info) |
332 | { |
333 | return info->type; |
334 | } |
335 | |
336 | const char *OSSL_STORE_INFO_get0_NAME(const OSSL_STORE_INFO *info) |
337 | { |
338 | if (info->type == OSSL_STORE_INFO_NAME) |
339 | return info->_.name.name; |
340 | return NULL; |
341 | } |
342 | |
343 | char *OSSL_STORE_INFO_get1_NAME(const OSSL_STORE_INFO *info) |
344 | { |
345 | if (info->type == OSSL_STORE_INFO_NAME) { |
346 | char *ret = OPENSSL_strdup(info->_.name.name); |
347 | |
348 | if (ret == NULL) |
349 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, |
350 | ERR_R_MALLOC_FAILURE); |
351 | return ret; |
352 | } |
353 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME, |
354 | OSSL_STORE_R_NOT_A_NAME); |
355 | return NULL; |
356 | } |
357 | |
358 | const char *OSSL_STORE_INFO_get0_NAME_description(const OSSL_STORE_INFO *info) |
359 | { |
360 | if (info->type == OSSL_STORE_INFO_NAME) |
361 | return info->_.name.desc; |
362 | return NULL; |
363 | } |
364 | |
365 | char *OSSL_STORE_INFO_get1_NAME_description(const OSSL_STORE_INFO *info) |
366 | { |
367 | if (info->type == OSSL_STORE_INFO_NAME) { |
368 | char *ret = OPENSSL_strdup(info->_.name.desc |
369 | ? info->_.name.desc : "" ); |
370 | |
371 | if (ret == NULL) |
372 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, |
373 | ERR_R_MALLOC_FAILURE); |
374 | return ret; |
375 | } |
376 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_NAME_DESCRIPTION, |
377 | OSSL_STORE_R_NOT_A_NAME); |
378 | return NULL; |
379 | } |
380 | |
381 | EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info) |
382 | { |
383 | if (info->type == OSSL_STORE_INFO_PARAMS) |
384 | return info->_.params; |
385 | return NULL; |
386 | } |
387 | |
388 | EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info) |
389 | { |
390 | if (info->type == OSSL_STORE_INFO_PARAMS) { |
391 | EVP_PKEY_up_ref(info->_.params); |
392 | return info->_.params; |
393 | } |
394 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PARAMS, |
395 | OSSL_STORE_R_NOT_PARAMETERS); |
396 | return NULL; |
397 | } |
398 | |
399 | EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info) |
400 | { |
401 | if (info->type == OSSL_STORE_INFO_PKEY) |
402 | return info->_.pkey; |
403 | return NULL; |
404 | } |
405 | |
406 | EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info) |
407 | { |
408 | if (info->type == OSSL_STORE_INFO_PKEY) { |
409 | EVP_PKEY_up_ref(info->_.pkey); |
410 | return info->_.pkey; |
411 | } |
412 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_PKEY, |
413 | OSSL_STORE_R_NOT_A_KEY); |
414 | return NULL; |
415 | } |
416 | |
417 | X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info) |
418 | { |
419 | if (info->type == OSSL_STORE_INFO_CERT) |
420 | return info->_.x509; |
421 | return NULL; |
422 | } |
423 | |
424 | X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info) |
425 | { |
426 | if (info->type == OSSL_STORE_INFO_CERT) { |
427 | X509_up_ref(info->_.x509); |
428 | return info->_.x509; |
429 | } |
430 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, |
431 | OSSL_STORE_R_NOT_A_CERTIFICATE); |
432 | return NULL; |
433 | } |
434 | |
435 | X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info) |
436 | { |
437 | if (info->type == OSSL_STORE_INFO_CRL) |
438 | return info->_.crl; |
439 | return NULL; |
440 | } |
441 | |
442 | X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info) |
443 | { |
444 | if (info->type == OSSL_STORE_INFO_CRL) { |
445 | X509_CRL_up_ref(info->_.crl); |
446 | return info->_.crl; |
447 | } |
448 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL, |
449 | OSSL_STORE_R_NOT_A_CRL); |
450 | return NULL; |
451 | } |
452 | |
453 | /* |
454 | * Free the OSSL_STORE_INFO |
455 | */ |
456 | void OSSL_STORE_INFO_free(OSSL_STORE_INFO *info) |
457 | { |
458 | if (info != NULL) { |
459 | switch (info->type) { |
460 | case OSSL_STORE_INFO_EMBEDDED: |
461 | BUF_MEM_free(info->_.embedded.blob); |
462 | OPENSSL_free(info->_.embedded.pem_name); |
463 | break; |
464 | case OSSL_STORE_INFO_NAME: |
465 | OPENSSL_free(info->_.name.name); |
466 | OPENSSL_free(info->_.name.desc); |
467 | break; |
468 | case OSSL_STORE_INFO_PARAMS: |
469 | EVP_PKEY_free(info->_.params); |
470 | break; |
471 | case OSSL_STORE_INFO_PKEY: |
472 | EVP_PKEY_free(info->_.pkey); |
473 | break; |
474 | case OSSL_STORE_INFO_CERT: |
475 | X509_free(info->_.x509); |
476 | break; |
477 | case OSSL_STORE_INFO_CRL: |
478 | X509_CRL_free(info->_.crl); |
479 | break; |
480 | } |
481 | OPENSSL_free(info); |
482 | } |
483 | } |
484 | |
485 | int OSSL_STORE_supports_search(OSSL_STORE_CTX *ctx, int search_type) |
486 | { |
487 | OSSL_STORE_SEARCH tmp_search; |
488 | |
489 | if (ctx->loader->find == NULL) |
490 | return 0; |
491 | tmp_search.search_type = search_type; |
492 | return ctx->loader->find(NULL, &tmp_search); |
493 | } |
494 | |
495 | /* Search term constructors */ |
496 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_name(X509_NAME *name) |
497 | { |
498 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); |
499 | |
500 | if (search == NULL) { |
501 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_NAME, |
502 | ERR_R_MALLOC_FAILURE); |
503 | return NULL; |
504 | } |
505 | |
506 | search->search_type = OSSL_STORE_SEARCH_BY_NAME; |
507 | search->name = name; |
508 | return search; |
509 | } |
510 | |
511 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_issuer_serial(X509_NAME *name, |
512 | const ASN1_INTEGER *serial) |
513 | { |
514 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); |
515 | |
516 | if (search == NULL) { |
517 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ISSUER_SERIAL, |
518 | ERR_R_MALLOC_FAILURE); |
519 | return NULL; |
520 | } |
521 | |
522 | search->search_type = OSSL_STORE_SEARCH_BY_ISSUER_SERIAL; |
523 | search->name = name; |
524 | search->serial = serial; |
525 | return search; |
526 | } |
527 | |
528 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_key_fingerprint(const EVP_MD *digest, |
529 | const unsigned char |
530 | *bytes, size_t len) |
531 | { |
532 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); |
533 | |
534 | if (search == NULL) { |
535 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, |
536 | ERR_R_MALLOC_FAILURE); |
537 | return NULL; |
538 | } |
539 | |
540 | if (digest != NULL && len != (size_t)EVP_MD_size(digest)) { |
541 | char buf1[20], buf2[20]; |
542 | |
543 | BIO_snprintf(buf1, sizeof(buf1), "%d" , EVP_MD_size(digest)); |
544 | BIO_snprintf(buf2, sizeof(buf2), "%zu" , len); |
545 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT, |
546 | OSSL_STORE_R_FINGERPRINT_SIZE_DOES_NOT_MATCH_DIGEST); |
547 | ERR_add_error_data(5, EVP_MD_name(digest), " size is " , buf1, |
548 | ", fingerprint size is " , buf2); |
549 | } |
550 | |
551 | search->search_type = OSSL_STORE_SEARCH_BY_KEY_FINGERPRINT; |
552 | search->digest = digest; |
553 | search->string = bytes; |
554 | search->stringlength = len; |
555 | return search; |
556 | } |
557 | |
558 | OSSL_STORE_SEARCH *OSSL_STORE_SEARCH_by_alias(const char *alias) |
559 | { |
560 | OSSL_STORE_SEARCH *search = OPENSSL_zalloc(sizeof(*search)); |
561 | |
562 | if (search == NULL) { |
563 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_SEARCH_BY_ALIAS, |
564 | ERR_R_MALLOC_FAILURE); |
565 | return NULL; |
566 | } |
567 | |
568 | search->search_type = OSSL_STORE_SEARCH_BY_ALIAS; |
569 | search->string = (const unsigned char *)alias; |
570 | search->stringlength = strlen(alias); |
571 | return search; |
572 | } |
573 | |
574 | /* Search term destructor */ |
575 | void OSSL_STORE_SEARCH_free(OSSL_STORE_SEARCH *search) |
576 | { |
577 | OPENSSL_free(search); |
578 | } |
579 | |
580 | /* Search term accessors */ |
581 | int OSSL_STORE_SEARCH_get_type(const OSSL_STORE_SEARCH *criterion) |
582 | { |
583 | return criterion->search_type; |
584 | } |
585 | |
586 | X509_NAME *OSSL_STORE_SEARCH_get0_name(const OSSL_STORE_SEARCH *criterion) |
587 | { |
588 | return criterion->name; |
589 | } |
590 | |
591 | const ASN1_INTEGER *OSSL_STORE_SEARCH_get0_serial(const OSSL_STORE_SEARCH |
592 | *criterion) |
593 | { |
594 | return criterion->serial; |
595 | } |
596 | |
597 | const unsigned char *OSSL_STORE_SEARCH_get0_bytes(const OSSL_STORE_SEARCH |
598 | *criterion, size_t *length) |
599 | { |
600 | *length = criterion->stringlength; |
601 | return criterion->string; |
602 | } |
603 | |
604 | const char *OSSL_STORE_SEARCH_get0_string(const OSSL_STORE_SEARCH *criterion) |
605 | { |
606 | return (const char *)criterion->string; |
607 | } |
608 | |
609 | const EVP_MD *OSSL_STORE_SEARCH_get0_digest(const OSSL_STORE_SEARCH *criterion) |
610 | { |
611 | return criterion->digest; |
612 | } |
613 | |
614 | /* Internal functions */ |
615 | OSSL_STORE_INFO *ossl_store_info_new_EMBEDDED(const char *new_pem_name, |
616 | BUF_MEM *embedded) |
617 | { |
618 | OSSL_STORE_INFO *info = store_info_new(OSSL_STORE_INFO_EMBEDDED, NULL); |
619 | |
620 | if (info == NULL) { |
621 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, |
622 | ERR_R_MALLOC_FAILURE); |
623 | return NULL; |
624 | } |
625 | |
626 | info->_.embedded.blob = embedded; |
627 | info->_.embedded.pem_name = |
628 | new_pem_name == NULL ? NULL : OPENSSL_strdup(new_pem_name); |
629 | |
630 | if (new_pem_name != NULL && info->_.embedded.pem_name == NULL) { |
631 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_INFO_NEW_EMBEDDED, |
632 | ERR_R_MALLOC_FAILURE); |
633 | OSSL_STORE_INFO_free(info); |
634 | info = NULL; |
635 | } |
636 | |
637 | return info; |
638 | } |
639 | |
640 | BUF_MEM *ossl_store_info_get0_EMBEDDED_buffer(OSSL_STORE_INFO *info) |
641 | { |
642 | if (info->type == OSSL_STORE_INFO_EMBEDDED) |
643 | return info->_.embedded.blob; |
644 | return NULL; |
645 | } |
646 | |
647 | char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info) |
648 | { |
649 | if (info->type == OSSL_STORE_INFO_EMBEDDED) |
650 | return info->_.embedded.pem_name; |
651 | return NULL; |
652 | } |
653 | |
654 | OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method, |
655 | void *ui_data) |
656 | { |
657 | OSSL_STORE_CTX *ctx = NULL; |
658 | const OSSL_STORE_LOADER *loader = NULL; |
659 | OSSL_STORE_LOADER_CTX *loader_ctx = NULL; |
660 | |
661 | if ((loader = ossl_store_get0_loader_int("file" )) == NULL |
662 | || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp)) == NULL)) |
663 | goto done; |
664 | if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { |
665 | OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, |
666 | ERR_R_MALLOC_FAILURE); |
667 | goto done; |
668 | } |
669 | |
670 | ctx->loader = loader; |
671 | ctx->loader_ctx = loader_ctx; |
672 | loader_ctx = NULL; |
673 | ctx->ui_method = ui_method; |
674 | ctx->ui_data = ui_data; |
675 | ctx->post_process = NULL; |
676 | ctx->post_process_data = NULL; |
677 | |
678 | done: |
679 | if (loader_ctx != NULL) |
680 | /* |
681 | * We ignore a returned error because we will return NULL anyway in |
682 | * this case, so if something goes wrong when closing, that'll simply |
683 | * just add another entry on the error stack. |
684 | */ |
685 | (void)loader->close(loader_ctx); |
686 | return ctx; |
687 | } |
688 | |
689 | int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx) |
690 | { |
691 | int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx); |
692 | |
693 | OPENSSL_free(ctx); |
694 | return loader_ret; |
695 | } |
696 | |