]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/decafsigners.cc
Merge pull request #7862 from pieterlexis/update-boost-m4
[thirdparty/pdns.git] / pdns / decafsigners.cc
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
10 using namespace decaf;
11
12 class DecafED25519DNSCryptoKeyEngine : public DNSCryptoKeyEngine
13 {
14 public:
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
37 private:
38 unsigned char d_pubkey[DECAF_EDDSA_25519_PUBLIC_BYTES];
39 unsigned char d_seckey[DECAF_EDDSA_25519_PRIVATE_BYTES];
40 };
41
42 void 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
57 int DecafED25519DNSCryptoKeyEngine::getBits() const
58 {
59 return DECAF_EDDSA_25519_PRIVATE_BYTES << 3;
60 }
61
62 DNSCryptoKeyEngine::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
78 void 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
99 std::string DecafED25519DNSCryptoKeyEngine::getPubKeyHash() const
100 {
101 return this->getPublicKeyString();
102 }
103
104 std::string DecafED25519DNSCryptoKeyEngine::getPublicKeyString() const
105 {
106 return string((char*)d_pubkey, DECAF_EDDSA_25519_PUBLIC_BYTES);
107 }
108
109 void 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
117 std::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
128 bool 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
148 class DecafED448DNSCryptoKeyEngine : public DNSCryptoKeyEngine
149 {
150 public:
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
173 private:
174 unsigned char d_pubkey[DECAF_EDDSA_448_PUBLIC_BYTES];
175 unsigned char d_seckey[DECAF_EDDSA_448_PRIVATE_BYTES];
176 };
177
178 void 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
193 int DecafED448DNSCryptoKeyEngine::getBits() const
194 {
195 return DECAF_EDDSA_448_PRIVATE_BYTES << 3;
196 }
197
198 DNSCryptoKeyEngine::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
214 void 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
235 std::string DecafED448DNSCryptoKeyEngine::getPubKeyHash() const
236 {
237 return this->getPublicKeyString();
238 }
239
240 std::string DecafED448DNSCryptoKeyEngine::getPublicKeyString() const
241 {
242 return string((char*)d_pubkey, DECAF_EDDSA_448_PUBLIC_BYTES);
243 }
244
245 void 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
253 std::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
264 bool 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
284 namespace {
285 struct LoaderDecafStruct
286 {
287 LoaderDecafStruct()
288 {
289 DNSCryptoKeyEngine::report(15, &DecafED25519DNSCryptoKeyEngine::maker, true);
290 DNSCryptoKeyEngine::report(16, &DecafED448DNSCryptoKeyEngine::maker);
291 }
292 } loaderdecaf;
293 }