From 224778b0d628a37d93fa7ff57f1982f1e4fd9b32 Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Wed, 26 Jan 2011 21:01:22 +0000 Subject: [PATCH] finish up support for GOST, including DS with digest type=3, plus abstract out relevant hashes to the signer objects. Plus update the formatting of the Russian anthem in botan19signers.cc ;-) git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1913 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/botan19signers.cc | 34 ++++++++++++++++++++++++++- pdns/dnssecinfra.cc | 51 ++++++++++++++-------------------------- pdns/dnssecinfra.hh | 1 + pdns/pdnssec.cc | 3 ++- pdns/polarrsakeyinfra.cc | 34 ++++++++++++++++++++++++--- 5 files changed, 84 insertions(+), 39 deletions(-) diff --git a/pdns/botan19signers.cc b/pdns/botan19signers.cc index e812cb588a..7b22d05af0 100644 --- a/pdns/botan19signers.cc +++ b/pdns/botan19signers.cc @@ -1,6 +1,10 @@ +// utf-8 UTF-8 utf8 UTF8 #include #include #include +#include +#include +#include #include #include #include "dnssecinfra.hh" @@ -11,7 +15,7 @@ using namespace Botan; (Gosudarstvenny Gimn Rossiyskoy Federatsii) "The National Anthem of the Russian Federation" - ~ Rossiya - svyashchennaya nasha derzhava, ~ + ~ Rossiya - svyashchennaya nasha derzhava, ~ ~ Rossiya - lyubimaya nasha strana. ~ ~ Moguchaya volya, velikaya slava - ~ ~ Tvoyo dostoyanye na vse vremena! ~ @@ -24,6 +28,7 @@ public: std::string convertToISC(unsigned int algorithm) const; std::string getPubKeyHash() const; std::string sign(const std::string& hash) const; + std::string hash(const std::string& hash) const; bool verify(const std::string& hash, const std::string& signature) const; std::string getPublicKeyString() const; int getBits() const; @@ -183,6 +188,16 @@ std::string GOSTDNSPrivateKey::sign(const std::string& hash) const return string((const char*)signature.begin(), (const char*) signature.end()); } +std::string GOSTDNSPrivateKey::hash(const std::string& orig) const +{ + SecureVector result; + + GOST_34_11 hasher; + result= hasher.process(orig); + + return string((const char*)result.begin(), (const char*) result.end()); +} + bool GOSTDNSPrivateKey::verify(const std::string& hash, const std::string& signature) const { GOST_3410_Verification_Operation ops(*d_key); @@ -206,6 +221,7 @@ public: std::string convertToISC(unsigned int algorithm) const; std::string getPubKeyHash() const; std::string sign(const std::string& hash) const; + std::string hash(const std::string& hash) const; bool verify(const std::string& hash, const std::string& signature) const; std::string getPublicKeyString() const; int getBits() const; @@ -343,6 +359,22 @@ std::string ECDSADNSPrivateKey::sign(const std::string& hash) const return string((const char*)signature.begin(), (const char*) signature.end()); } +std::string ECDSADNSPrivateKey::hash(const std::string& orig) const +{ + SecureVector result; + if(getBits() == 256) { // SHA256 + SHA_256 hasher; + result= hasher.process(orig); + } + else { // SHA384 + SHA_384 hasher; + result = hasher.process(orig); + } + + return string((const char*)result.begin(), (const char*) result.end()); +} + + bool ECDSADNSPrivateKey::verify(const std::string& hash, const std::string& signature) const { ECDSA_Verification_Operation ops(*d_key); diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index 0110508c74..7469607246 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -9,10 +9,7 @@ #include #include "dnssecinfra.hh" #include "dnsseckeeper.hh" - -#include -#include -#include +#include "polarssl/sha1.h" #include // for 'operator+=()' #include @@ -121,29 +118,8 @@ string getHashForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, toHash.append(rdata); } - // algorithm 12 needs special GOST hash - - if(rrc.d_algorithm <= 7 ) { // RSASHA1 - unsigned char hash[20]; - sha1((unsigned char*)toHash.c_str(), toHash.length(), hash); - return string((char*)hash, sizeof(hash)); - } else if(rrc.d_algorithm == 8 || rrc.d_algorithm == 13) { // RSASHA256 or ECDSAP256 - unsigned char hash[32]; - sha2((unsigned char*)toHash.c_str(), toHash.length(), hash, 0); - return string((char*)hash, sizeof(hash)); - } else if(rrc.d_algorithm == 10) { // RSASHA512 - unsigned char hash[64]; - sha4((unsigned char*)toHash.c_str(), toHash.length(), hash, 0); - return string((char*)hash, sizeof(hash)); - } else if(rrc.d_algorithm == 14) { // ECDSAP384 - unsigned char hash[48]; - sha4((unsigned char*)toHash.c_str(), toHash.length(), hash, 1); // == 384 - return string((char*)hash, sizeof(hash)); - } - else { - cerr<<"No idea how to hash for algorithm "<<(int)rrc.d_algorithm< dpk(DNSPrivateKey::make(rrc.d_algorithm)); + return dpk->hash(toHash); } DSRecordContent makeDSFromDNSKey(const std::string& qname, const DNSKEYRecordContent& drc, int digest) @@ -152,17 +128,24 @@ DSRecordContent makeDSFromDNSKey(const std::string& qname, const DNSKEYRecordCon toHash.assign(toLower(simpleCompress(qname))); toHash.append(const_cast(drc).serialize("", true, true)); - unsigned char hash[32]; - if(digest==1) - sha1((unsigned char*)toHash.c_str(), toHash.length(), hash); - else - sha2((unsigned char*)toHash.c_str(), toHash.length(), hash, 0); - + DSRecordContent dsrc; + if(digest==1) { + shared_ptr dpk(DNSPrivateKey::make(5)); // gives us SHA1 + dsrc.d_digest = dpk->hash(toHash); + } + else if(digest == 2) { + shared_ptr dpk(DNSPrivateKey::make(8)); // gives us SHA256 + dsrc.d_digest = dpk->hash(toHash); + } + else if(digest == 3) { + shared_ptr dpk(DNSPrivateKey::make(12)); // gives us GOST + dsrc.d_digest = dpk->hash(toHash); + } + dsrc.d_algorithm= drc.d_algorithm; dsrc.d_digesttype=digest; dsrc.d_tag=const_cast(drc).getTag(); - dsrc.d_digest.assign((const char*)hash, digest == 1 ? 20 : 32); return dsrc; } diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index 57914e5421..4ff91296eb 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -14,6 +14,7 @@ class DNSPrivateKey virtual std::string convertToISC(unsigned int algorithm) const =0; virtual std::string getPubKeyHash()const =0; virtual std::string sign(const std::string& hash) const =0; + virtual std::string hash(const std::string& hash) const =0; virtual std::string getPublicKeyString()const =0; virtual int getBits() const =0; diff --git a/pdns/pdnssec.cc b/pdns/pdnssec.cc index 30a507352d..cf2b8e5278 100644 --- a/pdns/pdnssec.cc +++ b/pdns/pdnssec.cc @@ -206,7 +206,8 @@ void showZone(DNSSECKeeper& dk, const std::string& zone) if(value.second.keyOrZone) { cout<<"KSK DNSKEY = "< #include #include +#include #include #include // for 'operator+=()' #include @@ -15,7 +16,7 @@ using namespace boost::assign; class RSADNSPrivateKey : public DNSPrivateKey { public: - RSADNSPrivateKey() + explicit RSADNSPrivateKey(unsigned int algorithm) : d_algorithm(algorithm) { memset(&d_context, 0, sizeof(d_context)); PDNSSEC_MI(N); @@ -36,6 +37,8 @@ public: RSADNSPrivateKey(const RSADNSPrivateKey& orig) { + d_algorithm = orig.d_algorithm; + d_context.ver = orig.d_context.ver; d_context.len = orig.d_context.len; @@ -50,6 +53,8 @@ public: RSADNSPrivateKey& operator=(const RSADNSPrivateKey& orig) { + d_algorithm = orig.d_algorithm; + d_context.ver = orig.d_context.ver; d_context.len = orig.d_context.len; @@ -80,6 +85,7 @@ public: std::string convertToISC(unsigned int algorithm) const; std::string getPubKeyHash() const; std::string sign(const std::string& hash) const; + std::string hash(const std::string& hash) const; std::string getPublicKeyString() const; int getBits() const { @@ -88,13 +94,14 @@ public: void fromISCString(DNSKEYRecordContent& drc, const std::string& content); void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw); - static DNSPrivateKey* maker(unsigned int) + static DNSPrivateKey* maker(unsigned int algorithm) { - return new RSADNSPrivateKey(); + return new RSADNSPrivateKey(algorithm); } private: rsa_context d_context; + unsigned int d_algorithm; }; // see above @@ -159,6 +166,27 @@ std::string RSADNSPrivateKey::sign(const std::string& hash) const return string((char*) signature, sizeof(signature)); } +std::string RSADNSPrivateKey::hash(const std::string& toHash) const +{ + if(d_algorithm <= 7 ) { // RSASHA1 + unsigned char hash[20]; + sha1((unsigned char*)toHash.c_str(), toHash.length(), hash); + return string((char*)hash, sizeof(hash)); + } + else if(d_algorithm == 8) { // RSASHA256 + unsigned char hash[32]; + sha2((unsigned char*)toHash.c_str(), toHash.length(), hash, 0); + return string((char*)hash, sizeof(hash)); + } + else if(d_algorithm == 10) { // RSASHA512 + unsigned char hash[64]; + sha4((unsigned char*)toHash.c_str(), toHash.length(), hash, 0); + return string((char*)hash, sizeof(hash)); + } + throw runtime_error("PolarSSL hashing method can't hash algorithm "+lexical_cast(d_algorithm)); +} + + std::string RSADNSPrivateKey::convertToISC(unsigned int algorithm) const { string ret; -- 2.47.3