From: Bert Hubert Date: Mon, 31 Jan 2011 10:37:03 +0000 (+0000) Subject: mostly so people can see it - this file should be able to sign ECDSA & RSA at high... X-Git-Tag: auth-3.0~300 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=92d05419396b441bc6bb152b5853ee1f8e48c715;p=pdns mostly so people can see it - this file should be able to sign ECDSA & RSA at high speed soon enough, but not right now git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1947 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/botan18signers.cc b/pdns/botan18signers.cc new file mode 100644 index 000000000..c250990c8 --- /dev/null +++ b/pdns/botan18signers.cc @@ -0,0 +1,241 @@ +// utf-8 UTF-8 utf8 UTF8 +#include +#include +#include +#include +#include +#include +#include +#include "dnssecinfra.hh" + +using namespace Botan; + +////////////////////////////// + +class ECDSADNSPrivateKey : public DNSPrivateKey +{ +public: + explicit ECDSADNSPrivateKey(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 fromISCString(DNSKEYRecordContent& drc, const std::string& content); + 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 ECDSADNSPrivateKey(algorithm); + } + +private: + static EC_Domain_Params getECParams(unsigned int algorithm); + shared_ptr d_key; + shared_ptr d_pubkey; + unsigned int d_algorithm; +}; + +EC_Domain_Params ECDSADNSPrivateKey::getECParams(unsigned int algorithm) +{ + if(algorithm==13) + return get_EC_Dom_Pars_by_oid("1.2.840.10045.3.1.7"); + else if(algorithm == 14) + return get_EC_Dom_Pars_by_oid("1.3.132.0.34"); + else + throw runtime_error("Requested for unknown EC domain parameters for algorithm "+lexical_cast(algorithm)); +} + +void ECDSADNSPrivateKey::create(unsigned int bits) +{ + AutoSeeded_RNG rng; + if(bits != 256 && bits != 384) { + throw runtime_error("Unknown key length of "+lexical_cast(bits)+" bits requested from ECDSA class"); + } + d_key = shared_ptr(new ECDSA_PrivateKey(rng, getECParams((bits == 256) ? 13 : 14))); + + + PKCS8_Encoder* pk8e= d_key->pkcs8_encoder(); + MemoryVector getbits=pk8e->key_bits(); + cerr<private_value(); + SecureVector buffer=BigInt::encode(x); + cerr<private_value(); + SecureVector buffer=BigInt::encode(x); + + Pipe pipe(new Base64_Encoder); + pipe.process_msg(buffer); + ret<(new ECDSA_PrivateKey); + cerr<<"Reading!"<pkcs8_decoder(rng); + unsigned char pkcs8header[]= {0x30, 0x25, 0x02, 0x01, 0x01, 0x04, 0x20}; + if(privateKey.length()*8 == 384) { + pkcs8header[1]+=0x10; + pkcs8header[6]+=0x10; + d_key->set_domain_parameters(getECParams(14)); + } + else + d_key->set_domain_parameters(getECParams(13)); + + string noIdea((char*)pkcs8header, sizeof(pkcs8header)); + noIdea.append(privateKey); + + MemoryVector tmp((byte*)noIdea.c_str(), noIdea.length()); + cerr<<"key_bits"<key_bits(tmp); + cerr<<"Done reading"<private_value(); + SecureVector buffer=BigInt::encode(x); + return string((const char*)buffer.begin(), (const char*)buffer.end()); +} + +std::string ECDSADNSPrivateKey::getPublicKeyString() const +{ + const BigInt&x =d_key->public_point().get_affine_x().get_value(); + const BigInt&y =d_key->public_point().get_affine_y().get_value(); + + 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()]); + return string((const char*)bits.begin(), (const char*)bits.end()); +} + +void ECDSADNSPrivateKey::fromPublicKeyString(unsigned int algorithm, const std::string&input) +{ + BigInt x, y; + + x.binary_decode((const byte*)input.c_str(), input.length()/2); + y.binary_decode((const byte*)input.c_str() + input.length()/2, input.length()/2); + + d_algorithm = algorithm; + + EC_Domain_Params params=getECParams(algorithm); + GFpElement gfpx(params.get_curve().get_ptr_mod(), x); + GFpElement gfpy(params.get_curve().get_ptr_mod(), y); + PointGFp point(params.get_curve(), gfpx,gfpy); + d_pubkey = shared_ptr(new ECDSA_PublicKey(params, point)); + d_key.reset(); +} + + +std::string ECDSADNSPrivateKey::sign(const std::string& hash) const +{ + AutoSeeded_RNG rng; + SecureVector signature=d_key->sign((byte*)hash.c_str(), hash.length(), rng); + + return string((const char*)signature.begin(), (const char*) signature.end()); +} + +std::string ECDSADNSPrivateKey::hash(const std::string& orig) const +{ + SecureVector result; + if(getBits() == 256) { // SHA256 + SHA_256 hasher; + result= hasher.process(orig); + } + else { // SHA384 + SHA_384 hasher; + result = hasher.process(orig); + } + + return string((const char*)result.begin(), (const char*) result.end()); +} + + +bool ECDSADNSPrivateKey::verify(const std::string& hash, const std::string& signature) const +{ + ECDSA_PublicKey* key; + if(d_key) + key = d_key.get(); + else + key = d_pubkey.get(); + + return key->verify((byte*)hash.c_str(), hash.length(), (byte*)signature.c_str(), signature.length()); +} + +namespace { +struct LoaderStruct +{ + LoaderStruct() + { + // DNSPrivateKey::report(12, &GOSTDNSPrivateKey::maker); + DNSPrivateKey::report(13, &ECDSADNSPrivateKey::maker); + DNSPrivateKey::report(14, &ECDSADNSPrivateKey::maker); + } +} loader; +}