]>
Commit | Line | Data |
---|---|---|
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" | |
12 | using namespace CryptoPP; | |
13 | ||
14 | template<class HASHER, class CURVE, int BITS> | |
15 | class CryptoPPECDSADNSCryptoKeyEngine : public DNSCryptoKeyEngine | |
16 | { | |
17 | public: | |
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 | ||
38 | private: | |
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 | ||
45 | template<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 | ||
60 | template<class HASHER, class CURVE, int BITS> | |
61 | int CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::getBits() const | |
62 | { | |
63 | return BITS; | |
64 | } | |
65 | ||
66 | template<class HASHER, class CURVE, int BITS> | |
2263e827 | 67 | DNSCryptoKeyEngine::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 |
89 | template<class HASHER, class CURVE, int BITS> |
90 | void 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 |
108 | template<class HASHER, class CURVE, int BITS> |
109 | std::string CryptoPPECDSADNSCryptoKeyEngine<HASHER,CURVE,BITS>::getPubKeyHash() const | |
110 | { | |
111 | return getPublicKeyString(); // sad, hashme please! | |
112 | } | |
113 | template<class HASHER, class CURVE, int BITS> | |
114 | std::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 | } | |
127 | template<class HASHER, class CURVE, int BITS> | |
128 | void 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 | } | |
142 | template<class HASHER, class CURVE, int BITS> | |
143 | std::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 | } | |
156 | template<class HASHER, class CURVE, int BITS> | |
157 | std::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 | } | |
167 | template<class HASHER, class CURVE, int BITS> | |
168 | bool 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 | ||
180 | namespace { | |
181 | struct WrapperSECP256R1 | |
182 | { | |
183 | operator CryptoPP::OID () const { return CryptoPP::ASN1::secp256r1(); } | |
184 | }; | |
185 | struct WrapperSECP384R1 | |
186 | { | |
187 | operator CryptoPP::OID () const { return CryptoPP::ASN1::secp384r1(); } | |
188 | }; | |
189 | struct 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 | } |