Browse Source

[trac781] use existing tsig key

Jelte Jansen 14 years ago
parent
commit
e29c4f167f
3 changed files with 94 additions and 29 deletions
  1. 64 9
      src/lib/crypto/crypto.cc
  2. 8 13
      src/lib/crypto/crypto.h
  3. 22 7
      src/lib/crypto/tests/crypto_unittests.cc

+ 64 - 9
src/lib/crypto/crypto.cc

@@ -24,6 +24,9 @@
 
 
 #include <dns/buffer.h>
 #include <dns/buffer.h>
 #include <dns/name.h>
 #include <dns/name.h>
+#include <dns/tsigkey.h>
+#include <dns/util/base64.h>
+
 #include <string>
 #include <string>
 
 
 using namespace Botan;
 using namespace Botan;
@@ -33,6 +36,7 @@ using namespace isc::dns;
 namespace isc {
 namespace isc {
 namespace crypto {
 namespace crypto {
 
 
+/*
 class TSIGKeyImpl {
 class TSIGKeyImpl {
 public:
 public:
     TSIGKeyImpl(const std::string& str) {
     TSIGKeyImpl(const std::string& str) {
@@ -81,11 +85,9 @@ size_t
 TSIGKey::getSecretLength() {
 TSIGKey::getSecretLength() {
     return impl_->getSecretLength();
     return impl_->getSecretLength();
 }
 }
+*/
 
 
-} // namespace crypto
-} // namespace isc
-
-void doHMAC(const OutputBuffer& data, char* key, isc::dns::OutputBuffer& result) {
+void doHMAC(const OutputBuffer& data, char* key, size_t key_len, isc::dns::OutputBuffer& result) {
 
 
     // needs to be in global scope; can we make a generalized
     // needs to be in global scope; can we make a generalized
     // subclassable singleton? (for hsm we'll need more initialization)
     // subclassable singleton? (for hsm we'll need more initialization)
@@ -94,14 +96,14 @@ void doHMAC(const OutputBuffer& data, char* key, isc::dns::OutputBuffer& result)
     // not used here, but we'd need a ctx
     // not used here, but we'd need a ctx
 
 
     // should get algorithm from key, then 'translate' to Botan-specific algo
     // should get algorithm from key, then 'translate' to Botan-specific algo
-    HashFunction* hash = get_hash("SHA-256");
+    HashFunction* hash = get_hash("MD5");
     HMAC::HMAC hmac(hash);
     HMAC::HMAC hmac(hash);
 
 
     // update the data from whatever we get (probably as a buffer)
     // update the data from whatever we get (probably as a buffer)
     hmac.update(reinterpret_cast<const byte*>(data.getData()), data.getLength());
     hmac.update(reinterpret_cast<const byte*>(data.getData()), data.getLength());
 
 
     // Take the 'secret' from the key
     // Take the 'secret' from the key
-    hmac.set_key(reinterpret_cast<byte*>(key), 3);
+    hmac.set_key(reinterpret_cast<byte*>(key), key_len);
 
 
     // And generate the mac
     // And generate the mac
     SecureVector<byte> b_result(hmac.final());
     SecureVector<byte> b_result(hmac.final());
@@ -119,11 +121,11 @@ void doHMAC(const OutputBuffer& data, char* key, isc::dns::OutputBuffer& result)
     std::cout << "HMAC SIG LEN2: " << result.getLength() << 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");
+bool verifyHMAC(const OutputBuffer& data, char* key, size_t key_len, const isc::dns::OutputBuffer& result) {
+    HashFunction* hash = get_hash("MD5");
     HMAC::HMAC hmac(hash);
     HMAC::HMAC hmac(hash);
     hmac.update(reinterpret_cast<const byte*>(data.getData()), data.getLength());
     hmac.update(reinterpret_cast<const byte*>(data.getData()), data.getLength());
-    hmac.set_key(reinterpret_cast<byte*>(key), 3);
+    hmac.set_key(reinterpret_cast<byte*>(key), key_len);
 
 
     SecureVector<byte> b_result(hmac.final());
     SecureVector<byte> b_result(hmac.final());
     for(byte* i = b_result.begin(); i != b_result.end(); ++i) {
     for(byte* i = b_result.begin(); i != b_result.end(); ++i) {
@@ -134,3 +136,56 @@ bool verifyHMAC(const OutputBuffer& data, char* key, const isc::dns::OutputBuffe
     std::cout << "HMAC SIG LEN3: " << result.getLength() << std::endl;
     std::cout << "HMAC SIG LEN3: " << result.getLength() << std::endl;
     return hmac.verify_mac(reinterpret_cast<const byte*>(result.getData()), result.getLength());
     return hmac.verify_mac(reinterpret_cast<const byte*>(result.getData()), result.getLength());
 }
 }
+
+isc::dns::TSIGKey
+TSIGKeyFromString(const std::string& str) {
+	std::cout << "[XX] key string: " << str << std::endl;
+	size_t pos = str.find(':');
+	if (pos == 0 || pos == str.npos) {
+		// error, TODO: raise
+		std::cout << "[XX] error bad key string" << std::endl;
+		isc_throw(InvalidParameter, "Invalid TSIG key string");
+	}
+	Name key_name(str.substr(0, pos));
+	
+	Name algo_name("hmac-md5.sig-alg.reg.int");
+	
+	// optional algorithm part
+	size_t pos2 = str.find(':', pos+1);
+	if (pos2 != str.npos) {
+		algo_name = Name(str.substr(pos2+1));
+		//pos2 = str.size() - pos - pos2;
+	} else {
+		pos2 = str.size() - pos;
+	}
+	
+	std::string secret_str = str.substr(pos + 1, pos2 - pos - 1);
+
+	std::cout << "[XX] KEY NAME: " << key_name << std::endl;
+	std::cout << "[XX] KEY ALGO: " << algo_name << std::endl;
+	std::cout << "[XX] SECRET:   " << secret_str << std::endl;
+	vector<uint8_t> secret;
+	decodeBase64(secret_str, secret);
+	unsigned char secret_b[secret.size()];
+	for (size_t i=0; i < secret.size(); ++i) {
+		secret_b[i] = secret[i];
+	}
+	return isc::dns::TSIGKey(key_name, algo_name, secret_b, secret.size());
+}
+
+std::string
+TSIGKeyToString(const isc::dns::TSIGKey& key) {
+	const uint8_t* secret_b = static_cast<const uint8_t*>(key.getSecret());
+	vector<uint8_t> secret_v;
+	for (size_t i=0; i < key.getSecretLength(); ++i) {
+		secret_v.push_back(secret_b[i]);
+	}
+	std::string secret_str = encodeBase64(secret_v);
+	
+	return key.getKeyName().toText() + ":" + secret_str + ":" + key.getAlgorithmName().toText();
+}
+
+
+} // namespace crypto
+} // namespace isc
+

+ 8 - 13
src/lib/crypto/crypto.h

@@ -27,22 +27,26 @@
 
 
 #include <string>
 #include <string>
 #include <dns/buffer.h>
 #include <dns/buffer.h>
+#include <dns/tsigkey.h>
 
 
 #ifndef _ISC_CRYPTO_H
 #ifndef _ISC_CRYPTO_H
 #define _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 isc {
 namespace crypto {
 namespace crypto {
 
 
+void doHMAC(const isc::dns::OutputBuffer& data, char* key, size_t key_len, isc::dns::OutputBuffer& result);
+bool verifyHMAC(const isc::dns::OutputBuffer& data, char* key, size_t key_len, const isc::dns::OutputBuffer& mac);
+isc::dns::TSIGKey TSIGKeyFromString(const std::string& str);
+std::string TSIGKeyToString(const isc::dns::TSIGKey& key);
+
 class Crypto {
 class Crypto {
     static Crypto& getInstance();
     static Crypto& getInstance();
     virtual void init() = 0;
     virtual void init() = 0;
     virtual void cleanup() = 0;
     virtual void cleanup() = 0;
 };
 };
 
 
+/*
 class TSIGKeyImpl;
 class TSIGKeyImpl;
 
 
 class TSIGKey {
 class TSIGKey {
@@ -61,16 +65,7 @@ public:
 private:
 private:
     TSIGKeyImpl* impl_;
     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 crypto
 } // namespace isc
 } // namespace isc
 
 

+ 22 - 7
src/lib/crypto/tests/crypto_unittests.cc

@@ -19,15 +19,30 @@
 #include <crypto/crypto_botan.h>
 #include <crypto/crypto_botan.h>
 #include <dns/buffer.h>
 #include <dns/buffer.h>
 
 
+using namespace isc::dns;
+using namespace isc::crypto;
+
 TEST(CryptoTest, HMAC_SIGN) {
 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);
+    char data_b[] = "Hi there";
+    OutputBuffer data(8);
+    data.writeData(data_b, 8);
+    char key[] = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b  };
+    OutputBuffer hmac_sig(1);
     
     
 
 
-    doHMAC(data, key, hmac_sig);
-    bool result = verifyHMAC(data, key, hmac_sig);
+    doHMAC(data, key, 16, hmac_sig);
+    bool result = verifyHMAC(data, key, 16, hmac_sig);
     EXPECT_TRUE(result);
     EXPECT_TRUE(result);
 }
 }
+
+TEST(CryptoText, TSIGKeyFromString) {
+	TSIGKey k1 = TSIGKeyFromString("test.example:MSG6Ng==:hmac-md5.sig-alg.reg.int");
+	TSIGKeyFromString("test.example.:MSG6Ng==:hmac-md5.sig-alg.reg.int.");
+	TSIGKeyFromString("test.example:MSG6Ng==");
+	//TSIGKeyFromString("test.example:");
+	//TSIGKeyFromString("::");
+	//TSIGKeyFromString("test.example:MSG6Ng==:hmac-md5.sig-alg.reg.int");
+	
+	std::string k1_str = TSIGKeyToString(k1);
+	std::cout << k1_str << std::endl;
+}