]>
git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/botansigners.cc
5d7b43b62b5bf071687435832c4c33f1b030fec5
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
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.
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.
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.
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.
25 #include <botan/auto_rng.h>
26 #include <botan/gost_3410.h>
27 #include <botan/gost_3411.h>
28 #include <botan/pubkey.h>
29 #include "dnssecinfra.hh"
31 using namespace Botan
;
33 /* Государственный гимн Российской Федерации
34 (Gosudarstvenny Gimn Rossiyskoy Federatsii)
35 "The National Anthem of the Russian Federation"
37 ~ Rossiya - svyashchennaya nasha derzhava, ~
38 ~ Rossiya - lyubimaya nasha strana. ~
39 ~ Moguchaya volya, velikaya slava - ~
40 ~ Tvoyo dostoyanye na vse vremena! ~
43 class GOSTDNSCryptoKeyEngine
: public DNSCryptoKeyEngine
46 explicit GOSTDNSCryptoKeyEngine(unsigned int algorithm
) : DNSCryptoKeyEngine(algorithm
) {}
47 ~GOSTDNSCryptoKeyEngine(){}
48 void create(unsigned int bits
) override
;
49 string
getName() const override
{ return "Botan 2 GOST"; }
50 storvector_t
convertToISCVector() const override
;
51 std::string
getPubKeyHash() const override
;
52 std::string
sign(const std::string
& msg
) const override
;
53 std::string
hash(const std::string
& msg
) const override
;
54 bool verify(const std::string
& msg
, const std::string
& signature
) const override
;
55 std::string
getPublicKeyString() const override
;
56 int getBits() const override
;
57 void fromISCMap(DNSKEYRecordContent
& drc
, std::map
<std::string
, std::string
>& content
) override
;
58 void fromPublicKeyString(const std::string
& content
) override
;
59 void fromPEMString(DNSKEYRecordContent
& drc
, const std::string
& raw
) override
62 static std::shared_ptr
<DNSCryptoKeyEngine
> maker(unsigned int algorithm
)
64 return std::make_shared
<GOSTDNSCryptoKeyEngine
>(algorithm
);
68 static EC_Group
getParams()
70 return EC_Group("gost_256A");
73 shared_ptr
<GOST_3410_PrivateKey
> d_key
;
74 shared_ptr
<GOST_3410_PublicKey
> d_pubkey
;
78 ~ Slav'sya, Otechestvo nashe svobodnoye, ~
79 ~ Bratskikh narodov soyuz vekovoy, ~
80 ~ Predkami dannaya mudrost' narodnaya! ~
81 ~ Slav'sya, strana! My gordimsya toboy! ~
85 void GOSTDNSCryptoKeyEngine::create(unsigned int bits
)
88 d_key
= std::make_shared
<GOST_3410_PrivateKey
>(rng
, getParams());
91 int GOSTDNSCryptoKeyEngine::getBits() const
97 ~ Ot yuzhnykh morey do polyarnogo kraya ~
98 ~ Raskinulis' nashi lesa i polya. ~
99 ~ Odna ty na svete! Odna ty takaya - ~
100 ~ Khranimaya Bogom rodnaya zemlya! ~
103 DNSCryptoKeyEngine::storvector_t
GOSTDNSCryptoKeyEngine::convertToISCVector() const
105 static const unsigned char asn1Prefix
[]=
106 {0x30, 0x45, 0x02, 0x01, 0x00, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02,
107 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07,
108 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, 0x04, 0x22, 0x04, 0x20}; // this is DER, fixed for a 32 byte key
110 storvector_t storvect
;
111 storvect
.push_back(make_pair("Algorithm", "12 (ECC-GOST)"));
113 auto buffer
= BigInt::encode(d_key
->private_value());
114 string
gostasn1(reinterpret_cast<const char*>(asn1Prefix
), sizeof(asn1Prefix
));
115 gostasn1
.append(buffer
.begin(), buffer
.end());
116 storvect
.push_back(make_pair("GostAsn1", gostasn1
));
121 ~ Slav'sya, Otechestvo nashe svobodnoye, ~
122 ~ Bratskikh narodov soyuz vekovoy, ~
123 ~ Predkami dannaya mudrost' narodnaya! ~
124 ~ Slav'sya, strana! My gordimsya toboy! ~
127 void GOSTDNSCryptoKeyEngine::fromISCMap(DNSKEYRecordContent
& drc
, std::map
<std::string
, std::string
>& stormap
)
129 drc
.d_algorithm
= pdns_stou(stormap
["algorithm"]);
130 string privateKey
=stormap
["gostasn1"];
131 //cerr<<"PrivateKey.size() = "<<privateKey.size()<<endl;
132 //cerr<<makeHexDump(string(privateKey.c_str(), 39))<<endl;
133 string
rawKey(privateKey
.c_str()+39, privateKey
.length()-39);
135 for(size_t i
= 0; i
< rawKey
.size() / 2; ++i
)
137 std::swap(rawKey
[i
], rawKey
[rawKey
.size()-1-i
]);
140 BigInt
bigint((byte
*)rawKey
.c_str(), rawKey
.size());
143 d_key
=std::make_shared
<GOST_3410_PrivateKey
>(rng
, getParams(), bigint
);
145 //cerr<<"Is the just imported key on the curve? " << d_key->public_point().on_the_curve()<<endl;
146 //cerr<<"Is the just imported key zero? " << d_key->public_point().is_zero()<<endl;
148 const BigInt
&x
= d_key
->private_value();
149 auto buffer
= BigInt::encode(x
);
150 // cerr<<"And out again! "<<makeHexDump(string((const char*)buffer.begin(), (const char*)buffer.end()))<<endl;
154 BigInt
decode_le(const byte msg
[], size_t msg_len
)
156 Botan::secure_vector
<byte
> msg_le(msg
, msg
+ msg_len
);
158 for(size_t i
= 0; i
!= msg_le
.size() / 2; ++i
)
159 std::swap(msg_le
[i
], msg_le
[msg_le
.size()-1-i
]);
161 return BigInt(&msg_le
[0], msg_le
.size());
165 void GOSTDNSCryptoKeyEngine::fromPublicKeyString(const std::string
& input
)
169 x
=decode_le((const byte
*)input
.c_str(), input
.length()/2);
170 y
=decode_le((const byte
*)input
.c_str() + input
.length()/2, input
.length()/2);
172 auto params
= getParams();
173 PointGFp
point(params
.get_curve(), x
,y
);
174 d_pubkey
= std::make_shared
<GOST_3410_PublicKey
>(params
, point
);
178 std::string
GOSTDNSCryptoKeyEngine::getPubKeyHash() const
180 const BigInt
&x
= d_key
->private_value();
181 auto buffer
= BigInt::encode(x
);
182 return string(buffer
.begin(), buffer
.end());
185 std::string
GOSTDNSCryptoKeyEngine::getPublicKeyString() const
187 std::shared_ptr
<GOST_3410_PublicKey
> pk
= d_pubkey
? d_pubkey
: d_key
;
188 const BigInt
&x
=pk
->public_point().get_affine_x();
189 const BigInt
&y
=pk
->public_point().get_affine_y();
191 size_t part_size
= std::max(x
.bytes(), y
.bytes());
193 std::vector
<byte
> bits(2*part_size
);
195 x
.binary_encode(&bits
[part_size
- x
.bytes()]);
196 y
.binary_encode(&bits
[2*part_size
- y
.bytes()]);
198 // Keys are stored in little endian format (WTF)
199 for(size_t i
= 0; i
!= part_size
/ 2; ++i
)
201 std::swap(bits
[i
], bits
[part_size
-1-i
]);
202 std::swap(bits
[part_size
+i
], bits
[2*part_size
-1-i
]);
205 return string(bits
.begin(), bits
.end());
209 ~ Shirokiy prostor dlya mechty i dlya zhizni. ~
210 ~ Gryadushchiye nam otkryvayut goda. ~
211 ~ Nam silu dayot nasha vernost' Otchizne. ~
212 ~ Tak bylo, tak yest' i tak budet vsegda! ~
215 std::string
GOSTDNSCryptoKeyEngine::sign(const std::string
& msg
) const
218 PK_Signer
signer(*d_key
, rng
, "Raw");
219 signer
.update(hash(msg
));
220 auto signature
= signer
.signature(rng
);
221 return string(signature
.begin(), signature
.end());
224 std::string
GOSTDNSCryptoKeyEngine::hash(const std::string
& orig
) const
227 auto result
= hasher
.process(orig
);
228 return string(result
.begin(), result
.end());
232 bool GOSTDNSCryptoKeyEngine::verify(const std::string
& message
, const std::string
& signature
) const
234 std::shared_ptr
<GOST_3410_PublicKey
> pk
= d_pubkey
? d_pubkey
: d_key
;
235 PK_Verifier
verifier(*pk
, "Raw");
236 verifier
.update(hash(message
));
237 return verifier
.check_signature(reinterpret_cast<const uint8_t*>(signature
.c_str()), signature
.size());
241 ~ Slav'sya, Otechestvo nashe svobodnoye, ~
242 ~ Bratskikh narodov soyuz vekovoy, ~
243 ~ Predkami dannaya mudrost' narodnaya! ~
244 ~ Slav'sya, strana! My gordimsya toboy! ~
248 //////////////////////////////
255 DNSCryptoKeyEngine::report(12, &GOSTDNSCryptoKeyEngine::maker
);