[openssl] master update

Dr. Paul Dale pauli at openssl.org
Wed Mar 10 23:26:46 UTC 2021


The branch master has been updated
       via  903a6558471812c8884a8ba279ad96dc29ccd4b0 (commit)
       via  925b5360f7ae234b5103effd1e0d713575906421 (commit)
       via  141cc94e44db93cded4ce3f0d97b9b5b928f43f2 (commit)
      from  7a45d51ce3268d16409405b9d54d7b4bb77a7fc3 (commit)


- Log -----------------------------------------------------------------
commit 903a6558471812c8884a8ba279ad96dc29ccd4b0
Author: Pauli <ppzgs1 at gmail.com>
Date:   Tue Mar 9 10:57:05 2021 +1000

    test: convert store test to use relative paths
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14419)

commit 925b5360f7ae234b5103effd1e0d713575906421
Author: Pauli <ppzgs1 at gmail.com>
Date:   Fri Mar 5 11:24:34 2021 +1000

    core: add up_ref callback for OSSL_CORE_BIO
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14419)

commit 141cc94e44db93cded4ce3f0d97b9b5b928f43f2
Author: Pauli <ppzgs1 at gmail.com>
Date:   Thu Mar 4 13:53:53 2021 +1000

    Add a real type for OSSL_CORE_BIO which is distinct from and not castable to BIO
    
    Providers (particularly the FIPS provider) needs access to BIOs from libcrypto.
    Libcrypto is allowed to change the internal format of the BIO structure and it
    is still expected to work with providers that were already built.  This means
    that the libcrypto BIO must be distinct from and not castable to the provider
    side OSSL_CORE_BIO.
    
    Unfortunately, this requirement was broken in both directions.  This fixes
    things by forcing the two to be different and any casts break loudly.
    
    Reviewed-by: Tomas Mraz <tomas at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/14419)

-----------------------------------------------------------------------

Summary of changes:
 crypto/bio/build.info                              |   2 +-
 crypto/bio/core_bio.c                              | 124 +++++++++++++++++++++
 crypto/encode_decode/decoder_lib.c                 |  10 +-
 crypto/encode_decode/encoder_lib.c                 |   8 +-
 crypto/provider_core.c                             |  20 ++--
 crypto/store/store_lib.c                           |   7 +-
 doc/man7/provider-base.pod                         |  28 ++---
 include/internal/bio.h                             |  16 +++
 include/openssl/core_dispatch.h                    |  14 ++-
 providers/common/bio_prov.c                        |  24 +++-
 providers/common/include/prov/bio.h                |   1 +
 .../implementations/storemgmt/file_store_der2obj.c |   6 +-
 test/ossl_store_test.c                             |  62 +++++++----
 test/recipes/66-test_ossl_store.t                  |   5 +-
 14 files changed, 267 insertions(+), 60 deletions(-)
 create mode 100644 crypto/bio/core_bio.c

diff --git a/crypto/bio/build.info b/crypto/bio/build.info
index 227071f0ce..2bee64fc62 100644
--- a/crypto/bio/build.info
+++ b/crypto/bio/build.info
@@ -5,7 +5,7 @@ SOURCE[../../libcrypto]=\
         bio_lib.c bio_cb.c bio_err.c \
         b_print.c b_dump.c b_addr.c \
         b_sock.c b_sock2.c \
-        bio_meth.c
+        bio_meth.c core_bio.c
 
 # Source / sink implementations
 SOURCE[../../libcrypto]=\
