diff options
-rw-r--r-- | src/lib/cryptolink/crypto.h | 13 | ||||
-rw-r--r-- | src/lib/cryptolink/crypto_hmac.cc | 68 | ||||
-rw-r--r-- | src/lib/cryptolink/crypto_hmac.h | 21 |
3 files changed, 80 insertions, 22 deletions
diff --git a/src/lib/cryptolink/crypto.h b/src/lib/cryptolink/crypto.h index 17978259d0..208d37afc7 100644 --- a/src/lib/cryptolink/crypto.h +++ b/src/lib/cryptolink/crypto.h @@ -59,6 +59,16 @@ public: CryptoLinkError(file, line, what) {} }; +/// This exception is raised when a general error that was not +/// specifically caught is thrown by the underlying library. It +/// is replaced by this one so as not have 'external' exceptions +/// bubbling up +class LibraryError : public CryptoLinkError { +public: + LibraryError(const char* file, size_t line, const char* what) : + CryptoLinkError(file, line, what) {} +}; + /// Forward declaration for pimpl class CryptoLinkImpl; @@ -106,6 +116,7 @@ public: /// the current implementation. /// /// \exception InitializationError if initialization fails + /// static void initialize(); /// \brief Factory function for HMAC objects @@ -126,6 +137,8 @@ public: /// \exception UnsupportedAlgorithmException if the given algorithm /// is unknown or not supported by the underlying library /// \exception InvalidKeyLength if the given key secret_len is bad + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library /// /// \param secret The secret to sign with /// \param secret_len The length of the secret diff --git a/src/lib/cryptolink/crypto_hmac.cc b/src/lib/cryptolink/crypto_hmac.cc index 564ad09ac8..dea85714bb 100644 --- a/src/lib/cryptolink/crypto_hmac.cc +++ b/src/lib/cryptolink/crypto_hmac.cc @@ -47,6 +47,8 @@ public: } catch (const Botan::Algorithm_Not_Found&) { isc_throw(isc::cryptolink::UnsupportedAlgorithm, "Unknown hash algorithm: " + hash_algorithm); + } catch (const Botan::Exception& exc) { + isc_throw(isc::cryptolink::LibraryError, exc.what()); } hmac_.reset(new Botan::HMAC::HMAC(hash)); @@ -65,6 +67,8 @@ public: } } catch (const Botan::Invalid_Key_Length& ikl) { isc_throw(BadKey, ikl.what()); + } catch (const Botan::Exception& exc) { + isc_throw(isc::cryptolink::LibraryError, exc.what()); } } @@ -75,33 +79,49 @@ public: } void update(const void* data, const size_t len) { - hmac_->update(static_cast<const Botan::byte*>(data), len); + try { + hmac_->update(static_cast<const Botan::byte*>(data), len); + } catch (const Botan::Exception& exc) { + isc_throw(isc::cryptolink::LibraryError, exc.what()); + } } void sign(isc::dns::OutputBuffer& result, size_t len) { - Botan::SecureVector<Botan::byte> b_result(hmac_->final()); - - if (len == 0 || len > b_result.size()) { - len = b_result.size(); + try { + Botan::SecureVector<Botan::byte> b_result(hmac_->final()); + + if (len == 0 || len > b_result.size()) { + len = b_result.size(); + } + result.writeData(b_result.begin(), len); + } catch (const Botan::Exception& exc) { + isc_throw(isc::cryptolink::LibraryError, exc.what()); } - result.writeData(b_result.begin(), len); } void sign(void* result, size_t len) { - Botan::SecureVector<Botan::byte> b_result(hmac_->final()); - size_t output_size = getOutputLength(); - if (output_size > len) { - output_size = len; + try { + Botan::SecureVector<Botan::byte> b_result(hmac_->final()); + size_t output_size = getOutputLength(); + if (output_size > len) { + output_size = len; + } + memcpy(result, b_result.begin(), output_size); + } catch (const Botan::Exception& exc) { + isc_throw(isc::cryptolink::LibraryError, exc.what()); } - memcpy(result, b_result.begin(), output_size); } std::vector<uint8_t> sign(size_t len) { - Botan::SecureVector<Botan::byte> b_result(hmac_->final()); - if (len == 0 || 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])); + try { + Botan::SecureVector<Botan::byte> b_result(hmac_->final()); + if (len == 0 || 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])); + } + } catch (const Botan::Exception& exc) { + isc_throw(isc::cryptolink::LibraryError, exc.what()); } } @@ -110,13 +130,17 @@ public: // Botan's verify_mac checks if len matches the output_length, // which causes it to fail for truncated signatures, so we do // the check ourselves - Botan::SecureVector<Botan::byte> our_mac = hmac_->final(); - if (len == 0 || len > getOutputLength()) { - len = getOutputLength(); + try { + Botan::SecureVector<Botan::byte> our_mac = hmac_->final(); + if (len == 0 || len > getOutputLength()) { + len = getOutputLength(); + } + return (Botan::same_mem(&our_mac[0], + static_cast<const unsigned char*>(sig), + len)); + } catch (const Botan::Exception& exc) { + isc_throw(isc::cryptolink::LibraryError, exc.what()); } - return (Botan::same_mem(&our_mac[0], - static_cast<const unsigned char*>(sig), - len)); } private: diff --git a/src/lib/cryptolink/crypto_hmac.h b/src/lib/cryptolink/crypto_hmac.h index daf05b012f..57f6626593 100644 --- a/src/lib/cryptolink/crypto_hmac.h +++ b/src/lib/cryptolink/crypto_hmac.h @@ -58,6 +58,8 @@ private: /// \exception UnsupportedAlgorithmException if the given algorithm /// is unknown or not supported by the underlying library /// \exception InvalidKeyLength if the given key secret_len is bad + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library /// /// Notes: if the secret is longer than the block size of its /// algorithm, the constructor will run it through the hash @@ -81,6 +83,9 @@ public: /// \brief Add data to digest /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// /// \param data The data to add /// \param len The size of the data void update(const void* data, const size_t len); @@ -89,6 +94,9 @@ public: /// /// The result will be appended to the given outputbuffer /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// /// \param result The OutputBuffer to append the result to /// \param len The number of bytes from the result to copy. If this /// value is smaller than the algorithms output size, the @@ -102,6 +110,9 @@ public: /// If len is larger than the output size, only output_size bytes /// will be copied. If it is smaller, the output will be truncated /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// /// At least len bytes of data must be available for writing at /// result void sign(void* result, size_t len); @@ -110,6 +121,9 @@ public: /// /// The result will be returned as a std::vector<uint8_t> /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// /// \param len The number of bytes from the result to copy. If this /// value is smaller than the algorithms output size, the /// result will be truncated. If this value is larger, or 0 @@ -119,6 +133,9 @@ public: /// \brief Verify an existing signature /// + /// \exception LibraryError if there was any unexpected exception + /// in the underlying library + /// /// \param sig The signature to verify /// \param len The length of the signature. If this is non-zero, /// and smaller than the output length of the algorithm, @@ -140,6 +157,8 @@ private: /// \exception UnsupportedAlgorithm if the given algorithm is unknown /// or not supported by the underlying library /// \exception BadKey if the given key secret_len is bad +/// \exception LibraryError if there was any unexpected exception +/// in the underlying library /// /// Notes: if the secret is longer than the block size of its /// algorithm, the constructor will run it through the hash @@ -172,6 +191,8 @@ void signHMAC(const void* data, /// \exception UnsupportedAlgorithm if the given algorithm is unknown /// or not supported by the underlying library /// \exception BadKey if the given key secret_len is bad +/// \exception LibraryError if there was any unexpected exception +/// in the underlying library /// /// Notes: if the secret is longer than the block size of its /// algorithm, the constructor will run it through the hash |