]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/botansigners.cc
Fix a warning on botan >= 2.5.0
[thirdparty/pdns.git] / pdns / botansigners.cc
CommitLineData
12471842
PL
1/*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
870a0fe4
AT
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
00f1924b 25#include <botan/auto_rng.h>
f7982887 26#include <botan/gost_3410.h>
224778b0 27#include <botan/gost_3411.h>
13f34f2e 28#include <botan/pubkey.h>
07402f63 29#include <botan/version.h>
022e5e0b
BH
30#include "dnssecinfra.hh"
31
32using namespace Botan;
33
f7982887
BH
34/* Государственный гимн Российской Федерации
35 (Gosudarstvenny Gimn Rossiyskoy Federatsii)
36 "The National Anthem of the Russian Federation"
37
224778b0 38 ~ Rossiya - svyashchennaya nasha derzhava, ~
f7982887
BH
39 ~ Rossiya - lyubimaya nasha strana. ~
40 ~ Moguchaya volya, velikaya slava - ~
41 ~ Tvoyo dostoyanye na vse vremena! ~
42 */
43
8d9f38f2 44class GOSTDNSCryptoKeyEngine : public DNSCryptoKeyEngine
f7982887
BH
45{
46public:
189bb9d2 47 explicit GOSTDNSCryptoKeyEngine(unsigned int algorithm) : DNSCryptoKeyEngine(algorithm) {}
3a168083 48 ~GOSTDNSCryptoKeyEngine(){}
e69c2dac 49 void create(unsigned int bits) override;
13f34f2e 50 string getName() const override { return "Botan 2 GOST"; }
e69c2dac
RG
51 storvector_t convertToISCVector() const override;
52 std::string getPubKeyHash() const override;
13f34f2e
RG
53 std::string sign(const std::string& msg) const override;
54 std::string hash(const std::string& msg) const override;
55 bool verify(const std::string& msg, const std::string& signature) const override;
e69c2dac
RG
56 std::string getPublicKeyString() const override;
57 int getBits() const override;
58 void fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& content) override;
59 void fromPublicKeyString(const std::string& content) override;
60 void fromPEMString(DNSKEYRecordContent& drc, const std::string& raw) override
f7982887
BH
61 {}
62
e69c2dac 63 static std::shared_ptr<DNSCryptoKeyEngine> maker(unsigned int algorithm)
f7982887 64 {
e69c2dac 65 return std::make_shared<GOSTDNSCryptoKeyEngine>(algorithm);
f7982887
BH
66 }
67
68private:
13f34f2e
RG
69 static EC_Group getParams()
70 {
71 return EC_Group("gost_256A");
72 }
13f34f2e 73
f7982887 74 shared_ptr<GOST_3410_PrivateKey> d_key;
aa65a832 75 shared_ptr<GOST_3410_PublicKey> d_pubkey;
f7982887
BH
76};
77
78/*
79 ~ Slav'sya, Otechestvo nashe svobodnoye, ~
80 ~ Bratskikh narodov soyuz vekovoy, ~
81 ~ Predkami dannaya mudrost' narodnaya! ~
82 ~ Slav'sya, strana! My gordimsya toboy! ~
83*/
84
85
8d9f38f2 86void GOSTDNSCryptoKeyEngine::create(unsigned int bits)
f7982887
BH
87{
88 AutoSeeded_RNG rng;
13f34f2e 89 d_key = std::make_shared<GOST_3410_PrivateKey>(rng, getParams());
f7982887
BH
90}
91
8d9f38f2 92int GOSTDNSCryptoKeyEngine::getBits() const
f7982887
BH
93{
94 return 256;
95}
96
97/*
98 ~ Ot yuzhnykh morey do polyarnogo kraya ~
99 ~ Raskinulis' nashi lesa i polya. ~
100 ~ Odna ty na svete! Odna ty takaya - ~
101 ~ Khranimaya Bogom rodnaya zemlya! ~
102*/
103
c99573a5 104DNSCryptoKeyEngine::storvector_t GOSTDNSCryptoKeyEngine::convertToISCVector() const
f7982887 105{
13f34f2e 106 static const unsigned char asn1Prefix[]=
f7982887
BH
107 {0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02,
108 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07,
109 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, 0x04, 0x22, 0x04, 0x20}; // this is DER, fixed for a 32 byte key
110
13f34f2e
RG
111 storvector_t storvect;
112 storvect.push_back(make_pair("Algorithm", "12 (ECC-GOST)"));
113
114 auto buffer = BigInt::encode(d_key->private_value());
115 string gostasn1(reinterpret_cast<const char*>(asn1Prefix), sizeof(asn1Prefix));
116 gostasn1.append(buffer.begin(), buffer.end());
c99573a5
BH
117 storvect.push_back(make_pair("GostAsn1", gostasn1));
118 return storvect;
f7982887
BH
119}
120
121/*
122 ~ Slav'sya, Otechestvo nashe svobodnoye, ~
123 ~ Bratskikh narodov soyuz vekovoy, ~
124 ~ Predkami dannaya mudrost' narodnaya! ~
125 ~ Slav'sya, strana! My gordimsya toboy! ~
126*/
127
8d9f38f2 128void GOSTDNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent& drc, std::map<std::string, std::string>& stormap )
f7982887 129{
335da0ba 130 drc.d_algorithm = pdns_stou(stormap["algorithm"]);
f309dacd 131 string privateKey=stormap["gostasn1"];
f7982887
BH
132 //cerr<<"PrivateKey.size() = "<<privateKey.size()<<endl;
133 //cerr<<makeHexDump(string(privateKey.c_str(), 39))<<endl;
134 string rawKey(privateKey.c_str()+39, privateKey.length()-39);
135
136 for(size_t i = 0; i < rawKey.size() / 2; ++i)
137 {
138 std::swap(rawKey[i], rawKey[rawKey.size()-1-i]);
139 }
140
141 BigInt bigint((byte*)rawKey.c_str(), rawKey.size());
142
a11fe644 143 AutoSeeded_RNG rng;
13f34f2e 144 d_key=std::make_shared<GOST_3410_PrivateKey>(rng, getParams(), bigint);
f7982887
BH
145
146 //cerr<<"Is the just imported key on the curve? " << d_key->public_point().on_the_curve()<<endl;
147 //cerr<<"Is the just imported key zero? " << d_key->public_point().is_zero()<<endl;
148
149 const BigInt&x = d_key->private_value();
13f34f2e 150 auto buffer = BigInt::encode(x);
f7982887
BH
151 // cerr<<"And out again! "<<makeHexDump(string((const char*)buffer.begin(), (const char*)buffer.end()))<<endl;
152}
aa65a832
BH
153namespace {
154
155BigInt decode_le(const byte msg[], size_t msg_len)
156 {
13f34f2e 157 Botan::secure_vector<byte> msg_le(msg, msg + msg_len);
aa65a832
BH
158
159 for(size_t i = 0; i != msg_le.size() / 2; ++i)
160 std::swap(msg_le[i], msg_le[msg_le.size()-1-i]);
161
162 return BigInt(&msg_le[0], msg_le.size());
163 }
164
165}
189bb9d2 166void GOSTDNSCryptoKeyEngine::fromPublicKeyString(const std::string& input)
aa65a832
BH
167{
168 BigInt x, y;
169
170 x=decode_le((const byte*)input.c_str(), input.length()/2);
171 y=decode_le((const byte*)input.c_str() + input.length()/2, input.length()/2);
172
13f34f2e 173 auto params = getParams();
07402f63 174#if BOTAN_VERSION_CODE < BOTAN_VERSION_CODE_FOR(2,5,0)
aa65a832 175 PointGFp point(params.get_curve(), x,y);
07402f63
RG
176#else
177 PointGFp point(params.point(x,y));
178#endif
13f34f2e 179 d_pubkey = std::make_shared<GOST_3410_PublicKey>(params, point);
a39da654 180 d_key.reset();
aa65a832 181}
f7982887 182
8d9f38f2 183std::string GOSTDNSCryptoKeyEngine::getPubKeyHash() const
f7982887
BH
184{
185 const BigInt&x = d_key->private_value();
13f34f2e
RG
186 auto buffer = BigInt::encode(x);
187 return string(buffer.begin(), buffer.end());
f7982887
BH
188}
189
8d9f38f2 190std::string GOSTDNSCryptoKeyEngine::getPublicKeyString() const
f7982887 191{
87557ae2
RG
192 std::shared_ptr<GOST_3410_PublicKey> pk = d_pubkey ? d_pubkey : d_key;
193 const BigInt&x =pk->public_point().get_affine_x();
194 const BigInt&y =pk->public_point().get_affine_y();
f7982887
BH
195
196 size_t part_size = std::max(x.bytes(), y.bytes());
197
13f34f2e 198 std::vector<byte> bits(2*part_size);
13f34f2e 199
f7982887
BH
200 x.binary_encode(&bits[part_size - x.bytes()]);
201 y.binary_encode(&bits[2*part_size - y.bytes()]);
202
203 // Keys are stored in little endian format (WTF)
204 for(size_t i = 0; i != part_size / 2; ++i)
205 {
206 std::swap(bits[i], bits[part_size-1-i]);
207 std::swap(bits[part_size+i], bits[2*part_size-1-i]);
208 }
209
13f34f2e 210 return string(bits.begin(), bits.end());
f7982887
BH
211}
212
213/*
214 ~ Shirokiy prostor dlya mechty i dlya zhizni. ~
215 ~ Gryadushchiye nam otkryvayut goda. ~
216 ~ Nam silu dayot nasha vernost' Otchizne. ~
217 ~ Tak bylo, tak yest' i tak budet vsegda! ~
218 */
219
8d9f38f2 220std::string GOSTDNSCryptoKeyEngine::sign(const std::string& msg) const
f7982887 221{
f7982887 222 AutoSeeded_RNG rng;
13f34f2e
RG
223 PK_Signer signer(*d_key, rng, "Raw");
224 signer.update(hash(msg));
225 auto signature = signer.signature(rng);
226 return string(signature.begin(), signature.end());
f7982887
BH
227}
228
8d9f38f2 229std::string GOSTDNSCryptoKeyEngine::hash(const std::string& orig) const
224778b0 230{
224778b0 231 GOST_34_11 hasher;
13f34f2e
RG
232 auto result = hasher.process(orig);
233 return string(result.begin(), result.end());
224778b0
BH
234}
235
aa65a832 236
8d9f38f2 237bool GOSTDNSCryptoKeyEngine::verify(const std::string& message, const std::string& signature) const
f7982887 238{
13f34f2e 239 std::shared_ptr<GOST_3410_PublicKey> pk = d_pubkey ? d_pubkey : d_key;
13f34f2e
RG
240 PK_Verifier verifier(*pk, "Raw");
241 verifier.update(hash(message));
242 return verifier.check_signature(reinterpret_cast<const uint8_t*>(signature.c_str()), signature.size());
f7982887
BH
243}
244
245/*
246 ~ Slav'sya, Otechestvo nashe svobodnoye, ~
247 ~ Bratskikh narodov soyuz vekovoy, ~
248 ~ Predkami dannaya mudrost' narodnaya! ~
249 ~ Slav'sya, strana! My gordimsya toboy! ~
250*/
251
252
253//////////////////////////////
254
022e5e0b
BH
255namespace {
256struct LoaderStruct
257{
258 LoaderStruct()
259 {
8d9f38f2 260 DNSCryptoKeyEngine::report(12, &GOSTDNSCryptoKeyEngine::maker);
022e5e0b 261 }
e11963ce 262} loaderBotan2;
022e5e0b 263}