You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by sz...@apache.org on 2023/10/02 12:02:48 UTC
[nifi-minifi-cpp] 01/06: MINIFICPP-2191 Replace deprecated OpenSSL API calls
This is an automated email from the ASF dual-hosted git repository.
szaszm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit a77c85727086a5e38aa14aaef22143acf70235ae
Author: Ferenc Gerlits <fg...@gmail.com>
AuthorDate: Mon Oct 2 13:55:02 2023 +0200
MINIFICPP-2191 Replace deprecated OpenSSL API calls
Closes #1656
Signed-off-by: Marton Szasz <sz...@apache.org>
---
libminifi/include/utils/tls/CertificateUtils.h | 3 +
libminifi/src/utils/tls/CertificateUtils.cpp | 119 ++++++++++++++--------
libminifi/test/unit/CertificateUtilsTests.cpp | 132 +++++++++++++++++++++++++
3 files changed, 213 insertions(+), 41 deletions(-)
diff --git a/libminifi/include/utils/tls/CertificateUtils.h b/libminifi/include/utils/tls/CertificateUtils.h
index 67ca46ee9..3c4a8ff6f 100644
--- a/libminifi/include/utils/tls/CertificateUtils.h
+++ b/libminifi/include/utils/tls/CertificateUtils.h
@@ -91,6 +91,9 @@ class WindowsCertStore {
// Returns nullptr on errors
X509_unique_ptr convertWindowsCertificate(PCCERT_CONTEXT certificate);
+// Returns nullptr on errors, or if the input is not an RSA key pair
+EVP_PKEY_unique_ptr convertWindowsRsaKeyPair(std::span<BYTE> data);
+
// Returns nullptr if the certificate has no associated private key, or the private key could not be extracted
EVP_PKEY_unique_ptr extractPrivateKey(PCCERT_CONTEXT certificate);
#endif // WIN32
diff --git a/libminifi/src/utils/tls/CertificateUtils.cpp b/libminifi/src/utils/tls/CertificateUtils.cpp
index fb508a10a..5b8763a3a 100644
--- a/libminifi/src/utils/tls/CertificateUtils.cpp
+++ b/libminifi/src/utils/tls/CertificateUtils.cpp
@@ -18,14 +18,19 @@
#include "utils/tls/CertificateUtils.h"
-#include <openssl/rsa.h>
-#include <openssl/err.h>
+#include "openssl/rsa.h"
+#include "openssl/err.h"
#ifdef WIN32
#include <winsock2.h>
#pragma comment(lib, "ncrypt.lib")
#pragma comment(lib, "Ws2_32.lib")
+
+#include "openssl/core_names.h"
+#include "openssl/evp.h"
+#include "openssl/param_build.h"
+#include "openssl/ssl.h"
#endif // WIN32
#include "utils/StringUtils.h"
@@ -87,6 +92,76 @@ X509_unique_ptr convertWindowsCertificate(const PCCERT_CONTEXT certificate) {
return X509_unique_ptr{d2i_X509(nullptr, &certificate_binary, certificate_length)};
}
+struct OSSL_PARAM_BLD_deleter {
+ void operator()(OSSL_PARAM_BLD* param_builder) const { OSSL_PARAM_BLD_free(param_builder); }
+};
+using OSSL_PARAM_BLD_unique_ptr = std::unique_ptr<OSSL_PARAM_BLD, OSSL_PARAM_BLD_deleter>;
+
+struct OSSL_PARAM_deleter {
+ void operator()(OSSL_PARAM* params) const { OSSL_PARAM_free(params); }
+};
+using OSSL_PARAM_unique_ptr = std::unique_ptr<OSSL_PARAM, OSSL_PARAM_deleter>;
+
+struct EVP_PKEY_CTX_deleter {
+ void operator()(EVP_PKEY_CTX* pkey_context) const { EVP_PKEY_CTX_free(pkey_context); }
+};
+using EVP_PKEY_CTX_unique_ptr = std::unique_ptr<EVP_PKEY_CTX, EVP_PKEY_CTX_deleter>;
+
+EVP_PKEY_unique_ptr convertWindowsRsaKeyPair(std::span<BYTE> data) {
+ // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob
+ auto const blob = reinterpret_cast<BCRYPT_RSAKEY_BLOB *>(data.data());
+
+ if (blob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC) {
+ OSSL_PARAM_BLD_unique_ptr param_builder{OSSL_PARAM_BLD_new()};
+ if (!param_builder) { return nullptr; }
+
+ // n is the modulus common to both public and private key
+ const auto* const n = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp, blob->cbModulus, nullptr);
+ // e is the public exponent
+ const auto* const e = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB), blob->cbPublicExp, nullptr);
+ // d is the private exponent
+ const auto* const d = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
+ + blob->cbPrime2 + blob->cbPrime1 + blob->cbPrime2 + blob->cbPrime1, blob->cbModulus, nullptr);
+
+ if (OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_N, n) == 0 ||
+ OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_E, e) == 0 ||
+ OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_D, d) == 0) { return nullptr; }
+
+ // p and q are the first and second factor of n
+ const auto* const p = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus,
+ blob->cbPrime1, nullptr);
+ const auto* const q = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1,
+ blob->cbPrime2, nullptr);
+
+ if (OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_FACTOR1, p) == 0 ||
+ OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_FACTOR2, q) == 0) { return nullptr; }
+
+ // dmp1, dmq1 and iqmp are the exponents and coefficient for CRT calculations
+ const auto* const dmp1 = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
+ + blob->cbPrime2, blob->cbPrime1, nullptr);
+ const auto* const dmq1 = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
+ + blob->cbPrime2 + blob->cbPrime1, blob->cbPrime2, nullptr);
+ const auto* const iqmp = BN_bin2bn(data.data() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
+ + blob->cbPrime2 + blob->cbPrime1 + blob->cbPrime2, blob->cbPrime1, nullptr);
+
+ if (OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_EXPONENT1, dmp1) == 0 ||
+ OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_EXPONENT2, dmq1) == 0 ||
+ OSSL_PARAM_BLD_push_BN(param_builder.get(), OSSL_PKEY_PARAM_RSA_COEFFICIENT1, iqmp) == 0) { return nullptr; }
+
+ OSSL_PARAM_unique_ptr params{OSSL_PARAM_BLD_to_param(param_builder.get())};
+ if (!params) { return nullptr; }
+
+ EVP_PKEY_CTX_unique_ptr context{EVP_PKEY_CTX_new_from_name(NULL, SSL_TXT_RSA, NULL)};
+ if (!context || EVP_PKEY_fromdata_init(context.get()) <= 0) { return nullptr; }
+
+ EVP_PKEY* keypair_raw = nullptr;
+ if (EVP_PKEY_fromdata(context.get(), &keypair_raw, EVP_PKEY_KEYPAIR, params.get()) <= 0) { return nullptr; }
+ return EVP_PKEY_unique_ptr{keypair_raw};
+ }
+
+ return nullptr;
+}
+
// from Shane Powell's answer at https://stackoverflow.com/questions/60180688, used with permission
EVP_PKEY_unique_ptr extractPrivateKey(const PCCERT_CONTEXT certificate) {
HCRYPTPROV_OR_NCRYPT_KEY_HANDLE key_handle;
@@ -114,45 +189,7 @@ EVP_PKEY_unique_ptr extractPrivateKey(const PCCERT_CONTEXT certificate) {
length,
&length,
0))) {
- // https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/ns-bcrypt-bcrypt_rsakey_blob
- auto const blob = reinterpret_cast<BCRYPT_RSAKEY_BLOB *>(data.get());
-
- if (blob->Magic == BCRYPT_RSAFULLPRIVATE_MAGIC) {
- auto rsa = RSA_new();
-
- // n is the modulus common to both public and private key
- auto const n = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp, blob->cbModulus, nullptr);
- // e is the public exponent
- auto const e = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB), blob->cbPublicExp, nullptr);
- // d is the private exponent
- auto const d = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
- + blob->cbPrime2 + blob->cbPrime1 + blob->cbPrime2 + blob->cbPrime1, blob->cbModulus, nullptr);
-
- RSA_set0_key(rsa, n, e, d);
-
- // p and q are the first and second factor of n
- auto const p = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus,
- blob->cbPrime1, nullptr);
- auto const q = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1,
- blob->cbPrime2, nullptr);
-
- RSA_set0_factors(rsa, p, q);
-
- // dmp1, dmq1 and iqmp are the exponents and coefficient for CRT calculations
- auto const dmp1 = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
- + blob->cbPrime2, blob->cbPrime1, nullptr);
- auto const dmq1 = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
- + blob->cbPrime2 + blob->cbPrime1, blob->cbPrime2, nullptr);
- auto const iqmp = BN_bin2bn(data.get() + sizeof(BCRYPT_RSAKEY_BLOB) + blob->cbPublicExp + blob->cbModulus + blob->cbPrime1
- + blob->cbPrime2 + blob->cbPrime1 + blob->cbPrime2, blob->cbPrime1, nullptr);
-
- RSA_set0_crt_params(rsa, dmp1, dmq1, iqmp);
-
- pkey.reset(EVP_PKEY_new());
-
- // ownership of rsa transferred to pkey
- EVP_PKEY_assign_RSA(pkey.get(), rsa);
- }
+ pkey = convertWindowsRsaKeyPair(std::span(data.get(), length));
}
}
diff --git a/libminifi/test/unit/CertificateUtilsTests.cpp b/libminifi/test/unit/CertificateUtilsTests.cpp
new file mode 100644
index 000000000..0c4380315
--- /dev/null
+++ b/libminifi/test/unit/CertificateUtilsTests.cpp
@@ -0,0 +1,132 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../Catch.h"
+#include "date/date.h"
+#include "openssl/core_names.h"
+#include "utils/file/FileUtils.h"
+#include "utils/span.h"
+#include "utils/StringUtils.h"
+#include "utils/tls/CertificateUtils.h"
+
+namespace utils = org::apache::nifi::minifi::utils;
+
+TEST_CASE("getCertificateExpiration() works correctly") {
+ using namespace date::literals;
+ using namespace std::literals::chrono_literals;
+
+ const auto executable_dir = utils::file::get_executable_dir();
+ const auto cert_location = executable_dir / "resources" / "goodCA.crt";
+
+ size_t num_times_called = 0;
+ utils::tls::processPEMCertificate(cert_location, {}, {[&](utils::tls::X509_unique_ptr cert) {
+ ++num_times_called;
+ CHECK(utils::tls::getCertificateExpiration(cert) == date::sys_days(date::year_month_day(2053_y / 4 / 30)) + 9h + 3min);
+ return std::error_code{};
+ }, {}, {}});
+ CHECK(num_times_called == 1);
+}
+
+#ifdef WIN32
+
+constexpr std::string_view BCRYPT_RSAFULLPRIVATE_BLOB_example =
+ "52534133000800000300000000010000800000008000000001000184CAF5B447EB8AC0C9FA70942B1DBDA43E1E52B58DCF9F"
+ "25F44F3962FCFDAF9DE160303E54604721C7F7E6FE5D7E07FE915FF24616FEF4F74E59DEE8BB24C8F711591B9BC92E201130"
+ "1CB8EE0109D6FE2FD83B11433D4E9AB53BF5BA816E07729ED59DD17036FD7242D214BFA3A35F8668E5F52DF8C8DDE9331136"
+ "9C8455C1568F9DBC4F012E35B5246A7A6253D2F1423911CB1639995319F51AA3FA59F17A250895AD7F771F841536CD420BE1"
+ "A7EC5B94FF459A071F353CCC6ED0D6DBDB0F8DF7651C168AF32633272B045CD6EB1E4C29C0441DCE596F33BFA0154F702B8C"
+ "D000E318E7670053120612B94C7825D0FA28F2D4CBF1A0C467BFD67F719C75CCBDCD930FD9DE2675D2F01A19E449CA6A22F8"
+ "3CFDB676E05E116939E3F454F23D00620C0D3B6216450391F840A16E982BE07B1EE282235E1A017B504CF2392525702C3F5E"
+ "22C907A34589D4796C33058DD780EB3B02C27028C0A68F53B54B745530141E43E82B8C2604A86DB9B223C89679C8268DF84D"
+ "56E34B36A6DF782598AD5BA55D9CFC26CFC82A2BF05D7096965E15DDAD3EC1999B8B41882C01F85A0DEDCEEC28DB304D8880"
+ "C9A1C286E98F0C9561EB7E66A8CAC4DD80368DE3A71331D07CEF5C56A790EC27C3F17F02ED729A3BD6AB69BCBE6C1EDA381D"
+ "76FADFEB56457F01657C66D9CA681D5B1FD02ED59843FC534418548F78D8DE04C70DDE8D0C11C77CFA72418EF82CDB8FD31E"
+ "78968FF394CCFC2F76D5B0B41FBBAC5134C2CBFE60143BA573BBBF3437E66F59C38AFC0278D8013FCDC478BA30BA6A684D3E"
+ "86A1CB1F6B6AEC94F10AC704F362DA6FEE697C61C920B81DC39852FF2FD5C13B5D3F491A8207E0C750CDF03901744AA3CC98"
+ "06F3B2D4CEE71DF2D35027856682DCDE4F283680936CD8C06348F615B2E85BBE9B70A1CD8E04CDA76A9333A872FD6B3FB63F"
+ "059C6FBD9B013E8720A7F02A02345D7087F76CFA8A2F171BAD1B7C2895C78E6A22B94BDC59213E6BFEA7F69814DB925372CE"
+ "1C3C6CB0424F1FFCD7F101B4BAB2DB3C0A42D20EC97CBC5AC2D8DC43441BF786372200903445532693451777476E201BB98D"
+ "5674360DACC054D1FB201F5F95BEBEE775B57EDE21B5C46147B02DF8ADD6B06900FC66AB4B52D7B42C65FD27D8986A476EBB"
+ "FB9CF90E01EA1A7EF228869E0472FB58542B49BA6D3509651E477FCD3ADF06F0F13C98B03733FFCAF0800A250D31FE9F07A8"
+ "CCF56D820E6A3F4E620A9B40EC64805EF935F0A2CC608C14780C83AB8A5D2AF6774A1F2CBE3ADB34500C43BC0642EBE0CACD"
+ "77BAB387FC781F1190AA04E53209D6E69E52DEF8707F0C211638B9381D5ED06F91C437195B2C2B661C0F58B2CCB373D9F5A5"
+ "E754627E1180995A99FAA1D249D9C8D3E697F34D14746D3234E7C053187AE6475D097E7870E9E81A2F2C35A40F85317F1C90"
+ "DE83BB11657ECB49BDEE5C8E5BE66DB471A3FD16F8BE31B07A62D1DB71D3E5BA6AE67DC0231A5F77F535B4057A14AB805B33"
+ "511B4E2CB5C4F6305416BF267E204D3153CC3E6C5710404E22BCEE710CC19050DDD73977D005FAD9898C9E6BF5CB9CD36B31"
+ "06DC17052A51D921C41A18563F68AE932C3793390819F4DC80958609E9";
+
+constexpr std::string_view expected_n =
+ "84CAF5B447EB8AC0C9FA70942B1DBDA43E1E52B58DCF9F25F44F3962FCFDAF9DE160303E54604721C7F7E6FE5D7E07FE915F"
+ "F24616FEF4F74E59DEE8BB24C8F711591B9BC92E2011301CB8EE0109D6FE2FD83B11433D4E9AB53BF5BA816E07729ED59DD1"
+ "7036FD7242D214BFA3A35F8668E5F52DF8C8DDE93311369C8455C1568F9DBC4F012E35B5246A7A6253D2F1423911CB163999"
+ "5319F51AA3FA59F17A250895AD7F771F841536CD420BE1A7EC5B94FF459A071F353CCC6ED0D6DBDB0F8DF7651C168AF32633"
+ "272B045CD6EB1E4C29C0441DCE596F33BFA0154F702B8CD000E318E7670053120612B94C7825D0FA28F2D4CBF1A0C467BFD6"
+ "7F719C75CCBD";
+constexpr std::string_view expected_e = "010001";
+constexpr std::string_view expected_d =
+ "14780C83AB8A5D2AF6774A1F2CBE3ADB34500C43BC0642EBE0CACD77BAB387FC781F1190AA04E53209D6E69E52DEF8707F0C"
+ "211638B9381D5ED06F91C437195B2C2B661C0F58B2CCB373D9F5A5E754627E1180995A99FAA1D249D9C8D3E697F34D14746D"
+ "3234E7C053187AE6475D097E7870E9E81A2F2C35A40F85317F1C90DE83BB11657ECB49BDEE5C8E5BE66DB471A3FD16F8BE31"
+ "B07A62D1DB71D3E5BA6AE67DC0231A5F77F535B4057A14AB805B33511B4E2CB5C4F6305416BF267E204D3153CC3E6C571040"
+ "4E22BCEE710CC19050DDD73977D005FAD9898C9E6BF5CB9CD36B3106DC17052A51D921C41A18563F68AE932C3793390819F4"
+ "DC80958609E9";
+constexpr std::string_view expected_p =
+ "CD930FD9DE2675D2F01A19E449CA6A22F83CFDB676E05E116939E3F454F23D00620C0D3B6216450391F840A16E982BE07B1E"
+ "E282235E1A017B504CF2392525702C3F5E22C907A34589D4796C33058DD780EB3B02C27028C0A68F53B54B745530141E43E8"
+ "2B8C2604A86DB9B223C89679C8268DF84D56E34B36A6DF782598AD5B";
+constexpr std::string_view expected_q =
+ "A55D9CFC26CFC82A2BF05D7096965E15DDAD3EC1999B8B41882C01F85A0DEDCEEC28DB304D8880C9A1C286E98F0C9561EB7E"
+ "66A8CAC4DD80368DE3A71331D07CEF5C56A790EC27C3F17F02ED729A3BD6AB69BCBE6C1EDA381D76FADFEB56457F01657C66"
+ "D9CA681D5B1FD02ED59843FC534418548F78D8DE04C70DDE8D0C11C7";
+constexpr std::string_view expected_dmp1 =
+ "7CFA72418EF82CDB8FD31E78968FF394CCFC2F76D5B0B41FBBAC5134C2CBFE60143BA573BBBF3437E66F59C38AFC0278D801"
+ "3FCDC478BA30BA6A684D3E86A1CB1F6B6AEC94F10AC704F362DA6FEE697C61C920B81DC39852FF2FD5C13B5D3F491A8207E0"
+ "C750CDF03901744AA3CC9806F3B2D4CEE71DF2D35027856682DCDE4F";
+constexpr std::string_view expected_dmq1 =
+ "283680936CD8C06348F615B2E85BBE9B70A1CD8E04CDA76A9333A872FD6B3FB63F059C6FBD9B013E8720A7F02A02345D7087"
+ "F76CFA8A2F171BAD1B7C2895C78E6A22B94BDC59213E6BFEA7F69814DB925372CE1C3C6CB0424F1FFCD7F101B4BAB2DB3C0A"
+ "42D20EC97CBC5AC2D8DC43441BF78637220090344553269345177747";
+constexpr std::string_view expected_iqmp =
+ "6E201BB98D5674360DACC054D1FB201F5F95BEBEE775B57EDE21B5C46147B02DF8ADD6B06900FC66AB4B52D7B42C65FD27D8"
+ "986A476EBBFB9CF90E01EA1A7EF228869E0472FB58542B49BA6D3509651E477FCD3ADF06F0F13C98B03733FFCAF0800A250D"
+ "31FE9F07A8CCF56D820E6A3F4E620A9B40EC64805EF935F0A2CC608C";
+
+TEST_CASE("convertWindowsRsaKeyPair() works correctly") {
+ std::vector<std::byte> windows_private_key_blob = utils::StringUtils::from_hex(BCRYPT_RSAFULLPRIVATE_BLOB_example);
+ utils::tls::EVP_PKEY_unique_ptr openssl_private_key = utils::tls::convertWindowsRsaKeyPair(utils::as_span<BYTE>(std::span{windows_private_key_blob}));
+ REQUIRE(openssl_private_key);
+
+ const auto checkParam = [&openssl_private_key](const char* param_name, std::string_view expected_value) {
+ BIGNUM* actual_value = nullptr;
+ REQUIRE(EVP_PKEY_get_bn_param(openssl_private_key.get(), param_name, &actual_value) == 1);
+ char* param_hex = BN_bn2hex(actual_value);
+ CHECK(param_hex == expected_value);
+ OPENSSL_free(param_hex);
+ BN_free(actual_value);
+ };
+
+ checkParam(OSSL_PKEY_PARAM_RSA_N, expected_n);
+ checkParam(OSSL_PKEY_PARAM_RSA_E, expected_e);
+ checkParam(OSSL_PKEY_PARAM_RSA_D, expected_d);
+ checkParam(OSSL_PKEY_PARAM_RSA_FACTOR1, expected_p);
+ checkParam(OSSL_PKEY_PARAM_RSA_FACTOR2, expected_q);
+ checkParam(OSSL_PKEY_PARAM_RSA_EXPONENT1, expected_dmp1);
+ checkParam(OSSL_PKEY_PARAM_RSA_EXPONENT2, expected_dmq1);
+ checkParam(OSSL_PKEY_PARAM_RSA_COEFFICIENT1, expected_iqmp);
+}
+
+#endif // WIN32