2 * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 /*****************************************************************************
28 BotanGOSTPrivateKey.cpp
30 Botan GOST R 34.10-2001 private key class
31 *****************************************************************************/
36 #include "BotanGOSTPrivateKey.h"
37 #include "BotanCryptoFactory.h"
39 #include "BotanUtil.h"
41 #include <botan/pkcs8.h>
42 #include <botan/ber_dec.h>
43 #include <botan/der_enc.h>
44 #include <botan/asn1_oid.h>
45 #include <botan/oids.h>
46 #include <botan/version.h>
49 BotanGOSTPrivateKey::BotanGOSTPrivateKey()
54 BotanGOSTPrivateKey::BotanGOSTPrivateKey(const Botan::GOST_3410_PrivateKey* inECKEY)
56 BotanGOSTPrivateKey();
58 setFromBotan(inECKEY);
62 BotanGOSTPrivateKey::~BotanGOSTPrivateKey()
68 /*static*/ const char* BotanGOSTPrivateKey::type = "Botan GOST Private Key";
70 // Get the base point order length
71 unsigned long BotanGOSTPrivateKey::getOrderLength() const
75 Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
76 return group.get_order().bytes();
80 ERROR_MSG("Can't get EC group for order length");
86 // Get the output length
87 unsigned long BotanGOSTPrivateKey::getOutputLength() const
89 return getOrderLength() * 2;
92 // Set from Botan representation
93 void BotanGOSTPrivateKey::setFromBotan(const Botan::GOST_3410_PrivateKey* inECKEY)
95 ByteString inEC = BotanUtil::ecGroup2ByteString(inECKEY->domain());
97 ByteString inD = BotanUtil::bigInt2ByteStringPrefix(inECKEY->private_value(), 32);
101 // Check if the key is of the given type
102 bool BotanGOSTPrivateKey::isOfType(const char* inType)
104 return !strcmp(type, inType);
107 // Setters for the GOST private key components
108 void BotanGOSTPrivateKey::setD(const ByteString& inD)
110 GOSTPrivateKey::setD(inD);
120 // Setters for the GOST public key components
121 void BotanGOSTPrivateKey::setEC(const ByteString& inEC)
123 GOSTPrivateKey::setEC(inEC);
133 ByteString BotanGOSTPrivateKey::serialise() const
135 return ec.serialise() +
139 bool BotanGOSTPrivateKey::deserialise(ByteString& serialised)
141 ByteString dEC = ByteString::chainDeserialise(serialised);
142 ByteString dD = ByteString::chainDeserialise(serialised);
144 if ((dEC.size() == 0) ||
156 // Encode into PKCS#8 DER
157 ByteString BotanGOSTPrivateKey::PKCS8Encode()
161 if (eckey == NULL) return der;
162 // Force EC_DOMPAR_ENC_OID
163 const size_t PKCS8_VERSION = 0;
164 #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0)
165 const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
166 const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
167 const Botan::secure_vector<Botan::byte> ber =
169 .start_cons(Botan::SEQUENCE)
170 .encode(PKCS8_VERSION)
172 .encode(eckey->private_key_bits(), Botan::OCTET_STRING)
175 #elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
176 const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
177 const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
178 const Botan::secure_vector<Botan::byte> ber =
180 .start_cons(Botan::SEQUENCE)
181 .encode(PKCS8_VERSION)
183 .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
187 const Botan::MemoryVector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID);
188 const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters);
189 const Botan::SecureVector<Botan::byte> ber =
191 .start_cons(Botan::SEQUENCE)
192 .encode(PKCS8_VERSION)
194 .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING)
198 der.resize(ber.size());
199 memcpy(&der[0], &ber[0], ber.size());
203 // Decode from PKCS#8 BER
204 bool BotanGOSTPrivateKey::PKCS8Decode(const ByteString& ber)
206 Botan::DataSource_Memory source(ber.const_byte_str(), ber.size());
207 if (source.end_of_data()) return false;
208 #if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0)
209 Botan::secure_vector<Botan::byte> keydata;
211 Botan::SecureVector<Botan::byte> keydata;
213 Botan::AlgorithmIdentifier alg_id;
214 Botan::GOST_3410_PrivateKey* key = NULL;
217 Botan::BER_Decoder(source)
218 .start_cons(Botan::SEQUENCE)
219 .decode_and_check<size_t>(0, "Unknown PKCS #8 version number")
221 .decode(keydata, Botan::OCTET_STRING)
225 throw Botan::Decoding_Error("PKCS #8 private key decoding failed");
226 if (Botan::OIDS::lookup(alg_id.oid).compare("GOST-34.10"))
228 ERROR_MSG("Decoded private key not GOST-34.10");
232 key = new Botan::GOST_3410_PrivateKey(alg_id, keydata);
233 if (key == NULL) return false;
239 catch (std::exception& e)
241 ERROR_MSG("Decode failed on %s", e.what());
249 // Retrieve the Botan representation of the key
250 Botan::GOST_3410_PrivateKey* BotanGOSTPrivateKey::getBotanKey()
260 // Create the Botan representation of the key
261 void BotanGOSTPrivateKey::createBotanKey()
263 if (ec.size() != 0 &&
274 BotanRNG* rng = (BotanRNG*)BotanCryptoFactory::i()->getRNG();
275 Botan::EC_Group group = BotanUtil::byteString2ECGroup(ec);
276 eckey = new Botan::GOST_3410_PrivateKey(*rng->getRNG(),
278 BotanUtil::byteString2bigInt(d));
282 ERROR_MSG("Could not create the Botan public key");