PROV BIO: add a BIO_vprintf() upcall, and a provider BIO library
authorRichard Levitte <levitte@openssl.org>
Mon, 18 Nov 2019 00:50:18 +0000 (01:50 +0100)
committerRichard Levitte <levitte@openssl.org>
Fri, 29 Nov 2019 19:55:16 +0000 (20:55 +0100)
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 <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10394)

crypto/provider_core.c
doc/man7/provider-base.pod
include/openssl/core_numbers.h
providers/common/bio_prov.c [new file with mode: 0644]
providers/common/build.info
providers/common/include/prov/bio.h [new file with mode: 0644]
providers/defltprov.c

index 9e92e96b1087704e0242a50a7c65cbbc4be699a1..c7c579a1c867e71ecb8fe6d17cf07fd8485f55cc 100644 (file)
@@ -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 },
index 08d807f572c846b8a48438c092b0ff088c9f8038..bb821321853b7611b8f5435e1f2d79aa3865f63a 100644 (file)
@@ -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<OSSL_DISPATCH> array are
 direct pointers to those public functions.
 
index 889362bc37fd4c125d58cb3253534179e99ef796..2d9c0f2f1caea14cdd2b646267e7867688af9722 100644 (file)
@@ -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 (file)
index 0000000..7b44004
--- /dev/null
@@ -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 <openssl/core_numbers.h>
+#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;
+}
+
index df05c49cd28b076eceb71be564180e6531e336cd..3f20fb3c09b3748289ed3786788c4c3392402a8d 100644 (file)
@@ -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 (file)
index 0000000..63f9d4e
--- /dev/null
@@ -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 <stdarg.h>
+#include <openssl/bio.h>
+#include <openssl/core.h>
+
+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, ...);
index 354c7a4a6d44f414d4acd2f20d8686dd099c9573..51d3d52ee9cc5796cd71fd1d3e752d999f7c0eef 100644 (file)
@@ -14,6 +14,7 @@
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
 #include <openssl/params.h>
+#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: