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