]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/cryptoppsigners.cc
Include config.h only in .cc files
[thirdparty/pdns.git] / pdns / cryptoppsigners.cc
CommitLineData
870a0fe4
AT
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
189bb9d2
BH
4#include <cryptopp/osrng.h>
5#include <cryptopp/aes.h>
6#include <cryptopp/integer.h>
7#include <cryptopp/sha.h>
8#include <cryptopp/eccrypto.h>
9#include <cryptopp/oids.h>
10#include <cryptopp/filters.h>
11#include "dnssecinfra.hh"
12using namespace CryptoPP;
13
14template<class HASHER, class CURVE, int BITS>
15class CryptoPPECDSADNSCryptoKeyEngine : public DNSCryptoKeyEngine
16{
17public:
18 explicit CryptoPPECDSADNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo)
19 {}
20 void create(unsigned int bits);
21 string getName() const { return "CryptoPP ECDSA"; }
2263e827 22 storvector_t convertToISCVector() const;
189bb9d2
BH
23 std::string getPubKeyHash() const;
24 std::string sign(const std::string& msg) const;
25 std::string hash(const std::string& hash) const;
26 bool verify(const std::string& msg, const std::string& signature) const;
27 std::string getPublicKeyString() const;
28 int getBits() const;
29 void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap);
30 void fromPublicKeyString(const std::string& content);
31 // void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw);
32
33 static DNSCryptoKeyEngine* maker(unsigned int algorithm)
34 {
35 return new CryptoPPECDSADNSCryptoKeyEngine(algorithm);
36 }
37
38private:
39 typedef typename ECDSA<ECP, HASHER>::PrivateKey privatekey_t;
40 typedef typename ECDSA<ECP, HASHER>::PublicKey publickey_t;
41 shared_ptr<privatekey_t> d_key;
42 shared_ptr<publickey_t> d_pubkey;
43};
44
45template<class HASHER, class CURVE, int BITS> void CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::create(unsigned int bits)
46{
47 if(bits != BITS)
48 throw runtime_error("This CryptoPP class can only hosts keys of length "+lexical_cast<string>(BITS));
49 AutoSeededRandomPool prng;
50 privatekey_t* privateKey = new privatekey_t();
51 CryptoPP::OID oid=CURVE();
52 privateKey->Initialize( prng, oid);
53 d_key= shared_ptr<privatekey_t>(privateKey);
54
55 publickey_t* publicKey = new publickey_t();
56 d_key->MakePublicKey(*publicKey);
57 d_pubkey = shared_ptr<publickey_t>(publicKey);
58}
59
60template<class HASHER, class CURVE, int BITS>
61int CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::getBits() const
62{
63 return BITS;
64}
65
66template<class HASHER, class CURVE, int BITS>
2263e827 67DNSCryptoKeyEngine::storvector_t CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::convertToISCVector() const
189bb9d2
BH
68{
69 /* Algorithm: 13 (ECDSAP256SHA256)
70 PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= */
71 string algostr=lexical_cast<string>(d_algorithm);
72 if(d_algorithm==13)
73 algostr+=" (ECDSAP256SHA256)";
74 else if(d_algorithm==14)
75 algostr+=" (ECDSAP384SHA384)";
76 else
77 algostr+=" (?)";
78
2263e827
BH
79 storvector_t storvect;
80 storvect.push_back(make_pair("Algorithm", algostr));
189bb9d2
BH
81
82 const CryptoPP::Integer& pe=d_key->GetPrivateExponent();
83 unsigned char buffer[pe.MinEncodedSize()];
84 pe.Encode(buffer, pe.MinEncodedSize());
2263e827
BH
85 storvect.push_back(make_pair("PrivateKey", string((char*)buffer, sizeof(buffer))));
86 return storvect;
189bb9d2 87}
9b9fca68 88
189bb9d2
BH
89template<class HASHER, class CURVE, int BITS>
90void CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
91{
9b9fca68 92 AutoSeededRandomPool prng;
189bb9d2 93 privatekey_t* privateKey = new privatekey_t;
9b9fca68 94 const CryptoPP::Integer x(reinterpret_cast<const unsigned char*>(stormap["privatekey"].c_str()), BITS/8); // well it should be this long
189bb9d2 95 CryptoPP::OID oid=CURVE();
9b9fca68
PD
96 privateKey->Initialize(oid, x);
97 bool result = privateKey->Validate(prng, 3);
98 if (!result) {
6d40be6a 99 throw runtime_error("Cannot load private key - validation failed!");
9b9fca68 100 }
189bb9d2
BH
101 d_key = shared_ptr<privatekey_t>(privateKey);
102 publickey_t* publicKey = new publickey_t();
103 d_key->MakePublicKey(*publicKey);
104 d_pubkey = shared_ptr<publickey_t>(publicKey);
9b9fca68 105 drc.d_algorithm = atoi(stormap["algorithm"].c_str());
189bb9d2 106}
9b9fca68 107
189bb9d2
BH
108template<class HASHER, class CURVE, int BITS>
109std::string CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::getPubKeyHash() const
110{
111 return getPublicKeyString(); // sad, hashme please!
112}
113template<class HASHER, class CURVE, int BITS>
114std::string CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::getPublicKeyString() const
115{
116 const ECP::Point& q = d_pubkey->GetPublicElement();
117
118 const CryptoPP::Integer& qx = q.x;
119 const CryptoPP::Integer& qy = q.y;
120
121 unsigned char buffer[qx.MinEncodedSize() + qy.MinEncodedSize()];
122 qx.Encode(buffer, qx.MinEncodedSize());
123 qy.Encode(buffer + qx.MinEncodedSize(), qy.MinEncodedSize());
124
125 return string((char*)buffer, sizeof(buffer));
126}
127template<class HASHER, class CURVE, int BITS>
128void CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::fromPublicKeyString(const std::string& rawString)
129{
130 CryptoPP::Integer x, y;
131 x.Decode((byte*)rawString.c_str(), rawString.size()/2);
132 y.Decode((byte*)rawString.c_str() + rawString.size()/2, rawString.size()/2);
133
134 ECP::Point q(x,y);
135
136 publickey_t* pubkey = new publickey_t;
137 CryptoPP::OID oid=CURVE();
138 pubkey->Initialize(oid, q);
139 d_pubkey = shared_ptr<publickey_t>(pubkey);
140 d_key.reset();
141}
142template<class HASHER, class CURVE, int BITS>
143std::string CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::sign(const std::string& msg) const
144{
145 string signature;
146 AutoSeededRandomPool prng;
147 StringSource( msg, true /*pump all*/,
148 new SignerFilter( prng,
149 typename ECDSA<ECP,HASHER>::Signer( *d_key ),
150 new StringSink( signature )
151 ) // SignerFilter
152 ); // StringSource
153 return signature;
154
155}
156template<class HASHER, class CURVE, int BITS>
157std::string CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::hash(const std::string& orig) const
158{
159 string hash;
160 HASHER hasher;
161 StringSource( orig, true /*pump all*/,
162 new HashFilter(hasher, new StringSink( hash )
163 ) // HashFilter
164 ); // StringSource
165 return hash;
166}
167template<class HASHER, class CURVE, int BITS>
168bool CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::verify(const std::string& msg, const std::string& signature) const
169{
170 byte result;
171 StringSource( signature+msg, true /*pump all*/,
172 new SignatureVerificationFilter(
173 typename ECDSA<ECP,HASHER>::Verifier(*d_pubkey),
174 new ArraySink( (byte*)&result, sizeof(result) )
175 ) // SignatureVerificationFilter
176 );
177 return result;
178}
179
180namespace {
181struct WrapperSECP256R1
182{
183 operator CryptoPP::OID () const { return CryptoPP::ASN1::secp256r1(); }
184};
185struct WrapperSECP384R1
186{
187 operator CryptoPP::OID () const { return CryptoPP::ASN1::secp384r1(); }
188};
189struct LoaderStruct
190{
191 LoaderStruct()
192 {
193 DNSCryptoKeyEngine::report(13, &CryptoPPECDSADNSCryptoKeyEngine<SHA256, WrapperSECP256R1, 256>::maker);
194 DNSCryptoKeyEngine::report(14, &CryptoPPECDSADNSCryptoKeyEngine<SHA384, WrapperSECP384R1, 384>::maker);
195 }
d01feff7 196} loaderCryptoPP;
189bb9d2 197}