pdns_server_LDADD= -lpolarssl
if BOTAN19
-pdns_server_SOURCES += botan19signers.cc
+pdns_server_SOURCES += botan19signers.cc botansigners.cc
pdns_server_LDADD += -lbotan -lgmp
endif
if BOTAN18
-pdns_server_SOURCES += botan18signers.cc
+pdns_server_SOURCES += botan18signers.cc botansigners.cc
pdns_server_LDADD += -lbotan -lgmp
endif
pdnssec_LDADD= -lpolarssl $(BOOST_PROGRAM_OPTIONS_LIBS)
if BOTAN19
-pdnssec_SOURCES += botan19signers.cc
+pdnssec_SOURCES += botan19signers.cc botansigners.cc
pdnssec_LDADD += -lbotan -lgmp
endif
if BOTAN18
-pdnssec_SOURCES += botan18signers.cc
+pdnssec_SOURCES += botan18signers.cc botansigners.cc
pdnssec_LDADD += -lbotan -lgmp
endif
using namespace Botan;
-//////////////////////////////
-
class ECDSADNSPrivateKey : public DNSPrivateKey
{
public:
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;
+ bool verify(const std::string& msg, const std::string& signature) const;
std::string getPublicKeyString() const;
int getBits() const;
- void fromISCString(DNSKEYRecordContent& drc, const std::string& content);
+ void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
void fromPublicKeyString(unsigned int algorithm, const std::string& content);
void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
{}
}
d_key = shared_ptr<ECDSA_PrivateKey>(new ECDSA_PrivateKey(rng, getECParams((bits == 256) ? 13 : 14)));
-
PKCS8_Encoder* pk8e= d_key->pkcs8_encoder();
MemoryVector<byte> getbits=pk8e->key_bits();
cerr<<makeHexDump(string((char*)&*getbits.begin(), (char*)&*getbits.end()))<<endl;
return ret.str();
}
-void ECDSADNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content )
+void ECDSADNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
{
/*Private-key-format: v1.2
Algorithm: 13 (ECDSAP256SHA256)
PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */
+
+ d_algorithm = drc.d_algorithm = atoi(stormap["algorithm"].c_str());
+ string privateKey = stormap["privatekey"];
- istringstream input(content);
- string sline, key, value, privateKey;
- while(getline(input, sline)) {
- tie(key,value)=splitField(sline, ':');
- trim(value);
- if(pdns_iequals(key,"Private-key-format")) {}
- else if(key=="Algorithm")
- drc.d_algorithm = atoi(value.c_str());
- else if(key=="PrivateKey") {
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(value);
- privateKey=pipe.read_all_as_string();
- }
- else
- throw runtime_error("Unknown field '"+key+"' in Private Key Representation of ECDSA");
- }
- d_algorithm = drc.d_algorithm;
BigInt bigint((byte*)privateKey.c_str(), privateKey.length());
EC_Domain_Params params=getECParams(drc.d_algorithm);
noIdea.append(privateKey);
MemoryVector<byte> tmp((byte*)noIdea.c_str(), noIdea.length());
- cerr<<"key_bits"<<endl;
p8e->key_bits(tmp);
- cerr<<"Done reading"<<endl;
delete p8e;
}
d_key.reset();
}
-
-std::string ECDSADNSPrivateKey::sign(const std::string& hash) const
+std::string ECDSADNSPrivateKey::sign(const std::string& msg) const
{
AutoSeeded_RNG rng;
+ string hash = this->hash(msg);
SecureVector<byte> signature=d_key->sign((byte*)hash.c_str(), hash.length(), rng);
return string((const char*)signature.begin(), (const char*) signature.end());
return string((const char*)result.begin(), (const char*) result.end());
}
-
-bool ECDSADNSPrivateKey::verify(const std::string& hash, const std::string& signature) const
+bool ECDSADNSPrivateKey::verify(const std::string& msg, const std::string& signature) const
{
- ECDSA_PublicKey* key;
- if(d_key)
- key = d_key.get();
- else
- key = d_pubkey.get();
-
+ string hash = this->hash(msg);
+ ECDSA_PublicKey* key = d_key ? d_key.get() : d_pubkey.get();
return key->verify((byte*)hash.c_str(), hash.length(), (byte*)signature.c_str(), signature.length());
}
-
namespace {
struct LoaderStruct
{
bool verify(const std::string& hash, const std::string& signature) const;
std::string getPublicKeyString() const;
int getBits() const;
- void fromISCString(DNSKEYRecordContent& drc, const std::string& content);
+ void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& content);
void fromPublicKeyString(unsigned int algorithm, const std::string& content);
void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
{}
*/
-void GOSTDNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content )
+void GOSTDNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
{
- istringstream input(content);
- string sline, key, value, privateKey;
- while(getline(input, sline)) {
- tie(key,value)=splitField(sline, ':');
- trim(value);
- if(pdns_iequals(key,"Private-key-format")) {}
- else if(key=="Algorithm")
- drc.d_algorithm = atoi(value.c_str());
- else if(key=="GostAsn1") {
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(value);
- privateKey=pipe.read_all_as_string();
- }
- else
- throw runtime_error("Unknown field '"+key+"' in Private Key Representation of GOST");
- }
+ drc.d_algorithm = atoi(stormap["algorithm"].c_str());
+ string privateKey=stormap["gostasn1"];
//cerr<<"PrivateKey.size() = "<<privateKey.size()<<endl;
//cerr<<makeHexDump(string(privateKey.c_str(), 39))<<endl;
string rawKey(privateKey.c_str()+39, privateKey.length()-39);
~ Tak bylo, tak yest' i tak budet vsegda! ~
*/
-std::string GOSTDNSPrivateKey::sign(const std::string& hash) const
+std::string GOSTDNSPrivateKey::sign(const std::string& msg) const
{
GOST_3410_Signature_Operation ops(*d_key);
AutoSeeded_RNG rng;
+
+ string hash= this->hash(msg);
+
SecureVector<byte> signature=ops.sign((byte*)hash.c_str(), hash.length(), rng);
#if BOTAN_VERSION_CODE <= BOTAN_VERSION_CODE_FOR(1,9,12) // see http://bit.ly/gTytUf
}
-bool GOSTDNSPrivateKey::verify(const std::string& hash, const std::string& signature) const
+bool GOSTDNSPrivateKey::verify(const std::string& message, const std::string& signature) const
{
+ string hash = this->hash(message);
GOST_3410_PublicKey* pk;
if(d_pubkey) {
pk =d_pubkey.get();
bool verify(const std::string& hash, const std::string& signature) const;
std::string getPublicKeyString() const;
int getBits() const;
- void fromISCString(DNSKEYRecordContent& drc, const std::string& content);
+ void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
void fromPublicKeyString(unsigned int algorithm, const std::string& content);
void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
{}
return ret.str();
}
-void ECDSADNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content )
+void ECDSADNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap)
{
/*Private-key-format: v1.2
Algorithm: 13 (ECDSAP256SHA256)
PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */
- istringstream input(content);
- string sline, key, value, privateKey;
- while(getline(input, sline)) {
- tie(key,value)=splitField(sline, ':');
- trim(value);
- if(pdns_iequals(key,"Private-key-format")) {}
- else if(key=="Algorithm")
- drc.d_algorithm = atoi(value.c_str());
- else if(key=="PrivateKey") {
- Pipe pipe(new Base64_Decoder);
- pipe.process_msg(value);
- privateKey=pipe.read_all_as_string();
- }
- else
- throw runtime_error("Unknown field '"+key+"' in Private Key Representation of ECDSA");
- }
+ drc.d_algorithm = atoi(stormap["algorithm"].c_str());
+ string privateKey=stormap["privatekey"];
+
d_algorithm = drc.d_algorithm;
BigInt bigint((byte*)privateKey.c_str(), privateKey.length());
EC_Domain_Params params=getECParams(drc.d_algorithm);
d_key=shared_ptr<ECDSA_PrivateKey>(new ECDSA_PrivateKey(params, bigint));
-
}
std::string ECDSADNSPrivateKey::getPubKeyHash() const
}
-std::string ECDSADNSPrivateKey::sign(const std::string& hash) const
+std::string ECDSADNSPrivateKey::sign(const std::string& msg) const
{
+ string hash = this->hash(msg);
ECDSA_Signature_Operation ops(*d_key);
AutoSeeded_RNG rng;
SecureVector<byte> signature=ops.sign((byte*)hash.c_str(), hash.length(), rng);
--- /dev/null
+#include <botan/botan.h>
+#include <botan/sha160.h>
+#include <botan/sha2_32.h>
+#include <botan/sha2_64.h>
+#include <botan/emsa3.h>
+#include <botan/rsa.h>
+#include <botan/pubkey.h>
+#include <botan/look_pk.h>
+#include "dnssecinfra.hh"
+
+using namespace Botan;
+
+class BotanRSADNSPrivateKey : public DNSPrivateKey
+{
+public:
+ explicit BotanRSADNSPrivateKey(unsigned int algo) :d_algorithm(algo)
+ {}
+ void create(unsigned int bits);
+ 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;
+ void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
+ void fromPublicKeyString(unsigned int algorithm, const std::string& content);
+ void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
+ {}
+
+ static DNSPrivateKey* maker(unsigned int algorithm)
+ {
+ return new BotanRSADNSPrivateKey(algorithm);
+ }
+
+private:
+ shared_ptr<RSA_PrivateKey> d_key;
+ shared_ptr<RSA_PublicKey> d_pubkey;
+ unsigned int d_algorithm;
+};
+
+void BotanRSADNSPrivateKey::create(unsigned int bits)
+{
+ AutoSeeded_RNG rng;
+ d_key = shared_ptr<RSA_PrivateKey>(new RSA_PrivateKey(rng, bits));
+}
+
+int BotanRSADNSPrivateKey::getBits() const
+{
+ return d_key->max_input_bits() + 1;
+}
+
+namespace {
+string asBase64(const BigInt& x)
+{
+ SecureVector<byte> buffer=BigInt::encode(x);
+
+ Pipe pipe(new Base64_Encoder);
+ pipe.process_msg(buffer);
+ return pipe.read_all_as_string();
+}
+
+BigInt fromRaw(const std::string& raw)
+{
+ if(raw.empty())
+ throw runtime_error("Unable to decode empty value");
+ return BigInt::decode((byte*)raw.c_str(), raw.length());
+}
+}
+std::string BotanRSADNSPrivateKey::convertToISC(unsigned int algorithm) const
+{
+ ostringstream ret;
+ ret<<"Private-key-format: v1.2\nAlgorithm: "<<d_algorithm;
+ switch(algorithm) {
+ case 5:
+ case 7 :
+ ret << " (RSASHA1)\n";
+ break;
+ case 8:
+ ret << " (RSASHA256)\n";
+ break;
+ default:
+ ret <<" (?)\n";
+ break;
+ }
+
+ ret<<"Modulus: " << asBase64(d_key->get_n())<<endl;
+ ret<<"PublicExponent: " << asBase64(d_key->get_e())<<endl;
+ ret<<"PrivateExponent: " << asBase64(d_key->get_d())<<endl;
+ ret<<"Prime1: " << asBase64(d_key->get_p())<<endl;
+ ret<<"Prime2: " << asBase64(d_key->get_q())<<endl;
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
+ BigInt d1 = d_key->get_d() % (d_key->get_p() - 1);
+ BigInt d2 = d_key->get_d() % (d_key->get_q() - 1);
+#else
+ BigInt d1 = d_key->get_d1();
+ BigInt d2 = d_key->get_d2();
+#endif
+ ret<<"Exponent1: " << asBase64(d1)<<endl;
+ ret<<"Exponent2: " << asBase64(d2)<<endl;
+ ret<<"Coefficient: " << asBase64(d_key->get_q())<<endl;
+ return ret.str();
+}
+
+void BotanRSADNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
+{
+ // wants p (Prime1), q (Prime2), d (PrivateExponent), e (PublicExponent) & n Modulus
+ BigInt n, e, d, p, q;
+
+ p=fromRaw(stormap["prime1"]);
+ q=fromRaw(stormap["prime2"]);
+ d=fromRaw(stormap["privateexponent"]);
+ e=fromRaw(stormap["publicexponent"]);
+ n=fromRaw(stormap["modulus"]);
+
+ d_algorithm = drc.d_algorithm = atoi(stormap["algorithm"].c_str());
+ AutoSeeded_RNG rng;
+ d_key = shared_ptr<RSA_PrivateKey>(new RSA_PrivateKey(rng, p, q, e, d, n));
+ d_pubkey.reset();
+}
+
+std::string BotanRSADNSPrivateKey::getPubKeyHash() const
+{
+ const BigInt& n = d_key->get_n();
+ const BigInt& e = d_key->get_e();
+ SecureVector<byte> buffer=BigInt::encode(n);
+
+ SHA_160 hasher;
+ hasher.update(buffer);
+ buffer=BigInt::encode(e);
+ hasher.update(buffer);
+ SecureVector<byte> hash=hasher.final();
+ return string((const char*)hash.begin(), (const char*)hash.end());
+}
+
+std::string BotanRSADNSPrivateKey::getPublicKeyString() const
+{
+ MemoryVector<byte> bits = BigInt::encode(d_key->get_e());
+ string exponent(&*bits.begin(), &*bits.end());
+ bits = BigInt::encode(d_key->get_n());
+ string modulus(&*bits.begin(), &*bits.end());
+
+ string keystring;
+ if(exponent.length() < 255)
+ keystring.assign(1, (char) (unsigned int) exponent.length());
+ else {
+ keystring.assign(1, 0);
+ uint16_t len=htons(exponent.length());
+ keystring.append((char*)&len, 2);
+ }
+ keystring.append(exponent);
+ keystring.append(modulus);
+ return keystring;
+}
+
+void BotanRSADNSPrivateKey::fromPublicKeyString(unsigned int algorithm, const std::string& rawString)
+{
+ d_algorithm = algorithm;
+ string exponent, modulus;
+ const unsigned char* raw = (const unsigned char*)rawString.c_str();
+
+ if(raw[0] != 0) {
+ exponent=rawString.substr(1, raw[0]);
+ modulus=rawString.substr(raw[0]+1);
+ } else {
+ exponent=rawString.substr(3, raw[1]*0xff + raw[2]);
+ modulus = rawString.substr(3+ raw[1]*0xff + raw[2]);
+ }
+
+ BigInt e = BigInt::decode((const byte*)exponent.c_str(), exponent.length());
+ BigInt n = BigInt::decode((const byte*)modulus.c_str(), modulus.length());
+
+ d_pubkey = shared_ptr<RSA_PublicKey>(new RSA_PublicKey(e,n));
+ d_key.reset();
+}
+
+std::string BotanRSADNSPrivateKey::sign(const std::string& msg) const
+{
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
+ EMSA* emsaptr;
+ if(d_algorithm == 5 || d_algorithm ==7)
+ emsaptr=new EMSA3(new SHA_160);
+ else if(d_algorithm==8)
+ emsaptr=new EMSA3(new SHA_256);
+ else
+ emsaptr=new EMSA3(new SHA_512);
+ PK_Signer pks(*d_key, emsaptr);
+#else
+ string emsa;
+ if(d_algorithm == 5 || d_algorithm ==7)
+ emsa="EMSA3(SHA-160)";
+ else if(d_algorithm==8)
+ emsa="EMSA3(SHA-256)";
+ else
+ emsa="EMSA3(SHA-512)";
+ PK_Signer pks(*d_key, emsa);
+#endif
+
+ AutoSeeded_RNG rng;
+ SecureVector<byte> signature= pks.sign_message((byte*)msg.c_str(), msg.length(), rng);
+ return string((const char*)signature.begin(), (const char*) signature.end());
+}
+
+std::string BotanRSADNSPrivateKey::hash(const std::string& orig) const
+{
+ SecureVector<byte> result;
+ if(d_algorithm == 5 || d_algorithm ==7 ) { // SHA160
+ SHA_160 hasher;
+ result= hasher.process(orig);
+ }
+ if(d_algorithm == 8) { // SHA256
+ SHA_256 hasher;
+ result= hasher.process(orig);
+ }
+ else if(d_algorithm==10) { // SHA512
+ SHA_512 hasher;
+ result = hasher.process(orig);
+ }
+
+ return string((const char*)result.begin(), (const char*) result.end());
+}
+
+
+bool BotanRSADNSPrivateKey::verify(const std::string& msg, const std::string& signature) const
+{
+ RSA_PublicKey* key = d_key ? d_key.get() : d_pubkey.get();
+
+ string emsa;
+
+ if(d_algorithm == 5 || d_algorithm ==7)
+ emsa = "EMSA3(SHA-1)";
+ else if(d_algorithm==8)
+ emsa = "EMSA3(SHA-256)";
+ else
+ emsa = "EMSA3(SHA-512)";
+
+#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
+ std::auto_ptr<PK_Verifier> ver(get_pk_verifier(*key, emsa));
+ return ver->verify_message((byte*)msg.c_str(), msg.length(), (byte*)signature.c_str(), signature.length());
+#else
+ RSA_Public_Operation ops(*key);
+ return ops.verify((byte*)msg.c_str(), msg.length(), (byte*)signature.c_str(), signature.length());
+#endif
+}
+
+namespace {
+struct LoaderStruct
+{
+ LoaderStruct()
+ {
+ Botan::LibraryInitializer init;
+
+ DNSPrivateKey::report(5, &BotanRSADNSPrivateKey::maker);
+ DNSPrivateKey::report(7, &BotanRSADNSPrivateKey::maker);
+ DNSPrivateKey::report(8, &BotanRSADNSPrivateKey::maker);
+ DNSPrivateKey::report(10, &BotanRSADNSPrivateKey::maker);
+ }
+} loader;
+}
+
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002-2009 PowerDNS.COM BV
+ Copyright (C) 2002-2011 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
#include "polarssl/sha1.h"
#include <boost/assign/std/vector.hpp> // for 'operator+=()'
#include <boost/assign/list_inserter.hpp>
+#include "base64.hh"
using namespace boost;
using namespace std;
DNSPrivateKey* DNSPrivateKey::makeFromISCFile(DNSKEYRecordContent& drc, const char* fname)
{
- string sline, isc, key, value;
+ string sline, isc;
FILE *fp=fopen(fname, "r");
if(!fp) {
throw runtime_error("Unable to read file '"+string(fname)+"' for generating DNS Private Key");
}
- int algorithm=0;
+
while(stringfgets(fp, sline)) {
- tie(key,value)=splitField(sline, ':');
- if(pdns_iequals(key,"algorithm"))
- algorithm = atoi(value.c_str());
- isc.append(sline);
+ isc += sline;
}
fclose(fp);
+ return makeFromISCString(drc, isc);
+}
+DNSPrivateKey* DNSPrivateKey::makeFromISCString(DNSKEYRecordContent& drc, const std::string& content)
+{
+ int algorithm = 0;
+ string sline, key, value, raw;
+ istringstream str(content);
+ map<string, string> stormap;
+ while(getline(str, sline)) {
+ tie(key,value)=splitField(sline, ':');
+ trim(value);
+ if(pdns_iequals(key,"algorithm")) {
+ algorithm = atoi(value.c_str());
+ stormap["algorithm"]=lexical_cast<string>(algorithm);
+ continue;
+ }
+ else if(pdns_iequals(key, "Private-key-format"))
+ continue;
+ raw.clear();
+ B64Decode(value, raw);
+ stormap[toLower(key)]=raw;
+ }
DNSPrivateKey* dpk=make(algorithm);
- dpk->fromISCString(drc, isc);
+ dpk->fromISCMap(drc, stormap);
return dpk;
}
+
DNSPrivateKey* DNSPrivateKey::make(unsigned int algo)
{
makers_t& makers = getMakers();
}
}
-void DNSPrivateKey::report(unsigned int algo, maker_t* maker)
+void DNSPrivateKey::report(unsigned int algo, maker_t* maker, bool fallback)
{
- getMakers()[algo]=maker;
-}
-DNSPrivateKey* DNSPrivateKey::makeFromISCString(DNSKEYRecordContent& drc, const std::string& content)
-{
- int algorithm = 0;
- string sline, key, value;
- istringstream str(content);
- while(getline(str, sline)) {
- tie(key,value)=splitField(sline, ':');
- if(pdns_iequals(key,"algorithm")) {
- algorithm = atoi(value.c_str());
- break;
- }
+ if(getMakers().count(algo) && fallback) {
+ return;
}
- DNSPrivateKey* dpk=make(algorithm);
- dpk->fromISCString(drc, content);
- return dpk;
+ getMakers()[algo]=maker;
}
DNSPrivateKey* DNSPrivateKey::makeFromPublicKeyString(unsigned int algorithm, const std::string& content)
return a->serialize("", true, true) < b->serialize("", true, true);
}
-string getHashForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& signRecords)
+string getMessageForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& signRecords)
{
sort(signRecords.begin(), signRecords.end(), sharedDNSSECCompare);
toHash.append(rdata);
}
- shared_ptr<DNSPrivateKey> dpk(DNSPrivateKey::make(rrc.d_algorithm));
- return dpk->hash(toHash);
+ return toHash;
}
DSRecordContent makeDSFromDNSKey(const std::string& qname, const DNSKEYRecordContent& drc, int digest)
virtual std::string getPublicKeyString()const =0;
virtual int getBits() const =0;
- virtual void fromISCString(DNSKEYRecordContent& drc, const std::string& content)=0;
+ virtual void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap)=0;
virtual void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)=0;
virtual void fromPublicKeyString(unsigned algorithm, const std::string& content)
{
typedef DNSPrivateKey* maker_t(unsigned int algorithm);
- static void report(unsigned int algorithm, maker_t* maker);
+ static void report(unsigned int algorithm, maker_t* maker, bool fallback=false);
private:
typedef std::map<unsigned int, maker_t*> makers_t;
};
bool sharedDNSSECCompare(const boost::shared_ptr<DNSRecordContent>& a, const shared_ptr<DNSRecordContent>& b);
-string getHashForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, std::vector<boost::shared_ptr<DNSRecordContent> >& signRecords);
+string getMessageForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, std::vector<boost::shared_ptr<DNSRecordContent> >& signRecords);
DSRecordContent makeDSFromDNSKey(const std::string& qname, const DNSKEYRecordContent& drc, int digest=1);
const DNSPrivateKey* rc = dpk.getKey();
rrc.d_tag = drc.getTag();
rrc.d_algorithm = drc.d_algorithm;
- string realhash=getHashForRRSET(signQName, rrc, toSign); // this is what we sign
- pair<string, string> lookup(rc->getPubKeyHash(), realhash);
+ string msg=getMessageForRRSET(signQName, rrc, toSign); // this is what we will hash & sign
+
+ pair<string, string> lookup(rc->getPubKeyHash(), msg); // we key on the whole message now!
{
Lock l(&g_signatures_lock);
; // cerr<<"Miss!"<<endl;
}
- rrc.d_signature = rc->sign(realhash);
+ //DTime dt;
+ //dt.set();
+ rrc.d_signature = rc->sign(msg);
+ //cerr<<dt.udiff()<<endl;
Lock l(&g_signatures_lock);
g_signatures[lookup] = rrc.d_signature;
/*
PowerDNS Versatile Database Driven Nameserver
- Copyright (C) 2002-2009 PowerDNS.COM BV
+ Copyright (C) 2002-2011 PowerDNS.COM BV
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
}
}
- string hash = getHashForRRSET(qname, rrc, toSign);
+ string msg = getMessageForRRSET(qname, rrc, toSign);
+ DNSPrivateKey* dpk = DNSPrivateKey::make(rrc.d_algorithm);
+ string hash = dpk->sign(msg);
cerr<<"Verify: "<<DNSPrivateKey::makeFromPublicKeyString(drc.d_algorithm, drc.d_key)->verify(hash, rrc.d_signature)<<endl;
if(dsrc.d_digesttype) {
cerr<<"Calculated DS: "<<apex<<" IN DS "<<makeDSFromDNSKey(apex, drc, dsrc.d_digesttype).getZoneRepresentation()<<endl;
{
return mpi_size(&d_context.N)*8;
}
- void fromISCString(DNSKEYRecordContent& drc, const std::string& content);
+ void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw);
void fromPublicKeyString(unsigned int algorithm, const std::string& raw);
static DNSPrivateKey* maker(unsigned int algorithm)
return string((char*)hash, sizeof(hash));
}
-std::string RSADNSPrivateKey::sign(const std::string& hash) const
+std::string RSADNSPrivateKey::sign(const std::string& msg) const
{
+ string hash = this->hash(msg);
unsigned char signature[mpi_size(&d_context.N)];
int hashKind;
if(hash.size()==20)
return string((char*) signature, sizeof(signature));
}
-bool RSADNSPrivateKey::verify(const std::string& hash, const std::string& signature) const
+bool RSADNSPrivateKey::verify(const std::string& msg, const std::string& signature) const
{
int hashKind;
+ string hash=this->hash(msg);
if(hash.size()==20)
hashKind= SIG_RSA_SHA1;
else if(hash.size()==32)
else
hashKind = SIG_RSA_SHA512;
+
+
int ret=rsa_pkcs1_verify(const_cast<rsa_context*>(&d_context), RSA_PUBLIC,
hashKind,
hash.size(),
}
-void RSADNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content)
+void RSADNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap)
{
string sline;
string key,value;
- map<string, mpi*> places;
+ typedef map<string, mpi*> places_t;
+ places_t places;
rsa_init(&d_context, RSA_PKCS_V15, 0, NULL, NULL );
places["Exponent1"]=&d_context.DP;
places["Exponent2"]=&d_context.DQ;
places["Coefficient"]=&d_context.QP;
-
- string modulus, exponent;
- istringstream str(content);
- unsigned char decoded[1024];
- while(getline(str, sline)) {
- tie(key,value)=splitField(sline, ':');
- trim(value);
-
- if(places.count(key)) {
- if(places[key]) {
- int len=sizeof(decoded);
- if(base64_decode(decoded, &len, (unsigned char*)value.c_str(), value.length()) < 0) {
- cerr<<"Error base64 decoding '"<<value<<"'\n";
- exit(1);
- }
- // B64Decode(value, decoded);
- // cerr<<key<<" decoded.length(): "<<8*len<<endl;
- mpi_read_binary(places[key], decoded, len);
- if(key=="Modulus")
- modulus.assign((const char*)decoded,len);
- if(key=="PublicExponent")
- exponent.assign((const char*)decoded,len);
- }
- }
- else {
- if(key == "Algorithm")
- drc.d_algorithm = atoi(value.c_str());
- else if(key != "Private-key-format")
- cerr<<"Unknown field '"<<key<<"'\n";
- }
+
+ drc.d_algorithm = atoi(stormap["algorithm"].c_str());
+
+ string raw;
+ BOOST_FOREACH(const places_t::value_type& val, places) {
+ raw=stormap[toLower(val.first)];
+ mpi_read_binary(val.second, (unsigned char*) raw.c_str(), raw.length());
}
- d_context.len = ( mpi_msb( &d_context.N ) + 7 ) >> 3; // no clue what this does
- if(exponent.length() < 255)
- drc.d_key.assign(1, (char) (unsigned int) exponent.length());
- else {
- drc.d_key.assign(1, 0);
- uint16_t len=htons(exponent.length());
- drc.d_key.append((char*)&len, 2);
- }
- drc.d_key.append(exponent);
- drc.d_key.append(modulus);
+ d_context.len = ( mpi_msb( &d_context.N ) + 7 ) >> 3; // no clue what this does
+ drc.d_key = this->getPublicKeyString();
drc.d_protocol=3;
}
keystring.append(modulus);
return keystring;
}
+
namespace {
struct LoaderStruct
{
LoaderStruct()
{
- DNSPrivateKey::report(5, &RSADNSPrivateKey::maker);
- DNSPrivateKey::report(7, &RSADNSPrivateKey::maker);
- DNSPrivateKey::report(8, &RSADNSPrivateKey::maker);
- DNSPrivateKey::report(10, &RSADNSPrivateKey::maker);
+ DNSPrivateKey::report(5, &RSADNSPrivateKey::maker, true);
+ DNSPrivateKey::report(7, &RSADNSPrivateKey::maker, true);
+ DNSPrivateKey::report(8, &RSADNSPrivateKey::maker, true);
+ DNSPrivateKey::report(10, &RSADNSPrivateKey::maker, true);
}
} loader;
}
+