]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/sodiumsigners.cc
spelling: syscall
[thirdparty/pdns.git] / pdns / sodiumsigners.cc
CommitLineData
d4f29089
KM
1extern "C" {
2#ifdef HAVE_CONFIG_H
3#include "config.h"
4#endif
5#include <sodium.h>
6}
7#include "dnssecinfra.hh"
8
9class SodiumED25519DNSCryptoKeyEngine : public DNSCryptoKeyEngine
10{
11public:
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
32private:
33 unsigned char d_pubkey[crypto_sign_ed25519_PUBLICKEYBYTES];
34 unsigned char d_seckey[crypto_sign_ed25519_SECRETKEYBYTES];
35};
36
37void 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
45int SodiumED25519DNSCryptoKeyEngine::getBits() const
46{
47 return crypto_sign_ed25519_SEEDBYTES * 8;
48}
49
50DNSCryptoKeyEngine::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
68void 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
88std::string SodiumED25519DNSCryptoKeyEngine::getPubKeyHash() const
89{
90 return this->getPublicKeyString();
91}
92
93std::string SodiumED25519DNSCryptoKeyEngine::getPublicKeyString() const
94{
95 return string((char*)d_pubkey, crypto_sign_ed25519_PUBLICKEYBYTES);
96}
97
98void 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
106std::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
116bool 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
132namespace {
133struct LoaderSodiumStruct
134{
135 LoaderSodiumStruct()
136 {
9d3727e0 137 DNSCryptoKeyEngine::report(15, &SodiumED25519DNSCryptoKeyEngine::maker);
d4f29089
KM
138 }
139} loadersodium;
140}