Changeset 1951

Show
Ignore:
Timestamp:
01/31/11 22:59:45 (2 years ago)
Author:
ahu
Message:

- scary commit -
add a generic botan1.8/botan1.9 signer/verifier for RSA
refactor the signer/verifier API so the more code moves out of the per-engine interface
add the ability to have multiple enginers for a single algorithm, plus add the notion of a 'fallback' engine, in our case polarssl
update some copyright statements

Location:
trunk/pdns/pdns
Files:
1 added
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/Makefile.am

    r1949 r1951  
    4848 
    4949if BOTAN19 
    50 pdns_server_SOURCES += botan19signers.cc 
     50pdns_server_SOURCES += botan19signers.cc botansigners.cc 
    5151pdns_server_LDADD += -lbotan -lgmp 
    5252endif 
    5353 
    5454if BOTAN18 
    55 pdns_server_SOURCES += botan18signers.cc 
     55pdns_server_SOURCES += botan18signers.cc botansigners.cc 
    5656pdns_server_LDADD += -lbotan -lgmp 
    5757endif 
     
    7272 
    7373if BOTAN19 
    74 pdnssec_SOURCES += botan19signers.cc 
     74pdnssec_SOURCES += botan19signers.cc botansigners.cc 
    7575pdnssec_LDADD += -lbotan -lgmp 
    7676endif 
    7777 
    7878if BOTAN18 
    79 pdnssec_SOURCES += botan18signers.cc 
     79pdnssec_SOURCES += botan18signers.cc botansigners.cc 
    8080pdnssec_LDADD += -lbotan -lgmp 
    8181endif 
  • trunk/pdns/pdns/botan18signers.cc

    r1947 r1951  
    1111using namespace Botan; 
    1212 
    13 ////////////////////////////// 
    14  
    1513class ECDSADNSPrivateKey : public DNSPrivateKey 
    1614{ 
     
    2321  std::string sign(const std::string& hash) const;  
    2422  std::string hash(const std::string& hash) const;  
    25   bool verify(const std::string& hash, const std::string& signature) const; 
     23  bool verify(const std::string& msg, const std::string& signature) const; 
    2624  std::string getPublicKeyString() const; 
    2725  int getBits() const; 
    28   void fromISCString(DNSKEYRecordContent& drc, const std::string& content); 
     26  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap); 
    2927  void fromPublicKeyString(unsigned int algorithm, const std::string& content); 
    3028  void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) 
     
    6058  } 
    6159  d_key = shared_ptr<ECDSA_PrivateKey>(new ECDSA_PrivateKey(rng, getECParams((bits == 256) ? 13 : 14))); 
    62    
    6360   
    6461  PKCS8_Encoder* pk8e= d_key->pkcs8_encoder(); 
     
    106103} 
    107104 
    108 void ECDSADNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content ) 
     105void ECDSADNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap ) 
    109106{ 
    110107  /*Private-key-format: v1.2 
    111108   Algorithm: 13 (ECDSAP256SHA256) 
    112109   PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */ 
    113    
    114   istringstream input(content); 
    115   string sline, key, value, privateKey; 
    116   while(getline(input, sline)) { 
    117     tie(key,value)=splitField(sline, ':'); 
    118     trim(value); 
    119     if(pdns_iequals(key,"Private-key-format")) {} 
    120     else if(key=="Algorithm") 
    121       drc.d_algorithm = atoi(value.c_str()); 
    122     else if(key=="PrivateKey") { 
    123       Pipe pipe(new Base64_Decoder); 
    124       pipe.process_msg(value); 
    125       privateKey=pipe.read_all_as_string(); 
    126     } 
    127     else 
    128       throw runtime_error("Unknown field '"+key+"' in Private Key Representation of ECDSA"); 
    129   } 
    130   d_algorithm = drc.d_algorithm; 
     110      
     111  d_algorithm = drc.d_algorithm = atoi(stormap["algorithm"].c_str()); 
     112  string privateKey = stormap["privatekey"]; 
     113   
    131114  BigInt bigint((byte*)privateKey.c_str(), privateKey.length()); 
    132115   
     
    150133   
    151134  MemoryVector<byte> tmp((byte*)noIdea.c_str(), noIdea.length()); 
    152   cerr<<"key_bits"<<endl; 
    153135  p8e->key_bits(tmp); 
    154   cerr<<"Done reading"<<endl; 
    155136  delete p8e; 
    156137} 
     
    193174} 
    194175 
    195  
    196 std::string ECDSADNSPrivateKey::sign(const std::string& hash) const 
     176std::string ECDSADNSPrivateKey::sign(const std::string& msg) const 
    197177{ 
    198178  AutoSeeded_RNG rng; 
     179  string hash = this->hash(msg); 
    199180  SecureVector<byte> signature=d_key->sign((byte*)hash.c_str(), hash.length(), rng); 
    200181   
     
    217198} 
    218199 
    219  
    220 bool ECDSADNSPrivateKey::verify(const std::string& hash, const std::string& signature) const 
    221 { 
    222   ECDSA_PublicKey* key; 
    223   if(d_key) 
    224     key = d_key.get(); 
    225   else 
    226     key = d_pubkey.get(); 
    227      
     200bool ECDSADNSPrivateKey::verify(const std::string& msg, const std::string& signature) const 
     201{ 
     202  string hash = this->hash(msg); 
     203  ECDSA_PublicKey* key = d_key ? d_key.get() : d_pubkey.get(); 
    228204  return key->verify((byte*)hash.c_str(), hash.length(), (byte*)signature.c_str(), signature.length()); 
    229205} 
    230  
    231206namespace { 
    232207struct LoaderStruct 
  • trunk/pdns/pdns/botan19signers.cc

    r1920 r1951  
    3333  std::string getPublicKeyString() const; 
    3434  int getBits() const; 
    35   void fromISCString(DNSKEYRecordContent& drc, const std::string& content); 
     35  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& content); 
    3636  void fromPublicKeyString(unsigned int algorithm, const std::string& content); 
    3737  void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) 
     
    106106 
    107107 
    108 void GOSTDNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content ) 
     108void GOSTDNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap ) 
    109109{  
    110   istringstream input(content); 
    111   string sline, key, value, privateKey; 
    112   while(getline(input, sline)) { 
    113     tie(key,value)=splitField(sline, ':'); 
    114     trim(value); 
    115     if(pdns_iequals(key,"Private-key-format")) {} 
    116     else if(key=="Algorithm") 
    117       drc.d_algorithm = atoi(value.c_str()); 
    118     else if(key=="GostAsn1") { 
    119       Pipe pipe(new Base64_Decoder); 
    120       pipe.process_msg(value); 
    121       privateKey=pipe.read_all_as_string(); 
    122     } 
    123     else 
    124       throw runtime_error("Unknown field '"+key+"' in Private Key Representation of GOST"); 
    125   } 
     110  drc.d_algorithm = atoi(stormap["algorithm"].c_str()); 
     111  string privateKey=stormap["gostasn1"]; 
    126112  //cerr<<"PrivateKey.size() = "<<privateKey.size()<<endl; 
    127113  //cerr<<makeHexDump(string(privateKey.c_str(), 39))<<endl; 
     
    207193 */ 
    208194 
    209 std::string GOSTDNSPrivateKey::sign(const std::string& hash) const 
     195std::string GOSTDNSPrivateKey::sign(const std::string& msg) const 
    210196{ 
    211197  GOST_3410_Signature_Operation ops(*d_key); 
    212198  AutoSeeded_RNG rng; 
     199   
     200  string hash= this->hash(msg); 
     201   
    213202  SecureVector<byte> signature=ops.sign((byte*)hash.c_str(), hash.length(), rng); 
    214203 
     
    232221 
    233222 
    234 bool GOSTDNSPrivateKey::verify(const std::string& hash, const std::string& signature) const 
    235 { 
     223bool GOSTDNSPrivateKey::verify(const std::string& message, const std::string& signature) const 
     224{ 
     225  string hash = this->hash(message); 
    236226  GOST_3410_PublicKey* pk; 
    237227  if(d_pubkey) { 
     
    274264  std::string getPublicKeyString() const; 
    275265  int getBits() const; 
    276   void fromISCString(DNSKEYRecordContent& drc, const std::string& content); 
     266  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap); 
    277267  void fromPublicKeyString(unsigned int algorithm, const std::string& content); 
    278268  void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) 
     
    352342} 
    353343 
    354 void ECDSADNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content ) 
     344void ECDSADNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) 
    355345{ 
    356346  /*Private-key-format: v1.2 
     
    358348   PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */ 
    359349   
    360   istringstream input(content); 
    361   string sline, key, value, privateKey; 
    362   while(getline(input, sline)) { 
    363     tie(key,value)=splitField(sline, ':'); 
    364     trim(value); 
    365     if(pdns_iequals(key,"Private-key-format")) {} 
    366     else if(key=="Algorithm") 
    367       drc.d_algorithm = atoi(value.c_str()); 
    368     else if(key=="PrivateKey") { 
    369       Pipe pipe(new Base64_Decoder); 
    370       pipe.process_msg(value); 
    371       privateKey=pipe.read_all_as_string(); 
    372     } 
    373     else 
    374       throw runtime_error("Unknown field '"+key+"' in Private Key Representation of ECDSA"); 
    375   } 
     350  drc.d_algorithm = atoi(stormap["algorithm"].c_str()); 
     351  string privateKey=stormap["privatekey"]; 
     352   
    376353  d_algorithm = drc.d_algorithm; 
    377354  BigInt bigint((byte*)privateKey.c_str(), privateKey.length()); 
     
    379356  EC_Domain_Params params=getECParams(drc.d_algorithm); 
    380357  d_key=shared_ptr<ECDSA_PrivateKey>(new ECDSA_PrivateKey(params, bigint)); 
    381    
    382358} 
    383359 
     
    418394 
    419395 
    420 std::string ECDSADNSPrivateKey::sign(const std::string& hash) const 
    421 { 
     396std::string ECDSADNSPrivateKey::sign(const std::string& msg) const 
     397{ 
     398  string hash = this->hash(msg); 
    422399  ECDSA_Signature_Operation ops(*d_key); 
    423400  AutoSeeded_RNG rng; 
  • trunk/pdns/pdns/communicator.cc

    r1859 r1951  
    11/* 
    22    PowerDNS Versatile Database Driven Nameserver 
    3     Copyright (C) 2002-2009  PowerDNS.COM BV 
     3    Copyright (C) 2002-2011  PowerDNS.COM BV 
    44 
    55    This program is free software; you can redistribute it and/or modify 
  • trunk/pdns/pdns/dnssecinfra.cc

    r1916 r1951  
    1313#include <boost/assign/std/vector.hpp> // for 'operator+=()' 
    1414#include <boost/assign/list_inserter.hpp> 
     15#include "base64.hh" 
    1516 
    1617using namespace boost; 
     
    2021DNSPrivateKey* DNSPrivateKey::makeFromISCFile(DNSKEYRecordContent& drc, const char* fname) 
    2122{ 
    22   string sline, isc, key, value; 
     23  string sline, isc; 
    2324  FILE *fp=fopen(fname, "r"); 
    2425  if(!fp) { 
    2526    throw runtime_error("Unable to read file '"+string(fname)+"' for generating DNS Private Key"); 
    2627  } 
    27   int algorithm=0; 
     28   
    2829  while(stringfgets(fp, sline)) { 
     30    isc += sline; 
     31  } 
     32  fclose(fp); 
     33  return makeFromISCString(drc, isc); 
     34} 
     35 
     36DNSPrivateKey* DNSPrivateKey::makeFromISCString(DNSKEYRecordContent& drc, const std::string& content) 
     37{ 
     38  int algorithm = 0; 
     39  string sline, key, value, raw; 
     40  istringstream str(content); 
     41  map<string, string> stormap; 
     42  while(getline(str, sline)) { 
    2943    tie(key,value)=splitField(sline, ':'); 
    30     if(pdns_iequals(key,"algorithm")) 
     44    trim(value); 
     45    if(pdns_iequals(key,"algorithm")) { 
    3146      algorithm = atoi(value.c_str()); 
    32     isc.append(sline); 
    33   } 
    34   fclose(fp); 
    35  
     47      stormap["algorithm"]=lexical_cast<string>(algorithm); 
     48      continue; 
     49    } 
     50    else if(pdns_iequals(key, "Private-key-format")) 
     51      continue; 
     52    raw.clear(); 
     53    B64Decode(value, raw); 
     54    stormap[toLower(key)]=raw; 
     55  } 
    3656  DNSPrivateKey* dpk=make(algorithm); 
    37   dpk->fromISCString(drc, isc); 
     57  dpk->fromISCMap(drc, stormap); 
    3858  return dpk; 
    3959} 
     60 
    4061 
    4162DNSPrivateKey* DNSPrivateKey::make(unsigned int algo) 
     
    5071} 
    5172 
    52 void DNSPrivateKey::report(unsigned int algo, maker_t* maker) 
    53 { 
     73void DNSPrivateKey::report(unsigned int algo, maker_t* maker, bool fallback) 
     74{ 
     75  if(getMakers().count(algo) && fallback) { 
     76    return; 
     77  } 
    5478  getMakers()[algo]=maker; 
    55 } 
    56 DNSPrivateKey* DNSPrivateKey::makeFromISCString(DNSKEYRecordContent& drc, const std::string& content) 
    57 { 
    58   int algorithm = 0; 
    59   string sline, key, value; 
    60   istringstream str(content); 
    61   while(getline(str, sline)) { 
    62     tie(key,value)=splitField(sline, ':'); 
    63     if(pdns_iequals(key,"algorithm")) { 
    64       algorithm = atoi(value.c_str()); 
    65       break; 
    66     } 
    67   } 
    68   DNSPrivateKey* dpk=make(algorithm); 
    69   dpk->fromISCString(drc, content); 
    70   return dpk; 
    7179} 
    7280 
     
    104112} 
    105113 
    106 string getHashForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& signRecords)  
     114string getMessageForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, vector<shared_ptr<DNSRecordContent> >& signRecords)  
    107115{ 
    108116  sort(signRecords.begin(), signRecords.end(), sharedDNSSECCompare); 
     
    126134  } 
    127135   
    128   shared_ptr<DNSPrivateKey> dpk(DNSPrivateKey::make(rrc.d_algorithm)); 
    129   return dpk->hash(toHash); 
     136  return toHash; 
    130137} 
    131138 
  • trunk/pdns/pdns/dnssecinfra.hh

    r1932 r1951  
    2020    virtual int getBits() const =0; 
    2121     
    22     virtual void fromISCString(DNSKEYRecordContent& drc, const std::string& content)=0; 
     22    virtual void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap)=0; 
    2323    virtual void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)=0; 
    2424    virtual void fromPublicKeyString(unsigned algorithm, const std::string& content) 
     
    3535    typedef DNSPrivateKey* maker_t(unsigned int algorithm); 
    3636     
    37     static void report(unsigned int algorithm, maker_t* maker); 
     37    static void report(unsigned int algorithm, maker_t* maker, bool fallback=false); 
    3838  private: 
    3939     
     
    8787 
    8888bool sharedDNSSECCompare(const boost::shared_ptr<DNSRecordContent>& a, const shared_ptr<DNSRecordContent>& b); 
    89 string getHashForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, std::vector<boost::shared_ptr<DNSRecordContent> >& signRecords); 
     89string getMessageForRRSET(const std::string& qname, const RRSIGRecordContent& rrc, std::vector<boost::shared_ptr<DNSRecordContent> >& signRecords); 
    9090 
    9191DSRecordContent makeDSFromDNSKey(const std::string& qname, const DNSKEYRecordContent& drc, int digest=1); 
  • trunk/pdns/pdns/dnssecsigner.cc

    r1932 r1951  
    115115  rrc.d_tag = drc.getTag(); 
    116116  rrc.d_algorithm = drc.d_algorithm; 
    117   string realhash=getHashForRRSET(signQName, rrc, toSign); // this is what we sign 
    118117 
    119   pair<string, string> lookup(rc->getPubKeyHash(), realhash); 
     118  string msg=getMessageForRRSET(signQName, rrc, toSign); // this is what we will hash & sign 
     119 
     120  pair<string, string> lookup(rc->getPubKeyHash(), msg); // we key on the whole message now! 
    120121   
    121122  { 
     
    130131  } 
    131132   
    132   rrc.d_signature = rc->sign(realhash); 
     133  //DTime dt; 
     134  //dt.set(); 
     135  rrc.d_signature = rc->sign(msg); 
     136  //cerr<<dt.udiff()<<endl; 
    133137 
    134138  Lock l(&g_signatures_lock); 
  • trunk/pdns/pdns/mastercommunicator.cc

    r1865 r1951  
    11/* 
    22    PowerDNS Versatile Database Driven Nameserver 
    3     Copyright (C) 2002-2009  PowerDNS.COM BV 
     3    Copyright (C) 2002-2011  PowerDNS.COM BV 
    44 
    55    This program is free software; you can redistribute it and/or modify 
  • trunk/pdns/pdns/pdnssec.cc

    r1939 r1951  
    209209  } 
    210210   
    211   string hash = getHashForRRSET(qname, rrc, toSign);         
     211  string msg = getMessageForRRSET(qname, rrc, toSign);         
     212  DNSPrivateKey* dpk = DNSPrivateKey::make(rrc.d_algorithm); 
     213  string hash = dpk->sign(msg); 
    212214  cerr<<"Verify: "<<DNSPrivateKey::makeFromPublicKeyString(drc.d_algorithm, drc.d_key)->verify(hash, rrc.d_signature)<<endl; 
    213215  if(dsrc.d_digesttype) { 
  • trunk/pdns/pdns/polarrsakeyinfra.cc

    r1915 r1951  
    9393    return mpi_size(&d_context.N)*8; 
    9494  } 
    95   void fromISCString(DNSKEYRecordContent& drc, const std::string& content); 
     95  void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap); 
    9696  void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw); 
    9797  void fromPublicKeyString(unsigned int algorithm, const std::string& raw); 
     
    145145} 
    146146 
    147 std::string RSADNSPrivateKey::sign(const std::string& hash) const 
    148 { 
     147std::string RSADNSPrivateKey::sign(const std::string& msg) const 
     148{ 
     149  string hash = this->hash(msg); 
    149150  unsigned char signature[mpi_size(&d_context.N)]; 
    150151  int hashKind; 
     
    168169} 
    169170 
    170 bool RSADNSPrivateKey::verify(const std::string& hash, const std::string& signature) const 
     171bool RSADNSPrivateKey::verify(const std::string& msg, const std::string& signature) const 
    171172{ 
    172173  int hashKind; 
     174  string hash=this->hash(msg); 
    173175  if(hash.size()==20) 
    174176    hashKind= SIG_RSA_SHA1; 
     
    177179  else 
    178180    hashKind = SIG_RSA_SHA512; 
     181   
     182   
    179183   
    180184  int ret=rsa_pkcs1_verify(const_cast<rsa_context*>(&d_context), RSA_PUBLIC,  
     
    248252 
    249253 
    250 void RSADNSPrivateKey::fromISCString(DNSKEYRecordContent& drc, const std::string& content) 
     254void RSADNSPrivateKey::fromISCMap(DNSKEYRecordContent& drc,  std::map<std::string, std::string>& stormap) 
    251255{ 
    252256  string sline; 
    253257  string key,value; 
    254   map<string, mpi*> places; 
     258  typedef map<string, mpi*> places_t; 
     259  places_t places; 
    255260   
    256261  rsa_init(&d_context, RSA_PKCS_V15, 0, NULL, NULL ); 
     
    264269  places["Exponent2"]=&d_context.DQ; 
    265270  places["Coefficient"]=&d_context.QP; 
    266  
    267   string modulus, exponent; 
    268   istringstream str(content); 
    269   unsigned char decoded[1024]; 
    270   while(getline(str, sline)) { 
    271     tie(key,value)=splitField(sline, ':'); 
    272     trim(value); 
    273  
    274     if(places.count(key)) { 
    275       if(places[key]) { 
    276         int len=sizeof(decoded); 
    277         if(base64_decode(decoded, &len, (unsigned char*)value.c_str(), value.length()) < 0) { 
    278           cerr<<"Error base64 decoding '"<<value<<"'\n"; 
    279           exit(1); 
    280         } 
    281         //      B64Decode(value, decoded); 
    282         //      cerr<<key<<" decoded.length(): "<<8*len<<endl; 
    283         mpi_read_binary(places[key], decoded, len); 
    284         if(key=="Modulus") 
    285           modulus.assign((const char*)decoded,len); 
    286         if(key=="PublicExponent") 
    287           exponent.assign((const char*)decoded,len); 
    288       } 
    289     } 
    290     else { 
    291       if(key == "Algorithm")  
    292         drc.d_algorithm = atoi(value.c_str()); 
    293       else if(key != "Private-key-format") 
    294         cerr<<"Unknown field '"<<key<<"'\n"; 
    295     } 
    296   } 
     271   
     272  drc.d_algorithm = atoi(stormap["algorithm"].c_str()); 
     273   
     274  string raw; 
     275  BOOST_FOREACH(const places_t::value_type& val, places) { 
     276    raw=stormap[toLower(val.first)]; 
     277    mpi_read_binary(val.second, (unsigned char*) raw.c_str(), raw.length()); 
     278  } 
     279 
    297280  d_context.len = ( mpi_msb( &d_context.N ) + 7 ) >> 3; // no clue what this does 
    298  
    299   if(exponent.length() < 255)  
    300     drc.d_key.assign(1, (char) (unsigned int) exponent.length()); 
    301   else { 
    302     drc.d_key.assign(1, 0); 
    303     uint16_t len=htons(exponent.length()); 
    304     drc.d_key.append((char*)&len, 2); 
    305   } 
    306   drc.d_key.append(exponent); 
    307   drc.d_key.append(modulus); 
     281  drc.d_key = this->getPublicKeyString(); 
    308282  drc.d_protocol=3; 
    309283} 
     
    394368  return keystring; 
    395369} 
     370 
    396371namespace { 
    397372struct LoaderStruct 
     
    399374  LoaderStruct() 
    400375  { 
    401     DNSPrivateKey::report(5, &RSADNSPrivateKey::maker); 
    402     DNSPrivateKey::report(7, &RSADNSPrivateKey::maker); 
    403     DNSPrivateKey::report(8, &RSADNSPrivateKey::maker); 
    404     DNSPrivateKey::report(10, &RSADNSPrivateKey::maker); 
     376    DNSPrivateKey::report(5, &RSADNSPrivateKey::maker, true); 
     377    DNSPrivateKey::report(7, &RSADNSPrivateKey::maker, true); 
     378    DNSPrivateKey::report(8, &RSADNSPrivateKey::maker, true); 
     379    DNSPrivateKey::report(10, &RSADNSPrivateKey::maker, true); 
    405380  } 
    406381} loader; 
    407382} 
     383