[openssl] master update
Richard Levitte
levitte at openssl.org
Thu Jun 4 14:42:52 UTC 2020
The branch master has been updated
via c8567c392c1dc3dd15651c0d2746a5b87b5a88dd (commit)
via f995e5bdcd5d4c2143323ff78e4dcc0b95c5e024 (commit)
from 4cbb196b1b33d6ff2089537df0fdb76ac4741e2a (commit)
- Log -----------------------------------------------------------------
commit c8567c392c1dc3dd15651c0d2746a5b87b5a88dd
Author: Richard Levitte <levitte at openssl.org>
Date: Sat May 23 16:39:18 2020 +0200
CORE: make sure activated fallback providers stay activated
Calling 'OSSL_PROVIDER_available(NULL, "default")' would search for
the "default" provider, and in doing so, activate it if necessary,
thereby detecting that it's available... and then immediately free
it, which could deactivate that provider, even though it should stay
available.
We solve this by incrementing the refcount for activated fallbacks one
extra time, thereby simulating an explicit OSSL_PROVIDER_load(), and
compensate for it with an extra ossl_provider_free() when emptying the
provider store.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11926)
commit f995e5bdcd5d4c2143323ff78e4dcc0b95c5e024
Author: Richard Levitte <levitte at openssl.org>
Date: Sat May 23 16:34:07 2020 +0200
TEST: Add provider_fallback_test, to test aspects of fallback providers
There are cases where the fallback providers aren't treated right.
For example, the following calls, in that order, will end up with
a failed EVP_KEYMGMT_fetch(), even thought the default provider
does supply an implementation of the "RSA" keytype.
EVP_KEYMGMT *rsameth = NULL;
OSSL_PROVIDER_available(NULL, "default");
rsameth = EVP_KEYMGMT_fetch(NULL, "RSA", NULL);
For good measure, this also tests that explicit loading of the default
provider won't fail.
Reviewed-by: Matt Caswell <matt at openssl.org>
(Merged from https://github.com/openssl/openssl/pull/11926)
-----------------------------------------------------------------------
Summary of changes:
crypto/provider_core.c | 42 +++++++++++++---
test/build.info | 5 ++
test/provider_fallback_test.c | 57 ++++++++++++++++++++++
...t_internal_ec.t => 04-test_provider_fallback.t} | 13 +++--
4 files changed, 103 insertions(+), 14 deletions(-)
create mode 100644 test/provider_fallback_test.c
copy test/recipes/{03-test_internal_ec.t => 04-test_provider_fallback.t} (52%)
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index f8aa5721b4..8b868fdb6b 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -42,7 +42,8 @@ struct provider_store_st; /* Forward declaration */
struct ossl_provider_st {
/* Flag bits */
unsigned int flag_initialized:1;
- unsigned int flag_fallback:1;
+ unsigned int flag_fallback:1; /* Can be used as fallback */
+ unsigned int flag_activated_as_fallback:1;
/* OpenSSL library side data */
CRYPTO_REF_COUNT refcnt;
@@ -104,6 +105,24 @@ struct provider_store_st {
unsigned int use_fallbacks:1;
};
+/*
+ * provider_deactivate_free() is a wrapper around ossl_provider_free()
+ * that also makes sure that activated fallback providers are deactivated.
+ * This is simply done by freeing them an extra time, to compensate for the
+ * refcount that provider_activate_fallbacks() gives them.
+ * Since this is only called when the provider store is being emptied, we
+ * don't need to care about any lock.
+ */
+static void provider_deactivate_free(OSSL_PROVIDER *prov)
+{
+ int extra_free = (prov->flag_initialized
+ && prov->flag_activated_as_fallback);
+
+ if (extra_free)
+ ossl_provider_free(prov);
+ ossl_provider_free(prov);
+}
+
static void provider_store_free(void *vstore)
{
struct provider_store_st *store = vstore;
@@ -111,7 +130,7 @@ static void provider_store_free(void *vstore)
if (store == NULL)
return;
OPENSSL_free(store->default_path);
- sk_OSSL_PROVIDER_pop_free(store->providers, ossl_provider_free);
+ sk_OSSL_PROVIDER_pop_free(store->providers, provider_deactivate_free);
CRYPTO_THREAD_lock_free(store->lock);
OPENSSL_free(store);
}
@@ -654,13 +673,22 @@ static void provider_activate_fallbacks(struct provider_store_st *store)
OSSL_PROVIDER *prov = sk_OSSL_PROVIDER_value(store->providers, i);
/*
- * Note that we don't care if the activation succeeds or not.
- * If it doesn't succeed, then any attempt to use any of the
- * fallback providers will fail anyway.
+ * Activated fallback providers get an extra refcount, to
+ * simulate a regular load.
+ * Note that we don't care if the activation succeeds or not,
+ * other than to maintain a correct refcount. If the activation
+ * doesn't succeed, then any future attempt to use the fallback
+ * provider will fail anyway.
*/
if (prov->flag_fallback) {
- activated_fallback_count++;
- provider_activate(prov);
+ if (ossl_provider_up_ref(prov)) {
+ if (!provider_activate(prov)) {
+ ossl_provider_free(prov);
+ } else {
+ prov->flag_activated_as_fallback = 1;
+ activated_fallback_count++;
+ }
+ }
}
}
diff --git a/test/build.info b/test/build.info
index 9697e55f12..3255a836de 100644
--- a/test/build.info
+++ b/test/build.info
@@ -731,6 +731,11 @@ IF[{- !$disabled{tests} -}]
DEPEND[]=provider_internal_test.cnf
GENERATE[provider_internal_test.cnf]=provider_internal_test.cnf.in
+ PROGRAMS{noinst}=provider_fallback_test
+ SOURCE[provider_fallback_test]=provider_fallback_test.c
+ INCLUDE[provider_fallback_test]=../include ../apps/include
+ DEPEND[provider_fallback_test]=../libcrypto libtestutil.a
+
PROGRAMS{noinst}=params_test
SOURCE[params_test]=params_test.c
INCLUDE[params_test]=.. ../include ../apps/include
diff --git a/test/provider_fallback_test.c b/test/provider_fallback_test.c
new file mode 100644
index 0000000000..ce62184551
--- /dev/null
+++ b/test/provider_fallback_test.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright 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
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stddef.h>
+#include <openssl/provider.h>
+#include <openssl/evp.h>
+#include "testutil.h"
+
+static int test_provider(OPENSSL_CTX *ctx)
+{
+ EVP_KEYMGMT *rsameth = NULL;
+ const OSSL_PROVIDER *prov = NULL;
+ int ok;
+
+ ok = TEST_true(OSSL_PROVIDER_available(ctx, "default"))
+ && TEST_ptr(rsameth = EVP_KEYMGMT_fetch(ctx, "RSA", NULL))
+ && TEST_ptr(prov = EVP_KEYMGMT_provider(rsameth))
+ && TEST_str_eq(OSSL_PROVIDER_name(prov), "default");
+
+ EVP_KEYMGMT_free(rsameth);
+ return ok;
+}
+
+static int test_fallback_provider(void)
+{
+ return test_provider(NULL);
+}
+
+static int test_explicit_provider(void)
+{
+ OPENSSL_CTX *ctx = NULL;
+ OSSL_PROVIDER *prov = NULL;
+ int ok;
+
+ ok = TEST_ptr(ctx = OPENSSL_CTX_new())
+ && TEST_ptr(prov = OSSL_PROVIDER_load(ctx, "default"))
+ && test_provider(ctx)
+ && TEST_true(OSSL_PROVIDER_unload(prov));
+
+ OPENSSL_CTX_free(ctx);
+ return ok;
+}
+
+
+int setup_tests(void)
+{
+ ADD_TEST(test_fallback_provider);
+ ADD_TEST(test_explicit_provider);
+ return 1;
+}
+
diff --git a/test/recipes/03-test_internal_ec.t b/test/recipes/04-test_provider_fallback.t
similarity index 52%
copy from test/recipes/03-test_internal_ec.t
copy to test/recipes/04-test_provider_fallback.t
index 0d31d0ac07..39d3b105dc 100644
--- a/test/recipes/03-test_internal_ec.t
+++ b/test/recipes/04-test_provider_fallback.t
@@ -7,13 +7,12 @@
# https://www.openssl.org/source/license.html
use strict;
-use OpenSSL::Test; # get 'plan'
+use File::Spec;
use OpenSSL::Test::Simple;
-use OpenSSL::Test::Utils;
-setup("test_internal_ec");
+# We must ensure that OPENSSL_CONF points at an empty file. Otherwise, we
+# risk that the configuration file contains statements that load providers,
+# which defeats the purpose of this test. The NUL device is good enough.
+$ENV{OPENSSL_CONF} = File::Spec->devnull();
-plan skip_all => "This test is unsupported in a no-ec build"
- if disabled("ec");
-
-simple_test("test_internal_ec", "ec_internal_test");
+simple_test("test_provider_fallback", "provider_fallback_test");
More information about the openssl-commits
mailing list