Browse Source

[trac781] intermediate checkin

Jelte Jansen 14 years ago
parent
commit
992f3702aa

+ 32 - 0
configure.ac

@@ -374,6 +374,38 @@ if test "$lcov" != "no"; then
 fi
 AC_SUBST(USE_LCOV)
 
+# Check for Botan
+botan_path=""
+AC_ARG_WITH([botan],
+  AC_HELP_STRING([--with-botan=PATH],
+    [specify exact directory of Botan library]),
+    [botan_path="$withval"])
+# If not specificed, try some common paths
+if test -z "$with_botan"; then
+    botandirs="/usr/local /usr/pkg /opt /opt/local /usr"
+    for d in $botandirs
+    do
+        if test -f $d/include/botan/botan.h; then
+            botan_path=$d
+            break
+        fi
+    done
+fi
+if test "${botan_path}" ; then
+    CPPFLAGS="$CPPFLAGS -I${botan_path}/include"
+    LDFLAGS="$LDFLAGS -L${botan_path}/lib -lbotan"
+fi
+AC_CHECK_HEADERS([botan/botan.h],,AC_MSG_ERROR([Missing required header files.]))
+AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM([#include <botan/botan.h>],
+                         [using namespace Botan;
+                          LibraryInitializer::initialize();
+                         ])],
+        [AC_MSG_RESULT([checking for Botan library... yes])],
+        [AC_MSG_RESULT([checking for Botan library... no])
+         AC_MSG_ERROR([Missing Botan library])]
+)
+
 #
 # Configure Boost header path
 #

+ 3 - 2
src/lib/crypto/Makefile.am

