BIND 10 trac781, updated. 24aa99548a4164d2c57adcf3829cc50f1fd34de5 [trac781] create hmac class to add update() functionality

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Apr 13 14:14:15 UTC 2011


The branch, trac781 has been updated
       via  24aa99548a4164d2c57adcf3829cc50f1fd34de5 (commit)
      from  aa0ddfbb4f0aa61cfee383f5459c2183b353674b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 24aa99548a4164d2c57adcf3829cc50f1fd34de5
Author: Jelte Jansen <jelte at isc.org>
Date:   Wed Apr 13 16:13:54 2011 +0200

    [trac781] create hmac class to add update() functionality

-----------------------------------------------------------------------

Summary of changes:
 src/lib/crypto/crypto.cc |  139 +++++++++++++++++++++++++++-------------------
 src/lib/crypto/crypto.h  |   13 ++++
 2 files changed, 94 insertions(+), 58 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/crypto/crypto.cc b/src/lib/crypto/crypto.cc
index 8d714ea..1d56d40 100644
--- a/src/lib/crypto/crypto.cc
+++ b/src/lib/crypto/crypto.cc
@@ -29,18 +29,17 @@
 
 #include <string>
 
-using namespace Botan;
 using namespace std;
 using namespace isc::dns;
 
 namespace {
-HashFunction* getHash(const Name& hash_name) {
+Botan::HashFunction* getHash(const Name& hash_name) {
     if (hash_name == TSIGKey::HMACMD5_NAME()) {
-        return get_hash("MD5");
+        return Botan::get_hash("MD5");
     } else if (hash_name == TSIGKey::HMACSHA1_NAME()) {
-        return get_hash("SHA-1");
+        return Botan::get_hash("SHA-1");
     } else if (hash_name == TSIGKey::HMACSHA256_NAME()) {
-        return get_hash("SHA-256");
+        return Botan::get_hash("SHA-256");
     } else {
         isc_throw(isc::crypto::UnsupportedAlgorithm,
                   "Unknown Hash type " + hash_name.toText());
@@ -50,76 +49,100 @@ HashFunction* getHash(const Name& hash_name) {
 // Library needs to have been inited during the entire program
 // should we make this a singleton? (for hsm we'll need more
 // initialization, and dynamic loading)
-LibraryInitializer init;
+Botan::LibraryInitializer init;
 
 } // local namespace
 
 namespace isc {
 namespace crypto {
 
-void
-signHMAC(const OutputBuffer& data, TSIGKey key,
-         isc::dns::OutputBuffer& result)
-{
-    // get algorithm from key, then 'translate' to Botan-specific algo
-    HashFunction* hash = getHash(key.getAlgorithmName());
-    HMAC::HMAC hmac(hash);
-
-    // Take the 'secret' from the key
-    // If the key length is larger than the block size, we hash the
-    // key itself first.
-    try {
-        if (key.getSecretLength() > hash->HASH_BLOCK_SIZE) {
-            SecureVector<byte> hashed_key =
-                hash->process(static_cast<const byte*>(key.getSecret()),
-                              key.getSecretLength());
-            hmac.set_key(hashed_key.begin(), hashed_key.size());
-        } else {
-            hmac.set_key(static_cast<const byte*>(key.getSecret()),
-                         key.getSecretLength());
+class HMACImpl {
+public:
+    explicit HMACImpl(const TSIGKey& key) {
+        Botan::HashFunction* hash = getHash(key.getAlgorithmName());
+        hmac_ = new Botan::HMAC::HMAC(hash);
+
+        // Take the 'secret' from the key
+        // If the key length is larger than the block size, we hash the
+        // key itself first.
+        try {
+            if (key.getSecretLength() > hash->HASH_BLOCK_SIZE) {
+                Botan::SecureVector<Botan::byte> hashed_key =
+                    hash->process(static_cast<const Botan::byte*>(key.getSecret()),
+                                  key.getSecretLength());
+                hmac_->set_key(hashed_key.begin(), hashed_key.size());
+            } else {
+                hmac_->set_key(static_cast<const Botan::byte*>(key.getSecret()),
+                             key.getSecretLength());
+            }
+        } catch (Botan::Invalid_Key_Length ikl) {
+            isc_throw(BadKey, ikl.what());
         }
-    } catch (Invalid_Key_Length ikl) {
-        isc_throw(BadKey, ikl.what());
     }
 
-    // update the data from whatever we get (probably as a buffer)
-    hmac.update(static_cast<const byte*>(data.getData()),
-                data.getLength());
+    ~HMACImpl() { delete hmac_; }
+
+    void update(const void* data, size_t len) {
+        // update the data from whatever we get (probably as a buffer)
+        hmac_->update(static_cast<const Botan::byte*>(data), len);
+    }
+
+    void sign(isc::dns::OutputBuffer& result) {
+        // And generate the mac
+        Botan::SecureVector<Botan::byte> b_result(hmac_->final());
+    
+        // write mac to result
+        result.writeData(b_result.begin(), b_result.size());
+    }
+    
+    bool verify(const void* sig, size_t len) {
+        return hmac_->verify_mac(static_cast<const Botan::byte*>(sig), len);
+    }
+
+private:
+    Botan::HMAC* hmac_;
+};
+
+HMAC::HMAC(const TSIGKey& key) {
+    impl_ = new HMACImpl(key);
+}
 
-    // And generate the mac
-    SecureVector<byte> b_result(hmac.final());
+HMAC::~HMAC() {
+    delete impl_;
+}
 
-    // write mac to result
-    result.writeData(b_result.begin(), b_result.size());
+void
+HMAC::update(const void* data, size_t len) {
+    impl_->update(data, len);
+}
+
+void
+HMAC::sign(isc::dns::OutputBuffer& result) {
+    impl_->sign(result);
 }
 
 bool
-verifyHMAC(const OutputBuffer& data, TSIGKey key,
-           const isc::dns::OutputBuffer& result)
+HMAC::verify(const void* sig, size_t len) {
+    return impl_->verify(sig, len);
+}
+
+void
+signHMAC(const OutputBuffer& data, TSIGKey key,
+         isc::dns::OutputBuffer& result)
 {
-    HashFunction* hash = getHash(key.getAlgorithmName());
-    HMAC::HMAC hmac(hash);
-    // If the key length is larger than the block size, we hash the
-    // key itself first.
-    try {
-        if (key.getSecretLength() > hash->HASH_BLOCK_SIZE) {
-            SecureVector<byte> hashed_key =
-                hash->process(static_cast<const byte*>(key.getSecret()),
-                              key.getSecretLength());
-            hmac.set_key(hashed_key.begin(), hashed_key.size());
-        } else {
-            hmac.set_key(static_cast<const byte*>(key.getSecret()),
-                         key.getSecretLength());
-        }
-    } catch (Invalid_Key_Length ikl) {
-        isc_throw(BadKey, ikl.what());
-    }
+    HMAC hmac(key);
+    hmac.update(data.getData(), data.getLength());
+    hmac.sign(result);
+}
 
-    hmac.update(static_cast<const byte*>(data.getData()),
-                data.getLength());
 
-    return hmac.verify_mac(static_cast<const byte*>(result.getData()),
-                           result.getLength());
+bool
+verifyHMAC(const OutputBuffer& data, TSIGKey key,
+           const isc::dns::OutputBuffer& result)
+{
+    HMAC hmac(key);
+    hmac.update(data.getData(), data.getLength());
+    return hmac.verify(result.getData(), result.getLength());
 }
 
 } // namespace crypto
diff --git a/src/lib/crypto/crypto.h b/src/lib/crypto/crypto.h
index 08e86d2..dffa18f 100644
--- a/src/lib/crypto/crypto.h
+++ b/src/lib/crypto/crypto.h
@@ -60,6 +60,19 @@ public:
         CryptoError(file, line, what) {}
 };
 
+class HMACImpl;
+
+class HMAC {
+public:
+    explicit HMAC(const isc::dns::TSIGKey& key);
+    ~HMAC();
+    void update(const void* data, size_t len);
+    void sign(isc::dns::OutputBuffer& result);
+    bool verify(const void* sig, size_t len);
+private:
+    HMACImpl* impl_;
+};
+
 /// \brief Create an HMAC signature for the given data
 ///
 /// Raises an UnsupportedAlgorithm if we do not support the given




More information about the bind10-changes mailing list