diff --git a/crypto/bio/core_bio.c b/crypto/bio/core_bio.c
new file mode 100644
index 0000000000..328302ea34
--- /dev/null
+++ b/crypto/bio/core_bio.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2021 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.h>
+#include "bio_local.h"
+
+/*-
+ * Core BIO structure
+ * This is distinct from a BIO to prevent casting between the two which could
+ * lead to versioning problems.
+ */
+struct ossl_core_bio_st {
+    CRYPTO_REF_COUNT ref_cnt;
+    CRYPTO_RWLOCK *ref_lock;
+    BIO *bio;
+};
+
+static OSSL_CORE_BIO *core_bio_new(void)
+{
+    OSSL_CORE_BIO *cb = OPENSSL_malloc(sizeof(*cb));
+
+    if (cb == NULL || (cb->ref_lock = CRYPTO_THREAD_lock_new()) == NULL) {
+        OPENSSL_free(cb);
+        return NULL;
+    }
+    cb->ref_cnt = 1;
+    return cb;
+}
+
+int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb)
+{
+    int ref = 0;
+
+    return CRYPTO_UP_REF(&cb->ref_cnt, &ref, cb->ref_lock);
+}
+
+int ossl_core_bio_free(OSSL_CORE_BIO *cb)
+{
+    int ref = 0, res = 1;
+
+    if (cb != NULL) {
+        CRYPTO_DOWN_REF(&cb->ref_cnt, &ref, cb->ref_lock);
+        if (ref <= 0) {
+            res = BIO_free(cb->bio);
+            CRYPTO_THREAD_lock_free(cb->ref_lock);
+            OPENSSL_free(cb);
+        }
+    }
+    return res;
+}
+
+OSSL_CORE_BIO *ossl_core_bio_new_from_bio(BIO *bio)
+{
+    OSSL_CORE_BIO *cb = core_bio_new();
+
+    if (cb == NULL || !BIO_up_ref(bio)) {
+        ossl_core_bio_free(cb);
+        return NULL;
+    }
+    cb->bio = bio;
+    return cb;
+}
+
+static OSSL_CORE_BIO *core_bio_new_from_new_bio(BIO *bio)
+{
+    OSSL_CORE_BIO *cb = NULL;
+
+    if (bio == NULL)
+        return NULL;
+    if ((cb = core_bio_new()) == NULL) {
+        BIO_free(bio);
+        return NULL;
+    }
+    cb->bio = bio;
+    return cb;
+}
+
+OSSL_CORE_BIO *ossl_core_bio_new_file(const char *filename, const char *mode)
+{
+    return core_bio_new_from_new_bio(BIO_new_file(filename, mode));
+}
+
+OSSL_CORE_BIO *ossl_core_bio_new_mem_buf(const void *buf, int len)
+{
+    return core_bio_new_from_new_bio(BIO_new_mem_buf(buf, len));
+}
+
+int ossl_core_bio_read_ex(OSSL_CORE_BIO *cb, void *data, size_t dlen,
+                          size_t *readbytes)
+{
+    return BIO_read_ex(cb->bio, data, dlen, readbytes);
+}
+
+int ossl_core_bio_write_ex(OSSL_CORE_BIO *cb, const void *data, size_t dlen,
+                           size_t *written)
+{
+    return BIO_write_ex(cb->bio, data, dlen, written);
+}
+
+int ossl_core_bio_gets(OSSL_CORE_BIO *cb, char *buf, int size)
+{
+    return BIO_gets(cb->bio, buf, size);
+}
+
+int ossl_core_bio_puts(OSSL_CORE_BIO *cb, const char *buf)
+{
+    return BIO_puts(cb->bio, buf);
+}
+
+long ossl_core_bio_ctrl(OSSL_CORE_BIO *cb, int cmd, long larg, void *parg)
+{
+    return BIO_ctrl(cb->bio, cmd, larg, parg);
+}
+
+int ossl_core_bio_vprintf(OSSL_CORE_BIO *cb, const char *format, va_list args)
+{
+    return BIO_vprintf(cb->bio, format, args);
+}
diff --git a/crypto/encode_decode/decoder_lib.c b/crypto/encode_decode/decoder_lib.c
index f161c7cd5b..9c01dc894b 100644
--- a/crypto/encode_decode/decoder_lib.c
+++ b/crypto/encode_decode/decoder_lib.c
@@ -17,6 +17,7 @@
 #include <openssl/x509err.h>
 #include <openssl/trace.h>
 #include "internal/passphrase.h"
+#include "internal/bio.h"
 #include "crypto/decoder.h"
 #include "encoder_local.h"
 #include "e_os.h"
@@ -520,6 +521,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
     OSSL_DECODER_CTX *ctx = data->ctx;
     OSSL_DECODER_INSTANCE *decoder_inst = NULL;
     OSSL_DECODER *decoder = NULL;
+    OSSL_CORE_BIO *cbio = NULL;
     BIO *bio = data->bio;
     long loc;
     size_t i;
@@ -633,6 +635,11 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
         goto end;
     }
 
+    if ((cbio = ossl_core_bio_new_from_bio(bio)) == NULL) {
+        ERR_raise(ERR_LIB_OSSL_DECODER, ERR_R_MALLOC_FAILURE);
+        goto end;
+    }
+
     for (i = data->current_decoder_inst_index; i-- > 0;) {
         OSSL_DECODER_INSTANCE *new_decoder_inst =
             sk_OSSL_DECODER_INSTANCE_value(ctx->decoder_insts, i);
@@ -740,7 +747,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
         } OSSL_TRACE_END(DECODER);
 
         new_data.current_decoder_inst_index = i;
