security: make HMAC compatible with OpenSSL 3

This is a temporary workaround until the internals
can be restructured to use EVP_MAC

Refs: #5251
Change-Id: I28854177a066a753a5cbacad591ee55f5c137622
diff --git a/ndn-cxx/security/impl/openssl-helper.cpp b/ndn-cxx/security/impl/openssl-helper.cpp
index 5abf6be..fe6aed7 100644
--- a/ndn-cxx/security/impl/openssl-helper.cpp
+++ b/ndn-cxx/security/impl/openssl-helper.cpp
@@ -23,6 +23,10 @@
 
 #include <limits>
 
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+#include <openssl/core_names.h>
+#endif
+
 namespace ndn::security::detail {
 
 const EVP_MD*
@@ -59,7 +63,16 @@
 int
 getEvpPkeyType(const EVP_PKEY* key)
 {
-  return EVP_PKEY_base_id(key);
+  int keyType = EVP_PKEY_base_id(key);
+  if (keyType > 0)
+    return keyType;
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+  if (EVP_PKEY_is_a(key, OSSL_MAC_NAME_HMAC))
+    return EVP_PKEY_HMAC;
+#endif
+
+  return keyType;
 }
 
 EvpMdCtx::EvpMdCtx()
diff --git a/ndn-cxx/security/transform/private-key.cpp b/ndn-cxx/security/transform/private-key.cpp
index 0acb648..95aad25 100644
--- a/ndn-cxx/security/transform/private-key.cpp
+++ b/ndn-cxx/security/transform/private-key.cpp
@@ -118,14 +118,14 @@
                     boost::lexical_cast<std::string>(getKeyType())));
 
   size_t len = 0;
-  const uint8_t* buf = EVP_PKEY_get0_hmac(m_impl->key, &len);
-  if (buf == nullptr)
-    NDN_THROW(Error("Failed to obtain raw key pointer"));
-  if (len * 8 != getKeySize())
-    NDN_THROW(Error("Key length mismatch"));
+  if (EVP_PKEY_get_raw_private_key(m_impl->key, nullptr, &len) != 1)
+    NDN_THROW(Error("Failed to get raw key length"));
+  Buffer digest(len);
+  if (EVP_PKEY_get_raw_private_key(m_impl->key, digest.data(), &len) != 1)
+    NDN_THROW(Error("Failed to get raw key"));
 
   OBufferStream os;
-  bufferSource(make_span(buf, len)) >> digestFilter(algo) >> streamSink(os);
+  bufferSource(digest) >> digestFilter(algo) >> streamSink(os);
   return os.buf();
 }
 
