]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Test that EVP_default_properties_is_fips_enabled() works early
authorMatt Caswell <matt@openssl.org>
Wed, 5 Aug 2020 13:46:48 +0000 (14:46 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 17 Aug 2020 10:27:51 +0000 (11:27 +0100)
We check that EVP_default_properties_is_fips_enabled() is working even
before other function calls have auto-loaded the config file.

Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12567)

test/build.info
test/defltfips_test.c [new file with mode: 0644]
test/evp_test.c
test/fips.cnf
test/recipes/30-test_defltfips.t [new file with mode: 0644]
test/tls-provider.c

index 1dd3db7c79c49c9ae5de98fc16934092ee4633fb..11fce8e2798caeb46ef449e83594d1302cef85ba 100644 (file)
@@ -57,7 +57,7 @@ IF[{- !$disabled{tests} -}]
           http_test servername_test ocspapitest fatalerrtest tls13ccstest \
           sysdefaulttest errtest ssl_ctx_test gosttest \
           context_internal_test aesgcmtest params_test evp_pkey_dparams_test \
-          keymgmt_internal_test hexstr_test provider_status_test
+          keymgmt_internal_test hexstr_test provider_status_test defltfips_test
 
   IF[{- !$disabled{'deprecated-3.0'} -}]
     PROGRAMS{noinst}=enginetest
@@ -324,6 +324,10 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[sslapitest]=../include ../apps/include ..
   DEPEND[sslapitest]=../libcrypto ../libssl libtestutil.a
 
+  SOURCE[defltfips_test]=defltfips_test.c
+  INCLUDE[defltfips_test]=../include  ../apps/include
+  DEPEND[defltfips_test]=../libcrypto libtestutil.a
+
   SOURCE[ocspapitest]=ocspapitest.c
   INCLUDE[ocspapitest]=../include ../apps/include
   DEPEND[ocspapitest]=../libcrypto libtestutil.a
diff --git a/test/defltfips_test.c b/test/defltfips_test.c
new file mode 100644 (file)
index 0000000..a834921
--- /dev/null
@@ -0,0 +1,81 @@
+#include <string.h>
+#include <openssl/evp.h>
+#include <openssl/provider.h>
+#include "testutil.h"
+
+static int is_fips;
+
+static int test_is_fips_enabled(void)
+{
+    int is_fips_enabled, is_fips_loaded;
+    EVP_MD *sha256 = NULL;
+
+    /*
+     * Check we're in FIPS mode when we're supposed to be. We do this early to
+     * confirm that EVP_default_properties_is_fips_enabled() works even before
+     * other function calls have auto-loaded the config file.
+     */
+    is_fips_enabled = EVP_default_properties_is_fips_enabled(NULL);
+    is_fips_loaded = OSSL_PROVIDER_available(NULL, "fips");
+
+    /*
+     * Check we're in an expected state. EVP_default_properties_is_fips_enabled
+     * can return true even if the FIPS provider isn't loaded - it is only based
+     * on the default properties. However we only set those properties if also
+     * loading the FIPS provider.
+     */
+    if (!TEST_int_eq(is_fips, is_fips_enabled)
+            || !TEST_int_eq(is_fips, is_fips_loaded))
+        return 0;
+
+    /*
+     * Fetching an algorithm shouldn't change the state and should come from
+     * expected provider.
+     */
+    sha256 = EVP_MD_fetch(NULL, "SHA2-256", NULL);
+    if (!TEST_ptr(sha256))
+        return 0;
+    if (is_fips
+            && !TEST_str_eq(OSSL_PROVIDER_name(EVP_MD_provider(sha256)), "fips")) {
+        EVP_MD_free(sha256);
+        return 0;
+    }
+    EVP_MD_free(sha256);
+
+    /* State should still be consistent */
+    is_fips_enabled = EVP_default_properties_is_fips_enabled(NULL);
+    if (!TEST_int_eq(is_fips, is_fips_enabled))
+        return 0;
+
+    return 1;
+}
+
+int setup_tests(void)
+{
+    size_t argc;
+
+    if (!test_skip_common_options()) {
+        TEST_error("Error parsing test options\n");
+        return 0;
+    }
+
+    argc = test_get_argument_count();
+    switch(argc) {
+    case 0:
+        is_fips = 0;
+        break;
+    case 1:
+        if (strcmp(test_get_argument(0), "fips") == 0) {
+            is_fips = 1;
+            break;
+        }
+        /* fall through */
+    default:
+        TEST_error("Invalid argument\n");
+        return 0;
+    }
+
+    /* Must be the first test before any other libcrypto calls are made */
+    ADD_TEST(test_is_fips_enabled);
+    return 1;
+}
index b980abc9440c353105fbb85f2ca98eb4b6a1b1b3..cd6077e10d0d4b5f902d06b3c8fd0cc43c6c10d4 100644 (file)
@@ -2095,7 +2095,8 @@ static int rand_test_init(EVP_TEST *t, const char *name)
     if (!TEST_ptr(rdata = OPENSSL_zalloc(sizeof(*rdata))))
         return 0;
 
