-// utf-8 UTF-8 utf8 UTF8
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <botan/botan.h>
-#include <botan/ecdsa.h>
#include <botan/gost_3410.h>
#include <botan/gost_3411.h>
-#include <botan/sha2_32.h>
-#include <botan/sha2_64.h>
-#include <botan/pubkey.h>
-#include <botan/look_pk.h>
#include "dnssecinfra.hh"
using namespace Botan;
//////////////////////////////
-class ECDSADNSCryptoKeyEngine : public DNSCryptoKeyEngine
-{
-public:
- explicit ECDSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo)
- {}
-
- ~ECDSADNSCryptoKeyEngine() {}
- // XXX FIXME NEEDS DEEP COPY CONSTRUCTOR SO WE DON'T SHARE KEYS
- string getName() const { return "Botan 1.10 ECDSA"; }
- void create(unsigned int bits);
- storvector_t convertToISCVector() 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 fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
- void fromPublicKeyString(const std::string& content);
- void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
- {}
-
- static DNSCryptoKeyEngine* maker(unsigned int algorithm)
- {
- return new ECDSADNSCryptoKeyEngine(algorithm);
- }
-
-private:
- static EC_Domain_Params getECParams(unsigned int algorithm);
- shared_ptr<ECDSA_PrivateKey> d_key;
- shared_ptr<ECDSA_PublicKey> d_pubkey;
-};
-
-EC_Domain_Params ECDSADNSCryptoKeyEngine::getECParams(unsigned int algorithm)
-{
- if(algorithm==13)
- return EC_Domain_Params("1.2.840.10045.3.1.7");
- else if(algorithm == 14)
- return EC_Domain_Params("1.3.132.0.34");
- else
- throw runtime_error("Requested for unknown EC domain parameters for algorithm "+to_string(algorithm));
-}
-
-void ECDSADNSCryptoKeyEngine::create(unsigned int bits)
-{
- AutoSeeded_RNG rng;
- EC_Domain_Params params;
- if(bits==256) {
- params = getECParams(13);
- }
- else if(bits == 384){
- params = getECParams(14);
- }
- else {
- throw runtime_error("Unknown key length of "+to_string(bits)+" bits requested from ECDSA class");
- }
- d_key = shared_ptr<ECDSA_PrivateKey>(new ECDSA_PrivateKey(rng, params));
-}
-
-int ECDSADNSCryptoKeyEngine::getBits() const
-{
- if(d_algorithm == 13)
- return 256;
- else if(d_algorithm == 14)
- return 384;
- return -1;
-}
-
-DNSCryptoKeyEngine::storvector_t ECDSADNSCryptoKeyEngine::convertToISCVector() const
-{
- /* Algorithm: 13 (ECDSAP256SHA256)
- PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */
- storvector_t storvect;
-
- string algorithm;
- if(getBits()==256)
- algorithm = "13 (ECDSAP256SHA256)";
- else if(getBits()==384)
- algorithm ="14 (ECDSAP384SHA384)";
- else
- algorithm =" ? (?)";
- storvect.push_back(make_pair("Algorithm", algorithm));
-
- const BigInt&x = d_key->private_value();
- SecureVector<byte> buffer=BigInt::encode(x);
- storvect.push_back(make_pair("PrivateKey", string((char*)&*buffer.begin(), (char*)&*buffer.end())));
-
- return storvect;
-}
-
-void ECDSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap)
-{
- /*Private-key-format: v1.2
- Algorithm: 13 (ECDSAP256SHA256)
- PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */
-
- drc.d_algorithm = pdns_stou(stormap["algorithm"]);
- if(drc.d_algorithm != d_algorithm)
- throw runtime_error("Tried to feed an algorithm "+to_string(drc.d_algorithm)+" to a "+to_string(d_algorithm)+" key!");
- string privateKey=stormap["privatekey"];
-
- BigInt bigint((byte*)privateKey.c_str(), privateKey.length());
- EC_Domain_Params params=getECParams(d_algorithm);
- AutoSeeded_RNG rng;
-
- d_key=shared_ptr<ECDSA_PrivateKey>(new ECDSA_PrivateKey(rng, params, bigint));
-}
-
-std::string ECDSADNSCryptoKeyEngine::getPubKeyHash() const
-{
- const BigInt&x = d_key->private_value(); // um, this is not the 'pubkeyhash', ahu
- SecureVector<byte> buffer=BigInt::encode(x);
- return string((const char*)buffer.begin(), (const char*)buffer.end());
-}
-
-std::string ECDSADNSCryptoKeyEngine::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<byte> 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 ECDSADNSCryptoKeyEngine::fromPublicKeyString(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);
-
- EC_Domain_Params params=getECParams(d_algorithm);
- PointGFp point(params.get_curve(), x,y);
- d_pubkey = shared_ptr<ECDSA_PublicKey>(new ECDSA_PublicKey(params, point));
- d_key.reset();
-}
-
-
-std::string ECDSADNSCryptoKeyEngine::sign(const std::string& msg) const
-{
- string hash = this->hash(msg);
- ECDSA_Signature_Operation ops(*d_key);
- AutoSeeded_RNG rng;
- SecureVector<byte> signature=ops.sign((byte*)hash.c_str(), hash.length(), rng);
-
- return string((const char*)signature.begin(), (const char*) signature.end());
-}
-
-std::string ECDSADNSCryptoKeyEngine::hash(const std::string& orig) const
-{
- SecureVector<byte> 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 ECDSADNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const
-{
- string hash = this->hash(msg);
- ECDSA_PublicKey* key;
- if(d_key)
- key = d_key.get();
- else
- key = d_pubkey.get();
- ECDSA_Verification_Operation ops(*key);
- return ops.verify ((byte*)hash.c_str(), hash.length(), (byte*)signature.c_str(), signature.length());
-}
-
namespace {
struct LoaderStruct
{
LoaderStruct()
{
- // 'botansigners' inits Botan for us
+ new Botan::LibraryInitializer("thread_safe=true");
+ // this leaks, but is fine
+ Botan::global_state().set_default_allocator("malloc"); // the other Botan allocator slows down for us
+
DNSCryptoKeyEngine::report(12, &GOSTDNSCryptoKeyEngine::maker);
- DNSCryptoKeyEngine::report(13, &ECDSADNSCryptoKeyEngine::maker, true);
- DNSCryptoKeyEngine::report(14, &ECDSADNSCryptoKeyEngine::maker, true);
}
-} loaderBotan19;
+} loaderBotan110;
}
+++ /dev/null
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-#include <botan/botan.h>
-#include <botan/sha160.h>
-#include <botan/sha2_32.h>
-#include <botan/sha2_64.h>
-#include <botan/emsa3.h>
-#include <botan/rsa.h>
-#include <botan/pubkey.h>
-#include <botan/look_pk.h>
-#include <botan/numthry.h>
-#include "dnssecinfra.hh"
-#include <stdlib.h>
-
-using namespace Botan;
-
-class BotanRSADNSCryptoKeyEngine : public DNSCryptoKeyEngine
-{
-public:
- explicit BotanRSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo)
- {
- // cerr<<"Called"<<endl;
- }
-
- ~BotanRSADNSCryptoKeyEngine(){}
-
- string getName() const { return "Botan RSA"; }
- void create(unsigned int bits);
- storvector_t convertToISCVector() const;
- std::string getPubKeyHash() const;
- std::string sign(const std::string& msg) const;
- std::string hash(const std::string& hash) const;
- bool verify(const std::string& msg, const std::string& signature) const;
- std::string getPublicKeyString() const;
- int getBits() const;
- void fromISCMap(DNSKEYRecordContent& drc, stormap_t& stormap);
- void fromPublicKeyString(const std::string& content);
- void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw)
- {}
-
- static DNSCryptoKeyEngine* maker(unsigned int algorithm)
- {
- return new BotanRSADNSCryptoKeyEngine(algorithm);
- }
-
-private:
- shared_ptr<RSA_PrivateKey> d_key;
- shared_ptr<RSA_PublicKey> d_pubkey;
-};
-
-void BotanRSADNSCryptoKeyEngine::create(unsigned int bits)
-{
- AutoSeeded_RNG rng;
- d_key = shared_ptr<RSA_PrivateKey>(new RSA_PrivateKey(rng, bits));
-}
-
-int BotanRSADNSCryptoKeyEngine::getBits() const
-{
- return d_key->max_input_bits() + 1;
-}
-
-namespace {
-string asRaw(const BigInt& x)
-{
- SecureVector<byte> buffer=BigInt::encode(x);
- return string((const char*)&*buffer.begin(), (const char*)&*buffer.end());
-}
-
-BigInt fromRaw(const std::string& raw)
-{
- if(raw.empty())
- throw runtime_error("Unable to decode empty value");
- return BigInt::decode((byte*)raw.c_str(), raw.length());
-}
-}
-
-DNSCryptoKeyEngine::storvector_t BotanRSADNSCryptoKeyEngine::convertToISCVector() const
-{
- storvector_t storvect;
- string algorithm = std::to_string(d_algorithm);
- if(d_algorithm == 5 || d_algorithm ==7 )
- algorithm += " (RSASHA1)";
- else if(d_algorithm == 8)
- algorithm += " (RSASHA256)";
- else if(d_algorithm == 10)
- algorithm += " (RSASHA512)";
- else
- algorithm += " (?)";
- storvect.push_back(make_pair("Algorithm", algorithm));
- storvect.push_back(make_pair("Modulus", asRaw(d_key->get_n())));
- storvect.push_back(make_pair("PublicExponent",asRaw(d_key->get_e())));
- storvect.push_back(make_pair("PrivateExponent",asRaw(d_key->get_d())));
- storvect.push_back(make_pair("Prime1",asRaw(d_key->get_p())));
- storvect.push_back(make_pair("Prime2",asRaw(d_key->get_q())));
-
-#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
- BigInt d1 = d_key->get_d() % (d_key->get_p() - 1);
- BigInt d2 = d_key->get_d() % (d_key->get_q() - 1);
- BigInt c = inverse_mod(d_key->get_q(), d_key->get_p());
-#else
- BigInt d1 = d_key->get_d1();
- BigInt d2 = d_key->get_d2();
- BigInt c = d_key->get_c();
-#endif
- storvect.push_back(make_pair("Exponent1", asRaw(d1)));
- storvect.push_back(make_pair("Exponent2", asRaw(d2)));
- storvect.push_back(make_pair("Coefficient", asRaw(c)));
- return storvect;
-}
-
-void BotanRSADNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
-{
- // wants p (Prime1), q (Prime2), d (PrivateExponent), e (PublicExponent) & n Modulus
- BigInt n, e, d, p, q;
-
- p=fromRaw(stormap["prime1"]);
- q=fromRaw(stormap["prime2"]);
- d=fromRaw(stormap["privateexponent"]);
- e=fromRaw(stormap["publicexponent"]);
- n=fromRaw(stormap["modulus"]);
-
- drc.d_algorithm = pdns_stou(stormap["algorithm"]);
- if(drc.d_algorithm != d_algorithm)
- throw runtime_error("Unpossible, loaded a key from storage with wrong algorithm!");
-
- AutoSeeded_RNG rng;
- d_key = shared_ptr<RSA_PrivateKey>(new RSA_PrivateKey(rng, p, q, e, d, n)); // this calculates d1, d2 & other stuff, plus does load checks..
-
- d_pubkey.reset();
-}
-
-std::string BotanRSADNSCryptoKeyEngine::getPubKeyHash() const
-{
- const BigInt& n = d_key->get_n();
- const BigInt& e = d_key->get_e();
- SecureVector<byte> buffer=BigInt::encode(n);
-
- SHA_160 hasher;
- hasher.update(buffer);
- buffer=BigInt::encode(e);
- hasher.update(buffer);
- SecureVector<byte> hash=hasher.final();
- return string((const char*)hash.begin(), (const char*)hash.end());
-}
-
-std::string BotanRSADNSCryptoKeyEngine::getPublicKeyString() const
-{
- MemoryVector<byte> bits = BigInt::encode(d_key->get_e());
- string exponent(&*bits.begin(), &*bits.end());
- bits = BigInt::encode(d_key->get_n());
- string modulus(&*bits.begin(), &*bits.end());
-
- string keystring;
- if(exponent.length() < 255)
- keystring.assign(1, (char) (unsigned int) exponent.length());
- else {
- keystring.assign(1, 0);
- uint16_t len=htons(exponent.length());
- keystring.append((char*)&len, 2);
- }
- keystring.append(exponent);
- keystring.append(modulus);
- return keystring;
-}
-
-void BotanRSADNSCryptoKeyEngine::fromPublicKeyString(const std::string& rawString)
-{
- 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]);
- }
- BigInt e = BigInt::decode((const byte*)exponent.c_str(), exponent.length());
- BigInt n = BigInt::decode((const byte*)modulus.c_str(), modulus.length());
-
- d_pubkey = shared_ptr<RSA_PublicKey>(new RSA_PublicKey(n, e));
- d_key.reset();
-}
-
-std::string BotanRSADNSCryptoKeyEngine::sign(const std::string& msg) const
-{
-#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
- EMSA* emsaptr;
- if(d_algorithm == 5 || d_algorithm ==7)
- emsaptr=new EMSA3(new SHA_160);
- else if(d_algorithm==8)
- emsaptr=new EMSA3(new SHA_256);
- else
- emsaptr=new EMSA3(new SHA_512);
- PK_Signer pks(*d_key, emsaptr);
-#else
- string emsa;
- if(d_algorithm == 5 || d_algorithm ==7)
- emsa="EMSA3(SHA-160)";
- else if(d_algorithm==8)
- emsa="EMSA3(SHA-256)";
- else
- emsa="EMSA3(SHA-512)";
- PK_Signer pks(*d_key, emsa);
-#endif
-
- AutoSeeded_RNG rng;
- SecureVector<byte> signature= pks.sign_message((byte*)msg.c_str(), msg.length(), rng);
- return string((const char*)signature.begin(), (const char*) signature.end());
-}
-
-std::string BotanRSADNSCryptoKeyEngine::hash(const std::string& orig) const
-{
- SecureVector<byte> result;
- if(d_algorithm == 5 || d_algorithm ==7 ) { // SHA160
- SHA_160 hasher;
- result= hasher.process(orig);
- }
- if(d_algorithm == 8) { // SHA256
- SHA_256 hasher;
- result= hasher.process(orig);
- }
- else if(d_algorithm==10) { // SHA512
- SHA_512 hasher;
- result = hasher.process(orig);
- }
-
- return string((const char*)result.begin(), (const char*) result.end());
-}
-
-
-bool BotanRSADNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const
-{
- RSA_PublicKey* key = d_key ? d_key.get() : d_pubkey.get();
-
- string emsa;
-
- if(d_algorithm == 5 || d_algorithm ==7)
- emsa = "EMSA3(SHA-1)";
- else if(d_algorithm==8)
- emsa = "EMSA3(SHA-256)";
- else
- emsa = "EMSA3(SHA-512)";
-
-#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(1,9,0)
- std::auto_ptr<PK_Verifier> ver(get_pk_verifier(*key, emsa));
- return ver->verify_message((byte*)msg.c_str(), msg.length(), (byte*)signature.c_str(), signature.length());
-#else
- PK_Verifier pkv(*key, emsa);
- return pkv.verify_message((byte*)msg.c_str(), msg.length(), (byte*)signature.c_str(), signature.length());
-#endif
-}
-
-namespace {
-struct LoaderBotanStruct
-{
- LoaderBotanStruct()
- {
- new Botan::LibraryInitializer("thread_safe=true");
- // this leaks, but is fine
- Botan::global_state().set_default_allocator("malloc"); // the other Botan allocator slows down for us
-
- DNSCryptoKeyEngine::report(5, &BotanRSADNSCryptoKeyEngine::maker);
- DNSCryptoKeyEngine::report(7, &BotanRSADNSCryptoKeyEngine::maker);
- DNSCryptoKeyEngine::report(8, &BotanRSADNSCryptoKeyEngine::maker);
- DNSCryptoKeyEngine::report(10, &BotanRSADNSCryptoKeyEngine::maker);
- }
-} loaderBotan;
-}
-