|
@@ -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,
|