-    rand = EVP_RAND_fetch(libctx, "TEST-RAND", NULL);
+    /* TEST-RAND is available in the FIPS provider but not with "fips=yes" */
+    rand = EVP_RAND_fetch(libctx, "TEST-RAND", "-fips");
     if (rand == NULL)
         goto err;
     rdata->parent = EVP_RAND_CTX_new(rand, NULL);
index d6c3c6be140eefe22f19159cd7372e07ae9b2db6..fa131a8bf6246d0911c2ca92d06582cacb8c13e9 100644 (file)
@@ -4,6 +4,13 @@ openssl_conf = openssl_init
 
 [openssl_init]
 providers = provider_sect
+alg_section = evp_properties
+
+[evp_properties]
+# Ensure FIPS non-approved algorithms in the FIPS module are suppressed (e.g.
+# TEST-RAND). This also means that EVP_default_properties_is_fips_enabled()
+# returns the expected value
+default_properties = "fips=yes"
 
 [provider_sect]
 fips = fips_sect
diff --git a/test/recipes/30-test_defltfips.t b/test/recipes/30-test_defltfips.t
new file mode 100644 (file)
index 0000000..c98591e
--- /dev/null
@@ -0,0 +1,43 @@
+#! /usr/bin/env perl
+# Copyright 2015-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
+
+
+use strict;
+use warnings;
+
+use OpenSSL::Test qw/:DEFAULT srctop_file srctop_dir bldtop_file bldtop_dir/;
+use OpenSSL::Test::Utils;
+use Cwd qw(abs_path);
+
+BEGIN {
+    setup("test_evp");
+}
+
+use lib srctop_dir('Configurations');
+use lib bldtop_dir('.');
+use platform;
+
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
+
+plan tests =>
+    ($no_fips ? 1 : 3);
+
+unless ($no_fips) {
+    my $infile = bldtop_file('providers', platform->dso('fips'));
+
+    ok(run(app(['openssl', 'fipsinstall',
+                '-out', bldtop_file('providers', 'fipsmodule.cnf'),
+                '-module', $infile])),
+       "fipsinstall");
+
+    $ENV{OPENSSL_CONF} = abs_path(srctop_file("test", "fips.cnf"));
+    ok(run(test(["defltfips_test", "fips"])), "running defltfips_test fips");
+}
+
+$ENV{OPENSSL_CONF} = abs_path(srctop_file("test", "default.cnf"));
+ok(run(test(["defltfips_test"])), "running defltfips_test");
index 496ba7ead95b99848a86c3d3ac43ce40be29bd9c..924ede501bc30c26b944df7fca04a60e85d82d9e 100644 (file)
@@ -180,7 +180,11 @@ static const OSSL_DISPATCH xor_keyexch_functions[] = {
 };
 
 static const OSSL_ALGORITHM tls_prov_keyexch[] = {
-    { "XOR", "provider=tls-provider", xor_keyexch_functions },
+    /*
+     * Obviously this is not FIPS approved, but in order to test in conjuction
+     * with the FIPS provider we pretend that it is.
+     */
+    { "XOR", "provider=tls-provider,fips=yes", xor_keyexch_functions },
     { NULL, NULL, NULL }
 };
 
@@ -414,7 +418,11 @@ static const OSSL_DISPATCH xor_keymgmt_functions[] = {
 };
 
 static const OSSL_ALGORITHM tls_prov_keymgmt[] = {
-    { "XOR", "provider=tls-provider", xor_keymgmt_functions },
+    /*
+     * Obviously this is not FIPS approved, but in order to test in conjuction
+     * with the FIPS provider we pretend that it is.
+     */
+    { "XOR", "provider=tls-provider,fips=yes", xor_keymgmt_functions },
     { NULL, NULL, NULL }
 };