From patchwork Tue Dec 14 05:59:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Selva Nair X-Patchwork-Id: 2183 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director10.mail.ord1d.rsapps.net ([172.30.191.6]) by backend41.mail.ord1d.rsapps.net with LMTP id oEyjM+rNuGHXWAAAqwncew (envelope-from ) for ; Tue, 14 Dec 2021 12:01:30 -0500 Received: from proxy14.mail.ord1d.rsapps.net ([172.30.191.6]) by director10.mail.ord1d.rsapps.net with LMTP id oDYfGevNuGHSegAApN4f7A (envelope-from ) for ; Tue, 14 Dec 2021 12:01:31 -0500 Received: from smtp19.gate.ord1d ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy14.mail.ord1d.rsapps.net with LMTPS id YGqeBe3NuGGwewAAtEH5vw (envelope-from ) for ; Tue, 14 Dec 2021 12:01:33 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp19.gate.ord1d.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dkim=fail (signature verification failed) header.d=gmail.com; dmarc=fail (p=none; dis=none) header.from=gmail.com X-Suspicious-Flag: YES X-Classification-ID: 7b3bd63c-5cff-11ec-854f-525400d67fa8-1-1 Received: from [216.105.38.7] ([216.105.38.7:34898] helo=lists.sourceforge.net) by smtp19.gate.ord1d.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 70/99-27429-9EDC8B16; Tue, 14 Dec 2021 12:01:30 -0500 Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.94.2) (envelope-from ) id 1mxBAB-00028g-65; Tue, 14 Dec 2021 17:00:27 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1mxBA8-000289-09 for openvpn-devel@lists.sourceforge.net; Tue, 14 Dec 2021 17:00:24 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=GVU3hUgfGaEIky/fSOYrCw8/VHXEkJFUwOJoVCWpwDk=; b=AIjJh9EH5uf+vjgFzOHXiP/62g b+Z62CnuMHp8QUbxCCShKqdzf4+eAZ+2ChH6ygKbQCC2TKqVHOw4+RvEMFrkkuZirDr/KwqT/rkjm A7qlPqh1ZSUVwDeE3NtQR8WbSnRZ3LoX1ahIl8Q/cag/FPTPsILo8sxegiLviGst+KM8=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=GVU3hUgfGaEIky/fSOYrCw8/VHXEkJFUwOJoVCWpwDk=; b=W05WJUAxTdc8kFH/yBuAvGDEJ9 AZMO9nS1eRrqqb16lASJUZyrCoaxdRpEZT+hxBu4kpv/iNS33kP4uGnkEm88Hw7rJ5G7maZFMAKpQ s9sW42W1vKPths0fKSrQAQDYnIOrcHM9HXbhIkfJMsgLXQhkjOuYoVjrPv974JLks3oE=; Received: from mail-io1-f41.google.com ([209.85.166.41]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.92.3) id 1mxB9x-00FKXo-NR for openvpn-devel@lists.sourceforge.net; Tue, 14 Dec 2021 17:00:23 +0000 Received: by mail-io1-f41.google.com with SMTP id x10so25333062ioj.9 for ; Tue, 14 Dec 2021 09:00:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=GVU3hUgfGaEIky/fSOYrCw8/VHXEkJFUwOJoVCWpwDk=; b=jV6qEdmv5gUf+uVDjKNph83bsNPKRjcRnXGL2VbE520Gm0MeOMCRbuQtoikQl7jvGr UiGWgdD3JE6K5PbDlDz1F1j0MVYh6vcFqArpFPnls7YnT3z2l52GP9KU6Kdaio2oewB9 tTId4Ryf3trp7ovlwm70/OrCsHuwpM2UDRFN8mSC71hExPAenCiB+TR9z8T/u5uGf6od dKem0vQfYdQ+x9noDyqQnbt9OCG3sJ47wIjUpSEM/UUNmBucqxlQYX6b0FqRAlgGXjiC QEnCbcGaF5gx0Z/M+PhInC12nFunpK5xBrXHUOFHowUV9c8kLkBc5w05ZMbMNJfKffLp b1jg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=GVU3hUgfGaEIky/fSOYrCw8/VHXEkJFUwOJoVCWpwDk=; b=kEiFqZDLIYCvEb+wFXWTN/LmXYVsE3miuiX2fzlPwfJtUobe9ZaRaPwFksR/N08rpZ bkHh8t2JK2YSFxK6fWD1Xp9vfqmxsPa+QUhAOFXDeSgywCNncm7+V8YxmXM04BK84Yna qxrkCWBG7YZvech80bHipRqJj9YBhe3z7jGy5Zak28VdzmqkVllqvavdRp3yNHNxmdVJ VPbfRmy/qg1bngXocNUu/h1lb1ty3KIArfDiTzuyiKAkUDQjBn0dgJE9oOWMGkbZKE9F tPsfchrxGBrq9ANfP6TeG6n586EjEjv7R45eMBk8Bnc/QTU6BdpcDgW6VcLCFI31dNbt OFRA== X-Gm-Message-State: AOAM533gW9eJ6SGhI1ZH4E/tL/0SODg1iRr3oIvqcGc+wtGCOOhDsk6u lJ++9gMgiZM1giDaTIgsMv3pqfWjyMU= X-Google-Smtp-Source: ABdhPJxUqvrgQV/aUlaYJ4RZVWzv+vH4UQCmPtbej37DDoRa6207MsMrbKDpYoUIqasxsj7E43AW5A== X-Received: by 2002:a05:6602:8da:: with SMTP id h26mr4430490ioz.76.1639501206226; Tue, 14 Dec 2021 09:00:06 -0800 (PST) Received: from uranus.home.sansel.ca (bras-vprn-tnhlon4053w-lp130-02-70-51-223-8.dsl.bell.ca. [70.51.223.8]) by smtp.gmail.com with ESMTPSA id e9sm178778ilm.44.2021.12.14.09.00.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Dec 2021 09:00:06 -0800 (PST) From: selva.nair@gmail.com To: openvpn-devel@lists.sourceforge.net Date: Tue, 14 Dec 2021 11:59:26 -0500 Message-Id: <20211214165928.30676-17-selva.nair@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211214165928.30676-1-selva.nair@gmail.com> References: <20211214165928.30676-1-selva.nair@gmail.com> MIME-Version: 1.0 X-Spam-Report: Spam detection software, running on the system "util-spamd-1.v13.lw.sourceforge.com", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Selva Nair Tests: - Check SIGNATURE and KEYMGMT methods can be fetched from the provider - Load sample RSA and EC keys as management-external-key and check that their sign callbacks are correctly exercised: with [...] Content analysis details: (0.2 points, 6.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.166.41 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.166.41 listed in wl.mailspike.net] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [selva.nair[at]gmail.com] 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid 0.1 DKIM_INVALID DKIM or DK signature exists, but is not valid X-Headers-End: 1mxB9x-00FKXo-NR Subject: [Openvpn-devel] [PATCH v3 16/18] Add a unit test for external key provider X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Selva Nair Tests: - Check SIGNATURE and KEYMGMT methods can be fetched from the provider - Load sample RSA and EC keys as management-external-key and check that their sign callbacks are correctly exercised: with and without digest support mocked in the client capability flag. Signed-off-by: Selva Nair Acked-By: Arne Schwabe --- configure.ac | 2 + tests/unit_tests/openvpn/Makefile.am | 20 ++ tests/unit_tests/openvpn/test_provider.c | 305 +++++++++++++++++++++++ 3 files changed, 327 insertions(+) create mode 100644 tests/unit_tests/openvpn/test_provider.c diff --git a/configure.ac b/configure.ac index e0f9c332..c446f631 100644 --- a/configure.ac +++ b/configure.ac @@ -766,6 +766,8 @@ PKG_CHECK_MODULES( [] ) +AM_CONDITIONAL([HAVE_XKEY_PROVIDER], [false]) + if test "${with_crypto_library}" = "openssl"; then AC_ARG_VAR([OPENSSL_CFLAGS], [C compiler flags for OpenSSL]) AC_ARG_VAR([OPENSSL_LIBS], [linker flags for OpenSSL]) diff --git a/tests/unit_tests/openvpn/Makefile.am b/tests/unit_tests/openvpn/Makefile.am index 44b77cc5..96b670ae 100644 --- a/tests/unit_tests/openvpn/Makefile.am +++ b/tests/unit_tests/openvpn/Makefile.am @@ -11,6 +11,10 @@ if HAVE_LD_WRAP_SUPPORT test_binaries += tls_crypt_testdriver endif +if HAVE_XKEY_PROVIDER +test_binaries += provider_testdriver +endif + TESTS = $(test_binaries) check_PROGRAMS = $(test_binaries) @@ -95,6 +99,22 @@ networking_testdriver_SOURCES = test_networking.c mock_msg.c \ $(openvpn_srcdir)/platform.c endif +if HAVE_XKEY_PROVIDER +provider_testdriver_CFLAGS = @TEST_CFLAGS@ \ + -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ + $(OPTIONAL_CRYPTO_CFLAGS) +provider_testdriver_LDFLAGS = @TEST_LDFLAGS@ \ + $(OPTIONAL_CRYPTO_LIBS) + +provider_testdriver_SOURCES = test_provider.c mock_msg.c \ + $(openvpn_srcdir)/xkey_helper.c \ + $(openvpn_srcdir)/xkey_provider.c \ + $(openvpn_srcdir)/buffer.c \ + $(openvpn_srcdir)/base64.c \ + mock_get_random.c \ + $(openvpn_srcdir)/platform.c +endif + auth_token_testdriver_CFLAGS = @TEST_CFLAGS@ \ -I$(openvpn_includedir) -I$(compat_srcdir) -I$(openvpn_srcdir) \ $(OPTIONAL_CRYPTO_CFLAGS) diff --git a/tests/unit_tests/openvpn/test_provider.c b/tests/unit_tests/openvpn/test_provider.c new file mode 100644 index 00000000..dcf39019 --- /dev/null +++ b/tests/unit_tests/openvpn/test_provider.c @@ -0,0 +1,305 @@ +/* + * OpenVPN -- An application to securely tunnel IP networks + * over a single UDP port, with support for SSL/TLS-based + * session authentication and key exchange, + * packet encryption, packet authentication, and + * packet compression. + * + * Copyright (C) 2021 Selva Nair + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 2 of the License, + * or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#elif defined(_MSC_VER) +#include "config-msvc.h" +#endif + +#include "syshead.h" + +#include +#include +#include +#include +#include +#include + +#include "manage.h" +#include "xkey_common.h" + +struct management *management; /* global */ +static int mgmt_callback_called; + +#ifndef _countof +#define _countof(x) sizeof((x))/sizeof(*(x)) +#endif + +static OSSL_PROVIDER *prov[2]; + +/* public keys for testing -- RSA and EC */ +static const char * const pubkey1 = "-----BEGIN PUBLIC KEY-----\n" + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7GWP6RLCGlvmVioIqYI6\n" + "LUR4owA7sJ/nJxBAk+/xzD6gqgSigBsTqeb+gdZwkKjY1N4w2DUA0r5i8Eja/BWN\n" + "xMZtC5nxK4MACtMqIwvlzfk130NhFXKtlZj2cyFBXqDdRyeg1ZrUQagcHVcgcReP\n" + "9yiePgfO7NUOQk8edEeOR53SFCgnLBQQ9dGWtZN0hO/5BN6NSm/fd6vq0VjTRP5a\n" + "BAH/BnqX9/3jV0jh8N9AE59mI1rjVVQ9VDnuAPkS8dLfdC661/CNxt0YWByTIgt1\n" + "+qjW4LUvLbnU/rlPhuJ1SBZg+z/JtDBCKfs7syu5WYFqRvNFg7/91Rr/NwxvW/1h\n" + "8QIDAQAB\n" + "-----END PUBLIC KEY-----\n"; + +static const char * const pubkey2 = "-----BEGIN PUBLIC KEY-----\n" + "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEO85iXW+HgnUkwlj1DohNVw0GsnGIh1gZ\n" + "u95ff1JiUaJIkYNIkZA+hwIPFVH5aJcSCv3SPIeDS2VUAESNKHZJBQ==\n" + "-----END PUBLIC KEY-----\n"; + +static const char *pubkeys[] = {pubkey1, pubkey2}; + +static const char *prov_name = "ovpn.xkey"; + +static const char* test_msg = "Lorem ipsum dolor sit amet, consectetur " + "adipisici elit, sed eiusmod tempor incidunt " + "ut labore et dolore magna aliqua."; + +static const char* test_msg_b64 = + "TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2ljaS" + "BlbGl0LCBzZWQgZWl1c21vZCB0ZW1wb3IgaW5jaWR1bnQgdXQgbGFib3JlIGV0IGRv" + "bG9yZSBtYWduYSBhbGlxdWEu"; + +/* Sha256 digest of test_msg excluding NUL terminator */ +static const uint8_t test_digest[] = + {0x77, 0x38, 0x65, 0x00, 0x1e, 0x96, 0x48, 0xc6, 0x57, 0x0b, 0xae, + 0xc0, 0xb7, 0x96, 0xf9, 0x66, 0x4d, 0x5f, 0xd0, 0xb7, 0xdb, 0xf3, + 0x3a, 0xbf, 0x02, 0xcc, 0x78, 0x61, 0x83, 0x20, 0x20, 0xee}; + +static const char *test_digest_b64 = "dzhlAB6WSMZXC67At5b5Zk1f0Lfb8zq/Asx4YYMgIO4="; + +/* Dummy signature used only to check that the expected callback + * was successfully exercised. Keep this shorter than 64 bytes + * --- the smallest size of the actual signature with the above + * keys. + */ +const uint8_t good_sig[] = + {0xd8, 0xa7, 0xd9, 0x81, 0xd8, 0xaa, 0xd8, 0xad, 0x20, 0xd9, 0x8a, 0xd8, + 0xa7, 0x20, 0xd8, 0xb3, 0xd9, 0x85, 0xd8, 0xb3, 0xd9, 0x85, 0x0}; + +const char *good_sig_b64 = "2KfZgdiq2K0g2YrYpyDYs9mF2LPZhQA="; + +static EVP_PKEY * +load_pubkey(const char *pem) +{ + BIO *in = BIO_new_mem_buf(pem, -1); + assert_non_null(in); + + EVP_PKEY *pkey = PEM_read_bio_PUBKEY(in, NULL, NULL, NULL); + assert_non_null(pkey); + + BIO_free(in); + return pkey; +} + +static void +init_test() +{ + prov[0] = OSSL_PROVIDER_load(NULL,"default"); + OSSL_PROVIDER_add_builtin(NULL, prov_name, xkey_provider_init); + prov[1] = OSSL_PROVIDER_load(NULL, prov_name); + + /* set default propq matching what we use in ssl_openssl.c */ + EVP_set_default_properties(NULL, "?provider!=ovpn.xkey"); + + management = test_calloc(sizeof(*management), 1); +} + +static void +uninit_test() +{ + for (size_t i = 0; i < _countof(prov); i++) + { + if (prov[i]) + { + OSSL_PROVIDER_unload(prov[i]); + } + } + test_free(management); +} + +/* Mock management callback for signature. + * We check that the received data to sign matches test_msg or + * test_digest and return a predefined string as signature so that + * the caller can validate all steps up to sending the data to + * the management client. + */ +char * +management_query_pk_sig(struct management *man, const char *b64_data, + const char *algorithm) +{ + char *out = NULL; + + /* indicate entry to the callback */ + mgmt_callback_called = 1; + + const char *expected_tbs = test_digest_b64; + if (strstr(algorithm, "data=message")) + { + expected_tbs = test_msg_b64; + } + + assert_string_equal(b64_data, expected_tbs); + + /* Return a predefined string as sig so that the caller + * can confirm that this callback was exercised. + */ + out = strdup(good_sig_b64); + assert_non_null(out); + + return out; +} + +/* Check signature and keymgmt methods can be fetched from the provider */ +static void +xkey_provider_test_fetch(void **state) +{ + assert_true(OSSL_PROVIDER_available(NULL, prov_name)); + + const char *algs[] = {"RSA", "ECDSA"}; + + for (size_t i = 0; i < _countof(algs); i++) + { + EVP_SIGNATURE *sig = EVP_SIGNATURE_fetch(NULL, algs[i], "provider=ovpn.xkey"); + assert_non_null(sig); + assert_string_equal(OSSL_PROVIDER_get0_name(EVP_SIGNATURE_get0_provider(sig)), prov_name); + + EVP_SIGNATURE_free(sig); + } + + const char *names[] = {"RSA", "EC"}; + + for (size_t i = 0; i < _countof(names); i++) + { + EVP_KEYMGMT *km = EVP_KEYMGMT_fetch(NULL, names[i], "provider=ovpn.xkey"); + assert_non_null(km); + assert_string_equal(OSSL_PROVIDER_get0_name(EVP_KEYMGMT_get0_provider(km)), prov_name); + + EVP_KEYMGMT_free(km); + } +} + +/* sign a test message using pkey -- caller must free the returned sig */ +static uint8_t * +digest_sign(EVP_PKEY *pkey) +{ + uint8_t *sig = NULL; + size_t siglen = 0; + + OSSL_PARAM params[6] = {OSSL_PARAM_END}; + + const char *mdname = "SHA256"; + const char *padmode = "pss"; + const char *saltlen = "digest"; + + if (EVP_PKEY_get_id(pkey) == EVP_PKEY_RSA) + { + params[0] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, (char *)mdname, 0); + params[1] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE, (char *)padmode, 0); + params[2] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, (char *)saltlen, 0); + /* same digest for mgf1 */ + params[3] = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, (char *)saltlen, 0); + params[4] = OSSL_PARAM_construct_end(); + } + + EVP_PKEY_CTX *pctx = NULL; + EVP_MD_CTX *mctx = EVP_MD_CTX_new(); + + if (!mctx + || EVP_DigestSignInit_ex(mctx, &pctx, mdname, NULL, NULL, pkey, params) <= 0) + { + fail_msg("Failed to initialize EVP_DigestSignInit_ex()"); + goto done; + } + + + /* sign with sig = NULL to get required siglen */ + assert_int_equal(EVP_DigestSign(mctx, sig, &siglen, (uint8_t*)test_msg, strlen(test_msg)), 1); + assert_true(siglen > 0); + + if ((sig = test_calloc(1, siglen)) == NULL) + { + fail_msg("Out of memory"); + } + assert_int_equal(EVP_DigestSign(mctx, sig, &siglen, (uint8_t*)test_msg, strlen(test_msg)), 1); + +done: + if (mctx) + { + EVP_MD_CTX_free(mctx); /* pctx is internally allocated and freed by mctx */ + } + return sig; +} + +/* Check loading of management external key and have sign callback exercised + * for RSA and EC keys with and without digest support in management client. + * Sha256 digest used for both cases with pss padding for RSA. + */ +static void +xkey_provider_test_mgmt_sign_cb(void **state) +{ + EVP_PKEY *pubkey; + for (size_t i = 0; i < _countof(pubkeys); i++) + { + pubkey = load_pubkey(pubkeys[i]); + assert_true(pubkey != NULL); + EVP_PKEY *privkey = xkey_load_management_key(NULL, pubkey); + assert_true(privkey != NULL); + + management->settings.flags = MF_EXTERNAL_KEY|MF_EXTERNAL_KEY_PSSPAD; + + /* first without digest support in management client */ +again: + mgmt_callback_called = 0; + uint8_t *sig = digest_sign(privkey); + assert_non_null(sig); + + /* check callback for signature got exercised */ + assert_int_equal(mgmt_callback_called, 1); + assert_memory_equal(sig, good_sig, sizeof(good_sig)); + test_free(sig); + + if (!(management->settings.flags & MF_EXTERNAL_KEY_DIGEST)) + { + management->settings.flags |= MF_EXTERNAL_KEY_DIGEST; + goto again; /* this time with digest support announced */ + } + + EVP_PKEY_free(pubkey); + EVP_PKEY_free(privkey); + } +} + +int +main(void) +{ + init_test(); + + const struct CMUnitTest tests[] = { + cmocka_unit_test(xkey_provider_test_fetch), + cmocka_unit_test(xkey_provider_test_mgmt_sign_cb), + }; + + int ret = cmocka_run_group_tests_name("xkey provider tests", tests, NULL, NULL); + + uninit_test(); + return ret; +}