From: Bert Hubert Date: Wed, 26 Jan 2011 16:04:37 +0000 (+0000) Subject: First part of the GOST support: R 34.10-2001, GOST R 34.11-94 will follow. As a speci... X-Git-Tag: auth-3.0~335 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7982887bca7ee7f7f32c5b53cadff69ba7628fd;p=pdns First part of the GOST support: R 34.10-2001, GOST R 34.11-94 will follow. As a special bonus, this code has a song in it! git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1912 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/botan19signers.cc b/pdns/botan19signers.cc index 63084ed7a..e812cb588 100644 --- a/pdns/botan19signers.cc +++ b/pdns/botan19signers.cc @@ -1,11 +1,204 @@ #include #include +#include #include #include #include "dnssecinfra.hh" using namespace Botan; +/* Государственный гимн Российской Федерации + (Gosudarstvenny Gimn Rossiyskoy Federatsii) + "The National Anthem of the Russian Federation" + + ~ Rossiya - svyashchennaya nasha derzhava, ~ + ~ Rossiya - lyubimaya nasha strana. ~ + ~ Moguchaya volya, velikaya slava - ~ + ~ Tvoyo dostoyanye na vse vremena! ~ + */ + +class GOSTDNSPrivateKey : public DNSPrivateKey +{ +public: + void create(unsigned int bits); + std::string convertToISC(unsigned int algorithm) const; + std::string getPubKeyHash() const; + std::string sign(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) + {} + + static DNSPrivateKey* maker(unsigned int algorithm) + { + return new GOSTDNSPrivateKey(); + } + +private: + shared_ptr d_key; +}; + +/* + ~ Slav'sya, Otechestvo nashe svobodnoye, ~ + ~ Bratskikh narodov soyuz vekovoy, ~ + ~ Predkami dannaya mudrost' narodnaya! ~ + ~ Slav'sya, strana! My gordimsya toboy! ~ +*/ + + +void GOSTDNSPrivateKey::create(unsigned int bits) +{ + AutoSeeded_RNG rng; + EC_Domain_Params params("1.2.643.2.2.35.1"); + d_key = shared_ptr(new GOST_3410_PrivateKey(rng, params)); + cerr<<"Made a key!"< buffer=BigInt::encode(d_key->private_value()); + + Pipe pipe(new Base64_Encoder); + pipe.start_msg(); + pipe.write(asn1Prefix, sizeof(asn1Prefix)); + pipe.write(buffer); + pipe.end_msg(); + ret<(new GOST_3410_PrivateKey(params, bigint)); + + //cerr<<"Is the just imported key on the curve? " << d_key->public_point().on_the_curve()<public_point().is_zero()<private_value(); + SecureVector buffer=BigInt::encode(x); + // cerr<<"And out again! "<private_value(); + SecureVector buffer=BigInt::encode(x); + return string((const char*)buffer.begin(), (const char*)buffer.end()); +} + +std::string GOSTDNSPrivateKey::getPublicKeyString() const +{ + const BigInt&x =d_key->public_point().get_affine_x(); + const BigInt&y =d_key->public_point().get_affine_y(); + + size_t part_size = std::max(x.bytes(), y.bytes()); + + MemoryVector bits(2*part_size); + + x.binary_encode(&bits[part_size - x.bytes()]); + y.binary_encode(&bits[2*part_size - y.bytes()]); + + // Keys are stored in little endian format (WTF) + for(size_t i = 0; i != part_size / 2; ++i) + { + std::swap(bits[i], bits[part_size-1-i]); + std::swap(bits[part_size+i], bits[2*part_size-1-i]); + } + + return string((const char*)bits.begin(), (const char*)bits.end()); +} + +/* + ~ Shirokiy prostor dlya mechty i dlya zhizni. ~ + ~ Gryadushchiye nam otkryvayut goda. ~ + ~ Nam silu dayot nasha vernost' Otchizne. ~ + ~ Tak bylo, tak yest' i tak budet vsegda! ~ + */ + +std::string GOSTDNSPrivateKey::sign(const std::string& hash) const +{ + GOST_3410_Signature_Operation ops(*d_key); + AutoSeeded_RNG rng; + SecureVector signature=ops.sign((byte*)hash.c_str(), hash.length(), rng); + + return string((const char*)signature.begin(), (const char*) signature.end()); +} + +bool GOSTDNSPrivateKey::verify(const std::string& hash, const std::string& signature) const +{ + GOST_3410_Verification_Operation ops(*d_key); + return ops.verify ((byte*)hash.c_str(), hash.length(), (byte*)signature.c_str(), signature.length()); +} + +/* + ~ Slav'sya, Otechestvo nashe svobodnoye, ~ + ~ Bratskikh narodov soyuz vekovoy, ~ + ~ Predkami dannaya mudrost' narodnaya! ~ + ~ Slav'sya, strana! My gordimsya toboy! ~ +*/ + + +////////////////////////////// + class ECDSADNSPrivateKey : public DNSPrivateKey { public: @@ -161,7 +354,7 @@ struct LoaderStruct { LoaderStruct() { - //DNSPrivateKey::report(12, &GOSTDNSPrivateKey::maker); + DNSPrivateKey::report(12, &GOSTDNSPrivateKey::maker); DNSPrivateKey::report(13, &ECDSADNSPrivateKey::maker); DNSPrivateKey::report(14, &ECDSADNSPrivateKey::maker); } diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index e2d31bb49..510b5357f 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -82,7 +82,7 @@ void DNSSECKeeper::addKey(const std::string& name, bool keyOrZone, int algorithm if(algorithm <= 10) bits = keyOrZone ? 2048 : 1024; else { - if(algorithm == 13) + if(algorithm == 12 || algorithm == 13) bits = 256; else if(algorithm == 14) bits = 384; diff --git a/pdns/pdnssec.cc b/pdns/pdnssec.cc index 7b2218193..30a507352 100644 --- a/pdns/pdnssec.cc +++ b/pdns/pdnssec.cc @@ -311,8 +311,10 @@ try algorithm=5; else if(pdns_iequals(cmds[n], "rsasha256")) algorithm=8; - else if(pdns_iequals(cmds[n], "gost")) + else if(pdns_iequals(cmds[n], "rsasha512")) algorithm=10; + else if(pdns_iequals(cmds[n], "gost")) + algorithm=12; else if(pdns_iequals(cmds[n], "ecdsa256")) algorithm=13; else if(pdns_iequals(cmds[n], "ecdsa384"))