Browse Source

[master] Finished merge of trac4633 (update cryptolink)

Francis Dupont 8 years ago
parent
commit
43281bd9de

+ 9 - 4
configure.ac

@@ -688,6 +688,7 @@ AC_DEFUN([ACX_TRY_BOTAN_TOOL], [
             #AC_MSG_RESULT([found])
             AC_LINK_IFELSE(
                 [AC_LANG_PROGRAM([#include <botan/botan.h>
+                                  #include <botan/init.h>
                                   #include <botan/hash.h>
                                  ],
                                  [using namespace Botan;
@@ -882,6 +883,7 @@ then
    LIBS="$LIBS $CRYPTO_LIBS"
    AC_LINK_IFELSE(
         [AC_LANG_PROGRAM([#include <botan/botan.h>
+                          #include <botan/init.h>
                           #include <botan/hash.h>
                          ],
                          [using namespace Botan;
@@ -915,7 +917,7 @@ then
 else
    CRYPTO_NAME="OpenSSL"
    DISABLED_CRYPTO="Botan"
-   CRYPTO_PACKAGE="openssl-1.0.1"
+   CRYPTO_PACKAGE="openssl-1.0.2"
    AC_DEFINE_UNQUOTED([WITH_OPENSSL], [], [Compile with OpenSSL crypto])
    AC_MSG_CHECKING(for OpenSSL library)
    # from bind9
@@ -1001,15 +1003,18 @@ EOF
     dnl Check HMAC API
     AC_MSG_CHECKING([HMAC functions returning ints])
     AC_LINK_IFELSE(
-         [AC_LANG_PROGRAM([#include <openssl/hmac.h>],
-                          [HMAC_CTX ctx, tmp;
+         [AC_LANG_PROGRAM([#include <openssl/opensslv.h>
+                           #include <openssl/hmac.h>],
+                          [#if OPENSSL_VERSION_NUMBER < 0x10100000L
+                           HMAC_CTX ctx, tmp;
                            int n = HMAC_Init(&ctx, NULL, 0, NULL);
                            n += HMAC_Update(&ctx, NULL, 0);
                            n += HMAC_CTX_copy(&tmp, &ctx);
                            n += HMAC_Final(&tmp, NULL, NULL);
+                           #endif
                            ])],
          [AC_MSG_RESULT([yes])],
-         [AC_MSG_ERROR([HMAC functions return void: the OpenSSL version should be too old, please change for >= 1.0.1])])
+         [AC_MSG_ERROR([HMAC functions return void: please use OpenSSL version 1.0.1 or later])])
     LIBS=${LIBS_SAVED}
     CPPFLAGS=${CPPFLAGS_SAVED}
 fi

+ 2 - 2
src/lib/cryptolink/botan_common.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -12,7 +12,7 @@ namespace btn {
 ///
 /// @param algorithm algorithm to be converted
 /// @return static text representation of the algorithm name
-const char*
+const std::string
 getHashAlgorithmName(isc::cryptolink::HashAlgorithm algorithm);
 
 } // namespace btn

+ 29 - 17
src/lib/cryptolink/botan_hash.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -16,7 +16,9 @@
 
 #include <cryptolink/botan_common.h>
 
-#include <cstring>
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,0)
+#define secure_vector SecureVector
+#endif
 
 namespace isc {
 namespace cryptolink {
@@ -25,7 +27,7 @@ namespace cryptolink {
 ///
 /// @param algorithm algorithm to be converted
 /// @return text representation of the algorithm name
-const char*
+const std::string
 btn::getHashAlgorithmName(HashAlgorithm algorithm) {
     switch (algorithm) {
     case isc::cryptolink::MD5:
@@ -60,13 +62,20 @@ public:
     : hash_algorithm_(hash_algorithm), hash_() {
         Botan::HashFunction* hash;
         try {
-            hash = Botan::get_hash(btn::getHashAlgorithmName(hash_algorithm));
+            const std::string& name =
+                btn::getHashAlgorithmName(hash_algorithm);
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+            hash = Botan::HashFunction::create(name).release();
+#else
+            hash = Botan::get_hash(name);
+#endif
         } catch (const Botan::Algorithm_Not_Found&) {
             isc_throw(isc::cryptolink::UnsupportedAlgorithm,
                       "Unknown hash algorithm: " <<
                       static_cast<int>(hash_algorithm));
         } catch (const Botan::Exception& exc) {
-            isc_throw(isc::cryptolink::LibraryError, exc.what());
+            isc_throw(isc::cryptolink::LibraryError,
+                      "Botan error: " << exc.what());
         }
 
         hash_.reset(hash);
@@ -102,7 +111,8 @@ public:
         try {
             hash_->update(static_cast<const Botan::byte*>(data), len);
         } catch (const Botan::Exception& exc) {
-            isc_throw(isc::cryptolink::LibraryError, exc.what());
+            isc_throw(isc::cryptolink::LibraryError,
+                      "Botan error: " << exc.what());
         }
     }
 
@@ -111,14 +121,15 @@ public:
     /// See @ref isc::cryptolink::Hash::final() for details.
     void final(isc::util::OutputBuffer& result, size_t len) {
         try {
-            Botan::SecureVector<Botan::byte> b_result(hash_->final());
+            Botan::secure_vector<Botan::byte> b_result(hash_->final());
 
             if (len > b_result.size()) {
                 len = b_result.size();
             }
-            result.writeData(b_result.begin(), len);
+            result.writeData(&b_result[0], len);
         } catch (const Botan::Exception& exc) {
-            isc_throw(isc::cryptolink::LibraryError, exc.what());
+            isc_throw(isc::cryptolink::LibraryError,
+                      "Botan error: " << exc.what());
         }
     }
 
@@ -127,14 +138,15 @@ public:
     /// See @ref isc::cryptolink::Hash::final() for details.
     void final(void* result, size_t len) {
         try {
-            Botan::SecureVector<Botan::byte> b_result(hash_->final());
+            Botan::secure_vector<Botan::byte> b_result(hash_->final());
             size_t output_size = getOutputLength();
             if (output_size > len) {
                 output_size = len;
             }
-            std::memcpy(result, b_result.begin(), output_size);
+            std::memcpy(result, &b_result[0], output_size);
         } catch (const Botan::Exception& exc) {
-            isc_throw(isc::cryptolink::LibraryError, exc.what());
+            isc_throw(isc::cryptolink::LibraryError,
+                      "Botan error: " << exc.what());
         }
     }
 
@@ -143,14 +155,14 @@ public:
     /// See @ref isc::cryptolink::Hash::final() for details.
     std::vector<uint8_t> final(size_t len) {
         try {
-            Botan::SecureVector<Botan::byte> b_result(hash_->final());
+            Botan::secure_vector<Botan::byte> b_result(hash_->final());
             if (len > b_result.size()) {
-                return (std::vector<uint8_t>(b_result.begin(), b_result.end()));
-            } else {
-                return (std::vector<uint8_t>(b_result.begin(), &b_result[len]));
+                len = b_result.size();
             }
+            return (std::vector<uint8_t>(&b_result[0], &b_result[len]));
         } catch (const Botan::Exception& exc) {
-            isc_throw(isc::cryptolink::LibraryError, exc.what());
+            isc_throw(isc::cryptolink::LibraryError,
+                      "Botan error: " << exc.what());
         }
     }
 

+ 35 - 22
src/lib/cryptolink/botan_hmac.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -17,7 +17,9 @@
 
 #include <cryptolink/botan_common.h>
 
-#include <cstring>
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,11,0)
+#define secure_vector SecureVector
+#endif
 
 namespace isc {
 namespace cryptolink {
@@ -38,13 +40,25 @@ public:
     : hash_algorithm_(hash_algorithm), hmac_() {
         Botan::HashFunction* hash;
         try {
-            hash = Botan::get_hash(btn::getHashAlgorithmName(hash_algorithm));
+            const std::string& name =
+                btn::getHashAlgorithmName(hash_algorithm);
+#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
+            std::unique_ptr<Botan::HashFunction> hash_ptr =
+                Botan::HashFunction::create(name);
+            if (hash_ptr) {
+                hash = hash_ptr.release();
+            } else {
+                throw Botan::Algorithm_Not_Found(name);
+            }
+#else
+            hash = Botan::get_hash(name);
+#endif
         } catch (const Botan::Algorithm_Not_Found&) {
             isc_throw(UnsupportedAlgorithm,
                       "Unknown hash algorithm: " <<
                       static_cast<int>(hash_algorithm));
         } catch (const Botan::Exception& exc) {
-            isc_throw(LibraryError, exc.what());
+            isc_throw(LibraryError, "Botan error: " << exc.what());
         }
 
         hmac_.reset(new Botan::HMAC(hash));
@@ -64,10 +78,10 @@ public:
             size_t block_length = 0;
 #endif
             if (secret_len > block_length) {
-                Botan::SecureVector<Botan::byte> hashed_key =
+                Botan::secure_vector<Botan::byte> hashed_key =
                     hash->process(static_cast<const Botan::byte*>(secret),
                                   secret_len);
-                hmac_->set_key(hashed_key.begin(), hashed_key.size());
+                hmac_->set_key(&hashed_key[0], hashed_key.size());
             } else {
                 // Botan 1.8 considers len 0 a bad key. 1.9 does not,
                 // but we won't accept it anyway, and fail early
@@ -80,7 +94,7 @@ public:
         } catch (const Botan::Invalid_Key_Length& ikl) {
             isc_throw(BadKey, ikl.what());
         } catch (const Botan::Exception& exc) {
-            isc_throw(LibraryError, exc.what());
+            isc_throw(LibraryError, "Botan error: " << exc.what());
         }
     }
 
@@ -115,7 +129,7 @@ public:
         try {
             hmac_->update(static_cast<const Botan::byte*>(data), len);
         } catch (const Botan::Exception& exc) {
-            isc_throw(LibraryError, exc.what());
+            isc_throw(LibraryError, "Botan error: " << exc.what());
         }
     }
 
@@ -124,14 +138,14 @@ public:
     /// See @ref isc::cryptolink::HMAC::sign() for details.
     void sign(isc::util::OutputBuffer& result, size_t len) {
         try {
-            Botan::SecureVector<Botan::byte> b_result(hmac_->final());
+            Botan::secure_vector<Botan::byte> b_result(hmac_->final());
 
             if (len > b_result.size()) {
                 len = b_result.size();
             }
-            result.writeData(b_result.begin(), len);
+            result.writeData(&b_result[0], len);
         } catch (const Botan::Exception& exc) {
-            isc_throw(LibraryError, exc.what());
+            isc_throw(LibraryError, "Botan error: " << exc.what());
         }
     }
 
@@ -140,14 +154,14 @@ public:
     /// See @ref isc::cryptolink::HMAC::sign() for details.
     void sign(void* result, size_t len) {
         try {
-            Botan::SecureVector<Botan::byte> b_result(hmac_->final());
+            Botan::secure_vector<Botan::byte> b_result(hmac_->final());
             size_t output_size = getOutputLength();
             if (output_size > len) {
                 output_size = len;
             }
-            std::memcpy(result, b_result.begin(), output_size);
+            std::memcpy(result, &b_result[0], output_size);
         } catch (const Botan::Exception& exc) {
-            isc_throw(LibraryError, exc.what());
+            isc_throw(LibraryError, "Botan error: " << exc.what());
         }
     }
 
@@ -156,14 +170,13 @@ public:
     /// See @ref isc::cryptolink::HMAC::sign() for details.
     std::vector<uint8_t> sign(size_t len) {
         try {
-            Botan::SecureVector<Botan::byte> b_result(hmac_->final());
+            Botan::secure_vector<Botan::byte> b_result(hmac_->final());
             if (len > b_result.size()) {
-                return (std::vector<uint8_t>(b_result.begin(), b_result.end()));
-            } else {
-                return (std::vector<uint8_t>(b_result.begin(), &b_result[len]));
+                len = b_result.size();
             }
+            return (std::vector<uint8_t>(&b_result[0], &b_result[len]));
         } catch (const Botan::Exception& exc) {
-            isc_throw(LibraryError, exc.what());
+            isc_throw(LibraryError, "Botan error: " << exc.what());
         }
     }
 
@@ -183,14 +196,14 @@ public:
             if (len > size) {
                 len = size;
             }
-            if (digest_.size() == 0) {
+            if (digest_.empty()) {
                 digest_ = hmac_->final();
             }
             return (Botan::same_mem(&digest_[0],
                                     static_cast<const unsigned char*>(sig),
                                     len));
         } catch (const Botan::Exception& exc) {
-            isc_throw(LibraryError, exc.what());
+            isc_throw(LibraryError, "Botan error: " << exc.what());
         }
     }
 
@@ -202,7 +215,7 @@ private:
     boost::scoped_ptr<Botan::HMAC> hmac_;
 
     /// @brief The digest cache for multiple verify
-    Botan::SecureVector<Botan::byte> digest_;
+    Botan::secure_vector<Botan::byte> digest_;
 };
 
 HMAC::HMAC(const void* secret, size_t secret_length,

+ 3 - 2
src/lib/cryptolink/botan_link.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2015,2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -9,6 +9,7 @@
 #include <cryptolink/crypto_hmac.h>
 
 #include <botan/botan.h>
+#include <botan/init.h>
 
 namespace isc {
 namespace cryptolink {
@@ -30,7 +31,7 @@ CryptoLink::initialize() {
         try {
             c.impl_ = new CryptoLinkImpl();
         } catch (const Botan::Exception& ex) {
-            isc_throw(InitializationError, ex.what());
+            isc_throw(InitializationError, "Botan error: " << ex.what());
         }
     }
 }

+ 1 - 1
src/lib/cryptolink/crypto_hash.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this

+ 1 - 1
src/lib/cryptolink/crypto_hmac.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this

+ 53 - 0
src/lib/cryptolink/openssl_compat.h

@@ -0,0 +1,53 @@
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <openssl/opensslv.h>
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+// This file is included by hash and hmac codes so KEA_H* macros
+// avoid to define unused inlines.
+
+#ifdef KEA_HASH
+
+// EVP_MD_CTX_new() is EVP_MD_CTX_create() in OpenSSL < 1.1
+
+inline EVP_MD_CTX* EVP_MD_CTX_new() {
+    return (EVP_MD_CTX_create());
+}
+
+// EVP_MD_CTX_free(ctx) is EVP_MD_CTX_destroy(ctx) in OpenSSL < 1.1 
+
+inline void EVP_MD_CTX_free(EVP_MD_CTX* ctx) {
+    EVP_MD_CTX_destroy(ctx);
+}
+
+#endif
+
+#ifdef KEA_HMAC
+
+// HMAC_CTX_new() implementation for OpenSSL < 1.1
+
+inline HMAC_CTX* HMAC_CTX_new() {
+    HMAC_CTX* ctx = static_cast<HMAC_CTX*>(OPENSSL_malloc(sizeof(HMAC_CTX)));
+    if (ctx != 0) {
+        HMAC_CTX_init(ctx);
+    }
+    return (ctx);
+}
+
+// HMAC_CTX_free() implementation for OpenSSL < 1.1
+
+inline void HMAC_CTX_free(HMAC_CTX* ctx) {
+    if (ctx != 0) {
+        HMAC_CTX_cleanup(ctx);
+        OPENSSL_free(ctx);
+    }
+}
+
+#endif
+
+#endif

+ 19 - 14
src/lib/cryptolink/openssl_hash.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -12,6 +12,8 @@
 #include <openssl/evp.h>
 
 #include <cryptolink/openssl_common.h>
+#define KEA_HASH
+#include <cryptolink/openssl_compat.h>
 
 #include <cstring>
 
@@ -55,7 +57,7 @@ public:
     ///
     /// @param hash_algorithm The hash algorithm
     explicit HashImpl(const HashAlgorithm hash_algorithm)
-    : hash_algorithm_(hash_algorithm), md_() {
+    : hash_algorithm_(hash_algorithm), md_(0) {
         const EVP_MD* algo = ossl::getHashAlgorithm(hash_algorithm);
         if (algo == 0) {
             isc_throw(isc::cryptolink::UnsupportedAlgorithm,
@@ -63,18 +65,21 @@ public:
                       static_cast<int>(hash_algorithm));
         }
 
-        md_.reset(new EVP_MD_CTX);
-
-        EVP_MD_CTX_init(md_.get());
+        md_ = EVP_MD_CTX_new();
+        if (md_ == 0) {
+            isc_throw(isc::cryptolink::LibraryError,
+                      "OpenSSL EVP_MD_CTX_new() failed");
+        }
 
-        EVP_DigestInit_ex(md_.get(), algo, NULL);
+        EVP_DigestInit_ex(md_, algo, NULL);
     }
 
     /// @brief Destructor
     ~HashImpl() {
         if (md_) {
-            EVP_MD_CTX_cleanup(md_.get());
+            EVP_MD_CTX_free(md_);
         }
+        md_ = 0;
     }
 
     /// @brief Returns the HashAlgorithm of the object
@@ -86,14 +91,14 @@ public:
     ///
     /// @return output size of the digest
     size_t getOutputLength() const {
-        return (EVP_MD_CTX_size(md_.get()));
+        return (EVP_MD_CTX_size(md_));
     }
 
     /// @brief Adds data to the digest
     ///
     /// See @ref isc::cryptolink::Hash::update() for details.
     void update(const void* data, const size_t len) {
-        EVP_DigestUpdate(md_.get(), data, len);
+        EVP_DigestUpdate(md_, data, len);
     }
 
     /// @brief Calculate the final digest
@@ -102,7 +107,7 @@ public:
     void final(isc::util::OutputBuffer& result, size_t len) {
         size_t size = getOutputLength();
         std::vector<unsigned char> digest(size);
-        EVP_DigestFinal_ex(md_.get(), &digest[0], NULL);
+        EVP_DigestFinal_ex(md_, &digest[0], NULL);
         if (len > size) {
              len = size;
         }
@@ -115,7 +120,7 @@ public:
     void final(void* result, size_t len) {
         size_t size = getOutputLength();
         std::vector<unsigned char> digest(size);
-        EVP_DigestFinal_ex(md_.get(), &digest[0], NULL);
+        EVP_DigestFinal_ex(md_, &digest[0], NULL);
         if (len > size) {
              len = size;
         }
@@ -128,7 +133,7 @@ public:
     std::vector<uint8_t> final(size_t len) {
         size_t size = getOutputLength();
         std::vector<unsigned char> digest(size);
-        EVP_DigestFinal_ex(md_.get(), &digest[0], NULL);
+        EVP_DigestFinal_ex(md_, &digest[0], NULL);
         if (len < size) {
             digest.resize(len);
         }
@@ -139,8 +144,8 @@ private:
     /// @brief The hash algorithm
     HashAlgorithm hash_algorithm_;
 
-    /// @brief The protected pointer to the OpenSSL EVP_MD_CTX structure
-    boost::scoped_ptr<EVP_MD_CTX> md_;
+    /// @brief The pointer to the OpenSSL EVP_MD_CTX structure
+    EVP_MD_CTX* md_;
 };
 
 Hash::Hash(const HashAlgorithm hash_algorithm)

+ 33 - 25
src/lib/cryptolink/openssl_hmac.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -12,6 +12,8 @@
 #include <openssl/hmac.h>
 
 #include <cryptolink/openssl_common.h>
+#define KEA_HMAC
+#include <cryptolink/openssl_compat.h>
 
 #include <cstring>
 
@@ -42,21 +44,24 @@ public:
             isc_throw(BadKey, "Bad HMAC secret length: 0");
         }
 
-        md_.reset(new HMAC_CTX);
-        HMAC_CTX_init(md_.get());
+        md_ = HMAC_CTX_new();
+        if (md_ == 0) {
+            isc_throw(LibraryError, "OpenSSL HMAC_CTX_new() failed");
+        }
 
-        if (!HMAC_Init_ex(md_.get(), secret,
+        if (!HMAC_Init_ex(md_, secret,
                           static_cast<int>(secret_len),
                           algo, NULL)) {
-            isc_throw(LibraryError, "HMAC_Init_ex");
+            isc_throw(LibraryError, "OpenSSL HMAC_Init_ex() failed");
         }
     }
 
     /// @brief Destructor
     ~HMACImpl() {
         if (md_) {
-            HMAC_CTX_cleanup(md_.get());
+            HMAC_CTX_free(md_);
         }
+        md_ = 0;
     }
 
     /// @brief Returns the HashAlgorithm of the object
@@ -68,9 +73,9 @@ public:
     ///
     /// @return output size of the digest
     size_t getOutputLength() const {
-        int size = HMAC_size(md_.get());
+        int size = HMAC_size(md_);
         if (size < 0) {
-            isc_throw(LibraryError, "HMAC_size");
+            isc_throw(LibraryError, "OpenSSL HMAC_size() failed");
         }
         return (static_cast<size_t>(size));
     }
@@ -79,10 +84,10 @@ public:
     ///
     /// See @ref isc::cryptolink::HMAC::update() for details.
     void update(const void* data, const size_t len) {
-        if (!HMAC_Update(md_.get(),
+        if (!HMAC_Update(md_,
                          static_cast<const unsigned char*>(data),
                          len)) {
-            isc_throw(LibraryError, "HMAC_Update");
+            isc_throw(LibraryError, "OpenSSLHMAC_Update() failed");
         }
     }
 
@@ -92,8 +97,8 @@ public:
     void sign(isc::util::OutputBuffer& result, size_t len) {
         size_t size = getOutputLength();
         ossl::SecBuf<unsigned char> digest(size);
-        if (!HMAC_Final(md_.get(), &digest[0], NULL)) {
-            isc_throw(LibraryError, "HMAC_Final");
+        if (!HMAC_Final(md_, &digest[0], NULL)) {
+            isc_throw(LibraryError, "OpenSSL HMAC_Final() failed");
         }
         if (len > size) {
             len = size;
@@ -107,8 +112,8 @@ public:
     void sign(void* result, size_t len) {
         size_t size = getOutputLength();
         ossl::SecBuf<unsigned char> digest(size);
-        if (!HMAC_Final(md_.get(), &digest[0], NULL)) {
-            isc_throw(LibraryError, "HMAC_Final");
+        if (!HMAC_Final(md_, &digest[0], NULL)) {
+            isc_throw(LibraryError, "OpenSSL HMAC_Final() failed");
         }
         if (len > size) {
             len = size;
@@ -122,8 +127,8 @@ public:
     std::vector<uint8_t> sign(size_t len) {
         size_t size = getOutputLength();
         ossl::SecBuf<unsigned char> digest(size);
-        if (!HMAC_Final(md_.get(), &digest[0], NULL)) {
-            isc_throw(LibraryError, "HMAC_Final");
+        if (!HMAC_Final(md_, &digest[0], NULL)) {
+            isc_throw(LibraryError, "OpenSSL HMAC_Final() failed");
         }
         if (len < size) {
             digest.resize(len);
@@ -141,17 +146,20 @@ public:
             return (false);
         }
         // Get the digest from a copy of the context
-        HMAC_CTX tmp;
-        HMAC_CTX_init(&tmp);
-        if (!HMAC_CTX_copy(&tmp, md_.get())) {
-            isc_throw(LibraryError, "HMAC_CTX_copy");
+        HMAC_CTX* tmp = HMAC_CTX_new();
+        if (tmp == 0) {
+            isc_throw(LibraryError, "OpenSSL HMAC_CTX_new() failed");
+        }
+        if (!HMAC_CTX_copy(tmp, md_)) {
+            HMAC_CTX_free(tmp);
+            isc_throw(LibraryError, "OpenSSL HMAC_CTX_copy() failed");
         }
         ossl::SecBuf<unsigned char> digest(size);
-        if (!HMAC_Final(&tmp, &digest[0], NULL)) {
-            HMAC_CTX_cleanup(&tmp);
-            isc_throw(LibraryError, "HMAC_Final");
+        if (!HMAC_Final(tmp, &digest[0], NULL)) {
+            HMAC_CTX_free(tmp);
+            isc_throw(LibraryError, "OpenSSL HMAC_Final() failed");
         }
-        HMAC_CTX_cleanup(&tmp);
+        HMAC_CTX_free(tmp);
         if (len > size) {
             len = size;
         }
@@ -163,7 +171,7 @@ private:
     HashAlgorithm hash_algorithm_;
 
     /// @brief The protected pointer to the OpenSSL HMAC_CTX structure
-    boost::scoped_ptr<HMAC_CTX> md_;
+    HMAC_CTX* md_;
 };
 
 HMAC::HMAC(const void* secret, size_t secret_length,