diff options
author | Richard Levitte <levitte@openssl.org> | 2018-10-12 16:46:41 +0200 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2020-05-13 18:51:14 +0200 |
commit | 6ab6ecfd6d2d659326f427dceb1b65ae1b4b012b (patch) | |
tree | 5c720e17e9d40fc415ab3049fb056bd9aa590cf4 /crypto | |
parent | 78906fff4a6cfd5857045df770b47ae9ebcf0766 (diff) |
OSSL_STORE: Make it possible to attach an OSSL_STORE to an opened BIO
This capability existed internally, and is now made public.
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/11756)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/err/openssl.txt | 5 | ||||
-rw-r--r-- | crypto/pem/pem_pkey.c | 19 | ||||
-rw-r--r-- | crypto/store/loader_file.c | 123 | ||||
-rw-r--r-- | crypto/store/store_err.c | 2 | ||||
-rw-r--r-- | crypto/store/store_lib.c | 44 | ||||
-rw-r--r-- | crypto/store/store_local.h | 11 | ||||
-rw-r--r-- | crypto/store/store_register.c | 7 |
7 files changed, 106 insertions, 105 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 133a935b0f..8449ecea74 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -948,6 +948,7 @@ OCSP_F_OCSP_MATCH_ISSUERID:109:ocsp_match_issuerid OCSP_F_OCSP_REQUEST_SIGN:110:OCSP_request_sign OCSP_F_OCSP_REQUEST_VERIFY:116:OCSP_request_verify OCSP_F_OCSP_RESPONSE_GET1_BASIC:111:OCSP_response_get1_basic +OSSL_STORE_F_FILE_ATTACH:128: OSSL_STORE_F_FILE_CTRL:129:file_ctrl OSSL_STORE_F_FILE_FIND:138:file_find OSSL_STORE_F_FILE_GET_PASS:118:file_get_pass @@ -955,10 +956,8 @@ OSSL_STORE_F_FILE_LOAD:119:file_load OSSL_STORE_F_FILE_LOAD_TRY_DECODE:124:file_load_try_decode OSSL_STORE_F_FILE_NAME_TO_URI:126:file_name_to_uri OSSL_STORE_F_FILE_OPEN:120:file_open -OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO:127:ossl_store_attach_pem_bio +OSSL_STORE_F_OSSL_STORE_ATTACH:127: OSSL_STORE_F_OSSL_STORE_EXPECT:130:OSSL_STORE_expect -OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT:128:\ - ossl_store_file_attach_pem_bio_int OSSL_STORE_F_OSSL_STORE_FIND:131:OSSL_STORE_find OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT:100:ossl_store_get0_loader_int OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT:101:OSSL_STORE_INFO_get1_CERT diff --git a/crypto/pem/pem_pkey.c b/crypto/pem/pem_pkey.c index a1e8403e2b..ee9b6764a6 100644 --- a/crypto/pem/pem_pkey.c +++ b/crypto/pem/pem_pkey.c @@ -39,8 +39,8 @@ EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL) return NULL; - if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u, libctx, - propq)) == NULL) + if ((ctx = OSSL_STORE_attach(bp, libctx, "file", propq, ui_method, u, + NULL, NULL)) == NULL) goto err; #ifndef OPENSSL_NO_SECURE_HEAP { @@ -56,13 +56,14 @@ EVP_PKEY *PEM_read_bio_PrivateKey_ex(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, break; } OSSL_STORE_INFO_free(info); + info = NULL; } if (ret != NULL && x != NULL) *x = ret; err: - ossl_store_detach_pem_bio(ctx); + OSSL_STORE_close(ctx); UI_destroy_method(ui_method); OSSL_STORE_INFO_free(info); return ret; @@ -105,7 +106,8 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) OSSL_STORE_CTX *ctx = NULL; OSSL_STORE_INFO *info = NULL; - if ((ctx = ossl_store_attach_pem_bio(bp, UI_null(), NULL, NULL, NULL)) == NULL) + if ((ctx = OSSL_STORE_attach(bp, NULL, "file", NULL, UI_null(), NULL, + NULL, NULL)) == NULL) goto err; while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { @@ -114,13 +116,14 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) break; } OSSL_STORE_INFO_free(info); + info = NULL; } if (ret != NULL && x != NULL) *x = ret; err: - ossl_store_detach_pem_bio(ctx); + OSSL_STORE_close(ctx); OSSL_STORE_INFO_free(info); return ret; } @@ -198,7 +201,8 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) if ((ui_method = UI_UTIL_wrap_read_pem_callback(cb, 0)) == NULL) return NULL; - if ((ctx = ossl_store_attach_pem_bio(bp, ui_method, u, NULL, NULL)) == NULL) + if ((ctx = OSSL_STORE_attach(bp, NULL, "file", NULL, ui_method, u, + NULL, NULL)) == NULL) goto err; while (!OSSL_STORE_eof(ctx) && (info = OSSL_STORE_load(ctx)) != NULL) { @@ -211,13 +215,14 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u) } } OSSL_STORE_INFO_free(info); + info = NULL; } if (ret != NULL && x != NULL) *x = ret; err: - ossl_store_detach_pem_bio(ctx); + OSSL_STORE_close(ctx); UI_destroy_method(ui_method); OSSL_STORE_INFO_free(info); return ret; diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c index 02178b29a8..b87e165705 100644 --- a/crypto/store/loader_file.c +++ b/crypto/store/loader_file.c @@ -718,6 +718,7 @@ struct ossl_store_loader_ctx_st { } type; int errcnt; #define FILE_FLAG_SECMEM (1<<0) +#define FILE_FLAG_ATTACHED (1<<1) unsigned int flags; union { struct { /* Used with is_raw and is_pem */ @@ -774,6 +775,23 @@ static void OSSL_STORE_LOADER_CTX_free(OSSL_STORE_LOADER_CTX *ctx) OPENSSL_free(ctx); } +static int file_find_type(OSSL_STORE_LOADER_CTX *ctx) +{ + BIO *buff = NULL; + char peekbuf[4096] = { 0, }; + + if ((buff = BIO_new(BIO_f_buffer())) == NULL) + return 0; + + ctx->_.file.file = BIO_push(buff, ctx->_.file.file); + if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) { + peekbuf[sizeof(peekbuf) - 1] = '\0'; + if (strstr(peekbuf, "-----BEGIN ") != NULL) + ctx->type = is_pem; + } + return 1; +} + static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader, const char *uri, const UI_METHOD *ui_method, @@ -891,22 +909,10 @@ static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader, } ctx->_.dir.end_reached = 1; } - } else { - BIO *buff = NULL; - char peekbuf[4096] = { 0, }; - - if ((buff = BIO_new(BIO_f_buffer())) == NULL - || (ctx->_.file.file = BIO_new_file(path, "rb")) == NULL) { - BIO_free_all(buff); - goto err; - } - - ctx->_.file.file = BIO_push(buff, ctx->_.file.file); - if (BIO_buffer_peek(ctx->_.file.file, peekbuf, sizeof(peekbuf) - 1) > 0) { - peekbuf[sizeof(peekbuf) - 1] = '\0'; - if (strstr(peekbuf, "-----BEGIN ") != NULL) - ctx->type = is_pem; - } + } else if ((ctx->_.file.file = BIO_new_file(path, "rb")) == NULL + || !file_find_type(ctx)) { + BIO_free_all(ctx->_.file.file); + goto err; } return ctx; @@ -915,6 +921,34 @@ static OSSL_STORE_LOADER_CTX *file_open(const OSSL_STORE_LOADER *loader, return NULL; } +static OSSL_STORE_LOADER_CTX *file_attach(const OSSL_STORE_LOADER *loader, + BIO *bp, OPENSSL_CTX *libctx, + const char *propq, + const UI_METHOD *ui_method, + void *ui_data) +{ + OSSL_STORE_LOADER_CTX *ctx; + + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL + || (propq != NULL && (ctx->propq = OPENSSL_strdup(propq)) == NULL)) { + OSSL_STOREerr(OSSL_STORE_F_FILE_ATTACH, ERR_R_MALLOC_FAILURE); + OSSL_STORE_LOADER_CTX_free(ctx); + return NULL; + } + + ctx->libctx = libctx; + ctx->flags |= FILE_FLAG_ATTACHED; + ctx->_.file.file = bp; + if (!file_find_type(ctx)) { + /* Safety measure */ + ctx->_.file.file = NULL; + OSSL_STORE_LOADER_CTX_free(ctx); + ctx = NULL; + } + + return ctx; +} + static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args) { int ret = 1; @@ -984,36 +1018,6 @@ static int file_find(OSSL_STORE_LOADER_CTX *ctx, return 0; } -/* Internal function to decode an already opened PEM file */ -OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp, - OPENSSL_CTX *libctx, - const char *propq) -{ - OSSL_STORE_LOADER_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); - - if (ctx == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT, - ERR_R_MALLOC_FAILURE); - return NULL; - } - - ctx->_.file.file = bp; - ctx->type = is_pem; - - ctx->libctx = libctx; - if (propq != NULL) { - ctx->propq = OPENSSL_strdup(propq); - if (ctx->propq == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT, - ERR_R_MALLOC_FAILURE); - OPENSSL_free(ctx); - return NULL; - } - } - - return ctx; -} - static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx, const char *pem_name, const char *pem_header, @@ -1435,17 +1439,25 @@ static int file_eof(OSSL_STORE_LOADER_CTX *ctx) static int file_close(OSSL_STORE_LOADER_CTX *ctx) { - if (ctx->type == is_dir) { - OPENSSL_DIR_end(&ctx->_.dir.ctx); + if ((ctx->flags & FILE_FLAG_ATTACHED) == 0) { + if (ctx->type == is_dir) + OPENSSL_DIR_end(&ctx->_.dir.ctx); + else + BIO_free_all(ctx->_.file.file); } else { - BIO_free_all(ctx->_.file.file); - } - OSSL_STORE_LOADER_CTX_free(ctx); - return 1; -} + /* + * Because file_attach() called file_find_type(), we know that a + * BIO_f_buffer() has been pushed on top of the regular BIO. + */ + BIO *buff = ctx->_.file.file; -int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx) -{ + /* Detach buff */ + (void)BIO_pop(ctx->_.file.file); + /* Safety measure */ + ctx->_.file.file = NULL; + + BIO_free(buff); + } OSSL_STORE_LOADER_CTX_free(ctx); return 1; } @@ -1455,6 +1467,7 @@ static OSSL_STORE_LOADER file_loader = "file", NULL, file_open, + file_attach, file_ctrl, file_expect, file_find, diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c index aa8ab4f9b0..3abb50bb21 100644 --- a/crypto/store/store_err.c +++ b/crypto/store/store_err.c @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index 5bcd17b13b..15c0862019 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -651,47 +651,33 @@ char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info) return NULL; } -OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method, - void *ui_data, OPENSSL_CTX *libctx, - const char *propq) +OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, OPENSSL_CTX *libctx, + const char *scheme, const char *propq, + const UI_METHOD *ui_method, void *ui_data, + OSSL_STORE_post_process_info_fn post_process, + void *post_process_data) { OSSL_STORE_CTX *ctx = NULL; const OSSL_STORE_LOADER *loader = NULL; OSSL_STORE_LOADER_CTX *loader_ctx = NULL; - if ((loader = ossl_store_get0_loader_int("file")) == NULL - || ((loader_ctx = ossl_store_file_attach_pem_bio_int(bp, libctx, - propq)) == NULL)) - goto done; + if ((loader = + ossl_store_get0_loader_int(scheme != NULL ? scheme : "file")) == NULL + || (loader_ctx = loader->attach(loader, bp, libctx, propq, + ui_method, ui_data)) == NULL) + return NULL; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { - OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, - ERR_R_MALLOC_FAILURE); - goto done; + OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH, ERR_R_MALLOC_FAILURE); + return NULL; } ctx->loader = loader; ctx->loader_ctx = loader_ctx; - loader_ctx = NULL; ctx->ui_method = ui_method; ctx->ui_data = ui_data; - ctx->post_process = NULL; - ctx->post_process_data = NULL; + ctx->post_process = post_process; + ctx->post_process_data = post_process_data; - done: - if (loader_ctx != NULL) - /* - * We ignore a returned error because we will return NULL anyway in - * this case, so if something goes wrong when closing, that'll simply - * just add another entry on the error stack. - */ - (void)loader->close(loader_ctx); return ctx; } - -int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx) -{ - int loader_ret = ossl_store_file_detach_pem_bio_int(ctx->loader_ctx); - - OPENSSL_free(ctx); - return loader_ret; -} diff --git a/crypto/store/store_local.h b/crypto/store/store_local.h index 7c86419031..31e04d13ad 100644 --- a/crypto/store/store_local.h +++ b/crypto/store/store_local.h @@ -102,6 +102,7 @@ struct ossl_store_loader_st { const char *scheme; ENGINE *engine; OSSL_STORE_open_fn open; + OSSL_STORE_attach_fn attach; OSSL_STORE_ctrl_fn ctrl; OSSL_STORE_expect_fn expect; OSSL_STORE_find_fn find; @@ -122,13 +123,3 @@ void ossl_store_destroy_loaders_int(void); int ossl_store_init_once(void); int ossl_store_file_loader_init(void); - -/*- - * 'file' scheme stuff - * ------------------- - */ - -OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp, - OPENSSL_CTX *libctx, - const char *propq); -int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx); diff --git a/crypto/store/store_register.c b/crypto/store/store_register.c index 399ec8c625..45fbd2fa1c 100644 --- a/crypto/store/store_register.c +++ b/crypto/store/store_register.c @@ -71,6 +71,13 @@ int OSSL_STORE_LOADER_set_open(OSSL_STORE_LOADER *loader, return 1; } +int OSSL_STORE_LOADER_set_attach(OSSL_STORE_LOADER *loader, + OSSL_STORE_attach_fn attach_function) +{ + loader->attach = attach_function; + return 1; +} + int OSSL_STORE_LOADER_set_ctrl(OSSL_STORE_LOADER *loader, OSSL_STORE_ctrl_fn ctrl_function) { |