summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Mraz <tomas@openssl.org>2022-09-13 22:38:30 +0200
committerPauli <pauli@openssl.org>2022-09-16 08:34:53 +1000
commite1289d90d0069ea1c3ea8ae80bfc3916077ec24e (patch)
tree9e8b5ce32338417fa988ecae7c25373550a4112d
parentc342004e07fd2c03a672f79353d13554fe0ffdaf (diff)
With fips provider 3.0.0 skip tests related to explicit curves handling
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Shane Lontis <shane.lontis@oracle.com> Reviewed-by: Paul Dale <pauli@openssl.org> (Merged from https://github.com/openssl/openssl/pull/19201)
-rw-r--r--test/build.info6
-rw-r--r--test/endecode_test.c8
-rw-r--r--test/evp_test.c74
-rw-r--r--test/fips_version_test.c78
-rw-r--r--test/recipes/25-test_verify.t12
-rw-r--r--test/testutil.h13
-rw-r--r--test/testutil/provider.c64
7 files changed, 178 insertions, 77 deletions
diff --git a/test/build.info b/test/build.info
index 0fac691cab..bab28035a8 100644
--- a/test/build.info
+++ b/test/build.info
@@ -63,7 +63,7 @@ IF[{- !$disabled{tests} -}]
keymgmt_internal_test hexstr_test provider_status_test defltfips_test \
bio_readbuffer_test user_property_test pkcs7_test upcallstest \
provfetchtest prov_config_test rand_test ca_internals_test \
- bio_tfo_test membio_test list_test
+ bio_tfo_test membio_test list_test fips_version_test
IF[{- !$disabled{'deprecated-3.0'} -}]
PROGRAMS{noinst}=enginetest
@@ -427,6 +427,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[defltfips_test]=../include ../apps/include
DEPEND[defltfips_test]=../libcrypto libtestutil.a
+ SOURCE[fips_version_test]=fips_version_test.c
+ INCLUDE[fips_version_test]=../include ../apps/include
+ DEPEND[fips_version_test]=../libcrypto libtestutil.a
+
SOURCE[ocspapitest]=ocspapitest.c
INCLUDE[ocspapitest]=../include ../apps/include
DEPEND[ocspapitest]=../libcrypto libtestutil.a
diff --git a/test/endecode_test.c b/test/endecode_test.c
index c139fe63be..14648287eb 100644
--- a/test/endecode_test.c
+++ b/test/endecode_test.c
@@ -47,6 +47,7 @@ OSSL_provider_init_fn ossl_legacy_provider_init;
static int default_libctx = 1;
static int is_fips = 0;
+static int is_fips_3_0_0 = 0;
static OSSL_LIB_CTX *testctx = NULL;
static OSSL_LIB_CTX *keyctx = NULL;
@@ -174,7 +175,7 @@ static int test_encode_decode(const char *file, const int line,
output_type, output_structure, pass, pcipher)))
goto end;
- if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips) {
+ if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips && !is_fips_3_0_0) {
if (TEST_false(decode_cb(file, line, (void **)&pkey2, encoded,
encoded_len, output_type, output_structure,
(flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
@@ -1323,6 +1324,11 @@ int setup_tests(void)
return 0;
}
+ /* FIPS(3.0.0): provider imports explicit params but they won't work #17998 */
+ is_fips_3_0_0 = fips_provider_version_eq(testctx, 3, 0, 0);
+ if (is_fips_3_0_0 < 0)
+ return 0;
+
#ifdef STATIC_LEGACY
/*
* This test is always statically linked against libcrypto. We must not
diff --git a/test/evp_test.c b/test/evp_test.c
index e4350c39b4..a5f7b93cfb 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -1596,7 +1596,7 @@ static int mac_test_run_mac(EVP_TEST *t)
goto err;
}
}
- /* FIPS 3.0.0 can't reinitialise MAC contexts #18100 */
+ /* FIPS(3.0.0): can't reinitialise MAC contexts #18100 */
if (reinit-- && fips_provider_version_gt(libctx, 3, 0, 0)) {
OSSL_PARAM ivparams[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
int ret;
@@ -2823,7 +2823,7 @@ static int kdf_test_run(EVP_TEST *t)
t->err = "INTERNAL_ERROR";
goto err;
}
- /* FIPS 3.0.0 can't dup KDF contexts #17572 */
+ /* FIPS(3.0.0): can't dup KDF contexts #17572 */
if (fips_provider_version_gt(libctx, 3, 0, 0)
&& (ctx = EVP_KDF_CTX_dup(expected->ctx)) != NULL) {
EVP_KDF_CTX_free(expected->ctx);
@@ -2922,7 +2922,7 @@ static int pkey_kdf_test_run(EVP_TEST *t)
size_t got_len = 0;
if (fips_provider_version_eq(libctx, 3, 0, 0)) {
- /* FIPS 3.0.0 can't deal with oversized output buffers #18533 */
+ /* FIPS(3.0.0): can't deal with oversized output buffers #18533 */
got_len = expected->output_len;
} else {
/* Find out the KDF output size */
@@ -3737,72 +3737,6 @@ static int prov_available(char *providers)
return 0;
}
-static int check_fips_versions(char *versions, const EVP_TEST *t)
-{
- char *p;
- int major, minor, patch, r;
- enum {
- MODE_EQ, MODE_NE, MODE_LE, MODE_GT
- } mode;
-
- while (*versions != '\0') {
- for (; isspace(*versions); versions++)
- continue;
- if (*versions == '\0')
- break;
- for (p = versions; *versions != '\0' && !isspace(*versions); versions++)
- continue;
- if (*versions != '\0')
- *versions++ = '\0';
- if (*p == '!') {
- mode = MODE_NE;
- p++;
- } else if (*p == '=') {
- mode = MODE_EQ;
- p++;
- } else if (*p == '<' && p[1] == '=') {
- mode = MODE_LE;
- p += 2;
- } else if (*p == '>') {
- mode = MODE_GT;
- p++;
- } else if (isdigit(*p)) {
- mode = MODE_EQ;
- } else {
- TEST_info("Line %d: error matching FIPS version: mode %s\n",
- t->s.curr, p);
- return -1;
- }
- if (sscanf(p, "%d.%d.%d", &major, &minor, &patch) != 3) {
- TEST_info("Line %d: error matching FIPS version: version %s\n",
- t->s.curr, p);
- return -1;
- }
- switch (mode) {
- case MODE_EQ:
- r = fips_provider_version_eq(libctx, major, minor, patch);
- break;
- case MODE_NE:
- r = fips_provider_version_ne(libctx, major, minor, patch);
- break;
- case MODE_LE:
- r = fips_provider_version_le(libctx, major, minor, patch);
- break;
- case MODE_GT:
- r = fips_provider_version_gt(libctx, major, minor, patch);
- break;
- }
- if (r < 0) {
- TEST_info("Line %d: error matching FIPS version: internal error\n",
- t->s.curr);
- return -1;
- }
- if (r == 0)
- return 0;
- }
- return 1;
-}
-
/* Read and parse one test. Return 0 if failure, 1 if okay. */
static int parse(EVP_TEST *t)
{
@@ -3901,7 +3835,7 @@ start:
goto start;
} else if (strcmp(pp->key, "FIPSversion") == 0) {
if (prov_available("fips")) {
- j = check_fips_versions(pp->value, t);
+ j = fips_provider_version_match(libctx, pp->value);
if (j < 0) {
TEST_info("Line %d: error matching FIPS versions\n", t->s.curr);
return 0;
diff --git a/test/fips_version_test.c b/test/fips_version_test.c
new file mode 100644
index 0000000000..dd23bb51e5
--- /dev/null
+++ b/test/fips_version_test.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2022 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/evp.h>
+#include <openssl/provider.h>
+#include "testutil.h"
+
+static OSSL_LIB_CTX *libctx = NULL;
+static OSSL_PROVIDER *libprov = NULL;
+
+typedef enum OPTION_choice {
+ OPT_ERR = -1,
+ OPT_EOF = 0,
+ OPT_CONFIG_FILE,
+ OPT_TEST_ENUM
+} OPTION_CHOICE;
+
+const OPTIONS *test_get_options(void)
+{
+ static const OPTIONS test_options[] = {
+ OPT_TEST_OPTIONS_DEFAULT_USAGE,
+ { "config", OPT_CONFIG_FILE, '<',
+ "The configuration file to use for the libctx" },
+ { NULL }
+ };
+ return test_options;
+}
+
+static int test_fips_version(int n)
+{
+ const char *version = test_get_argument(n);
+
+ if (!TEST_ptr(version))
+ return 0;
+ return TEST_int_eq(fips_provider_version_match(libctx, version), 1);
+}
+
+int setup_tests(void)
+{
+ char *config_file = NULL;
+ OPTION_CHOICE o;
+ int n;
+
+ while ((o = opt_next()) != OPT_EOF) {
+ switch (o) {
+ case OPT_CONFIG_FILE:
+ config_file = opt_arg();
+ break;
+ case OPT_TEST_CASES:
+ break;
+ default:
+ case OPT_ERR:
+ return 0;
+ }
+ }
+
+ if (!test_get_libctx(&libctx, NULL, config_file, &libprov, NULL))
+ return 0;
+
+ n = test_get_argument_count();
+ if (n == 0)
+ return 0;
+
+ ADD_ALL_TESTS(test_fips_version, n);
+ return 1;
+}
+
+void cleanup_tests(void)
+{
+ OSSL_PROVIDER_unload(libprov);
+ OSSL_LIB_CTX_free(libctx);
+}
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index d6d25759b5..2bb77f2189 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -354,12 +354,18 @@ SKIP: {
# Same as above but with base provider used for decoding
SKIP: {
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
- skip "EC is not supported or FIPS is disabled", 3
- if disabled("ec") || $no_fips;
-
my $provconf = srctop_file("test", "fips-and-base.cnf");
my $provpath = bldtop_dir("providers");
my @prov = ("-provider-path", $provpath);
+
+ skip "EC is not supported or FIPS is disabled", 3
+ if disabled("ec") || $no_fips;
+
+ run(test(["fips_version_test", "-config", $provconf, ">3.0.0"]),
+ capture => 1, statusvar => \my $exit);
+ skip "FIPS provider version is too old", 3
+ if !$exit;
+
$ENV{OPENSSL_CONF} = $provconf;
ok(!verify("ee-cert-ec-explicit", "", ["root-cert"],
diff --git a/test/testutil.h b/test/testutil.h
index 3a3e0f279e..0a050bb060 100644
--- a/test/testutil.h
+++ b/test/testutil.h
@@ -240,7 +240,7 @@ void cleanup_tests(void);
/*
* Helper functions to detect specific versions of the FIPS provider being in use.
* Because of FIPS rules, code changes after a module has been validated are
- * difficult and because we provide an hard guarantee of ABI and behavioural
+ * difficult and because we provide a hard guarantee of ABI and behavioural
* stability going forwards, it is a requirement to have tests be conditional
* on specific FIPS provider versions. Without this, bug fixes cannot be tested
* in later releases.
@@ -260,6 +260,17 @@ int fips_provider_version_le(OSSL_LIB_CTX *libctx, int major, int minor, int pat
int fips_provider_version_gt(OSSL_LIB_CTX *libctx, int major, int minor, int patch);
/*
+ * This function matches fips provider version with (potentially multiple)
+ * <operator>maj.min.patch version strings in versions.
+ * The operator can be one of = ! <= or > comparison symbols.
+ * If the fips provider matches all the version comparisons (or if there is no
+ * fips provider available) the function returns 1.
+ * If the fips provider does not match the version comparisons, it returns 0.
+ * On error the function returns -1.
+ */
+int fips_provider_version_match(OSSL_LIB_CTX *libctx, const char *versions);
+
+/*
* Used to supply test specific command line options,
* If non optional parameters are used, then the first entry in the OPTIONS[]
* should contain:
diff --git a/test/testutil/provider.c b/test/testutil/provider.c
index f9b37cca8f..c8b5dfc061 100644
--- a/test/testutil/provider.c
+++ b/test/testutil/provider.c
@@ -8,6 +8,7 @@
*/
#include "../testutil.h"
+#include <ctype.h>
#include <openssl/provider.h>
#include <openssl/core_names.h>
#include <string.h>
@@ -88,7 +89,7 @@ static int fips_provider_version(OSSL_LIB_CTX *libctx, FIPS_VERSION *vers)
|| sscanf(vs, "%d.%d.%d", &vers->major, &vers->minor, &vers->patch) != 3)
goto err;
if (!OSSL_PROVIDER_unload(fips_prov))
- return -1; /* WTF do we do here??? */
+ return -1;
return 1;
err:
OSSL_PROVIDER_unload(fips_prov);
@@ -140,3 +141,64 @@ int fips_provider_version_gt(OSSL_LIB_CTX *libctx, int major, int minor, int pat
&& (prov.minor > minor
|| (prov.minor == minor && prov.patch > patch)));
}
+
+int fips_provider_version_match(OSSL_LIB_CTX *libctx, const char *versions)
+{
+ const char *p;
+ int major, minor, patch, r;
+ enum {
+ MODE_EQ, MODE_NE, MODE_LE, MODE_GT
+ } mode;
+
+ while (*versions != '\0') {
+ for (; isspace(*versions); versions++)
+ continue;
+ if (*versions == '\0')
+ break;
+ for (p = versions; *versions != '\0' && !isspace(*versions); versions++)
+ continue;
+ if (*p == '!') {
+ mode = MODE_NE;
+ p++;
+ } else if (*p == '=') {
+ mode = MODE_EQ;
+ p++;
+ } else if (*p == '<' && p[1] == '=') {
+ mode = MODE_LE;
+ p += 2;
+ } else if (*p == '>') {
+ mode = MODE_GT;
+ p++;
+ } else if (isdigit(*p)) {
+ mode = MODE_EQ;
+ } else {
+ TEST_info("Error matching FIPS version: mode %s\n", p);
+ return -1;
+ }
+ if (sscanf(p, "%d.%d.%d", &major, &minor, &patch) != 3) {
+ TEST_info("Error matching FIPS version: version %s\n", p);
+ return -1;
+ }
+ switch (mode) {
+ case MODE_EQ:
+ r = fips_provider_version_eq(libctx, major, minor, patch);
+ break;
+ case MODE_NE:
+ r = fips_provider_version_ne(libctx, major, minor, patch);
+ break;
+ case MODE_LE:
+ r = fips_provider_version_le(libctx, major, minor, patch);
+ break;
+ case MODE_GT:
+ r = fips_provider_version_gt(libctx, major, minor, patch);
+ break;
+ }
+ if (r < 0) {
+ TEST_info("Error matching FIPS version: internal error\n");
+ return -1;
+ }
+ if (r == 0)
+ return 0;
+ }
+ return 1;
+}