From 5a02d13d3e274748c695bfe19238f885489e021e Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 17 Oct 2019 00:26:44 +0200 Subject: [PATCH] test/keymgmt_internal_test.c: New test of keymgmt internals This tests diverse internal KEYMGMT features. The current existing test checks that evp_keymgmt_export_to_provider() passes the key data correctly through two instances of the default provider, and that the resulting numbers at the end match the initial numbers. Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/10190) --- test/build.info | 7 +- test/keymgmt_internal_test.c | 198 ++++++++++++++++++++++++ test/recipes/02-test_internal_keymgmt.t | 18 +++ 3 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 test/keymgmt_internal_test.c create mode 100644 test/recipes/02-test_internal_keymgmt.t diff --git a/test/build.info b/test/build.info index 2de9733bd5..f50c2eaa40 100644 --- a/test/build.info +++ b/test/build.info @@ -56,7 +56,8 @@ IF[{- !$disabled{tests} -}] time_offset_test pemtest ssl_cert_table_internal_test ciphername_test \ servername_test ocspapitest rsa_mp_test fatalerrtest tls13ccstest \ sysdefaulttest errtest gosttest \ - context_internal_test aesgcmtest params_test evp_pkey_dparams_test + context_internal_test aesgcmtest params_test evp_pkey_dparams_test \ + keymgmt_internal_test SOURCE[versions]=versions.c INCLUDE[versions]=../include ../apps/include @@ -588,6 +589,10 @@ IF[{- !$disabled{tests} -}] SOURCE[asn1_dsa_internal_test]=asn1_dsa_internal_test.c INCLUDE[asn1_dsa_internal_test]=.. ../include ../apps/include ../crypto/include DEPEND[asn1_dsa_internal_test]=../libcrypto.a libtestutil.a + + SOURCE[keymgmt_internal_test]=keymgmt_internal_test.c + INCLUDE[keymgmt_internal_test]=.. ../include ../apps/include + DEPEND[keymgmt_internal_test]=../libcrypto.a libtestutil.a ENDIF IF[{- !$disabled{mdc2} -}] diff --git a/test/keymgmt_internal_test.c b/test/keymgmt_internal_test.c new file mode 100644 index 0000000000..1fd831d72f --- /dev/null +++ b/test/keymgmt_internal_test.c @@ -0,0 +1,198 @@ +/* + * Copyright 2019 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 + +#include +#include +#include +#include +#include +#include +#include "internal/nelem.h" +#include "crypto/evp.h" /* For the internal API */ +#include "testutil.h" + +typedef struct { + OPENSSL_CTX *ctx1; + OSSL_PROVIDER *prov1; + OPENSSL_CTX *ctx2; + OSSL_PROVIDER *prov2; +} FIXTURE; + +static void tear_down(FIXTURE *fixture) +{ + if (fixture != NULL) { + OSSL_PROVIDER_unload(fixture->prov1); + OSSL_PROVIDER_unload(fixture->prov2); + OPENSSL_CTX_free(fixture->ctx1); + OPENSSL_CTX_free(fixture->ctx2); + OPENSSL_free(fixture); + } +} + +static FIXTURE *set_up(const char *testcase_name) +{ + FIXTURE *fixture; + + if (!TEST_ptr(fixture = OPENSSL_zalloc(sizeof(*fixture))) + || !TEST_ptr(fixture->ctx1 = OPENSSL_CTX_new()) + || !TEST_ptr(fixture->prov1 = OSSL_PROVIDER_load(fixture->ctx1, + "default")) + || !TEST_ptr(fixture->ctx2 = OPENSSL_CTX_new()) + || !TEST_ptr(fixture->prov2 = OSSL_PROVIDER_load(fixture->ctx2, + "default"))) { + tear_down(fixture); + return NULL; + } + return fixture; +} + +static int test_pass_rsa(FIXTURE *fixture) +{ + /* Array indexes */ +#define N 0 +#define E 1 +#define D 2 +#define P 3 +#define Q 4 +#define F3 5 /* Extra factor */ +#define DP 6 +#define DQ 7 +#define E3 8 /* Extra exponent */ +#define QINV 9 +#define C3 10 /* Extra coefficient */ + + size_t i; + int ret = 0; + RSA *rsa = NULL; + BIGNUM *bn1 = NULL, *bn2 = NULL, *bn3 = NULL; + EVP_PKEY *pk = NULL; + EVP_KEYMGMT *km1 = NULL, *km2 = NULL; + void *provdata = NULL; + /* + * 32-bit RSA key, extracted from this command, + * executed with OpenSSL 1.0.2: + * + * openssl genrsa 32 | openssl rsa -text + */ + static BN_ULONG expected[] = { + 0xbc747fc5, /* N */ + 0x10001, /* E */ + 0x7b133399, /* D */ + 0xe963, /* P */ + 0xceb7, /* Q */ + 0, /* F3 */ + 0x8599, /* DP */ + 0xbd87, /* DQ */ + 0, /* E3 */ + 0xcc3b, /* QINV */ + 0, /* C3 */ + 0 /* Extra, should remain zero */ + }; + static unsigned long keydata[OSSL_NELEM(expected)] = { 0, }; + OSSL_PARAM params[] = { + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_N, &keydata[N]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_E, &keydata[E]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_D, &keydata[D]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR, &keydata[P]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR, &keydata[Q]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_FACTOR, &keydata[F3]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT, &keydata[DP]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT, &keydata[DQ]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_EXPONENT, &keydata[E3]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT, &keydata[QINV]), + OSSL_PARAM_ulong(OSSL_PKEY_PARAM_RSA_COEFFICIENT, &keydata[C3]), + OSSL_PARAM_END + }; + + if (!TEST_ptr(rsa = RSA_new())) + goto err; + + if (!TEST_ptr(bn1 = BN_new()) + || !TEST_true(BN_set_word(bn1, expected[N])) + || !TEST_ptr(bn2 = BN_new()) + || !TEST_true(BN_set_word(bn2, expected[E])) + || !TEST_ptr(bn3 = BN_new()) + || !TEST_true(BN_set_word(bn3, expected[D])) + || !TEST_true(RSA_set0_key(rsa, bn1, bn2, bn3))) + goto err; + + if (!TEST_ptr(bn1 = BN_new()) + || !TEST_true(BN_set_word(bn1, expected[P])) + || !TEST_ptr(bn2 = BN_new()) + || !TEST_true(BN_set_word(bn2, expected[Q])) + || !TEST_true(RSA_set0_factors(rsa, bn1, bn2))) + goto err; + + if (!TEST_ptr(bn1 = BN_new()) + || !TEST_true(BN_set_word(bn1, expected[DP])) + || !TEST_ptr(bn2 = BN_new()) + || !TEST_true(BN_set_word(bn2, expected[DQ])) + || !TEST_ptr(bn3 = BN_new()) + || !TEST_true(BN_set_word(bn3, expected[QINV])) + || !TEST_true(RSA_set0_crt_params(rsa, bn1, bn2, bn3))) + goto err; + bn1 = bn2 = bn3 = NULL; + + if (!TEST_ptr(pk = EVP_PKEY_new()) + || !TEST_true(EVP_PKEY_assign_RSA(pk, rsa))) + goto err; + rsa = NULL; + + if (!TEST_ptr(km1 = EVP_KEYMGMT_fetch(fixture->ctx1, "RSA", NULL)) + || !TEST_ptr(km2 = EVP_KEYMGMT_fetch(fixture->ctx2, "RSA", NULL)) + || !TEST_ptr_ne(km1, km2)) + goto err; + + if (!TEST_ptr(evp_keymgmt_export_to_provider(pk, km1, 0)) + || !TEST_ptr(provdata = evp_keymgmt_export_to_provider(pk, km2, 0))) + goto err; + + if (!TEST_true(evp_keymgmt_exportkey(km2, provdata, params))) + goto err; + + /* + * At this point, the hope is that keydata will have all the numbers + * from the key. + */ + + for (i = 0; i < OSSL_NELEM(expected); i++) + ret += !! TEST_int_eq(expected[i], keydata[i]); + + ret = (ret == OSSL_NELEM(expected)); + + err: + RSA_free(rsa); + BN_free(bn1); + BN_free(bn2); + BN_free(bn3); + EVP_PKEY_free(pk); + EVP_KEYMGMT_free(km1); + EVP_KEYMGMT_free(km2); + + return ret; +} + +static int (*tests[])(FIXTURE *) = { + test_pass_rsa +}; + +static int test_pass_key(int n) +{ + SETUP_TEST_FIXTURE(FIXTURE, set_up); + EXECUTE_TEST(tests[n], tear_down); + return result; +} + +int setup_tests(void) +{ + ADD_ALL_TESTS(test_pass_key, 1); + return 1; +} diff --git a/test/recipes/02-test_internal_keymgmt.t b/test/recipes/02-test_internal_keymgmt.t new file mode 100644 index 0000000000..f7b2eb3f1c --- /dev/null +++ b/test/recipes/02-test_internal_keymgmt.t @@ -0,0 +1,18 @@ +#! /usr/bin/env perl +# Copyright 2019 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 OpenSSL::Test qw(:DEFAULT bldtop_dir); +use OpenSSL::Test::Simple; +use OpenSSL::Test::Utils; + +setup("test_internal_provider"); + +$ENV{OPENSSL_MODULES} = bldtop_dir("test"); + +simple_test("test_internal_keymgmt", "keymgmt_internal_test"); -- 2.25.1