-        ok = new_decoder->decode(new_decoderctx, (OSSL_CORE_BIO *)bio,
+        ok = new_decoder->decode(new_decoderctx, cbio,
                                  new_data.ctx->selection,
                                  decoder_process, &new_data,
                                  ossl_pw_passphrase_callback_dec,
@@ -776,6 +783,7 @@ static int decoder_process(const OSSL_PARAM params[], void *arg)
     }
 
  end:
+    ossl_core_bio_free(cbio);
     BIO_free(new_data.bio);
     return ok;
 }
diff --git a/crypto/encode_decode/encoder_lib.c b/crypto/encode_decode/encoder_lib.c
index d15fb27fde..b25529e073 100644
--- a/crypto/encode_decode/encoder_lib.c
+++ b/crypto/encode_decode/encoder_lib.c
@@ -15,6 +15,7 @@
 #include <openssl/params.h>
 #include <openssl/provider.h>
 #include <openssl/trace.h>
+#include "internal/bio.h"
 #include "encoder_local.h"
 
 struct encoder_process_data_st {
@@ -604,6 +605,7 @@ static int encoder_process(struct encoder_process_data_st *data)
         /* Calling the encoder implementation */
 
         if (ok) {
+            OSSL_CORE_BIO *cbio = NULL;
             BIO *current_out = NULL;
 
             /*
@@ -616,9 +618,10 @@ static int encoder_process(struct encoder_process_data_st *data)
                      == NULL)
                 ok = 0;     /* Assume BIO_new() recorded an error */
 
+            if (ok)
+                ok = (cbio = ossl_core_bio_new_from_bio(current_out)) != NULL;
             if (ok) {
-                ok = current_encoder->encode(current_encoder_ctx,
-                                             (OSSL_CORE_BIO *)current_out,
+                ok = current_encoder->encode(current_encoder_ctx, cbio,
                                              original_data, current_abstract,
                                              data->ctx->selection,
                                              ossl_pw_passphrase_callback_enc,
@@ -631,6 +634,7 @@ static int encoder_process(struct encoder_process_data_st *data)
                 } OSSL_TRACE_END(ENCODER);
             }
 
+            ossl_core_bio_free(cbio);
             data->prev_encoder_inst = current_encoder_inst;
         }
     }
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 1326f83f7e..9536cb65d1 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -20,6 +20,7 @@
 #include "internal/thread_once.h"
 #include "internal/provider.h"
 #include "internal/refcount.h"
+#include "internal/bio.h"
 #include "provider_local.h"
 #ifndef FIPS_MODULE
 # include <openssl/self_test.h>
@@ -1191,15 +1192,16 @@ static const OSSL_DISPATCH core_dispatch_[] = {
     { OSSL_FUNC_CORE_CLEAR_LAST_ERROR_MARK,
       (void (*)(void))core_clear_last_error_mark },
     { OSSL_FUNC_CORE_POP_ERROR_TO_MARK, (void (*)(void))core_pop_error_to_mark },
-    { OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))BIO_new_file },
-    { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))BIO_new_mem_buf },
-    { OSSL_FUNC_BIO_READ_EX, (void (*)(void))BIO_read_ex },
-    { OSSL_FUNC_BIO_WRITE_EX, (void (*)(void))BIO_write_ex },
-    { OSSL_FUNC_BIO_GETS, (void (*)(void))BIO_gets },
-    { OSSL_FUNC_BIO_PUTS, (void (*)(void))BIO_puts },
-    { OSSL_FUNC_BIO_CTRL, (void (*)(void))BIO_ctrl },
-    { OSSL_FUNC_BIO_FREE, (void (*)(void))BIO_free },
-    { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))BIO_vprintf },
+    { OSSL_FUNC_BIO_NEW_FILE, (void (*)(void))ossl_core_bio_new_file },
+    { OSSL_FUNC_BIO_NEW_MEMBUF, (void (*)(void))ossl_core_bio_new_mem_buf },
+    { OSSL_FUNC_BIO_READ_EX, (void (*)(void))ossl_core_bio_read_ex },
+    { OSSL_FUNC_BIO_WRITE_EX, (void (*)(void))ossl_core_bio_write_ex },
+    { OSSL_FUNC_BIO_GETS, (void (*)(void))ossl_core_bio_gets },
+    { OSSL_FUNC_BIO_PUTS, (void (*)(void))ossl_core_bio_puts },
+    { OSSL_FUNC_BIO_CTRL, (void (*)(void))ossl_core_bio_ctrl },
+    { OSSL_FUNC_BIO_UP_REF, (void (*)(void))ossl_core_bio_up_ref },
+    { OSSL_FUNC_BIO_FREE, (void (*)(void))ossl_core_bio_free },
+    { OSSL_FUNC_BIO_VPRINTF, (void (*)(void))ossl_core_bio_vprintf },
     { OSSL_FUNC_BIO_VSNPRINTF, (void (*)(void))BIO_vsnprintf },
     { OSSL_FUNC_SELF_TEST_CB, (void (*)(void))OSSL_SELF_TEST_get_callback },
     { OSSL_FUNC_GET_ENTROPY, (void (*)(void))ossl_rand_get_entropy },
