From 4c17819c41b32f6652662d4a2942e35c67d7d650 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Tue, 6 Dec 2016 14:41:33 +0100 Subject: [PATCH] Add internal functions to fetch PEM data from an opened BIO store_attach_pem_bio() creates a STORE_CTX with the 'file' scheme loader backend in PEM reading mode on an already opened BIO. store_detach_pem_bio() detaches the STORE_CTX from the BIO and destroys it (without destroying the BIO). These two functions can be used in place of STORE_open() and STORE_close(), and are present as internal support for other OpenSSL functions. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/2745) --- crypto/err/openssl.txt | 3 ++ crypto/include/internal/store_int.h | 33 ++++++++++++++++++++++ crypto/store/loader_file.c | 24 ++++++++++++++++ crypto/store/store_err.c | 4 +++ crypto/store/store_lib.c | 44 +++++++++++++++++++++++++++++ crypto/store/store_locl.h | 8 ++++++ include/openssl/storeerr.h | 2 ++ 7 files changed, 118 insertions(+) create mode 100644 crypto/include/internal/store_int.h diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index d62957727d..87aea05511 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -730,6 +730,9 @@ 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_FILE_ATTACH_PEM_BIO_INT:128:\ + ossl_store_file_attach_pem_bio_int 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 OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL:102:OSSL_STORE_INFO_get1_CRL diff --git a/crypto/include/internal/store_int.h b/crypto/include/internal/store_int.h new file mode 100644 index 0000000000..9966aefa67 --- /dev/null +++ b/crypto/include/internal/store_int.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef HEADER_STORE_INT_H +# define HEADER_STORE_INT_H + +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + +/* + * Two functions to read PEM data off an already opened BIO. To be used + * instead of OSSLSTORE_open() and OSSLSTORE_close(). Everything is done + * as usual with OSSLSTORE_load() and OSSLSTORE_eof(). + */ +OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method, + void *ui_data); +int ossl_store_detach_pem_bio(OSSL_STORE_CTX *ctx); + +# ifdef __cplusplus +} +# endif +#endif diff --git a/crypto/store/loader_file.c b/crypto/store/loader_file.c index 8c8b81eb74..2b0f213df0 100644 --- a/crypto/store/loader_file.c +++ b/crypto/store/loader_file.c @@ -25,6 +25,7 @@ #include "internal/asn1_int.h" #include "internal/o_dir.h" #include "internal/cryptlib.h" +#include "internal/store_int.h" #include "store_locl.h" #include "e_os.h" @@ -800,6 +801,23 @@ static int file_ctrl(OSSL_STORE_LOADER_CTX *ctx, int cmd, va_list args) return ret; } +/* Internal function to decode an already opened PEM file */ +OSSL_STORE_LOADER_CTX *ossl_store_file_attach_pem_bio_int(BIO *bp) +{ + 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; + + return ctx; +} + static OSSL_STORE_INFO *file_load_try_decode(OSSL_STORE_LOADER_CTX *ctx, const char *pem_name, const char *pem_header, @@ -1158,6 +1176,12 @@ static int file_close(OSSL_STORE_LOADER_CTX *ctx) return 1; } +int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx) +{ + OSSL_STORE_LOADER_CTX_free(ctx); + return 1; +} + static OSSL_STORE_LOADER file_loader = { "file", diff --git a/crypto/store/store_err.c b/crypto/store/store_err.c index 8f1a9be195..aad643b163 100644 --- a/crypto/store/store_err.c +++ b/crypto/store/store_err.c @@ -23,6 +23,10 @@ static const ERR_STRING_DATA OSSL_STORE_str_functs[] = { {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_NAME_TO_URI, 0), "file_name_to_uri"}, {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_FILE_OPEN, 0), "file_open"}, + {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, 0), + "ossl_store_attach_pem_bio"}, + {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT, 0), + "ossl_store_file_attach_pem_bio_int"}, {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT, 0), "ossl_store_get0_loader_int"}, {ERR_PACK(ERR_LIB_OSSL_STORE, OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT, 0), diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c index 2c8ce86a27..d5bb8b88ce 100644 --- a/crypto/store/store_lib.c +++ b/crypto/store/store_lib.c @@ -14,6 +14,7 @@ #include #include #include "internal/thread_once.h" +#include "internal/store_int.h" #include "store_locl.h" struct ossl_store_ctx_st { @@ -407,3 +408,46 @@ char *ossl_store_info_get0_EMBEDDED_pem_name(OSSL_STORE_INFO *info) return info->_.embedded.pem_name; return NULL; } + +OSSL_STORE_CTX *ossl_store_attach_pem_bio(BIO *bp, const UI_METHOD *ui_method, + void *ui_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)) == NULL)) + goto done; + if ((ctx = OPENSSL_zalloc(sizeof(*ctx))) == NULL) { + OSSL_STOREerr(OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO, + ERR_R_MALLOC_FAILURE); + goto done; + } + + 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; + + 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_locl.h b/crypto/store/store_locl.h index a954c577c4..789d332810 100644 --- a/crypto/store/store_locl.h +++ b/crypto/store/store_locl.h @@ -92,3 +92,11 @@ 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); +int ossl_store_file_detach_pem_bio_int(OSSL_STORE_LOADER_CTX *ctx); diff --git a/include/openssl/storeerr.h b/include/openssl/storeerr.h index a049726a3d..4e0818d7ac 100644 --- a/include/openssl/storeerr.h +++ b/include/openssl/storeerr.h @@ -28,6 +28,8 @@ int ERR_load_OSSL_STORE_strings(void); # define OSSL_STORE_F_FILE_LOAD_TRY_DECODE 124 # define OSSL_STORE_F_FILE_NAME_TO_URI 126 # define OSSL_STORE_F_FILE_OPEN 120 +# define OSSL_STORE_F_OSSL_STORE_ATTACH_PEM_BIO 127 +# define OSSL_STORE_F_OSSL_STORE_FILE_ATTACH_PEM_BIO_INT 128 # define OSSL_STORE_F_OSSL_STORE_GET0_LOADER_INT 100 # define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CERT 101 # define OSSL_STORE_F_OSSL_STORE_INFO_GET1_CRL 102 -- 2.34.1