@@ -6,6 +6,7 @@ AM_CXXFLAGS = $(B10_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
 
-lib_LTLIBRARIES = libcrypto.la
+lib_LTLIBRARIES = libbcrypto.la
 
-libcrypto_la_SOURCES = crypto.h
+libbcrypto_la_SOURCES = crypto.h crypto.cc
+libbcrypto_la_SOURCES += crypto_botan.h crypto_botan.cc

+ 113 - 2
src/lib/crypto/crypto.cc

@@ -14,12 +14,123 @@
 
 #include "crypto.h"
 
+#include <iostream>
+#include <iomanip>
+
+#include "crypto_botan.h"
+#include <botan/botan.h>
+#include <botan/hmac.h>
+#include <botan/types.h>
+
+#include <dns/buffer.h>
+#include <dns/name.h>
+#include <string>
+
+using namespace Botan;
+using namespace std;
+using namespace isc::dns;
+
 namespace isc {
 namespace crypto {
 
-void
-init() {
+class TSIGKeyImpl {
+public:
+    TSIGKeyImpl(const std::string& str) {
+        (void) str;
+        name_ = new Name("");
+        secret_ = NULL;
+        secret_length_ = 0;
+    };
+
+    TSIGKeyImpl(const isc::dns::Name& name, TSIGKey::algorithms alg,
+                const char* secret, size_t secret_length) :
+                    name_(new Name(name)), algorithm_(alg),
+                    secret_length_(secret_length)
+    {
+        secret_ = (char*)malloc(secret_length_);
+        memcpy(secret_, secret, secret_length_);
+    }
+    ~TSIGKeyImpl() { delete secret_; delete name_; };
+
+    TSIGKey::algorithms getAlgorithm() { return algorithm_; }
+    const char* getSecret() const { return secret_; }
+    size_t getSecretLength() const { return secret_length_; }
+    
+private:
+    isc::dns::Name* name_;
+    TSIGKey::algorithms algorithm_;
+    char* secret_;
+    size_t secret_length_;
+};
+
+TSIGKey::TSIGKey(const std::string& str) {
+    impl_ = new TSIGKeyImpl(str);
+}
+
+TSIGKey::algorithms
+TSIGKey::getAlgorithm() {
+    return impl_->getAlgorithm();
+}
+
+const char*
+TSIGKey::getSecret() {
+    return impl_->getSecret();
+}
+
+size_t
+TSIGKey::getSecretLength() {
+    return impl_->getSecretLength();
 }
 
 } // namespace crypto
 } // namespace isc
+
+void doHMAC(const OutputBuffer& data, char* key, isc::dns::OutputBuffer& result) {
+
+    // needs to be in global scope; can we make a generalized
+    // subclassable singleton? (for hsm we'll need more initialization)
+    LibraryInitializer init;
+
+    // not used here, but we'd need a ctx
+
+    // should get algorithm from key, then 'translate' to Botan-specific algo
+    HashFunction* hash = get_hash("SHA-256");
+    HMAC::HMAC hmac(hash);
+
+    // update the data from whatever we get (probably as a buffer)
+    hmac.update(reinterpret_cast<const byte*>(data.getData()), data.getLength());
+
+    // Take the 'secret' from the key
+    hmac.set_key(reinterpret_cast<byte*>(key), 3);
+
+    // And generate the mac
+    SecureVector<byte> b_result(hmac.final());
+
+    // just some debug
+    for(byte* i = b_result.begin(); i != b_result.end(); ++i) {
+        std::cout << hex << setfill('0') << setw(2) << nouppercase << (unsigned int)(*i);
+    }
+    std::cout << std::endl;
+
+    // write mac to result
+    result.writeData(b_result.begin(), b_result.size());
+
+    std::cout << "HMAC SIG LEN: " << b_result.size() << std::endl;
+    std::cout << "HMAC SIG LEN2: " << result.getLength() << std::endl;
+}
+
+bool verifyHMAC(const OutputBuffer& data, char* key, const isc::dns::OutputBuffer& result) {
+    HashFunction* hash = get_hash("SHA-256");
+    HMAC::HMAC hmac(hash);
+    hmac.update(reinterpret_cast<const byte*>(data.getData()), data.getLength());
+    hmac.set_key(reinterpret_cast<byte*>(key), 3);
+
+    SecureVector<byte> b_result(hmac.final());
+    for(byte* i = b_result.begin(); i != b_result.end(); ++i) {
+        std::cout << hex << setfill('0') << setw(2) << nouppercase << (unsigned int)(*i);
+    }
+    std::cout << std::endl;
+
+    std::cout << "HMAC SIG LEN3: " << result.getLength() << std::endl;
+    return hmac.verify_mac(reinterpret_cast<const byte*>(result.getData()), result.getLength());
+}

+ 52 - 1
src/lib/crypto/crypto.h

@@ -12,13 +12,64 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
+// This is an abstraction layer from an actual crypto implementation
+// The abstraction works as follows; we provide abstract base classes,
+// one general one for the entire library, one for a per-operation
+// context, and one for 'keys', in all their forms as we need them
+// for BIND10.
+// Any implementation (we currently use Botan as a backend), should
+// subclass all of these, and provide the necessary translations
+// between our calls and the underlying library. This also includes
+// translating between 'real' algorithm identifiers and ours.
+//
+// For future expansion, we may need to introduce a fourth type; sessions
+//
+
+#include <string>
+#include <dns/buffer.h>
+
 #ifndef _ISC_CRYPTO_H
 #define _ISC_CRYPTO_H
 
+void doHMAC(const isc::dns::OutputBuffer& data, char* key, isc::dns::OutputBuffer& result);
+bool verifyHMAC(const isc::dns::OutputBuffer& data, char* key, const isc::dns::OutputBuffer& mac);
+
 namespace isc {
 namespace crypto {
 
-void init();
+class Crypto {
+    static Crypto& getInstance();
+    virtual void init() = 0;
+    virtual void cleanup() = 0;
+};
+
+class TSIGKeyImpl;
+
+class TSIGKey {
+public:
+    enum algorithms {
+        TSIG_HMAC_MD5 = 1,
+        TSIG_HMAC_SHA256 = 2
+    };
+
+    TSIGKey(const std::string& str);
+    ~TSIGKey();
+    algorithms getAlgorithm();
+    const char* getSecret();
+    size_t getSecretLength();
+    
+private:
+    TSIGKeyImpl* impl_;
+};
+
+class Context {
+    virtual ~Context();
+    
+    virtual void update(void *data, size_t length) = 0;
+    virtual void signTSIG(void *result, TSIGKey* key) = 0;
+    virtual void verifyTSIG(void *signature, TSIGKey* key) = 0;
+    virtual void digest(void *result) = 0;
+};
 
 } // namespace crypto
 } // namespace isc

+ 16 - 0
src/lib/crypto/crypto_botan.cc

@@ -0,0 +1,16 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+// TMP!!!
+// Just do a full HMAC digestion to get an overview of what we need

+ 35 - 0
src/lib/crypto/crypto_botan.h

@@ -0,0 +1,35 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef _CRYPTO_CRYPTO_BOTAN_H
+#define _CRYPTO_CRYPTO_BOTAN_H
+
+#include <crypto/crypto.h>
+#include <dns/buffer.h>
+
+
+namespace isc {
+namespace crypto {
+
+class CryptoBotan : public Crypto {
+    void init() {};
+    void cleanup() {};
+};
+
+
+
+} // namespace crypto
+} // namespace isc
+
+#endif // _CRYPTO_CRYPTO_BOTAN_H

+ 3 - 0
src/lib/crypto/tests/Makefile.am

@@ -14,9 +14,12 @@ TESTS =
 if HAVE_GTEST
 TESTS += run_unittests
 run_unittests_SOURCES = run_unittests.cc
+run_unittests_SOURCES += crypto_unittests.cc
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
 run_unittests_LDADD = $(GTEST_LDADD)
+run_unittests_LDADD += $(top_builddir)/src/lib/crypto/libbcrypto.la
+run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
 run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
 endif
 

+ 33 - 0
src/lib/crypto/tests/crypto_unittests.cc

@@ -0,0 +1,33 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <gtest/gtest.h>
+
+#include <crypto/crypto.h>
+#include <crypto/crypto_botan.h>
+#include <dns/buffer.h>
+
+TEST(CryptoTest, HMAC_SIGN) {
+    char data_b[] = { 0xff, 0x21, 0x56 };
+    isc::dns::OutputBuffer data(3);
+    data.writeData(data_b, 3);
+    char key[] = { 0x02, 0x03, 0x04 };
+    isc::dns::OutputBuffer hmac_sig(1);
+    
+
+    doHMAC(data, key, hmac_sig);
+    bool result = verifyHMAC(data, key, hmac_sig);
+    EXPECT_TRUE(result);
+}