Browse Source

[trac781] catch all (unexpected) Botan errors and rethrow them as LibraryError

Jelte Jansen 14 years ago
parent
commit
246e56b3bb
3 changed files with 80 additions and 22 deletions
  1. 13 0
      src/lib/cryptolink/crypto.h
  2. 46 22
      src/lib/cryptolink/crypto_hmac.cc
  3. 21 0
      src/lib/cryptolink/crypto_hmac.h

+ 13 - 0
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

+ 46 - 22
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:

+ 21 - 0
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