diff --git a/crypto/store/store_lib.c b/crypto/store/store_lib.c
index 5d0b3e7397..1aaf9f89a4 100644
--- a/crypto/store/store_lib.c
+++ b/crypto/store/store_lib.c
@@ -26,6 +26,7 @@
 #include "internal/thread_once.h"
 #include "internal/cryptlib.h"
 #include "internal/provider.h"
+#include "internal/bio.h"
 #include "crypto/store.h"
 #include "store_local.h"
 
@@ -941,9 +942,10 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme,
         const OSSL_PROVIDER *provider =
             OSSL_STORE_LOADER_provider(fetched_loader);
         void *provctx = OSSL_PROVIDER_get0_provider_ctx(provider);
+        OSSL_CORE_BIO *cbio = ossl_core_bio_new_from_bio(bp);
 
-        if ((loader_ctx =
-             fetched_loader->p_attach(provctx, (OSSL_CORE_BIO *)bp)) == NULL) {
+        if (cbio == NULL
+            || (loader_ctx = fetched_loader->p_attach(provctx, cbio)) == NULL) {
             OSSL_STORE_LOADER_free(fetched_loader);
             fetched_loader = NULL;
         } else if (propq != NULL) {
@@ -961,6 +963,7 @@ OSSL_STORE_CTX *OSSL_STORE_attach(BIO *bp, const char *scheme,
             }
         }
         loader = fetched_loader;
+        ossl_core_bio_free(cbio);
     }
 
     if (loader_ctx == NULL) {
diff --git a/doc/man7/provider-base.pod b/doc/man7/provider-base.pod
index 3b4416dac0..29f5468c9f 100644
--- a/doc/man7/provider-base.pod
+++ b/doc/man7/provider-base.pod
@@ -56,28 +56,29 @@ provider-base
  int CRYPTO_secure_allocated(const void *ptr);
  void OPENSSL_cleanse(void *ptr, size_t len);
 
- OSSL_CORE_BIO * BIO_new_file(const char *filename, const char *mode)
- OSSL_CORE_BIO * BIO_new_membuf(const void *buf, int len)
+ OSSL_CORE_BIO *BIO_new_file(const char *filename, const char *mode);
+ OSSL_CORE_BIO *BIO_new_membuf(const void *buf, int len);
  int BIO_read_ex(OSSL_CORE_BIO *bio, void *data, size_t data_len,
-                 size_t *bytes_read))
+                 size_t *bytes_read);
  int BIO_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len,
-                  size_t *written)
- int BIO_free(OSSL_CORE_BIO *bio))
- int BIO_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list args)
- int BIO_vsnprintf(char *buf, size_t n, const char *fmt, va_list args)
+                  size_t *written);
+ int BIO_up_ref(OSSL_CORE_BIO *bio);
+ int BIO_free(OSSL_CORE_BIO *bio);
+ int BIO_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list args);
+ int BIO_vsnprintf(char *buf, size_t n, const char *fmt, va_list args);
 
- void self_test_cb(OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb, void **cbarg)
+ void self_test_cb(OPENSSL_CORE_CTX *ctx, OSSL_CALLBACK **cb, void **cbarg);
 
  size_t get_entropy(const OSSL_CORE_HANDLE *handle,
                     unsigned char **pout, int entropy,
-                    size_t min_len, size_t max_len)
+                    size_t min_len, size_t max_len);
  void cleanup_entropy(const OSSL_CORE_HANDLE *handle,
-                      unsigned char *buf, size_t len)
+                      unsigned char *buf, size_t len);
  size_t get_nonce(const OSSL_CORE_HANDLE *handle,
                   unsigned char **pout, size_t min_len, size_t max_len,
-                  const void *salt, size_t salt_len)
+                  const void *salt, size_t salt_len);
  void cleanup_nonce(const OSSL_CORE_HANDLE *handle,
-                    unsigned char *buf, size_t len)
+                    unsigned char *buf, size_t len);
 
  /* Functions offered by the provider to libcrypto */
  void provider_teardown(void *provctx);
