|
@@ -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
|
|
@@ -30,7 +30,8 @@ public:
|
|
|
/// @param secret_len The length of the secret
|
|
|
/// @param hash_algorithm The hash algorithm
|
|
|
explicit HMACImpl(const void* secret, size_t secret_len,
|
|
|
- const HashAlgorithm hash_algorithm) {
|
|
|
+ const HashAlgorithm hash_algorithm)
|
|
|
+ : hash_algorithm_(hash_algorithm), md_() {
|
|
|
const EVP_MD* algo = ossl::getHashAlgorithm(hash_algorithm);
|
|
|
if (algo == 0) {
|
|
|
isc_throw(UnsupportedAlgorithm,
|
|
@@ -44,9 +45,11 @@ public:
|
|
|
md_.reset(new HMAC_CTX);
|
|
|
HMAC_CTX_init(md_.get());
|
|
|
|
|
|
- HMAC_Init_ex(md_.get(), secret,
|
|
|
- static_cast<int>(secret_len),
|
|
|
- algo, NULL);
|
|
|
+ if (!HMAC_Init_ex(md_.get(), secret,
|
|
|
+ static_cast<int>(secret_len),
|
|
|
+ algo, NULL)) {
|
|
|
+ isc_throw(LibraryError, "HMAC_Init_ex");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// @brief Destructor
|
|
@@ -56,13 +59,18 @@ public:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /// @brief Returns the HashAlgorithm of the object
|
|
|
+ HashAlgorithm getHashAlgorithm() const {
|
|
|
+ return (hash_algorithm_);
|
|
|
+ }
|
|
|
+
|
|
|
/// @brief Returns the output size of the digest
|
|
|
///
|
|
|
/// @return output size of the digest
|
|
|
size_t getOutputLength() const {
|
|
|
int size = HMAC_size(md_.get());
|
|
|
if (size < 0) {
|
|
|
- isc_throw(isc::cryptolink::LibraryError, "EVP_MD_CTX_size");
|
|
|
+ isc_throw(LibraryError, "HMAC_size");
|
|
|
}
|
|
|
return (static_cast<size_t>(size));
|
|
|
}
|
|
@@ -71,7 +79,11 @@ public:
|
|
|
///
|
|
|
/// See @ref isc::cryptolink::HMAC::update() for details.
|
|
|
void update(const void* data, const size_t len) {
|
|
|
- HMAC_Update(md_.get(), static_cast<const unsigned char*>(data), len);
|
|
|
+ if (!HMAC_Update(md_.get(),
|
|
|
+ static_cast<const unsigned char*>(data),
|
|
|
+ len)) {
|
|
|
+ isc_throw(LibraryError, "HMAC_Update");
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// @brief Calculate the final signature
|
|
@@ -80,7 +92,9 @@ public:
|
|
|
void sign(isc::util::OutputBuffer& result, size_t len) {
|
|
|
size_t size = getOutputLength();
|
|
|
ossl::SecBuf<unsigned char> digest(size);
|
|
|
- HMAC_Final(md_.get(), &digest[0], NULL);
|
|
|
+ if (!HMAC_Final(md_.get(), &digest[0], NULL)) {
|
|
|
+ isc_throw(LibraryError, "HMAC_Final");
|
|
|
+ }
|
|
|
if (len > size) {
|
|
|
len = size;
|
|
|
}
|
|
@@ -93,7 +107,9 @@ public:
|
|
|
void sign(void* result, size_t len) {
|
|
|
size_t size = getOutputLength();
|
|
|
ossl::SecBuf<unsigned char> digest(size);
|
|
|
- HMAC_Final(md_.get(), &digest[0], NULL);
|
|
|
+ if (!HMAC_Final(md_.get(), &digest[0], NULL)) {
|
|
|
+ isc_throw(LibraryError, "HMAC_Final");
|
|
|
+ }
|
|
|
if (len > size) {
|
|
|
len = size;
|
|
|
}
|
|
@@ -106,7 +122,9 @@ public:
|
|
|
std::vector<uint8_t> sign(size_t len) {
|
|
|
size_t size = getOutputLength();
|
|
|
ossl::SecBuf<unsigned char> digest(size);
|
|
|
- HMAC_Final(md_.get(), &digest[0], NULL);
|
|
|
+ if (!HMAC_Final(md_.get(), &digest[0], NULL)) {
|
|
|
+ isc_throw(LibraryError, "HMAC_Final");
|
|
|
+ }
|
|
|
if (len < size) {
|
|
|
digest.resize(len);
|
|
|
}
|
|
@@ -117,12 +135,23 @@ public:
|
|
|
///
|
|
|
/// See @ref isc::cryptolink::HMAC::verify() for details.
|
|
|
bool verify(const void* sig, size_t len) {
|
|
|
+ // Check the length
|
|
|
size_t size = getOutputLength();
|
|
|
if (len < 10 || len < size / 2) {
|
|
|
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");
|
|
|
+ }
|
|
|
ossl::SecBuf<unsigned char> digest(size);
|
|
|
- HMAC_Final(md_.get(), &digest[0], NULL);
|
|
|
+ if (!HMAC_Final(&tmp, &digest[0], NULL)) {
|
|
|
+ HMAC_CTX_cleanup(&tmp);
|
|
|
+ isc_throw(LibraryError, "HMAC_Final");
|
|
|
+ }
|
|
|
+ HMAC_CTX_cleanup(&tmp);
|
|
|
if (len > size) {
|
|
|
len = size;
|
|
|
}
|
|
@@ -130,6 +159,8 @@ public:
|
|
|
}
|
|
|
|
|
|
private:
|
|
|
+ /// @brief The hash algorithm
|
|
|
+ HashAlgorithm hash_algorithm_;
|
|
|
|
|
|
/// @brief The protected pointer to the OpenSSL HMAC_CTX structure
|
|
|
boost::scoped_ptr<HMAC_CTX> md_;
|
|
@@ -145,6 +176,11 @@ HMAC::~HMAC() {
|
|
|
delete impl_;
|
|
|
}
|
|
|
|
|
|
+HashAlgorithm
|
|
|
+HMAC::getHashAlgorithm() const {
|
|
|
+ return (impl_->getHashAlgorithm());
|
|
|
+}
|
|
|
+
|
|
|
size_t
|
|
|
HMAC::getOutputLength() const {
|
|
|
return (impl_->getOutputLength());
|