security: use high-level EVP routines in HmacFilter
Change-Id: I58aabf111193d3b554c8777b4ec41e3f761be263
diff --git a/src/security/transform/hmac-filter.cpp b/src/security/transform/hmac-filter.cpp
index 07a1796..81f7a27 100644
--- a/src/security/transform/hmac-filter.cpp
+++ b/src/security/transform/hmac-filter.cpp
@@ -22,6 +22,8 @@
#include "hmac-filter.hpp"
#include "../detail/openssl-helper.hpp"
+#include <boost/lexical_cast.hpp>
+
namespace ndn {
namespace security {
namespace transform {
@@ -29,43 +31,29 @@
class HmacFilter::Impl
{
public:
+ Impl() noexcept
+ : key(nullptr)
+ {
#if OPENSSL_VERSION_NUMBER < 0x1010000fL
- Impl()
- {
- HMAC_CTX_init(&m_context);
- }
-
- ~Impl()
- {
- HMAC_CTX_cleanup(&m_context);
- }
-
- operator HMAC_CTX*()
- {
- return &m_context;
- }
-
-private:
- HMAC_CTX m_context;
+ ctx = EVP_MD_CTX_create();
#else
- Impl()
- : m_context(HMAC_CTX_new())
- {
+ ctx = EVP_MD_CTX_new();
+#endif
}
~Impl()
{
- HMAC_CTX_free(m_context);
+#if OPENSSL_VERSION_NUMBER < 0x1010000fL
+ EVP_MD_CTX_destroy(ctx);
+#else
+ EVP_MD_CTX_free(ctx);
+#endif
+ EVP_PKEY_free(key);
}
- operator HMAC_CTX*()
- {
- return m_context;
- }
-
-private:
- HMAC_CTX* m_context;
-#endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
+public:
+ EVP_MD_CTX* ctx;
+ EVP_PKEY* key;
};
@@ -75,12 +63,18 @@
BOOST_ASSERT(key != nullptr);
BOOST_ASSERT(keyLen > 0);
- const EVP_MD* algorithm = detail::digestAlgorithmToEvpMd(algo);
- if (algorithm == nullptr)
- BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm"));
+ const EVP_MD* md = detail::digestAlgorithmToEvpMd(algo);
+ if (md == nullptr)
+ BOOST_THROW_EXCEPTION(Error(getIndex(), "Unsupported digest algorithm " +
+ boost::lexical_cast<std::string>(algo)));
- if (HMAC_Init_ex(*m_impl, key, keyLen, algorithm, nullptr) == 0)
- BOOST_THROW_EXCEPTION(Error(getIndex(), "Cannot initialize HMAC"));
+ m_impl->key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr, key, static_cast<int>(keyLen));
+ if (m_impl->key == nullptr)
+ BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to create HMAC key"));
+
+ if (EVP_DigestSignInit(m_impl->ctx, nullptr, md, nullptr, m_impl->key) != 1)
+ BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to initialize HMAC context with " +
+ boost::lexical_cast<std::string>(algo) + " digest"));
}
HmacFilter::~HmacFilter() = default;
@@ -88,8 +82,8 @@
size_t
HmacFilter::convert(const uint8_t* buf, size_t size)
{
- if (HMAC_Update(*m_impl, buf, size) == 0)
- BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to update HMAC"));
+ if (EVP_DigestSignUpdate(m_impl->ctx, buf, size) != 1)
+ BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to accept more input"));
return size;
}
@@ -98,12 +92,12 @@
HmacFilter::finalize()
{
auto buffer = make_unique<OBuffer>(EVP_MAX_MD_SIZE);
- unsigned int mdLen = 0;
+ size_t hmacLen = 0;
- if (HMAC_Final(*m_impl, buffer->data(), &mdLen) == 0)
+ if (EVP_DigestSignFinal(m_impl->ctx, buffer->data(), &hmacLen) != 1)
BOOST_THROW_EXCEPTION(Error(getIndex(), "Failed to finalize HMAC"));
- buffer->erase(buffer->begin() + mdLen, buffer->end());
+ buffer->erase(buffer->begin() + hmacLen, buffer->end());
setOutputBuffer(std::move(buffer));
flushAllOutput();
diff --git a/src/security/transform/hmac-filter.hpp b/src/security/transform/hmac-filter.hpp
index d0770b3..92c1905 100644
--- a/src/security/transform/hmac-filter.hpp
+++ b/src/security/transform/hmac-filter.hpp
@@ -36,7 +36,7 @@
{
public:
/**
- * @brief Create a HMAC module to generate HMAC using algorithm @p algo and @p key
+ * @brief Create a module to generate HMAC using digest algorithm @p algo and key @p key
* @pre @p key must not be nullptr, and @p size must be a positive integer.
*/
HmacFilter(DigestAlgorithm algo, const uint8_t* key, size_t keyLen);
@@ -45,7 +45,7 @@
private:
/**
- * @brief write data @p buf into HMAC signer
+ * @brief Write data @p buf into HMAC signer
*
* @return The number of bytes that are actually accepted
*/