@@ -140,6 +141,7 @@ provider):
  BIO_new_file                   OSSL_FUNC_BIO_NEW_FILE
  BIO_new_mem_buf                OSSL_FUNC_BIO_NEW_MEMBUF
  BIO_read_ex                    OSSL_FUNC_BIO_READ_EX
+ BIO_up_ref                     OSSL_FUNC_BIO_UP_REF
  BIO_free                       OSSL_FUNC_BIO_FREE
  BIO_vprintf                    OSSL_FUNC_BIO_VPRINTF
  OPENSSL_cleanse                OSSL_FUNC_OPENSSL_CLEANSE
@@ -225,7 +227,7 @@ CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(),
 CRYPTO_realloc(), CRYPTO_clear_realloc(), CRYPTO_secure_malloc(),
 CRYPTO_secure_zalloc(), CRYPTO_secure_free(),
 CRYPTO_secure_clear_free(), CRYPTO_secure_allocated(),
-BIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_free(),
+BIO_new_file(), BIO_new_mem_buf(), BIO_read_ex(), BIO_up_ref(), BIO_free(),
 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
diff --git a/include/internal/bio.h b/include/internal/bio.h
index e057298318..b905845a1a 100644
--- a/include/internal/bio.h
+++ b/include/internal/bio.h
@@ -11,6 +11,7 @@
 # define OSSL_INTERNAL_BIO_H
 # pragma once
 