diff --git a/ndn-cxx/security/transform/verifier-filter.cpp b/ndn-cxx/security/transform/verifier-filter.cpp
index 4893c4c..4809faa 100644
--- a/ndn-cxx/security/transform/verifier-filter.cpp
+++ b/ndn-cxx/security/transform/verifier-filter.cpp
@@ -103,7 +103,7 @@
   bool ok = false;
   if (m_keyType == KeyType::HMAC) {
     auto hmacBuf = make_unique<OBuffer>(EVP_MAX_MD_SIZE);
-    size_t hmacLen = 0;
+    size_t hmacLen = EVP_MAX_MD_SIZE;
 
     if (EVP_DigestSignFinal(m_impl->ctx, hmacBuf->data(), &hmacLen) != 1)
       NDN_THROW(Error(getIndex(), "Failed to finalize HMAC"));
diff --git a/tests/unit/security/key-chain.t.cpp b/tests/unit/security/key-chain.t.cpp
index c154851..15bf4cd 100644
--- a/tests/unit/security/key-chain.t.cpp
+++ b/tests/unit/security/key-chain.t.cpp
@@ -537,11 +537,9 @@
   EcdsaSigning<DataPkt>,
   EcdsaSigning<InterestV02Pkt>,
   EcdsaSigning<InterestV03Pkt>,
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
   HmacSigning<DataPkt>,
   HmacSigning<InterestV02Pkt>,
   HmacSigning<InterestV03Pkt>,
-#endif
   Sha256Signing<DataPkt>,
   Sha256Signing<InterestV02Pkt>,
   Sha256Signing<InterestV03Pkt>,
diff --git a/tests/unit/security/signing-info.t.cpp b/tests/unit/security/signing-info.t.cpp
index a1aee15..29fd8ad 100644
--- a/tests/unit/security/signing-info.t.cpp
+++ b/tests/unit/security/signing-info.t.cpp
@@ -99,14 +99,12 @@
   BOOST_CHECK_EQUAL(infoSha.getDigestAlgorithm(), DigestAlgorithm::SHA256);
   BOOST_CHECK_EQUAL(infoSha.getSignedInterestFormat(), SignedInterestFormat::V02);
 
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
   std::string encodedKey("QjM3NEEyNkE3MTQ5MDQzN0FBMDI0RTRGQURENUI0OTdGRE"
                          "ZGMUE4RUE2RkYxMkY2RkI2NUFGMjcyMEI1OUNDRg==");
   info.setSigningHmacKey(encodedKey);
   BOOST_CHECK_EQUAL(info.getSignerType(), SigningInfo::SIGNER_TYPE_HMAC);
   BOOST_CHECK_EQUAL(info.getDigestAlgorithm(), DigestAlgorithm::SHA256);
   BOOST_CHECK_EQUAL(info.getSignedInterestFormat(), SignedInterestFormat::V02);
-#endif
 
   SigningInfo infoHmac(SigningInfo::SIGNER_TYPE_HMAC, info.getSignerName());
   BOOST_CHECK_EQUAL(infoHmac.getSignerType(), SigningInfo::SIGNER_TYPE_HMAC);
@@ -151,13 +149,11 @@
   BOOST_CHECK_EQUAL(infoCert.getSignerName(), "/my-cert");
   BOOST_CHECK_EQUAL(infoCert.getDigestAlgorithm(), DigestAlgorithm::SHA256);
 
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
   SigningInfo infoHmac("hmac-sha256:QjM3NEEyNkE3MTQ5MDQzN0FBMDI0RTRGQURENU"
                        "I0OTdGREZGMUE4RUE2RkYxMkY2RkI2NUFGMjcyMEI1OUNDRg==");
   BOOST_CHECK_EQUAL(infoHmac.getSignerType(), SigningInfo::SIGNER_TYPE_HMAC);
   BOOST_CHECK_EQUAL(infoHmac.getSignerName().getPrefix(3), SigningInfo::getHmacIdentity());
   BOOST_CHECK_EQUAL(infoHmac.getDigestAlgorithm(), DigestAlgorithm::SHA256);
-#endif
 
   SigningInfo infoSha("id:/localhost/identity/digest-sha256");
   BOOST_CHECK_EQUAL(infoSha.getSignerType(), SigningInfo::SIGNER_TYPE_SHA256);
diff --git a/tests/unit/security/tpm/back-end.t.cpp b/tests/unit/security/tpm/back-end.t.cpp
index 34d79b4..da22029 100644
--- a/tests/unit/security/tpm/back-end.t.cpp
+++ b/tests/unit/security/tpm/back-end.t.cpp
@@ -88,14 +88,12 @@
 {
   Name identity("/Test/Identity/HMAC");
 
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
   BackEndWrapperMem mem;
   BackEnd& memTpm = mem.getTpm();
   auto key = memTpm.createKey(identity, HmacKeyParams());
   BOOST_REQUIRE(key != nullptr);
   BOOST_CHECK(!key->getKeyName().empty());
   BOOST_CHECK(memTpm.hasKey(key->getKeyName()));
-#endif
 
   BackEndWrapperFile file;
   BackEnd& fileTpm = file.getTpm();
@@ -226,7 +224,6 @@
   BOOST_CHECK_EQUAL(tpm.hasKey(ecKeyName), false);
 }
 
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
 BOOST_AUTO_TEST_CASE(HmacSigningAndVerifying)
 {
   BackEndWrapperMem wrapper;
@@ -254,7 +251,6 @@
   tpm.deleteKey(hmacKeyName);
   BOOST_CHECK_EQUAL(tpm.hasKey(hmacKeyName), false);
 }
-#endif
 
 BOOST_AUTO_TEST_CASE_TEMPLATE(ImportExport, T, TestBackEnds)
 {
diff --git a/tests/unit/security/transform/private-key.t.cpp b/tests/unit/security/transform/private-key.t.cpp
index f9a511d..3d77d6c 100644
--- a/tests/unit/security/transform/private-key.t.cpp
+++ b/tests/unit/security/transform/private-key.t.cpp
@@ -61,7 +61,6 @@
   BOOST_CHECK_THROW(sKey.savePkcs8(os, passwd.data(), passwd.size()), PrivateKey::Error);
 }
 
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
 BOOST_AUTO_TEST_CASE(KeyDigest)
 {
   const Buffer buf(16);
@@ -76,17 +75,14 @@
   BOOST_CHECK_EQUAL_COLLECTIONS(digest->begin(), digest->end(),
                                 expected, expected + sizeof(expected));
 }
-#endif
 
 BOOST_AUTO_TEST_CASE(LoadRaw)
 {
   const Buffer buf(32);
   PrivateKey sKey;
   sKey.loadRaw(KeyType::HMAC, buf);
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
   BOOST_CHECK_EQUAL(sKey.getKeyType(), KeyType::HMAC);
   BOOST_CHECK_EQUAL(sKey.getKeySize(), 256);
-#endif
 
   PrivateKey sKey2;
   BOOST_CHECK_THROW(sKey2.loadRaw(KeyType::NONE, buf), std::invalid_argument);
@@ -650,9 +646,7 @@
 };
 
 using KeyGenParams = boost::mpl::vector<
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
   HmacKeyGenParams,
-#endif
   RsaKeyGenParams,
   EcKeyGenParams
 >;
diff --git a/tests/unit/security/transform/verifier-filter.t.cpp b/tests/unit/security/transform/verifier-filter.t.cpp
index e04415c..4f659be 100644
--- a/tests/unit/security/transform/verifier-filter.t.cpp
+++ b/tests/unit/security/transform/verifier-filter.t.cpp
@@ -165,14 +165,12 @@
 
   BOOST_CHECK_THROW(VerifierFilter(DigestAlgorithm::NONE, *sKey, *sig), Error);
 
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
   bool result = false;
   bufferSource(DATA) >>
     verifierFilter(DigestAlgorithm::SHA256, *sKey, *sig) >>
     boolSink(result);
 
   BOOST_CHECK_EQUAL(result, true);
-#endif
 }
 
 BOOST_AUTO_TEST_CASE(InvalidKey)
diff --git a/tests/unit/security/verification-helpers.t.cpp b/tests/unit/security/verification-helpers.t.cpp
index 868333d..540a133 100644
--- a/tests/unit/security/verification-helpers.t.cpp
+++ b/tests/unit/security/verification-helpers.t.cpp
@@ -592,7 +592,6 @@
   // - pib::Key version is tested as part of key-chain.t.cpp (Security/TestKeyChain)
 }
 
-#if OPENSSL_VERSION_NUMBER < 0x30000000L // FIXME #5154
 BOOST_FIXTURE_TEST_CASE(VerifyHmac, KeyChainFixture)
 {
   const Tpm& tpm = m_keyChain.getTpm();
@@ -616,7 +615,6 @@
   BOOST_CHECK(verifySignature(interest, tpm, signingInfo.getSignerName(), DigestAlgorithm::SHA256));
   BOOST_CHECK(verifySignature(interestOldFormat, tpm, signingInfo.getSignerName(), DigestAlgorithm::SHA256));
 }
-#endif
 
 using DigestDatasets = boost::mpl::vector<Sha256Dataset>;