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