+# include <openssl/core.h>
 # include <openssl/bio.h>
 
 struct bio_method_st {
@@ -70,4 +71,19 @@ int bread_conv(BIO *bio, char *data, size_t datal, size_t *read);
 # define BIO_clear_ktls_ctrl_msg(b) \
      BIO_ctrl(b, BIO_CTRL_CLEAR_KTLS_TX_CTRL_MSG, 0, NULL)
 
+/* Functions to allow the core to offer the CORE_BIO type to providers */
+OSSL_CORE_BIO *ossl_core_bio_new_from_bio(BIO *bio);
+OSSL_CORE_BIO *ossl_core_bio_new_file(const char *filename, const char *mode);
+OSSL_CORE_BIO *ossl_core_bio_new_mem_buf(const void *buf, int len);
+int ossl_core_bio_read_ex(OSSL_CORE_BIO *cb, void *data, size_t dlen,
+                          size_t *readbytes);
+int ossl_core_bio_write_ex(OSSL_CORE_BIO *cb, const void *data, size_t dlen,
+                           size_t *written);
+int ossl_core_bio_gets(OSSL_CORE_BIO *cb, char *buf, int size);
+int ossl_core_bio_puts(OSSL_CORE_BIO *cb, const char *buf);
+long ossl_core_bio_ctrl(OSSL_CORE_BIO *cb, int cmd, long larg, void *parg);
+int ossl_core_bio_up_ref(OSSL_CORE_BIO *cb);
+int ossl_core_bio_free(OSSL_CORE_BIO *cb);
+int ossl_core_bio_vprintf(OSSL_CORE_BIO *cb, const char *format, va_list args);
+
 #endif
diff --git a/include/openssl/core_dispatch.h b/include/openssl/core_dispatch.h
index 76fd0ada6c..eb71bc5469 100644
--- a/include/openssl/core_dispatch.h
+++ b/include/openssl/core_dispatch.h
@@ -135,12 +135,13 @@ OSSL_CORE_MAKE_FUNC(void,
 #define OSSL_FUNC_BIO_NEW_MEMBUF              41
 #define OSSL_FUNC_BIO_READ_EX                 42
 #define OSSL_FUNC_BIO_WRITE_EX                43
-#define OSSL_FUNC_BIO_FREE                    44
-#define OSSL_FUNC_BIO_VPRINTF                 45
-#define OSSL_FUNC_BIO_VSNPRINTF               46
-#define OSSL_FUNC_BIO_PUTS                    47
-#define OSSL_FUNC_BIO_GETS                    48
-#define OSSL_FUNC_BIO_CTRL                    49
+#define OSSL_FUNC_BIO_UP_REF                  44
+#define OSSL_FUNC_BIO_FREE                    45
+#define OSSL_FUNC_BIO_VPRINTF                 46
+#define OSSL_FUNC_BIO_VSNPRINTF               47
+#define OSSL_FUNC_BIO_PUTS                    48
+#define OSSL_FUNC_BIO_GETS                    49
+#define OSSL_FUNC_BIO_CTRL                    50
 
 
 OSSL_CORE_MAKE_FUNC(OSSL_CORE_BIO *, BIO_new_file, (const char *filename,
@@ -152,6 +153,7 @@ OSSL_CORE_MAKE_FUNC(int, BIO_write_ex, (OSSL_CORE_BIO *bio, const void *data,
                                         size_t data_len, size_t *written))
 OSSL_CORE_MAKE_FUNC(int, BIO_gets, (OSSL_CORE_BIO *bio, char *buf, int size))
 OSSL_CORE_MAKE_FUNC(int, BIO_puts, (OSSL_CORE_BIO *bio, const char *str))
+OSSL_CORE_MAKE_FUNC(int, BIO_up_ref, (OSSL_CORE_BIO *bio))
 OSSL_CORE_MAKE_FUNC(int, BIO_free, (OSSL_CORE_BIO *bio))
 OSSL_CORE_MAKE_FUNC(int, BIO_vprintf, (OSSL_CORE_BIO *bio, const char *format,
                                        va_list args))
diff --git a/providers/common/bio_prov.c b/providers/common/bio_prov.c
index afdeb80d80..47f04c47e2 100644
--- a/providers/common/bio_prov.c
+++ b/providers/common/bio_prov.c
@@ -19,6 +19,7 @@ static OSSL_FUNC_BIO_write_ex_fn *c_bio_write_ex = NULL;
 static OSSL_FUNC_BIO_gets_fn *c_bio_gets = NULL;
 static OSSL_FUNC_BIO_puts_fn *c_bio_puts = NULL;
 static OSSL_FUNC_BIO_ctrl_fn *c_bio_ctrl = NULL;
+static OSSL_FUNC_BIO_up_ref_fn *c_bio_up_ref = NULL;
 static OSSL_FUNC_BIO_free_fn *c_bio_free = NULL;
 static OSSL_FUNC_BIO_vprintf_fn *c_bio_vprintf = NULL;
 
@@ -54,6 +55,10 @@ int ossl_prov_bio_from_dispatch(const OSSL_DISPATCH *fns)
             if (c_bio_ctrl == NULL)
                 c_bio_ctrl = OSSL_FUNC_BIO_ctrl(fns);
             break;
+        case OSSL_FUNC_BIO_UP_REF:
+            if (c_bio_up_ref == NULL)
+                c_bio_up_ref = OSSL_FUNC_BIO_up_ref(fns);
+            break;
         case OSSL_FUNC_BIO_FREE:
             if (c_bio_free == NULL)
                 c_bio_free = OSSL_FUNC_BIO_free(fns);
@@ -119,6 +124,13 @@ int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr)
     return c_bio_ctrl(bio, cmd, num, ptr);
 }
 
+int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio)
+{
+    if (c_bio_up_ref == NULL)
+        return 0;
+    return c_bio_up_ref(bio);
+}
+
 int ossl_prov_bio_free(OSSL_CORE_BIO *bio)
 {
     if (c_bio_free == NULL)
@@ -186,6 +198,7 @@ static int bio_core_new(BIO *bio)
 static int bio_core_free(BIO *bio)
 {
     BIO_set_init(bio, 0);
+    ossl_prov_bio_free(BIO_get_data(bio));
 
     return 1;
 }
@@ -218,10 +231,13 @@ BIO *bio_new_from_core_bio(PROV_CTX *provctx, OSSL_CORE_BIO *corebio)
     if (corebiometh == NULL)
         return NULL;
 
-    outbio = BIO_new(corebiometh);
-    if (outbio != NULL)
-        BIO_set_data(outbio, corebio);
-
+    if ((outbio = BIO_new(corebiometh)) == NULL)
+        return NULL;
+    if (!ossl_prov_bio_up_ref(corebio)) {
+        BIO_free(outbio);
+        return NULL;
+    }
+    BIO_set_data(outbio, corebio);
     return outbio;
 }
 
diff --git a/providers/common/include/prov/bio.h b/providers/common/include/prov/bio.h
index 9dd9f44bad..fc8237a249 100644
--- a/providers/common/include/prov/bio.h
+++ b/providers/common/include/prov/bio.h
@@ -23,6 +23,7 @@ int ossl_prov_bio_write_ex(OSSL_CORE_BIO *bio, const void *data, size_t data_len
 int ossl_prov_bio_gets(OSSL_CORE_BIO *bio, char *buf, int size);
 int ossl_prov_bio_puts(OSSL_CORE_BIO *bio, const char *str);
 int ossl_prov_bio_ctrl(OSSL_CORE_BIO *bio, int cmd, long num, void *ptr);
+int ossl_prov_bio_up_ref(OSSL_CORE_BIO *bio);
 int ossl_prov_bio_free(OSSL_CORE_BIO *bio);
 int ossl_prov_bio_vprintf(OSSL_CORE_BIO *bio, const char *format, va_list ap);
 int ossl_prov_bio_printf(OSSL_CORE_BIO *bio, const char *format, ...);
diff --git a/providers/implementations/storemgmt/file_store_der2obj.c b/providers/implementations/storemgmt/file_store_der2obj.c
index 74a18eb70b..d34e90540d 100644
--- a/providers/implementations/storemgmt/file_store_der2obj.c
+++ b/providers/implementations/storemgmt/file_store_der2obj.c
@@ -85,10 +85,13 @@ static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
      * We're called from file_store.c, so we know that OSSL_CORE_BIO is a
      * BIO in this case.
      */
-    BIO *in = (BIO *)cin;
+    BIO *in = bio_new_from_core_bio(provctx, cin);
     BUF_MEM *mem = NULL;
     int err, ok;
 
+    if (in == NULL)
+        return 0;
+
     ERR_set_mark();
     ok = (asn1_d2i_read_bio(in, &mem) >= 0);
     /*
@@ -117,6 +120,7 @@ static int der2obj_decode(void *provctx, OSSL_CORE_BIO *cin, int selection,
         OPENSSL_free(mem->data);
         OPENSSL_free(mem);
     }
+    BIO_free(in);
     return ok;
 }
 
diff --git a/test/ossl_store_test.c b/test/ossl_store_test.c
index 7424aed0dd..773c696fec 100644
--- a/test/ossl_store_test.c
+++ b/test/ossl_store_test.c
@@ -23,12 +23,16 @@
 typedef enum OPTION_choice {
     OPT_ERR = -1,
     OPT_EOF = 0,
+    OPT_INPUTDIR,
     OPT_INFILE,
+    OPT_SM2FILE,
     OPT_DATADIR,
     OPT_TEST_ENUM
 } OPTION_CHOICE;
 
+static const char *inputdir = NULL;
 static const char *infile = NULL;
+static const char *sm2file = NULL;
 static const char *datadir = NULL;
 
 static int test_store_open(void)
@@ -37,16 +41,19 @@ static int test_store_open(void)
     OSSL_STORE_CTX *sctx = NULL;
     OSSL_STORE_SEARCH *search = NULL;
     UI_METHOD *ui_method = NULL;
+    char *input = test_mk_file_path(inputdir, infile);
 
-    ret = TEST_ptr(search = OSSL_STORE_SEARCH_by_alias("nothing"))
+    ret = TEST_ptr(input)
+          && TEST_ptr(search = OSSL_STORE_SEARCH_by_alias("nothing"))
           && TEST_ptr(ui_method= UI_create_method("DummyUI"))
-          && TEST_ptr(sctx = OSSL_STORE_open_ex(infile, NULL, NULL, ui_method,
+          && TEST_ptr(sctx = OSSL_STORE_open_ex(input, NULL, NULL, ui_method,
                                                 NULL, NULL, NULL))
           && TEST_false(OSSL_STORE_find(sctx, NULL))
           && TEST_true(OSSL_STORE_find(sctx, search));
     UI_destroy_method(ui_method);
     OSSL_STORE_SEARCH_free(search);
     OSSL_STORE_close(sctx);
+    OPENSSL_free(input);
     return ret;
 }
 
@@ -139,24 +146,27 @@ static int test_store_get_params(int idx)
 static int test_store_attach_unregistered_scheme(void)
 {
     int ret;
-    OSSL_STORE_CTX *store_ctx;
-    OSSL_PROVIDER *provider;
-    OSSL_LIB_CTX *libctx;
-    BIO *bio;
-    libctx = OSSL_LIB_CTX_new();
-    provider = OSSL_PROVIDER_load(libctx, "default");
-    bio = BIO_new_file("test/certs/sm2-root.crt", "r");
-
-    ret = TEST_ptr(store_ctx = OSSL_STORE_attach(bio, "file", libctx, NULL,
-                                                 NULL, NULL, NULL, NULL)) &&
-          TEST_int_ne(ERR_GET_LIB(ERR_peek_error()), ERR_LIB_OSSL_STORE) &&
-          TEST_int_ne(ERR_GET_REASON(ERR_peek_error()),
-                      OSSL_STORE_R_UNREGISTERED_SCHEME);
+    OSSL_STORE_CTX *store_ctx = NULL;
+    OSSL_PROVIDER *provider = NULL;
+    OSSL_LIB_CTX *libctx = NULL;
+    BIO *bio = NULL;
+    char *input = test_mk_file_path(inputdir, sm2file);
+
+    ret = TEST_ptr(input)
+          && TEST_ptr(libctx = OSSL_LIB_CTX_new())
+          && TEST_ptr(provider = OSSL_PROVIDER_load(libctx, "default"))
+          && TEST_ptr(bio = BIO_new_file(input, "r"))
+          && TEST_ptr(store_ctx = OSSL_STORE_attach(bio, "file", libctx, NULL,
+                                                    NULL, NULL, NULL, NULL))
+          && TEST_int_ne(ERR_GET_LIB(ERR_peek_error()), ERR_LIB_OSSL_STORE)
+          && TEST_int_ne(ERR_GET_REASON(ERR_peek_error()),
+                         OSSL_STORE_R_UNREGISTERED_SCHEME);
 
     BIO_free(bio);
     OSSL_STORE_close(store_ctx);
     OSSL_PROVIDER_unload(provider);
     OSSL_LIB_CTX_free(libctx);
+    OPENSSL_free(input);
     return ret;
 }
 
@@ -164,7 +174,9 @@ const OPTIONS *test_get_options(void)
 {
     static const OPTIONS test_options[] = {
         OPT_TEST_OPTIONS_DEFAULT_USAGE,
-        { "in", OPT_INFILE, '<', },
+        { "dir", OPT_INPUTDIR, '/' },
+        { "in", OPT_INFILE, '<' },
+        { "sm2", OPT_SM2FILE, '<' },
         { "data", OPT_DATADIR, 's' },
         { NULL }
     };
@@ -177,9 +189,15 @@ int setup_tests(void)
 
     while ((o = opt_next()) != OPT_EOF) {
         switch (o) {
+        case OPT_INPUTDIR:
+            inputdir = opt_arg();
+            break;
         case OPT_INFILE:
             infile = opt_arg();
             break;
+        case OPT_SM2FILE:
+            sm2file = opt_arg();
+            break;
         case OPT_DATADIR:
             datadir = opt_arg();
             break;
@@ -192,13 +210,19 @@ int setup_tests(void)
     }
 
     if (datadir == NULL) {
-        TEST_error("No datadir specified");
+        TEST_error("No data directory specified");
+        return 0;
+    }
+    if (inputdir == NULL) {
+        TEST_error("No input directory specified");
         return 0;
     }
 
-    ADD_TEST(test_store_open);
+    if (infile != NULL)
+        ADD_TEST(test_store_open);
     ADD_TEST(test_store_search_by_key_fingerprint_fail);
     ADD_ALL_TESTS(test_store_get_params, 3);
-    ADD_TEST(test_store_attach_unregistered_scheme);
+    if (sm2file != NULL)
+        ADD_TEST(test_store_attach_unregistered_scheme);
     return 1;
 }
diff --git a/test/recipes/66-test_ossl_store.t b/test/recipes/66-test_ossl_store.t
index 08d66977a5..0385e452b7 100644
--- a/test/recipes/66-test_ossl_store.t
+++ b/test/recipes/66-test_ossl_store.t
@@ -10,11 +10,12 @@ use strict;
 use warnings;
 
 use OpenSSL::Test::Simple;
-use OpenSSL::Test qw/:DEFAULT srctop_file data_dir/;
+use OpenSSL::Test qw/:DEFAULT srctop_dir data_dir/;
 
 setup("test_ossl_store");
 
 plan tests => 1;
 
-ok(run(test(["ossl_store_test", "-in", srctop_file("test", "testrsa.pem"),
+ok(run(test(["ossl_store_test", "-dir", srctop_dir("test"),
+             "-in", "testrsa.pem", "-sm2", "certs/sm2-root.crt",
              "-data", data_dir()])));


More information about the openssl-commits mailing list