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 <fgerl...@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 <sza...@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

Reply via email to