]>
Commit | Line | Data |
---|---|---|
d4f29089 KM |
1 | extern "C" { |
2 | #ifdef HAVE_CONFIG_H | |
3 | #include "config.h" | |
4 | #endif | |
5 | #include <sodium.h> | |
6 | } | |
7 | #include "dnssecinfra.hh" | |
8 | ||
9 | class SodiumED25519DNSCryptoKeyEngine : public DNSCryptoKeyEngine | |
10 | { | |
11 | public: | |
12 | explicit SodiumED25519DNSCryptoKeyEngine(unsigned int algo) : DNSCryptoKeyEngine(algo) | |
13 | {} | |
e69c2dac RG |
14 | string getName() const override { return "Sodium ED25519"; } |
15 | void create(unsigned int bits) override; | |
16 | storvector_t convertToISCVector() const override; | |
17 | std::string getPubKeyHash() const override; | |
7c9c554a | 18 | std::string sign(const std::string& msg) const override; |
e69c2dac RG |
19 | bool verify(const std::string& msg, const std::string& signature) const override; |
20 | std::string getPublicKeyString() const override; | |
21 | int getBits() const override; | |
22 | void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap) override; | |
23 | void fromPublicKeyString(const std::string& content) override; | |
24 | void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) override | |
d4f29089 KM |
25 | {} |
26 | ||
e69c2dac | 27 | static std::shared_ptr<DNSCryptoKeyEngine> maker(unsigned int algorithm) |
d4f29089 | 28 | { |
e69c2dac | 29 | return std::make_shared<SodiumED25519DNSCryptoKeyEngine>(algorithm); |
d4f29089 KM |
30 | } |
31 | ||
32 | private: | |
33 | unsigned char d_pubkey[crypto_sign_ed25519_PUBLICKEYBYTES]; | |
34 | unsigned char d_seckey[crypto_sign_ed25519_SECRETKEYBYTES]; | |
35 | }; | |
36 | ||
37 | void SodiumED25519DNSCryptoKeyEngine::create(unsigned int bits) | |
38 | { | |
39 | if(bits != crypto_sign_ed25519_SEEDBYTES * 8) { | |
335da0ba | 40 | throw runtime_error("Unsupported key length of "+std::to_string(bits)+" bits requested, SodiumED25519 class"); |
d4f29089 KM |
41 | } |
42 | crypto_sign_ed25519_keypair(d_pubkey, d_seckey); | |
43 | } | |
44 | ||
45 | int SodiumED25519DNSCryptoKeyEngine::getBits() const | |
46 | { | |
47 | return crypto_sign_ed25519_SEEDBYTES * 8; | |
48 | } | |
49 | ||
50 | DNSCryptoKeyEngine::storvector_t SodiumED25519DNSCryptoKeyEngine::convertToISCVector() const | |
51 | { | |
52 | /* | |
53 | Private-key-format: v1.2 | |
9d3727e0 | 54 | Algorithm: 15 (ED25519) |
d4f29089 KM |
55 | PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= |
56 | */ | |
57 | ||
58 | storvector_t storvector; | |
9d3727e0 | 59 | string algorithm = "15 (ED25519)"; |
d4f29089 KM |
60 | |
61 | storvector.push_back(make_pair("Algorithm", algorithm)); | |
62 | ||
63 | vector<unsigned char> buffer; | |
64 | storvector.push_back(make_pair("PrivateKey", string((char*)d_seckey, crypto_sign_ed25519_SEEDBYTES))); | |
65 | return storvector; | |
66 | } | |
67 | ||
68 | void SodiumED25519DNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap ) | |
69 | { | |
70 | /* | |
71 | Private-key-format: v1.2 | |
9d3727e0 | 72 | Algorithm: 15 (ED25519) |
d4f29089 KM |
73 | PrivateKey: GU6SnQ/Ou+xC5RumuIUIuJZteXT2z0O/ok1s38Et6mQ= |
74 | */ | |
75 | ||
335da0ba | 76 | drc.d_algorithm = pdns_stou(stormap["algorithm"]); |
d4f29089 KM |
77 | string privateKey = stormap["privatekey"]; |
78 | ||
79 | if (privateKey.length() != crypto_sign_ed25519_SEEDBYTES) | |
80 | throw runtime_error("Seed size mismatch in ISCMap, SodiumED25519 class"); | |
81 | ||
82 | std::unique_ptr<unsigned char[]> seed(new unsigned char[crypto_sign_ed25519_SEEDBYTES]); | |
83 | ||
84 | memcpy(seed.get(), privateKey.c_str(), crypto_sign_ed25519_SEEDBYTES); | |
85 | crypto_sign_ed25519_seed_keypair(d_pubkey, d_seckey, seed.get()); | |
86 | } | |
87 | ||
88 | std::string SodiumED25519DNSCryptoKeyEngine::getPubKeyHash() const | |
89 | { | |
90 | return this->getPublicKeyString(); | |
91 | } | |
92 | ||
93 | std::string SodiumED25519DNSCryptoKeyEngine::getPublicKeyString() const | |
94 | { | |
95 | return string((char*)d_pubkey, crypto_sign_ed25519_PUBLICKEYBYTES); | |
96 | } | |
97 | ||
98 | void SodiumED25519DNSCryptoKeyEngine::fromPublicKeyString(const std::string& input) | |
99 | { | |
100 | if (input.length() != crypto_sign_ed25519_PUBLICKEYBYTES) | |
101 | throw runtime_error("Public key size mismatch, SodiumED25519 class"); | |
102 | ||
103 | memcpy(d_pubkey, input.c_str(), crypto_sign_ed25519_PUBLICKEYBYTES); | |
104 | } | |
105 | ||
106 | std::string SodiumED25519DNSCryptoKeyEngine::sign(const std::string& msg) const | |
107 | { | |
7c9c554a | 108 | unsigned long long smlen = msg.length() + crypto_sign_ed25519_BYTES; |
d4f29089 KM |
109 | std::unique_ptr<unsigned char[]> sm(new unsigned char[smlen]); |
110 | ||
7c9c554a | 111 | crypto_sign_ed25519(sm.get(), &smlen, (const unsigned char*)msg.c_str(), msg.length(), d_seckey); |
d4f29089 KM |
112 | |
113 | return string((const char*)sm.get(), crypto_sign_ed25519_BYTES); | |
114 | } | |
115 | ||
d4f29089 KM |
116 | bool SodiumED25519DNSCryptoKeyEngine::verify(const std::string& msg, const std::string& signature) const |
117 | { | |
118 | if (signature.length() != crypto_sign_ed25519_BYTES) | |
119 | return false; | |
120 | ||
7c9c554a | 121 | unsigned long long smlen = msg.length() + crypto_sign_ed25519_BYTES; |
d4f29089 KM |
122 | std::unique_ptr<unsigned char[]> sm(new unsigned char[smlen]); |
123 | ||
124 | memcpy(sm.get(), signature.c_str(), crypto_sign_ed25519_BYTES); | |
7c9c554a | 125 | memcpy(sm.get() + crypto_sign_ed25519_BYTES, msg.c_str(), msg.length()); |
d4f29089 KM |
126 | |
127 | std::unique_ptr<unsigned char[]> m(new unsigned char[smlen]); | |
128 | ||
129 | return crypto_sign_ed25519_open(m.get(), &smlen, sm.get(), smlen, d_pubkey) == 0; | |
130 | } | |
131 | ||
132 | namespace { | |
133 | struct LoaderSodiumStruct | |
134 | { | |
135 | LoaderSodiumStruct() | |
136 | { | |
9d3727e0 | 137 | DNSCryptoKeyEngine::report(15, &SodiumED25519DNSCryptoKeyEngine::maker); |
d4f29089 KM |
138 | } |
139 | } loadersodium; | |
140 | } |