std::string getPublicKeyString() const;
int getBits() const;
void fromISCString(DNSKEYRecordContent& drc, const std::string& content);
+ void fromPublicKeyString(unsigned int algorithm, const std::string& content);
void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
{}
private:
shared_ptr<GOST_3410_PrivateKey> d_key;
+ shared_ptr<GOST_3410_PublicKey> d_pubkey;
};
/*
SecureVector<byte> buffer=BigInt::encode(x);
// cerr<<"And out again! "<<makeHexDump(string((const char*)buffer.begin(), (const char*)buffer.end()))<<endl;
}
+namespace {
+
+BigInt decode_le(const byte msg[], size_t msg_len)
+ {
+ SecureVector<byte> msg_le(msg, msg_len);
+
+ for(size_t i = 0; i != msg_le.size() / 2; ++i)
+ std::swap(msg_le[i], msg_le[msg_le.size()-1-i]);
+
+ return BigInt(&msg_le[0], msg_le.size());
+ }
+
+}
+void GOSTDNSPrivateKey::fromPublicKeyString(unsigned int algorithm, const std::string& input)
+{
+ BigInt x, y;
+
+ x=decode_le((const byte*)input.c_str(), input.length()/2);
+ y=decode_le((const byte*)input.c_str() + input.length()/2, input.length()/2);
+
+ EC_Domain_Params params("1.2.643.2.2.35.1");
+ PointGFp point(params.get_curve(), x,y);
+ d_pubkey = shared_ptr<GOST_3410_PublicKey>(new GOST_3410_PublicKey(params, point));
+
+}
std::string GOSTDNSPrivateKey::getPubKeyHash() const
{
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);
+ GOST_3410_PublicKey* pk;
+ if(d_pubkey) {
+ cerr<<"Worked from the public key"<<endl;
+ pk =d_pubkey.get();
+ }
+ else
+ pk = d_key.get();
+
+ GOST_3410_Verification_Operation ops(*pk);
+ /*
+ string rhash(hash);
+ for(string::size_type pos = 0 ; pos < rhash.size()/2; ++pos)
+ swap(rhash[pos], rhash[rhash.size()-1-pos]);
+ */
return ops.verify ((byte*)hash.c_str(), hash.length(), (byte*)signature.c_str(), signature.length());
}
std::string getPublicKeyString() const;
int getBits() const;
void fromISCString(DNSKEYRecordContent& drc, const std::string& content);
+ //void fromPublicKeyString(const std::string& content);
void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
{}
return dpk;
}
+DNSPrivateKey* DNSPrivateKey::makeFromPublicKeyString(unsigned int algorithm, const std::string& content)
+{
+ DNSPrivateKey* dpk=make(algorithm);
+ dpk->fromPublicKeyString(algorithm, content);
+ return dpk;
+}
+
DNSPrivateKey* DNSPrivateKey::makeFromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
{
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 bool verify(const std::string& hash, const std::string& signature) const =0;
virtual std::string getPublicKeyString()const =0;
virtual int getBits() const =0;
virtual void fromISCString(DNSKEYRecordContent& drc, const std::string& content)=0;
virtual void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)=0;
+ virtual void fromPublicKeyString(unsigned algorithm, const std::string& content)
+ {
+ throw std::runtime_error("Can't import from public key string");
+ }
static DNSPrivateKey* makeFromISCFile(DNSKEYRecordContent& drc, const char* fname);
static DNSPrivateKey* makeFromISCString(DNSKEYRecordContent& drc, const std::string& content);
static DNSPrivateKey* makeFromPEMString(DNSKEYRecordContent& drc, const std::string& raw);
+ static DNSPrivateKey* makeFromPublicKeyString(unsigned int algorithm, const std::string& raw);
static DNSPrivateKey* make(unsigned int algorithm);
typedef DNSPrivateKey* maker_t(unsigned int algorithm);
#include "ueberbackend.hh"
#include "arguments.hh"
#include "packetcache.hh"
-
+#include "zoneparser-tng.hh"
StatBag S;
PacketCache PC;
cerr<<"Checked "<<numrecords<<" records, "<<numerrors<<" errors"<<endl;
}
+void verifyCrypto(const string& zone)
+{
+ ZoneParserTNG zpt(zone);
+ DNSResourceRecord rr;
+ DNSKEYRecordContent drc;
+ RRSIGRecordContent rrc;
+ vector<shared_ptr<DNSRecordContent> > toSign;
+ unsigned int ttl;
+ string qname;
+
+ while(zpt.get(rr)) {
+ if(rr.qtype.getCode() == QType::DNSKEY) {
+ cerr<<"got DNSKEY!"<<endl;
+ drc = *dynamic_cast<DNSKEYRecordContent*>(DNSRecordContent::mastermake(QType::DNSKEY, 1, rr.content));
+ }
+ else if(rr.qtype.getCode() == QType::RRSIG) {
+ cerr<<"got RRSIG"<<endl;
+ rrc = *dynamic_cast<RRSIGRecordContent*>(DNSRecordContent::mastermake(QType::RRSIG, 1, rr.content));
+ }
+ else {
+ qname = rr.qname;
+ ttl = rr.ttl;
+ toSign.push_back(shared_ptr<DNSRecordContent>(DNSRecordContent::mastermake(rr.qtype.getCode(), 1, rr.content)));
+ }
+ }
+ DNSPrivateKey* dpk = DNSPrivateKey::makeFromPublicKeyString(drc.d_algorithm, drc.d_key);
+ string hash = getHashForRRSET(qname, rrc, toSign);
+ cerr<<"Verify: "<<dpk->verify(hash, rrc.d_signature)<<endl;
+}
+
void showZone(DNSSECKeeper& dk, const std::string& zone)
{
if(!dk.isSecuredZone(zone)) {
cout << "keys: "<<endl;
BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type value, keyset) {
cout<<"ID = "<<value.second.id<<" ("<<(value.second.keyOrZone ? "KSK" : "ZSK")<<"), tag = "<<value.first.getDNSKEY().getTag();
- cout<<", algo = "<<(int)value.first.d_algorithm<<", bits = "<<value.first.getKey()->getBits()<<"\tActive: "<<value.second.active<< endl; // humanTime(value.second.beginValidity)<<" - "<<humanTime(value.second.endValidity)<<endl;
+ cout<<", algo = "<<(int)value.first.d_algorithm<<", bits = "<<value.first.getKey()->getBits()<<"\tActive: "<<value.second.active<< endl;
if(value.second.keyOrZone) {
cout<<"KSK DNSKEY = "<<zone<<" IN DNSKEY "<< value.first.getDNSKEY().getZoneRepresentation() << endl;
cout<<"DS = "<<zone<<" IN DS "<<makeDSFromDNSKey(zone, value.first.getDNSKEY(), 1).getZoneRepresentation() << endl;
}
checkZone(dk, cmds[1]);
}
+ else if(cmds[0] == "verify-crypto") {
+ if(cmds.size() != 2) {
+ cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl;
+ return 0;
+ }
+ verifyCrypto(cmds[1]);
+ }
else if(cmds[0] == "show-zone") {
if(cmds.size() != 2) {
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 fromISCString(DNSKEYRecordContent& drc, const std::string& content);
void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw);
-
+ void fromPublicKeyString(unsigned int algorithm, const std::string& raw);
static DNSPrivateKey* maker(unsigned int algorithm)
{
return new RSADNSPrivateKey(algorithm);
return string((char*) signature, sizeof(signature));
}
+bool RSADNSPrivateKey::verify(const std::string& hash, const std::string& signature) const
+{
+ int hashKind;
+ if(hash.size()==20)
+ hashKind= SIG_RSA_SHA1;
+ else if(hash.size()==32)
+ hashKind= SIG_RSA_SHA256;
+ else
+ hashKind = SIG_RSA_SHA512;
+
+ int ret=rsa_pkcs1_verify(const_cast<rsa_context*>(&d_context), RSA_PUBLIC,
+ hashKind,
+ hash.size(),
+ (const unsigned char*) hash.c_str(), (unsigned char*) signature.c_str());
+ cerr<<"verification returned: "<<ret<<endl;
+ return ret==0; // 0 really IS ok ;-)
+}
+
+
std::string RSADNSPrivateKey::hash(const std::string& toHash) const
{
if(d_algorithm <= 7 ) { // RSASHA1
drc.d_key.append(modulus);
drc.d_protocol=3;
}
-#if 0
-void makeRSAPublicKeyFromDNS(rsa_context* rc, const DNSKEYRecordContent& dkrc)
-{
- rsa_init(rc, RSA_PKCS_V15, 0, NULL, NULL );
- mpi_read_binary(&rc->E, (unsigned char*)dkrc.getExponent().c_str(), dkrc.getExponent().length()); // exponent
- mpi_read_binary(&rc->N, (unsigned char*)dkrc.getModulus().c_str(), dkrc.getModulus().length()); // modulus
- rc->len = ( mpi_msb( &rc->N ) + 7 ) >> 3; // no clue what this does
+void RSADNSPrivateKey::fromPublicKeyString(unsigned int algorithm, const std::string& rawString)
+{
+ rsa_init(&d_context, RSA_PKCS_V15, 0, NULL, NULL );
+ 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]);
+ }
+ mpi_read_binary(&d_context.E, (unsigned char*)exponent.c_str(), exponent.length());
+ mpi_read_binary(&d_context.N, (unsigned char*)modulus.c_str(), modulus.length());
+ d_context.len = ( mpi_msb( &d_context.N ) + 7 ) >> 3; // no clue what this does
}
-#endif
+
string RSADNSPrivateKey::getPublicKeyString() const
{
string keystring;