Browse Source

[4633] Added OpenSSL 1.1 and Botan 1.11 support

Francis Dupont 8 years ago
parent
commit
f2edfc32fc

+ 7 - 2
configure.ac

@@ -587,6 +587,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;
@@ -781,6 +782,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;
@@ -900,12 +902,15 @@ 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])])

+ 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

+ 18 - 11
src/lib/cryptolink/botan_hash.cc

@@ -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,7 +62,13 @@ 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: " <<
@@ -111,12 +119,12 @@ 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());
         }
@@ -127,12 +135,12 @@ 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());
         }
@@ -143,12 +151,11 @@ 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());
         }

+ 26 - 13
src/lib/cryptolink/botan_hmac.cc

@@ -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,7 +40,19 @@ 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: " <<
@@ -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
@@ -124,12 +138,12 @@ 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());
         }
@@ -140,12 +154,12 @@ 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());
         }
@@ -156,12 +170,11 @@ 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());
         }
@@ -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,

+ 1 - 0
src/lib/cryptolink/botan_link.cc

@@ -9,6 +9,7 @@
 #include <cryptolink/crypto_hmac.h>
 
 #include <botan/botan.h>
+#include <botan/init.h>
 
 namespace isc {
 namespace cryptolink {

+ 17 - 13
src/lib/cryptolink/openssl_hash.cc

@@ -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,20 @@ 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, "EVP_MD_CTX_new");
+        }
 
-        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 +90,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 +106,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 +119,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 +132,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 +143,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)

+ 24 - 16
src/lib/cryptolink/openssl_hmac.cc

@@ -12,6 +12,8 @@
 #include <openssl/hmac.h>
 
 #include <cryptolink/openssl_common.h>
+#define KEA_HMAC
+#include <cryptolink/openssl_compat.h>
 
 #include <cstring>
 
@@ -42,10 +44,12 @@ 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, "HMAC_CTX_new");
+        }
 
-        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");
@@ -55,8 +59,9 @@ public:
     /// @brief Destructor
     ~HMACImpl() {
         if (md_) {
-            HMAC_CTX_cleanup(md_.get());
+            HMAC_CTX_free(md_);
         }
+        md_ = 0;
     }
 
     /// @brief Returns the HashAlgorithm of the object
@@ -68,7 +73,7 @@ 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");
         }
@@ -79,7 +84,7 @@ 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");
@@ -92,7 +97,7 @@ 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)) {
+        if (!HMAC_Final(md_, &digest[0], NULL)) {
             isc_throw(LibraryError, "HMAC_Final");
         }
         if (len > size) {
@@ -107,7 +112,7 @@ 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)) {
+        if (!HMAC_Final(md_, &digest[0], NULL)) {
             isc_throw(LibraryError, "HMAC_Final");
         }
         if (len > size) {
@@ -122,7 +127,7 @@ 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)) {
+        if (!HMAC_Final(md_, &digest[0], NULL)) {
             isc_throw(LibraryError, "HMAC_Final");
         }
         if (len < size) {
@@ -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())) {
+        HMAC_CTX* tmp = HMAC_CTX_new();
+        if (tmp == 0) {
+            isc_throw(LibraryError, "HMAC_CTX_new");
+        }
+        if (!HMAC_CTX_copy(tmp, md_)) {
+            HMAC_CTX_free(tmp);
             isc_throw(LibraryError, "HMAC_CTX_copy");
         }
         ossl::SecBuf<unsigned char> digest(size);
-        if (!HMAC_Final(&tmp, &digest[0], NULL)) {
-            HMAC_CTX_cleanup(&tmp);
+        if (!HMAC_Final(tmp, &digest[0], NULL)) {
+            HMAC_CTX_free(tmp);
             isc_throw(LibraryError, "HMAC_Final");
         }
-        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,