[openssl] master update

Matt Caswell matt at openssl.org
Thu May 28 16:08:47 UTC 2020


The branch master has been updated
       via  5ddec6a7d3206c61209a016db4227b847dcaad27 (commit)
       via  b533510f3bc70957dbf447f7ea8ec20765c5b314 (commit)
      from  9e6cb4344233aeefe91c6092567f887015ee345a (commit)


- Log -----------------------------------------------------------------
commit 5ddec6a7d3206c61209a016db4227b847dcaad27
Author: Matt Caswell <matt at openssl.org>
Date:   Thu May 14 11:33:01 2020 +0100

    Add a test for fetching EVP_PKEY style algs without a provider
    
    Following on from the previous commit, add a test to check that we fail
    to create an EVP_PKEY_CTX if an algorithm is not available in any provider,
    *unless* it is an algorithm that has no provider support.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11826)

commit b533510f3bc70957dbf447f7ea8ec20765c5b314
Author: Matt Caswell <matt at openssl.org>
Date:   Wed May 13 17:17:35 2020 +0100

    Fail if we fail to fetch the EVP_KEYMGMT
    
    If we failed to fetch an EVP_KEYMGMT then we were falling back to legacy.
    This is because some algorithms (such as MACs and KDFs used via an old
    style EVP_PKEY) have not been transferred to providers.
    
    Unfortunately this means that you cannot stop some algorithms from being
    used by not loading the provider.
    
    For example if you wanted to prevent RSA from being used, you might expect
    to just not load any providers that make it available. Unfortunately that
    doesn't work because we simply fall back to legacy if we fail to fetch
    the EVP_KEYMGMT.
    
    Instead we should fail *unless* the key type is one of those legacy key
    types that we have not transferred.
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11826)

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

Summary of changes:
 crypto/evp/pmeth_lib.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++---
 test/evp_extra_test.c  | 42 ++++++++++++++++++++++++++++++++++++++++++
 test/evp_test.c        |  3 ++-
 3 files changed, 91 insertions(+), 4 deletions(-)

diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 355565de63..ea8bdec388 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -137,6 +137,40 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
 }
 #endif /* FIPS_MODULE */
 
+static int is_legacy_alg(int id, const char *keytype)
+{
+#ifndef FIPS_MODULE
+    /* Certain EVP_PKEY keytypes are only available in legacy form */
+    if (id == -1) {
+        id = OBJ_sn2nid(keytype);
+        if (id == NID_undef)
+            id = OBJ_ln2nid(keytype);
+        if (id == NID_undef)
+            return  0;
+    }
+    switch (id) {
+    /*
+     * TODO(3.0): Remove SM2 and DHX when they are converted to have provider
+     * support
+     */
+    case EVP_PKEY_SM2:
+    case EVP_PKEY_DHX:
+    case EVP_PKEY_SCRYPT:
+    case EVP_PKEY_TLS1_PRF:
+    case EVP_PKEY_HKDF:
+    case EVP_PKEY_CMAC:
+    case EVP_PKEY_HMAC:
+    case EVP_PKEY_SIPHASH:
+    case EVP_PKEY_POLY1305:
+        return 1;
+    default:
+        return 0;
+    }
+#else
+    return 0;
+#endif
+}
+
 static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
                                  EVP_PKEY *pkey, ENGINE *e,
                                  const char *keytype, const char *propquery,
@@ -228,10 +262,20 @@ static EVP_PKEY_CTX *int_ctx_new(OPENSSL_CTX *libctx,
      * implementation.
      */
     if (e == NULL && keytype != NULL) {
-        /* This could fail so ignore errors */
-        ERR_set_mark();
+        int legacy = is_legacy_alg(id, keytype);
+
+        if (legacy) {
+            /* This could fail so ignore errors */
+            ERR_set_mark();
+        }
+
         keymgmt = EVP_KEYMGMT_fetch(libctx, keytype, propquery);
-        ERR_pop_to_mark();
+        if (legacy) {
+            ERR_pop_to_mark();
+        } else if (keymgmt == NULL) {
+            EVPerr(EVP_F_INT_CTX_NEW, EVP_R_FETCH_FAILED);
+            return NULL;
+        }
     }
 
     ret = OPENSSL_zalloc(sizeof(*ret));
diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
index 53d2f3afdb..2ab4be89a3 100644
--- a/test/evp_extra_test.c
+++ b/test/evp_extra_test.c
@@ -1625,6 +1625,47 @@ static int test_keygen_with_empty_template(int n)
     return ret;
 }
 
+/*
+ * Test that we fail if we attempt to use an algorithm that is not available
+ * in the current library context (unless we are using an algorithm that should
+ * be made available via legacy codepaths).
+ */
+static int test_pkey_ctx_fail_without_provider(int tst)
+{
+    OPENSSL_CTX *tmpctx = OPENSSL_CTX_new();
+    OSSL_PROVIDER *nullprov = NULL;
+    EVP_PKEY_CTX *pctx = NULL;
+    int ret = 0;
+
+    if (!TEST_ptr(tmpctx))
+        goto err;
+
+    nullprov = OSSL_PROVIDER_load(tmpctx, "null");
+    if (!TEST_ptr(nullprov))
+        goto err;
+
+    pctx = EVP_PKEY_CTX_new_from_name(tmpctx, tst == 0 ? "RSA" : "HMAC", "");
+
+    /* RSA is not available via any provider so we expect this to fail */
+    if (tst == 0 && !TEST_ptr_null(pctx))
+        goto err;
+
+    /*
+     * HMAC is always available because it is implemented via legacy codepaths
+     * and not in a provider at all. We expect this to pass.
+     */
+    if (tst == 1 && !TEST_ptr(pctx))
+        goto err;
+
+    ret = 1;
+
+ err:
+    EVP_PKEY_CTX_free(pctx);
+    OSSL_PROVIDER_unload(nullprov);
+    OPENSSL_CTX_free(tmpctx);
+    return ret;
+}
+
 int setup_tests(void)
 {
     testctx = OPENSSL_CTX_new();
@@ -1673,6 +1714,7 @@ int setup_tests(void)
     ADD_TEST(test_EVP_PKEY_set1_DH);
 #endif
     ADD_ALL_TESTS(test_keygen_with_empty_template, 2);
+    ADD_ALL_TESTS(test_pkey_ctx_fail_without_provider, 2);
 
     return 1;
 }
diff --git a/test/evp_test.c b/test/evp_test.c
index 813218a42a..6ed5bafba6 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -2995,7 +2995,8 @@ static int key_unsupported(void)
     long err = ERR_peek_error();
 
     if (ERR_GET_LIB(err) == ERR_LIB_EVP
-            && ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM) {
+            && (ERR_GET_REASON(err) == EVP_R_UNSUPPORTED_ALGORITHM
+                || ERR_GET_REASON(err) == EVP_R_FETCH_FAILED)) {
         ERR_clear_error();
         return 1;
     }


More information about the openssl-commits mailing list