security: deduplicate RAII wrapper class for EVP_MD_CTX

Change-Id: I256588a8bc601b06548f7ec45aee020ddabb9597
diff --git a/src/security/detail/openssl-helper.cpp b/src/security/detail/openssl-helper.cpp
index d854776..865bc36 100644
--- a/src/security/detail/openssl-helper.cpp
+++ b/src/security/detail/openssl-helper.cpp
@@ -47,6 +47,26 @@
 #endif // OPENSSL_VERSION_NUMBER < 0x1010000fL
 }
 
+EvpMdCtx::EvpMdCtx()
+#if OPENSSL_VERSION_NUMBER < 0x1010000fL
+  : m_ctx(EVP_MD_CTX_create())
+#else
+  : m_ctx(EVP_MD_CTX_new())
+#endif
+{
+  if (m_ctx == nullptr)
+    BOOST_THROW_EXCEPTION(std::runtime_error("EVP_MD_CTX creation failed"));
+}
+
+EvpMdCtx::~EvpMdCtx()
+{
+#if OPENSSL_VERSION_NUMBER < 0x1010000fL
+  EVP_MD_CTX_destroy(m_ctx);
+#else
+  EVP_MD_CTX_free(m_ctx);
+#endif
+}
+
 EvpPkeyCtx::EvpPkeyCtx(EVP_PKEY* key)
   : m_ctx(EVP_PKEY_CTX_new(key, nullptr))
 {
diff --git a/src/security/detail/openssl-helper.hpp b/src/security/detail/openssl-helper.hpp
index 51a4a36..58690ca 100644
--- a/src/security/detail/openssl-helper.hpp
+++ b/src/security/detail/openssl-helper.hpp
@@ -35,6 +35,22 @@
 int
 getEvpPkeyType(EVP_PKEY* key);
 
+class EvpMdCtx : noncopyable
+{
+public:
+  EvpMdCtx();
+
+  ~EvpMdCtx();
+
+  operator EVP_MD_CTX*() const
+  {
+    return m_ctx;
+  }
+
+private:
+  EVP_MD_CTX* m_ctx;
+};
+
 class EvpPkeyCtx : noncopyable
 {
 public:
diff --git a/src/security/transform/digest-filter.cpp b/src/security/transform/digest-filter.cpp
index 44fe429..04a2f5c 100644
--- a/src/security/transform/digest-filter.cpp
+++ b/src/security/transform/digest-filter.cpp
@@ -28,33 +28,10 @@
 namespace security {
 namespace transform {
 
-/**
- * Implementation class that contains the internal state of the
- * digest calculator, including openssl-specific structures.
- */
 class DigestFilter::Impl
 {
 public:
-  Impl() noexcept
-  {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    ctx = EVP_MD_CTX_create();
-#else
-    ctx = EVP_MD_CTX_new();
-#endif
-  }
-
-  ~Impl()
-  {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    EVP_MD_CTX_destroy(ctx);
-#else
-    EVP_MD_CTX_free(ctx);
-#endif
-  }
-
-public:
-  EVP_MD_CTX* ctx;
+  detail::EvpMdCtx ctx;
 };
 
 
diff --git a/src/security/transform/hmac-filter.cpp b/src/security/transform/hmac-filter.cpp
index 81f7a27..12de2ea 100644
--- a/src/security/transform/hmac-filter.cpp
+++ b/src/security/transform/hmac-filter.cpp
@@ -31,28 +31,18 @@
 class HmacFilter::Impl
 {
 public:
-  Impl() noexcept
+  Impl()
     : key(nullptr)
   {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    ctx = EVP_MD_CTX_create();
-#else
-    ctx = EVP_MD_CTX_new();
-#endif
   }
 
   ~Impl()
   {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    EVP_MD_CTX_destroy(ctx);
-#else
-    EVP_MD_CTX_free(ctx);
-#endif
     EVP_PKEY_free(key);
   }
 
 public:
-  EVP_MD_CTX* ctx;
+  detail::EvpMdCtx ctx;
   EVP_PKEY* key;
 };
 
diff --git a/src/security/transform/signer-filter.cpp b/src/security/transform/signer-filter.cpp
index 959723c..2fbe647 100644
--- a/src/security/transform/signer-filter.cpp
+++ b/src/security/transform/signer-filter.cpp
@@ -32,26 +32,7 @@
 class SignerFilter::Impl
 {
 public:
-  Impl() noexcept
-  {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    ctx = EVP_MD_CTX_create();
-#else
-    ctx = EVP_MD_CTX_new();
-#endif
-  }
-
-  ~Impl()
-  {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    EVP_MD_CTX_destroy(ctx);
-#else
-    EVP_MD_CTX_free(ctx);
-#endif
-  }
-
-public:
-  EVP_MD_CTX* ctx;
+  detail::EvpMdCtx ctx;
 };
 
 
diff --git a/src/security/transform/verifier-filter.cpp b/src/security/transform/verifier-filter.cpp
index e5977a1..fca982a 100644
--- a/src/security/transform/verifier-filter.cpp
+++ b/src/security/transform/verifier-filter.cpp
@@ -32,29 +32,14 @@
 class VerifierFilter::Impl
 {
 public:
-  Impl(const uint8_t* sig, size_t siglen) noexcept
+  Impl(const uint8_t* sig, size_t siglen)
     : sig(sig)
     , siglen(siglen)
   {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    ctx = EVP_MD_CTX_create();
-#else
-    ctx = EVP_MD_CTX_new();
-#endif
-  }
-
-  ~Impl()
-  {
-#if OPENSSL_VERSION_NUMBER < 0x1010000fL
-    EVP_MD_CTX_destroy(ctx);
-#else
-    EVP_MD_CTX_free(ctx);
-#endif
   }
 
 public:
-  EVP_MD_CTX* ctx;
-
+  detail::EvpMdCtx ctx;
   const uint8_t* sig;
   size_t siglen;
 };