From 63665fff84a4c79cd2acece4409036699f2e44a7 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Mon, 18 Nov 2019 01:50:18 +0100 Subject: [PATCH] PROV BIO: add a BIO_vprintf() upcall, and a provider BIO library The BIO_vprintf() will allow the provider to print any text, given a BIO supplied by libcrypto. Additionally, we add a provider library with functions to collect all the currently supplied BIO upcalls, as well as wrappers around those upcalls. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/10394) --- crypto/provider_core.c | 1 + doc/man7/provider-base.pod | 5 +- include/openssl/core_numbers.h | 3 + providers/common/bio_prov.c | 96 +++++++++++++++++++++++++++++ providers/common/build.info | 2 +- providers/common/include/prov/bio.h | 22 +++++++ providers/defltprov.c | 3 + 7 files changed, 129 insertions(+), 3 deletions(-) create mode 100644 providers/common/bio_prov.c create mode 100644 providers/common/include/prov/bio.h diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 9e92e96b10..c7c579a1c8 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -873,6 +873,7 @@ static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))BIO_new_mem_buf }, { OSSL_FUNC_BIO_READ_EX, (void (*)(void))BIO_read_ex }, { OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free }, + { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf }, #endif { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc }, diff --git a/doc/man7/provider-base.pod b/doc/man7/provider-base.pod index 08d807f572..bb82132185 100644 --- a/doc/man7/provider-base.pod +++ b/doc/man7/provider-base.pod @@ -113,6 +113,7 @@ provider): BIO_new_mem_buf OSSL_FUNC_BIO_NEW_MEMBUF BIO_read_ex OSSL_FUNC_BIO_READ_EX BIO_free OSSL_FUNC_BIO_FREE + BIO_vprintf OSSL_FUNC_BIO_VPRINTF OPENSSL_cleanse OSSL_FUNC_OPENSSL_CLEANSE OPENSSL_hexstr2buf OSSL_FUNC_OPENSSL_HEXSTR2BUF @@ -184,8 +185,8 @@ CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(), CRYPTO_secure_zalloc(), CRYPTO_secure_free(), CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(), CRYPTO_mem_ctrl(), BIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_free(), -OPENSSL_cleanse(), and OPENSSL_hexstr2buf() correspond exactly to the -public functions with the same name. +BIO_vprintf(), OPENSSL_cleanse(), and OPENSSL_hexstr2buf() +correspond exactly to the public functions with the same name. As a matter of fact, the pointers in the B array are direct pointers to those public functions. diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 889362bc37..2d9c0f2f1c 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -127,12 +127,15 @@ OSSL_CORE_MAKE_FUNC(int, CRYPTO_mem_ctrl, (int mode)) #define OSSL_FUNC_BIO_NEW_MEMBUF 24 #define OSSL_FUNC_BIO_READ_EX 25 #define OSSL_FUNC_BIO_FREE 26 +#define OSSL_FUNC_BIO_VPRINTF 27 OSSL_CORE_MAKE_FUNC(BIO *, BIO_new_file, (const char *filename, const char *mode)) OSSL_CORE_MAKE_FUNC(BIO *, BIO_new_membuf, (const void *buf, int len)) OSSL_CORE_MAKE_FUNC(int, BIO_read_ex, (BIO *bio, void *data, size_t data_len, size_t *bytes_read)) OSSL_CORE_MAKE_FUNC(int, BIO_free, (BIO *bio)) +OSSL_CORE_MAKE_FUNC(int, BIO_vprintf, (BIO *bio, const char *format, + va_list args)) /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */ # define OSSL_FUNC_PROVIDER_TEARDOWN 1024 diff --git a/providers/common/bio_prov.c b/providers/common/bio_prov.c new file mode 100644 index 0000000000..7b44004399 --- /dev/null +++ b/providers/common/bio_prov.c @@ -0,0 +1,96 @@ +/* + * Copyright 2019 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "prov/bio.h" + +static OSSL_BIO_new_file_fn *c_bio_new_file = NULL; +static OSSL_BIO_new_membuf_fn *c_bio_new_membuf = NULL; +static OSSL_BIO_read_ex_fn *c_bio_read_ex = NULL; +static OSSL_BIO_free_fn *c_bio_free = NULL; +static OSSL_BIO_vprintf_fn *c_bio_vprintf = NULL; + +int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns) +{ + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_FUNC_BIO_NEW_FILE: + if (c_bio_new_file == NULL) + c_bio_new_file = OSSL_get_BIO_new_file(fns); + break; + case OSSL_FUNC_BIO_NEW_MEMBUF: + if (c_bio_new_membuf == NULL) + c_bio_new_membuf = OSSL_get_BIO_new_membuf(fns); + break; + case OSSL_FUNC_BIO_READ_EX: + if (c_bio_read_ex == NULL) + c_bio_read_ex = OSSL_get_BIO_read_ex(fns); + break; + case OSSL_FUNC_BIO_FREE: + if (c_bio_free == NULL) + c_bio_free = OSSL_get_BIO_free(fns); + break; + case OSSL_FUNC_BIO_VPRINTF: + if (c_bio_vprintf == NULL) + c_bio_vprintf = OSSL_get_BIO_vprintf(fns); + break; + } + } + + return 1; +} + +BIO *ossl_prov_bio_new_file(const char *filename, const char *mode) +{ + if (c_bio_new_file == NULL) + return NULL; + return c_bio_new_file(filename, mode); +} + +BIO *ossl_prov_bio_new_membuf(const char *filename, int len) +{ + if (c_bio_new_membuf == NULL) + return NULL; + return c_bio_new_membuf(filename, len); +} + +int ossl_prov_bio_read_ex(BIO *bio, void *data, size_t data_len, + size_t *bytes_read) +{ + if (c_bio_read_ex == NULL) + return 0; + return c_bio_read_ex(bio, data, data_len, bytes_read); +} + +int ossl_prov_bio_free(BIO *bio) +{ + if (c_bio_free == NULL) + return 0; + return c_bio_free(bio); +} + +int ossl_prov_bio_vprintf(BIO *bio, const char *format, va_list ap) +{ + if (c_bio_vprintf == NULL) + return -1; + return c_bio_vprintf(bio, format, ap); +} + +int ossl_prov_bio_printf(BIO *bio, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = ossl_prov_bio_vprintf(bio, format, ap); + va_end(ap); + + return ret; +} + diff --git a/providers/common/build.info b/providers/common/build.info index df05c49cd2..3f20fb3c09 100644 --- a/providers/common/build.info +++ b/providers/common/build.info @@ -1,6 +1,6 @@ SUBDIRS=digests ciphers -SOURCE[../libcommon.a]=provider_err.c +SOURCE[../libcommon.a]=provider_err.c bio_prov.c $FIPSCOMMON=provider_util.c SOURCE[../libnonfips.a]=$FIPSCOMMON nid_to_name.c SOURCE[../libfips.a]=$FIPSCOMMON diff --git a/providers/common/include/prov/bio.h b/providers/common/include/prov/bio.h new file mode 100644 index 0000000000..63f9d4ec3a --- /dev/null +++ b/providers/common/include/prov/bio.h @@ -0,0 +1,22 @@ +/* + * Copyright 2019 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns); + +BIO *ossl_prov_bio_new_file(const char *filename, const char *mode); +BIO *ossl_prov_bio_new_membuf(const char *filename, int len); +int ossl_prov_bio_read_ex(BIO *bio, void *data, size_t data_len, + size_t *bytes_read); +int ossl_prov_bio_free(BIO *bio); +int ossl_prov_bio_vprintf(BIO *bio, const char *format, va_list ap); +int ossl_prov_bio_printf(BIO *bio, const char *format, ...); diff --git a/providers/defltprov.c b/providers/defltprov.c index 354c7a4a6d..51d3d52ee9 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -14,6 +14,7 @@ #include #include #include +#include "prov/bio.h" #include "prov/implementations.h" /* Functions provided by the core */ @@ -427,6 +428,8 @@ int ossl_default_provider_init(const OSSL_PROVIDER *provider, { OSSL_core_get_library_context_fn *c_get_libctx = NULL; + if (!ossl_prov_bio_from_dispatch(in)) + return 0; for (; in->function_id != 0; in++) { switch (in->function_id) { case OSSL_FUNC_CORE_GETTABLE_PARAMS: -- 2.25.1