From: Francis Dupont Date: Fri, 26 Aug 2016 19:17:03 +0000 (+0200) Subject: [4633] Added OpenSSL 1.1 and Botan 1.11 support X-Git-Tag: trac3590_base~4^2~1^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f2edfc32fcf5ab2679ab6ec7059a493694126fb1;p=thirdparty%2Fkea.git [4633] Added OpenSSL 1.1 and Botan 1.11 support --- diff --git a/configure.ac b/configure.ac index e25f3265e3..1a6056846c 100644 --- a/configure.ac +++ b/configure.ac @@ -587,6 +587,7 @@ AC_DEFUN([ACX_TRY_BOTAN_TOOL], [ #AC_MSG_RESULT([found]) AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include + #include #include ], [using namespace Botan; @@ -781,6 +782,7 @@ then LIBS="$LIBS $CRYPTO_LIBS" AC_LINK_IFELSE( [AC_LANG_PROGRAM([#include + #include #include ], [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 ], - [HMAC_CTX ctx, tmp; + [AC_LANG_PROGRAM([#include + #include ], + [#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])]) diff --git a/src/lib/cryptolink/botan_common.h b/src/lib/cryptolink/botan_common.h index 96ef1cd508..5c06276713 100644 --- a/src/lib/cryptolink/botan_common.h +++ b/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 diff --git a/src/lib/cryptolink/botan_hash.cc b/src/lib/cryptolink/botan_hash.cc index 3220ca1bee..8e87786c42 100644 --- a/src/lib/cryptolink/botan_hash.cc +++ b/src/lib/cryptolink/botan_hash.cc @@ -16,7 +16,9 @@ #include -#include +#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 b_result(hash_->final()); + Botan::secure_vector 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 b_result(hash_->final()); + Botan::secure_vector 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 final(size_t len) { try { - Botan::SecureVector b_result(hash_->final()); + Botan::secure_vector b_result(hash_->final()); if (len > b_result.size()) { - return (std::vector(b_result.begin(), b_result.end())); - } else { - return (std::vector(b_result.begin(), &b_result[len])); + len = b_result.size(); } + return (std::vector(&b_result[0], &b_result[len])); } catch (const Botan::Exception& exc) { isc_throw(isc::cryptolink::LibraryError, exc.what()); } diff --git a/src/lib/cryptolink/botan_hmac.cc b/src/lib/cryptolink/botan_hmac.cc index 75afd401fe..713dad1bb0 100644 --- a/src/lib/cryptolink/botan_hmac.cc +++ b/src/lib/cryptolink/botan_hmac.cc @@ -17,7 +17,9 @@ #include -#include +#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 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 hashed_key = + Botan::secure_vector hashed_key = hash->process(static_cast(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 b_result(hmac_->final()); + Botan::secure_vector 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 b_result(hmac_->final()); + Botan::secure_vector 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 sign(size_t len) { try { - Botan::SecureVector b_result(hmac_->final()); + Botan::secure_vector b_result(hmac_->final()); if (len > b_result.size()) { - return (std::vector(b_result.begin(), b_result.end())); - } else { - return (std::vector(b_result.begin(), &b_result[len])); + len = b_result.size(); } + return (std::vector(&b_result[0], &b_result[len])); } catch (const Botan::Exception& exc) { isc_throw(LibraryError, exc.what()); } @@ -202,7 +215,7 @@ private: boost::scoped_ptr hmac_; /// @brief The digest cache for multiple verify - Botan::SecureVector digest_; + Botan::secure_vector digest_; }; HMAC::HMAC(const void* secret, size_t secret_length, diff --git a/src/lib/cryptolink/botan_link.cc b/src/lib/cryptolink/botan_link.cc index c8f4a95c38..965d1256e9 100644 --- a/src/lib/cryptolink/botan_link.cc +++ b/src/lib/cryptolink/botan_link.cc @@ -9,6 +9,7 @@ #include #include +#include namespace isc { namespace cryptolink { diff --git a/src/lib/cryptolink/openssl_hash.cc b/src/lib/cryptolink/openssl_hash.cc index e1f5aa8047..6b19c6fcbe 100644 --- a/src/lib/cryptolink/openssl_hash.cc +++ b/src/lib/cryptolink/openssl_hash.cc @@ -12,6 +12,8 @@ #include #include +#define KEA_HASH +#include #include @@ -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(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 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 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 final(size_t len) { size_t size = getOutputLength(); std::vector 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 md_; + /// @brief The pointer to the OpenSSL EVP_MD_CTX structure + EVP_MD_CTX* md_; }; Hash::Hash(const HashAlgorithm hash_algorithm) diff --git a/src/lib/cryptolink/openssl_hmac.cc b/src/lib/cryptolink/openssl_hmac.cc index d73b373f52..0da7278f11 100644 --- a/src/lib/cryptolink/openssl_hmac.cc +++ b/src/lib/cryptolink/openssl_hmac.cc @@ -12,6 +12,8 @@ #include #include +#define KEA_HMAC +#include #include @@ -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(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(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 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 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 sign(size_t len) { size_t size = getOutputLength(); ossl::SecBuf 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 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 md_; + HMAC_CTX* md_; }; HMAC::HMAC(const void* secret, size_t secret_length,