Commit ec8cb347 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[master] Merge branch 'master' of ssh://git.kea.isc.org/git/kea

parents c31e4c35 8777a1dd
......@@ -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
......
// 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
......
// 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());
}
}
......
// 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());
}
}
......@@ -190,7 +203,7 @@ public:
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,
......
// 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());
}
}
}
......
// 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
......
// 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
......
// 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
// 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)
......
// 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");