]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/decafsigners.cc
Merge pull request #9073 from pieterlexis/runtime-dirs-virtual-hosting
[thirdparty/pdns.git] / pdns / decafsigners.cc
CommitLineData
21a8834a
KM
1#ifdef HAVE_CONFIG_H
2#include "config.h"
3#endif
4#include <decaf.hxx>
5#include <decaf/eddsa.hxx>
6#include <decaf/spongerng.hxx>
7
8#include "dnssecinfra.hh"
9
10using namespace decaf;
11
12class DecafED25519DNSCryptoKeyEngine : public DNSCryptoKeyEngine
13{
14public:
15 explicit DecafED25519DNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo)
16 {
17
18 }
19 string getName() const override { return "Decaf ED25519"; }
20 void create(unsigned int bits) override;
21 storvector_t convertToISCVector() const override;
22 std::string getPubKeyHash() const override;
23 std::string sign(const std::string& msg) const override;
24 bool verify(const std::string& msg, const std::string& signature) const override;
25 std::string getPublicKeyString() const override;
26 int getBits() const override;
27 void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) override;
28 void fromPublicKeyString(const std::string& content) override;
29 void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) override
30 {}
31
32 static std::shared_ptr<DNSCryptoKeyEngine> maker(unsigned int algorithm)
33 {
34 return std::make_shared<DecafED25519DNSCryptoKeyEngine>(algorithm);
35 }
36
37private:
38 unsigned char d_pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES];
39 unsigned char d_seckey[DECAF_EDDSA_25519_PRIVATE_BYTES];
40};
41
42void DecafED25519DNSCryptoKeyEngine::create(unsigned int bits)
43{
44 if(bits != (unsigned int)getBits()) {
45 throw runtime_error("Unsupported key length of "+std::to_string(bits)+" bits requested, DecafED25519 class");
46 }
47
48 SpongeRng rng("/dev/urandom");
49
50 typename EdDSA<IsoEd25519>::PrivateKey priv(rng);
51 typename EdDSA<IsoEd25519>::PublicKey pub(priv);
52
53 priv.serialize_into(d_seckey);
54 pub.serialize_into(d_pubkey);
55}
56
57int DecafED25519DNSCryptoKeyEngine::getBits() const
58{
59 return DECAF_EDDSA_25519_PRIVATE_BYTES << 3;
60}
61
62DNSCryptoKeyEngine::storvector_t DecafED25519DNSCryptoKeyEngine::convertToISCVector() const
63{
64 /*
65 Private-key-format: v1.2
66 Algorithm: 15 (ED25519)
67 PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=
68 */
69
70 storvector_t storvector;
71
72 storvector.push_back(make_pair("Algorithm", "15 (ED25519)"));
73 storvector.push_back(make_pair("PrivateKey", string((char*)d_seckey, DECAF_EDDSA_25519_PRIVATE_BYTES)));
74
75 return storvector;
76}
77
78void DecafED25519DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
79{
80 /*
81 Private-key-format: v1.2
82 Algorithm: 15 (ED25519)
83 PrivateKey: ODIyNjAzODQ2MjgwODAxMjI2NDUxOTAyMDQxNDIyNjI=
84 */
85
86 drc.d_algorithm = pdns_stou(stormap["algorithm"]);
87 string privateKey = stormap["privatekey"];
88
89 if (privateKey.length() != DECAF_EDDSA_25519_PRIVATE_BYTES)
90 throw runtime_error("Private key size mismatch in ISCMap, DecafED25519 class");
91
92 typename EdDSA<IsoEd25519>::PrivateKey priv(Block((const unsigned char*)privateKey.c_str(), DECAF_EDDSA_25519_PRIVATE_BYTES));
93 typename EdDSA<IsoEd25519>::PublicKey pub(priv);
94
95 priv.serialize_into(d_seckey);
96 pub.serialize_into(d_pubkey);
97}
98
99std::string DecafED25519DNSCryptoKeyEngine::getPubKeyHash() const
100{
101 return this->getPublicKeyString();
102}
103
104std::string DecafED25519DNSCryptoKeyEngine::getPublicKeyString() const
105{
106 return string((char*)d_pubkey, DECAF_EDDSA_25519_PUBLIC_BYTES);
107}
108
109void DecafED25519DNSCryptoKeyEngine::fromPublicKeyString(const std::string& input)
110{
111 if (input.length() != DECAF_EDDSA_25519_PUBLIC_BYTES)
112 throw runtime_error("Public key size mismatch, DecafED25519 class");
113
114 memcpy(d_pubkey, input.c_str(), DECAF_EDDSA_25519_PUBLIC_BYTES);
115}
116
117std::string DecafED25519DNSCryptoKeyEngine::sign(const std::string& msg) const
118{
119 typename EdDSA<IsoEd25519>::PrivateKey priv(Block(d_seckey, DECAF_EDDSA_25519_PRIVATE_BYTES));
120
121 SecureBuffer message(msg.begin(), msg.end());
122
123 SecureBuffer sig = priv.sign(message);
124
125 return string(sig.begin(), sig.end());
126}
127
128bool DecafED25519DNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const
129{
130 if (signature.length() != DECAF_EDDSA_25519_SIGNATURE_BYTES)
131 return false;
132
133 typename EdDSA<IsoEd25519>::PublicKey pub(Block(d_pubkey, DECAF_EDDSA_25519_PUBLIC_BYTES));
134
135 SecureBuffer sig(signature.begin(), signature.end());
136 SecureBuffer message(msg.begin(), msg.end());
137
138 try {
139 pub.verify(sig, message);
140 } catch(CryptoException) {
141 return false;
142 }
143
144 return true;
145}
146
147
148class DecafED448DNSCryptoKeyEngine : public DNSCryptoKeyEngine
149{
150public:
151 explicit DecafED448DNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo)
152 {
153
154 }
155 string getName() const override { return "Decaf ED448"; }
156 void create(unsigned int bits) override;
157 storvector_t convertToISCVector() const override;
158 std::string getPubKeyHash() const override;
159 std::string sign(const std::string& msg) const override;
160 bool verify(const std::string& msg, const std::string& signature) const override;
161 std::string getPublicKeyString() const override;
162 int getBits() const override;
163 void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) override;
164 void fromPublicKeyString(const std::string& content) override;
165 void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) override
166 {}
167
168 static std::shared_ptr<DNSCryptoKeyEngine> maker(unsigned int algorithm)
169 {
170 return std::make_shared<DecafED448DNSCryptoKeyEngine>(algorithm);
171 }
172
173private:
174 unsigned char d_pubkey[DECAF_EDDSA_448_PUBLIC_BYTES];
175 unsigned char d_seckey[DECAF_EDDSA_448_PRIVATE_BYTES];
176};
177
178void DecafED448DNSCryptoKeyEngine::create(unsigned int bits)
179{
180 if(bits != (unsigned int)getBits()) {
181 throw runtime_error("Unsupported key length of "+std::to_string(bits)+" bits requested, DecafED448 class");
182 }
183
184 SpongeRng rng("/dev/urandom");
185
186 typename EdDSA<Ed448Goldilocks>::PrivateKey priv(rng);
187 typename EdDSA<Ed448Goldilocks>::PublicKey pub(priv);
188
189 priv.serialize_into(d_seckey);
190 pub.serialize_into(d_pubkey);
191}
192
193int DecafED448DNSCryptoKeyEngine::getBits() const
194{
195 return DECAF_EDDSA_448_PRIVATE_BYTES << 3;
196}
197
198DNSCryptoKeyEngine::storvector_t DecafED448DNSCryptoKeyEngine::convertToISCVector() const
199{
200 /*
201 Private-key-format: v1.2
202 Algorithm: 16 (ED448)
203 PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA
204 */
205
206 storvector_t storvector;
207
208 storvector.push_back(make_pair("Algorithm", "16 (ED448)"));
209 storvector.push_back(make_pair("PrivateKey", string((char*)d_seckey, DECAF_EDDSA_448_PRIVATE_BYTES)));
210
211 return storvector;
212}
213
214void DecafED448DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
215{
216 /*
217 Private-key-format: v1.2
218 Algorithm: 16 (ED448)
219 PrivateKey: xZ+5Cgm463xugtkY5B0Jx6erFTXp13rYegst0qRtNsOYnaVpMx0Z/c5EiA9x8wWbDDct/U3FhYWA
220 */
221
222 drc.d_algorithm = pdns_stou(stormap["algorithm"]);
223 string privateKey = stormap["privatekey"];
224
225 if (privateKey.length() != DECAF_EDDSA_448_PRIVATE_BYTES)
226 throw runtime_error("Private key size mismatch in ISCMap, DecafED448 class");
227
228 typename EdDSA<Ed448Goldilocks>::PrivateKey priv(Block((const unsigned char*)privateKey.c_str(), DECAF_EDDSA_448_PRIVATE_BYTES));
229 typename EdDSA<Ed448Goldilocks>::PublicKey pub(priv);
230
231 priv.serialize_into(d_seckey);
232 pub.serialize_into(d_pubkey);
233}
234
235std::string DecafED448DNSCryptoKeyEngine::getPubKeyHash() const
236{
237 return this->getPublicKeyString();
238}
239
240std::string DecafED448DNSCryptoKeyEngine::getPublicKeyString() const
241{
242 return string((char*)d_pubkey, DECAF_EDDSA_448_PUBLIC_BYTES);
243}
244
245void DecafED448DNSCryptoKeyEngine::fromPublicKeyString(const std::string& input)
246{
247 if (input.length() != DECAF_EDDSA_448_PUBLIC_BYTES)
248 throw runtime_error("Public key size mismatch, DecafED448 class");
249
250 memcpy(d_pubkey, input.c_str(), DECAF_EDDSA_448_PUBLIC_BYTES);
251}
252
253std::string DecafED448DNSCryptoKeyEngine::sign(const std::string& msg) const
254{
255 typename EdDSA<Ed448Goldilocks>::PrivateKey priv(Block(d_seckey, DECAF_EDDSA_448_PRIVATE_BYTES));
256
257 SecureBuffer message(msg.begin(), msg.end());
258
259 SecureBuffer sig = priv.sign(message);
260
261 return string(sig.begin(), sig.end());
262}
263
264bool DecafED448DNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const
265{
266 if (signature.length() != DECAF_EDDSA_448_SIGNATURE_BYTES)
267 return false;
268
269 typename EdDSA<Ed448Goldilocks>::PublicKey pub(Block(d_pubkey, DECAF_EDDSA_448_PUBLIC_BYTES));
270
271 SecureBuffer sig(signature.begin(), signature.end());
272 SecureBuffer message(msg.begin(), msg.end());
273
274 try {
275 pub.verify(sig, message);
276 } catch(CryptoException) {
277 return false;
278 }
279
280 return true;
281}
282
283
284namespace {
285struct LoaderDecafStruct
286{
287 LoaderDecafStruct()
288 {
48551c95 289 DNSCryptoKeyEngine::report(15, &DecafED25519DNSCryptoKeyEngine::maker, true);
21a8834a
KM
290 DNSCryptoKeyEngine::report(16, &DecafED448DNSCryptoKeyEngine::maker);
291 }
292} loaderdecaf;
293}