2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved.
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
12 #include <openssl/bio.h>
13 #include <openssl/dsa.h> /* For d2i_DSAPrivateKey */
14 #include <openssl/err.h>
15 #include <openssl/evp.h>
16 #include <openssl/pem.h>
17 #include <openssl/pkcs12.h> /* For the PKCS8 stuff o.O */
18 #include <openssl/rsa.h> /* For d2i_RSAPrivateKey */
19 #include <openssl/safestack.h>
20 #include <openssl/store.h>
21 #include <openssl/ui.h>
22 #include <openssl/x509.h> /* For the PKCS8 stuff o.O */
23 #include "internal/asn1_int.h"
24 #include "store_locl.h"
32 static char *file_get_pass(const UI_METHOD *ui_method, char *pass,
33 size_t maxsize, const char *prompt_info, void *data)
39 OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_MALLOC_FAILURE);
43 if (ui_method != NULL)
44 UI_set_method(ui, ui_method);
45 UI_add_user_data(ui, data);
47 if ((prompt = UI_construct_prompt(ui, "pass phrase",
48 prompt_info)) == NULL) {
49 OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_MALLOC_FAILURE);
51 } else if (!UI_add_input_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD,
52 pass, 0, maxsize - 1)) {
53 OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_UI_LIB);
56 switch (UI_process(ui)) {
58 OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS,
59 OSSL_STORE_R_UI_PROCESS_INTERRUPTED_OR_CANCELLED);
63 OSSL_STOREerr(OSSL_STORE_F_FILE_GET_PASS, ERR_R_UI_LIB);
76 struct pem_pass_data {
77 const UI_METHOD *ui_method;
79 const char *prompt_info;
81 static int file_fill_pem_pass_data(struct pem_pass_data *pass_data,
82 const char *prompt_info,
83 const UI_METHOD *ui_method, void *ui_data)
85 if (pass_data == NULL)
87 pass_data->ui_method = ui_method;
88 pass_data->data = ui_data;
89 pass_data->prompt_info = prompt_info;
92 static int file_get_pem_pass(char *buf, int num, int w, void *data)
94 struct pem_pass_data *pass_data = data;
95 char *pass = file_get_pass(pass_data->ui_method, buf, num,
96 pass_data->prompt_info, pass_data->data);
98 return pass == NULL ? 0 : strlen(pass);
102 * The file scheme handlers
106 * The try_decode function is called to check if the blob of data can
107 * be used by this handler, and if it can, decodes it into a supported
108 * OpenSSL type and returns a OSSL_STORE_INFO with the decoded data.
110 * pem_name: If this blob comes from a PEM file, this holds
111 * the PEM name. If it comes from another type of
112 * file, this is NULL.
113 * pem_header: If this blob comes from a PEM file, this holds
114 * the PEM headers. If it comes from another type of
115 * file, this is NULL.
116 * blob: The blob of data to match with what this handler
118 * len: The length of the blob.
119 * handler_ctx: For a handler marked repeatable, this pointer can
120 * be used to create a context for the handler. IT IS
121 * THE HANDLER'S RESPONSIBILITY TO CREATE AND DESTROY
122 * THIS CONTEXT APPROPRIATELY, i.e. create on first call
123 * and destroy when about to return NULL.
124 * ui_method: Application UI method for getting a password, pin
125 * or any other interactive data.
126 * ui_data: Application data to be passed to ui_method when
131 typedef OSSL_STORE_INFO *(*file_try_decode_fn)(const char *pem_name,
132 const char *pem_header,
133 const unsigned char *blob,
134 size_t len, void **handler_ctx,
135 const UI_METHOD *ui_method,
138 * The eof function should return 1 if there's no more data to be found
139 * with the handler_ctx, otherwise 0. This is only used when the handler is
142 typedef int (*file_eof_fn)(void *handler_ctx);
144 * The destroy_ctx function is used to destroy the handler_ctx that was
145 * intiated by a repeatable try_decode fuction. This is only used when
146 * the handler is marked repeatable.
148 typedef void (*file_destroy_ctx_fn)(void **handler_ctx);
150 typedef struct file_handler_st {
152 file_try_decode_fn try_decode;
154 file_destroy_ctx_fn destroy_ctx;
160 int pem_check_suffix(const char *pem_str, const char *suffix);
161 static OSSL_STORE_INFO *try_decode_PrivateKey(const char *pem_name,
162 const char *pem_header,
163 const unsigned char *blob,
164 size_t len, void **pctx,
165 const UI_METHOD *ui_method,
168 OSSL_STORE_INFO *store_info = NULL;
169 EVP_PKEY *pkey = NULL;
170 const EVP_PKEY_ASN1_METHOD *ameth = NULL;
172 if (pem_name != NULL) {
175 if ((slen = pem_check_suffix(pem_name, "PRIVATE KEY")) > 0
176 && (ameth = EVP_PKEY_asn1_find_str(NULL, pem_name, slen)) != NULL)
177 pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
181 for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
182 ameth = EVP_PKEY_asn1_get0(i);
183 if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
185 pkey = d2i_PrivateKey(ameth->pkey_id, NULL, &blob, len);
194 store_info = OSSL_STORE_INFO_new_PKEY(pkey);
195 if (store_info == NULL)
200 static FILE_HANDLER PrivateKey_handler = {
202 try_decode_PrivateKey
205 static OSSL_STORE_INFO *try_decode_PUBKEY(const char *pem_name,
206 const char *pem_header,
207 const unsigned char *blob,
208 size_t len, void **pctx,
209 const UI_METHOD *ui_method,
212 OSSL_STORE_INFO *store_info = NULL;
213 EVP_PKEY *pkey = NULL;
215 if (pem_name != NULL && strcmp(pem_name, PEM_STRING_PUBLIC) != 0)
219 if ((pkey = d2i_PUBKEY(NULL, &blob, len)) != NULL)
220 store_info = OSSL_STORE_INFO_new_PKEY(pkey);
224 static FILE_HANDLER PUBKEY_handler = {
229 static OSSL_STORE_INFO *try_decode_params(const char *pem_name,
230 const char *pem_header,
231 const unsigned char *blob,
232 size_t len, void **pctx,
233 const UI_METHOD *ui_method,
236 OSSL_STORE_INFO *store_info = NULL;
237 EVP_PKEY *pkey = EVP_PKEY_new();
238 const EVP_PKEY_ASN1_METHOD *ameth = NULL;
242 OSSL_STOREerr(OSSL_STORE_F_TRY_DECODE_PARAMS, ERR_R_EVP_LIB);
246 if (pem_name != NULL) {
249 if ((slen = pem_check_suffix(pem_name, "PARAMETERS")) > 0
250 && EVP_PKEY_set_type_str(pkey, pem_name, slen)
251 && (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
252 && ameth->param_decode != NULL
253 && ameth->param_decode(pkey, &blob, len))
258 for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
259 ameth = EVP_PKEY_asn1_get0(i);
260 if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
262 if (EVP_PKEY_set_type(pkey, ameth->pkey_id)
263 && (ameth = EVP_PKEY_get0_asn1(pkey)) != NULL
264 && ameth->param_decode != NULL
265 && ameth->param_decode(pkey, &blob, len)) {
273 store_info = OSSL_STORE_INFO_new_PARAMS(pkey);
274 if (store_info == NULL)
279 static FILE_HANDLER params_handler = {
284 static OSSL_STORE_INFO *try_decode_X509Certificate(const char *pem_name,
285 const char *pem_header,
286 const unsigned char *blob,
287 size_t len, void **pctx,
288 const UI_METHOD *ui_method,
291 OSSL_STORE_INFO *store_info = NULL;
295 * In most cases, we can try to interpret the serialized data as a trusted
296 * cert (X509 + X509_AUX) and fall back to reading it as a normal cert
297 * (just X509), but if the PEM name specifically declares it as a trusted
298 * cert, then no fallback should be engaged. |ignore_trusted| tells if
299 * the fallback can be used (1) or not (0).
301 int ignore_trusted = 1;
303 if (pem_name != NULL) {
304 if (strcmp(pem_name, PEM_STRING_X509_TRUSTED) == 0)
306 else if (strcmp(pem_name, PEM_STRING_X509_OLD) != 0
307 && strcmp(pem_name, PEM_STRING_X509) != 0)
312 if ((cert = d2i_X509_AUX(NULL, &blob, len)) != NULL
313 || (ignore_trusted && (cert = d2i_X509(NULL, &blob, len)) != NULL))
314 store_info = OSSL_STORE_INFO_new_CERT(cert);
316 if (store_info == NULL)
321 static FILE_HANDLER X509Certificate_handler = {
323 try_decode_X509Certificate
326 static OSSL_STORE_INFO *try_decode_X509CRL(const char *pem_name,
327 const char *pem_header,
328 const unsigned char *blob,
329 size_t len, void **pctx,
330 const UI_METHOD *ui_method,
333 OSSL_STORE_INFO *store_info = NULL;
334 X509_CRL *crl = NULL;
337 && strcmp(pem_name, PEM_STRING_X509_CRL) != 0)
341 if ((crl = d2i_X509_CRL(NULL, &blob, len)) != NULL)
342 store_info = OSSL_STORE_INFO_new_CRL(crl);
344 if (store_info == NULL)
349 static FILE_HANDLER X509CRL_handler = {
354 static const FILE_HANDLER *file_handlers[] = {
355 &X509Certificate_handler,
367 struct ossl_store_loader_ctx_st {
372 /* The following are used when the handler is marked as repeatable */
373 const FILE_HANDLER *last_handler;
374 void *last_handler_ctx;
377 static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader,
379 const UI_METHOD *ui_method,
384 OSSL_STORE_LOADER_CTX *ctx = NULL;
385 const char *path = NULL;
387 if (strncasecmp(uri, "file:", 5) == 0) {
388 if (strncmp(&uri[5], "//localhost/", 12) == 0) {
390 } else if (strncmp(&uri[5], "///", 3) == 0) {
392 } else if (strncmp(&uri[5], "//", 2) != 0) {
395 OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN,
396 OSSL_STORE_R_URI_AUTHORITY_UNSUPPORED);
401 * If the scheme "file" was an explicit part of the URI, the path must
402 * be absolute. So says RFC 8089
404 if (path[0] != '/') {
405 OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN,
406 OSSL_STORE_R_PATH_MUST_BE_ABSOLUTE);
411 /* Windows file: URIs with a drive letter start with a / */
412 if (path[0] == '/' && path[2] == ':' && path[3] == '/')
420 ctx = OPENSSL_zalloc(sizeof(*ctx));
422 OSSL_STOREerr(OSSL_STORE_F_FILE_OPEN, ERR_R_MALLOC_FAILURE);
426 if ((buff = BIO_new(BIO_f_buffer())) == NULL)
428 if ((ctx->file = BIO_new_file(path, "rb")) == NULL) {
431 ctx->file = BIO_push(buff, ctx->file);
432 if (BIO_buffer_peek(ctx->file, peekbuf, sizeof(peekbuf)-1) > 0) {
433 peekbuf[sizeof(peekbuf)-1] = '\0';
434 if (strstr(peekbuf, "-----BEGIN ") != NULL)
446 static int file_eof(OSSL_STORE_LOADER_CTX *ctx);
447 static int file_error(OSSL_STORE_LOADER_CTX *ctx);
448 static OSSL_STORE_INFO *file_load(OSSL_STORE_LOADER_CTX *ctx,
449 const UI_METHOD *ui_method, void *ui_data)
451 OSSL_STORE_INFO *result = NULL;
454 if (ctx->last_handler != NULL) {
455 result = ctx->last_handler->try_decode(NULL, NULL, NULL, 0,
456 &ctx->last_handler_ctx,
462 ctx->last_handler->destroy_ctx(&ctx->last_handler_ctx);
463 ctx->last_handler_ctx = NULL;
464 ctx->last_handler = NULL;
471 char *pem_name = NULL; /* PEM record name */
472 char *pem_header = NULL; /* PEM record header */
473 unsigned char *data = NULL; /* DER encoded data */
475 long len = 0; /* DER encoded data length */
480 r = PEM_read_bio(ctx->file, &pem_name, &pem_header, &data, &len);
488 * 10 is the number of characters in "Proc-Type:", which
489 * PEM_get_EVP_CIPHER_INFO() requires to be present.
490 * If the PEM header has less characters than that, it's
491 * not worth spending cycles on it.
493 if (strlen(pem_header) > 10) {
494 EVP_CIPHER_INFO cipher;
495 struct pem_pass_data pass_data;
497 if (!PEM_get_EVP_CIPHER_INFO(pem_header, &cipher)
498 || !file_fill_pem_pass_data(&pass_data, "PEM", ui_method,
500 || !PEM_do_header(&cipher, data, &len, file_get_pem_pass,
507 if ((len = asn1_d2i_read_bio(ctx->file, &mem)) < 0) {
513 data = (unsigned char *)mem->data;
514 len = (long)mem->length;
521 void *handler_ctx = NULL;
522 const FILE_HANDLER **matching_handlers =
523 OPENSSL_zalloc(sizeof(*matching_handlers)
524 * OSSL_NELEM(file_handlers));
526 if (matching_handlers == NULL) {
527 OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD, ERR_R_MALLOC_FAILURE);
532 for (i = 0; i < OSSL_NELEM(file_handlers); i++) {
533 const FILE_HANDLER *handler = file_handlers[i];
534 void *tmp_handler_ctx = NULL;
535 OSSL_STORE_INFO *tmp_result =
536 handler->try_decode(pem_name, pem_header, data, len,
537 &tmp_handler_ctx, ui_method, ui_data);
539 if (tmp_result == NULL) {
540 OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD, OSSL_STORE_R_IS_NOT_A);
541 ERR_add_error_data(1, handler->name);
543 if (matching_handlers)
544 matching_handlers[matchcount] = handler;
547 handler->destroy_ctx(&handler_ctx);
548 handler_ctx = tmp_handler_ctx;
550 if (++matchcount == 1) {
554 /* more than one match => ambiguous, kill any result */
555 OSSL_STORE_INFO_free(result);
556 OSSL_STORE_INFO_free(tmp_result);
557 if (handler->destroy_ctx != NULL)
558 handler->destroy_ctx(&handler_ctx);
566 OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD,
567 OSSL_STORE_R_AMBIGUOUS_CONTENT_TYPE);
569 OSSL_STOREerr(OSSL_STORE_F_FILE_LOAD,
570 OSSL_STORE_R_UNSUPPORTED_CONTENT_TYPE);
571 else if (matching_handlers[0]->repeatable) {
572 ctx->last_handler = matching_handlers[0];
573 ctx->last_handler_ctx = handler_ctx;
578 OPENSSL_free(matching_handlers);
585 OPENSSL_free(pem_name);
586 OPENSSL_free(pem_header);
591 } while (matchcount == 0 && !file_eof(ctx) && !file_error(ctx));
593 /* We bail out on ambiguity */
601 static int file_error(OSSL_STORE_LOADER_CTX *ctx)
603 return ctx->errcnt > 0;
606 static int file_eof(OSSL_STORE_LOADER_CTX *ctx)
608 if (ctx->last_handler != NULL
609 && !ctx->last_handler->eof(ctx->last_handler_ctx))
611 return BIO_eof(ctx->file);
614 static int file_close(OSSL_STORE_LOADER_CTX *ctx)
616 if (ctx->last_handler != NULL) {
617 ctx->last_handler->destroy_ctx(&ctx->last_handler_ctx);
618 ctx->last_handler_ctx = NULL;
619 ctx->last_handler = NULL;
621 BIO_free_all(ctx->file);
626 static OSSL_STORE_LOADER file_loader =
637 static void store_file_loader_deinit(void)
639 ossl_store_unregister_loader_int(file_loader.scheme);
642 int ossl_store_file_loader_init(void)
644 int ret = ossl_store_register_loader_int(&file_loader);
646 OPENSSL_atexit(store_file_loader_deinit);