From: Bert Hubert Date: Sun, 9 Jan 2011 15:54:20 +0000 (+0000) Subject: move some non-'keeper' dnssec signing logic away to a separate file, dnssecsigner.cc X-Git-Tag: auth-3.0~399 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=882358c881b8d2195eaad36759cda0e8800526ff;p=pdns move some non-'keeper' dnssec signing logic away to a separate file, dnssecsigner.cc git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1848 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 4282594b9..500f27d3d 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -44,7 +44,7 @@ rcpgenerator.cc dnsparser.cc dns_random.hh aes/aescpp.h \ aes/aescrypt.c aes/aes.h aes/aeskey.c aes/aes_modes.c aes/aesopt.h \ aes/aestab.c aes/aestab.h aes/brg_endian.h aes/brg_types.h aes/dns_random.cc \ randomhelper.cc namespaces.hh nsecrecords.cc base32.cc dbdnsseckeeper.cc dnssecinfra.cc \ -dnsseckeeper.hh dnssecinfra.hh base32.hh dns.cc +dnsseckeeper.hh dnssecinfra.hh base32.hh dns.cc dnssecsigner.cc # pdns_server_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ $(BOOST_FILESYSTEM_LDFLAGS) -Lext/polarssl/library @@ -58,7 +58,7 @@ pdnssec_SOURCES=pdnssec.cc dbdnsseckeeper.cc sstuff.hh dnsparser.cc dnsparser.hh backends/bind/bindparser.cc backends/bind/bindlexer.c \ backends/gsql/gsqlbackend.cc \ backends/gsql/gsqlbackend.hh backends/gsql/ssql.hh zoneparser-tng.cc \ - dynlistener.cc dns.cc randombackend.cc + dynlistener.cc dns.cc randombackend.cc dnssecsigner.cc pdnssec_LDFLAGS=@moduleobjects@ @modulelibs@ @DYNLINKFLAGS@ @LIBDL@ @THREADFLAGS@ -Lext/polarssl/library/ pdnssec_LDADD=$(BOOST_FILESYSTEM_LIBS) $(BOOST_SYSTEM_LIBS) -lpolarssl $(BOOST_PROGRAM_OPTIONS_LIBS) diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 041e377b3..9d8faca62 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -1,3 +1,21 @@ +/* + PowerDNS Versatile Database Driven Nameserver + Copyright (C) 2001 - 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 + published by the Free Software Foundation + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + #include "dnsseckeeper.hh" #include "dnssecinfra.hh" #include "ueberbackend.hh" @@ -177,138 +195,3 @@ void DNSSECKeeper::secureZone(const std::string& name, int algorithm) { addKey(name, true, algorithm); } - -// nobody should ever call this function, you know the SOA/auth already! -bool getSignerApexFor(DNSSECKeeper& dk, const std::string& qname, std::string &signer) -{ - // cerr<<"getSignerApexFor: called, and should not be, should go away!"< >& toSign, vector& rrcs, bool ksk) -{ - if(toSign.empty()) - return -1; - RRSIGRecordContent rrc; - rrc.d_type=signQType; - - // d_algorithm gets filled out by getSignerAPEX, since only it looks up the key - rrc.d_labels=countLabels(signQName); - rrc.d_originalttl=signTTL; - rrc.d_siginception=getCurrentInception();; - rrc.d_sigexpire = rrc.d_siginception + 14*86400; // XXX should come from zone metadata - rrc.d_tag = 0; - - // XXX we know the apex already.. is is the SOA name which we determined earlier - if(!getSignerApexFor(dk, signQName, rrc.d_signer)) { - cerr<<"No signer known for '"< KSKs, ZSKs; - vector* signingKeys; - - // if ksk==1, only get KSKs - // if ksk==0, get ZSKs, unless there is no ZSK, then get KSK - BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type& keymeta, keys) { - if(!keymeta.second.active) - continue; - - if(keymeta.second.keyOrZone) - KSKs.push_back(keymeta.first); - else if(!ksk) - ZSKs.push_back(keymeta.first); - } - if(ksk) - signingKeys = &KSKs; - else { - if(ZSKs.empty()) - signingKeys = &KSKs; - else - signingKeys =&ZSKs; - } - - BOOST_FOREACH(DNSSECPrivateKey& dpk, *signingKeys) { - fillOutRRSIG(dpk, signQName, rrc, toSign); - rrcs.push_back(rrc); - } - return 0; -} - -// this is the entrypoint from DNSPacket -void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType, - uint32_t signTTL, DNSPacketWriter::Place signPlace, - vector >& toSign, uint16_t maxReplyLen, DNSPacketWriter& pw) -{ - // cerr<<"Asked to sign '"< rrcs; - if(toSign.empty()) - return; - - if(getRRSIGsForRRSET(dk, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs, signQType == QType::DNSKEY) < 0) { - cerr<<"Error signing a record!"< maxReplyLen) { - pw.rollback(); - pw.getHeader()->tc=1; - return; - } - } - pw.commit(); - - toSign.clear(); -} - -static pthread_mutex_t g_signatures_lock = PTHREAD_MUTEX_INITIALIZER; -static map, string> g_signatures; - -void fillOutRRSIG(DNSSECPrivateKey& dpk, const std::string& signQName, RRSIGRecordContent& rrc, vector >& toSign) -{ - DNSKEYRecordContent drc= dpk.getDNSKEY(); - RSAContext& rc = dpk.d_key; - rrc.d_tag = drc.getTag(); - rrc.d_algorithm = drc.d_algorithm; - string realhash=getHashForRRSET(signQName, rrc, toSign); // this is what we sign - - unsigned char signature[mpi_size(&rc.getContext().N)]; - - { - Lock l(&g_signatures_lock); - if(g_signatures.count(make_pair(rc, realhash))) { - rrc.d_signature=g_signatures[make_pair(rc, realhash)]; - return; - } - } - - int ret=rsa_pkcs1_sign(&rc.getContext(), RSA_PRIVATE, - rrc.d_algorithm < 8 ? SIG_RSA_SHA1 : SIG_RSA_SHA256, - rrc.d_algorithm < 8 ? 20 : 32, - (unsigned char*) realhash.c_str(), signature); - - if(ret!=0) { - cerr<<"signing returned: "< +#include "dnsseckeeper.hh" +#include "lock.hh" + +// nobody should ever call this function, you know the SOA/auth already! +bool getSignerApexFor(DNSSECKeeper& dk, const std::string& qname, std::string &signer) +{ + // cerr<<"getSignerApexFor: called, and should not be, should go away!"< >& toSign, vector& rrcs, bool ksk) +{ + if(toSign.empty()) + return -1; + RRSIGRecordContent rrc; + rrc.d_type=signQType; + + // d_algorithm gets filled out by getSignerAPEX, since only it looks up the key + rrc.d_labels=countLabels(signQName); + rrc.d_originalttl=signTTL; + rrc.d_siginception=getCurrentInception();; + rrc.d_sigexpire = rrc.d_siginception + 14*86400; // XXX should come from zone metadata + rrc.d_tag = 0; + + // XXX we know the apex already.. is is the SOA name which we determined earlier + if(!getSignerApexFor(dk, signQName, rrc.d_signer)) { + cerr<<"No signer known for '"< KSKs, ZSKs; + vector* signingKeys; + + // if ksk==1, only get KSKs + // if ksk==0, get ZSKs, unless there is no ZSK, then get KSK + BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type& keymeta, keys) { + if(!keymeta.second.active) + continue; + + if(keymeta.second.keyOrZone) + KSKs.push_back(keymeta.first); + else if(!ksk) + ZSKs.push_back(keymeta.first); + } + if(ksk) + signingKeys = &KSKs; + else { + if(ZSKs.empty()) + signingKeys = &KSKs; + else + signingKeys =&ZSKs; + } + + BOOST_FOREACH(DNSSECPrivateKey& dpk, *signingKeys) { + fillOutRRSIG(dpk, signQName, rrc, toSign); + rrcs.push_back(rrc); + } + return 0; +} + +// this is the entrypoint from DNSPacket +void addSignature(DNSSECKeeper& dk, const std::string signQName, const std::string& wildcardname, uint16_t signQType, + uint32_t signTTL, DNSPacketWriter::Place signPlace, + vector >& toSign, uint16_t maxReplyLen, DNSPacketWriter& pw) +{ + // cerr<<"Asked to sign '"< rrcs; + if(toSign.empty()) + return; + + if(getRRSIGsForRRSET(dk, wildcardname.empty() ? signQName : wildcardname, signQType, signTTL, toSign, rrcs, signQType == QType::DNSKEY) < 0) { + cerr<<"Error signing a record!"< maxReplyLen) { + pw.rollback(); + pw.getHeader()->tc=1; + return; + } + } + pw.commit(); + + toSign.clear(); +} + +static pthread_mutex_t g_signatures_lock = PTHREAD_MUTEX_INITIALIZER; +static map, string> g_signatures; + +void fillOutRRSIG(DNSSECPrivateKey& dpk, const std::string& signQName, RRSIGRecordContent& rrc, vector >& toSign) +{ + DNSKEYRecordContent drc= dpk.getDNSKEY(); + RSAContext& rc = dpk.d_key; + rrc.d_tag = drc.getTag(); + rrc.d_algorithm = drc.d_algorithm; + string realhash=getHashForRRSET(signQName, rrc, toSign); // this is what we sign + + unsigned char signature[mpi_size(&rc.getContext().N)]; + + { + Lock l(&g_signatures_lock); + + // this is mindbogglingly inefficient, we store the whole private key as index! + if(g_signatures.count(make_pair(rc, realhash))) { + rrc.d_signature=g_signatures[make_pair(rc, realhash)]; + return; + } + } + + int ret=rsa_pkcs1_sign(&rc.getContext(), RSA_PRIVATE, + rrc.d_algorithm < 8 ? SIG_RSA_SHA1 : SIG_RSA_SHA256, + rrc.d_algorithm < 8 ? 20 : 32, + (unsigned char*) realhash.c_str(), signature); + + if(ret!=0) { + cerr<<"signing returned: "<