]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
ed25519 implementation is now in line with draft-sury-dnskey-ed25519-00 https://datat...
authorKees Monshouwer <mind04@monshouwer.org>
Fri, 31 Jul 2015 00:57:15 +0000 (02:57 +0200)
committermind04 <mind04@monshouwer.org>
Sat, 8 Aug 2015 12:31:00 +0000 (14:31 +0200)
pdns/dbdnsseckeeper.cc
pdns/dnssecinfra.cc
pdns/ed25519signers.cc
pdns/pdnssec.cc

index 615f2cf333b2ddb438d5e617b07e0b1ac980c0cf..591208575040da4069d096b0175244d5f79cb067 100644 (file)
@@ -80,9 +80,9 @@ bool DNSSECKeeper::addKey(const DNSName& name, bool keyOrZone, int algorithm, in
     if(algorithm <= 10)
       bits = keyOrZone ? 2048 : 1024;
     else {
-      if(algorithm == 12 || algorithm == 13 || algorithm == 250) // ECDSA, GOST, ED25519
+      if(algorithm == 12 || algorithm == 13 || algorithm == 250) // GOST, ECDSAP256SHA256, ED25519SHA512
         bits = 256;
-      else if(algorithm == 14)
+      else if(algorithm == 14) // ECDSAP384SHA384
         bits = 384;
       else {
         throw runtime_error("Can't guess key size for algorithm "+lexical_cast<string>(algorithm));
index 5db7895ebb15d4d6b1c1e09d3209d5284a0f3f10..6262b82fcd62074b7f2f05c11969747d72ebd8c5 100644 (file)
@@ -187,11 +187,13 @@ pair<unsigned int, unsigned int> DNSCryptoKeyEngine::testMakers(unsigned int alg
   unsigned int bits;
   if(algo <= 10)
     bits=1024;
-  else if(algo == 12 || algo == 13 || algo == 250) // GOST or nistp256 or ED25519
+  else if(algo == 12 || algo == 13 || algo == 250) // ECC-GOST or ECDSAP256SHA256 or ED25519SHA512
     bits=256;
-  else 
-    bits=384;
-    
+  else if(algo == 14) // ECDSAP384SHA384
+    bits = 384;
+  else
+    throw runtime_error("Can't guess key size for algorithm "+lexical_cast<string>(algo));
+
   dckeCreate->create(bits);
 
   { // FIXME: this block copy/pasted from makeFromISCString
index 176bbeb0ee7f7b89490680789cf00c7a9b30c72c..e4208b6fe4f010ad4edd95e05fdae0ee3f723b1c 100644 (file)
@@ -4,11 +4,14 @@ extern "C" {
 #include "config.h"
 #endif
 #include "ext/ed25519/crypto_sign.h"
+#include "ext/ed25519/crypto_hash_sha512.h"
 }
 #include "dnssecinfra.hh"
 #include <boost/scoped_ptr.hpp>
 using boost::scoped_ptr;
 
+#define SECRETBYTES SECRETKEYBYTES-PUBLICKEYBYTES
+
 class ED25519DNSCryptoKeyEngine : public DNSCryptoKeyEngine
 {
 public:
@@ -34,7 +37,6 @@ public:
   }
 
 private:
-  unsigned int d_algorithm;
   unsigned char d_pubkey[PUBLICKEYBYTES];
   unsigned char d_seckey[SECRETKEYBYTES];
             
@@ -55,30 +57,36 @@ int ED25519DNSCryptoKeyEngine::getBits() const
 
 DNSCryptoKeyEngine::storvector_t ED25519DNSCryptoKeyEngine::convertToISCVector() const
 {
-  /*Algorithm: 13 (ED25519P256SHA256)
-    PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */
+  /*
+    Private-key-format: v1.2
+    Algorithm: 250 (ED25519SHA512)
+    PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=
+  */
+
   storvector_t storvector;
-  string algorithm = "250 (ED25519)";
-  
+  string algorithm = "250 (ED25519SHA512)";
+
   storvector.push_back(make_pair("Algorithm", algorithm));
 
   vector<unsigned char> buffer;
-  storvector.push_back(make_pair("PrivateKey", string((char*)d_seckey, (char*)d_seckey+SECRETKEYBYTES)));
+  storvector.push_back(make_pair("PrivateKey", string((char*)d_seckey, SECRETBYTES)));
   return storvector;
 }
 
 void ED25519DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
 {
-  /*Private-key-format: v1.2
-   Algorithm: 250 (ED25519)
-   PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */
-     
-  d_algorithm = drc.d_algorithm = atoi(stormap["algorithm"].c_str());
+  /*
+    Private-key-format: v1.2
+    Algorithm: 250 (ED25519SHA512)
+    PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ=
+  */
+
+  drc.d_algorithm = atoi(stormap["algorithm"].c_str());
   string privateKey = stormap["privatekey"];
 
-  memcpy(d_seckey, privateKey.c_str(), SECRETKEYBYTES);
-  memcpy(d_pubkey, privateKey.c_str() + PUBLICKEYBYTES, PUBLICKEYBYTES);
-  // need to set d_pubkey too..
+  memcpy(d_seckey, privateKey.c_str(), SECRETBYTES);
+  crypto_sign_publickey(d_pubkey, d_seckey, d_seckey);
+  //memcpy(d_pubkey, privateKey.c_str() + SECRETBYTES, PUBLICKEYBYTES);
 }
 
 // used for the cache, nothing external
@@ -99,32 +107,33 @@ void ED25519DNSCryptoKeyEngine::fromPublicKeyString(const std::string&input)
 
 std::string ED25519DNSCryptoKeyEngine::sign(const std::string& msg) const
 {
-  // full signature, including us making the hash from the message
-  unsigned long long smlen = msg.length() + SIGNATUREBYTES;
-  scoped_ptr<unsigned char> sm(new unsigned char[smlen]);  
+  string hash=this->hash(msg);
+  unsigned long long smlen = hash.length() + SIGNATUREBYTES;
+
+  scoped_ptr<unsigned char> sm(new unsigned char[smlen]);
+  crypto_sign(sm.get(), &smlen, (const unsigned char*)hash.c_str(), hash.length(), d_seckey);
 
-  crypto_sign(sm.get(), &smlen, (const unsigned char*)msg.c_str(), msg.length(), d_seckey);
-  
   return string((const char*)sm.get(), SIGNATUREBYTES);
 }
 
 std::string ED25519DNSCryptoKeyEngine::hash(const std::string& orig) const
 {
-  throw runtime_error("hash not implemented");
-  return ""; // probably SHA512 for ED25519
+  unsigned char out[crypto_hash_sha512_BYTES];
+  crypto_hash_sha512(out, (const unsigned char*)orig.c_str(), orig.length());
+
+  return string((char*)out, crypto_hash_sha512_BYTES);
 }
 
 bool ED25519DNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const
 {
-  // we have to do the hash too
-  // full signature, including us making the hash from the message
-  unsigned long long smlen = msg.length() + SIGNATUREBYTES;
-  scoped_ptr<unsigned char> sm(new unsigned char[smlen]);  
+  string hash=this->hash(msg);
+  unsigned long long smlen = hash.length() + SIGNATUREBYTES;
 
+  scoped_ptr<unsigned char> sm(new unsigned char[smlen]);
   memcpy(sm.get(), signature.c_str(), SIGNATUREBYTES);
-  memcpy(sm.get() + SIGNATUREBYTES, msg.c_str(), msg.length());
-  
-  scoped_ptr<unsigned char> m(new unsigned char[smlen]);   
+  memcpy(sm.get() + SIGNATUREBYTES, hash.c_str(), hash.length());
+
+  scoped_ptr<unsigned char> m(new unsigned char[smlen]);
 
   return crypto_sign_open(m.get(), &smlen, sm.get(), smlen, d_pubkey) == 0;
 }
index b619701a46c90f5cf05847a0a21c2da46ae7f835..88c5b91190d06770e6131581761778083e8a89fd 100644 (file)
@@ -82,6 +82,8 @@ static void algorithm2name(uint8_t algo, string &name) {
            name = "ECDSAP256SHA256"; return;
         case 14:
            name = "ECDSAP384SHA384"; return;
+        case 250:
+           name = "ED25519SHA512"; return;
         case 252:
            name = "INDIRECT"; return;
         case 253:
@@ -1279,7 +1281,7 @@ try
     cerr<<"                                   Enable TSIG key for a zone"<<endl;
     cerr<<"activate-zone-key ZONE KEY-ID      Activate the key with key id KEY-ID in ZONE"<<endl;
     cerr<<"add-zone-key ZONE zsk|ksk [bits] [active|passive]"<<endl;
-    cerr<<"             [rsasha1|rsasha256|rsasha512|gost|ecdsa256|ecdsa384]"<<endl;
+    cerr<<"             [rsasha1|rsasha256|rsasha512|gost|ecdsa256|ecdsa384|ed25519]"<<endl;
     cerr<<"                                   Add a ZSK or KSK to zone and specify algo&bits"<<endl;
     cerr<<"backend-cmd BACKEND CMD [CMD..]    Perform one or more backend commands"<<endl;
     cerr<<"b2b-migrate old new                Move all data from one backend to another"<<endl;