#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;
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;
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])])
-// 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
///
/// @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
#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 {
///
/// @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:
: 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: " <<
/// 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());
}
/// 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());
}
/// 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());
}
#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 {
: 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: " <<
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
/// 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());
}
/// 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());
}
/// 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());
}
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,
#include <cryptolink/crypto_hmac.h>
#include <botan/botan.h>
+#include <botan/init.h>
namespace isc {
namespace cryptolink {
#include <openssl/evp.h>
#include <cryptolink/openssl_common.h>
+#define KEA_HASH
+#include <cryptolink/openssl_compat.h>
#include <cstring>
///
/// @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,
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
///
/// @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
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;
}
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;
}
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);
}
/// @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)
#include <openssl/hmac.h>
#include <cryptolink/openssl_common.h>
+#define KEA_HMAC
+#include <cryptolink/openssl_compat.h>
#include <cstring>
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");
/// @brief Destructor
~HMACImpl() {
if (md_) {
- HMAC_CTX_cleanup(md_.get());
+ HMAC_CTX_free(md_);
}
+ md_ = 0;
}
/// @brief Returns the HashAlgorithm of the object
///
/// @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");
}
///
/// 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");
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) {
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) {
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) {
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;
}
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,