diff options
Diffstat (limited to 'SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp')
-rw-r--r-- | SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp | 93 |
1 files changed, 89 insertions, 4 deletions
diff --git a/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp b/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp index 890f135..e5bb3b4 100644 --- a/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp +++ b/SoftHSMv2/src/lib/crypto/BotanGOSTPrivateKey.cpp @@ -38,6 +38,12 @@ #include "BotanRNG.h" #include "BotanUtil.h" #include <string.h> +#include <botan/pkcs8.h> +#include <botan/ber_dec.h> +#include <botan/der_enc.h> +#include <botan/asn1_oid.h> +#include <botan/oids.h> +#include <botan/version.h> // Constructors BotanGOSTPrivateKey::BotanGOSTPrivateKey() @@ -151,14 +157,93 @@ bool BotanGOSTPrivateKey::deserialise(ByteString& serialised) ByteString BotanGOSTPrivateKey::PKCS8Encode() { ByteString der; - // TODO - return der; + createBotanKey(); + if (eckey == NULL) return der; + // Force EC_DOMPAR_ENC_OID + const size_t PKCS8_VERSION = 0; +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(2,0,0) + const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID); + const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters); + const Botan::secure_vector<Botan::byte> ber = + Botan::DER_Encoder() + .start_cons(Botan::SEQUENCE) + .encode(PKCS8_VERSION) + .encode(alg_id) + .encode(eckey->private_key_bits(), Botan::OCTET_STRING) + .end_cons() + .get_contents(); +#elif BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + const std::vector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID); + const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters); + const Botan::secure_vector<Botan::byte> ber = + Botan::DER_Encoder() + .start_cons(Botan::SEQUENCE) + .encode(PKCS8_VERSION) + .encode(alg_id) + .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING) + .end_cons() + .get_contents(); +#else + const Botan::MemoryVector<Botan::byte> parameters = eckey->domain().DER_encode(Botan::EC_DOMPAR_ENC_OID); + const Botan::AlgorithmIdentifier alg_id(eckey->get_oid(), parameters); + const Botan::SecureVector<Botan::byte> ber = + Botan::DER_Encoder() + .start_cons(Botan::SEQUENCE) + .encode(PKCS8_VERSION) + .encode(alg_id) + .encode(eckey->pkcs8_private_key(), Botan::OCTET_STRING) + .end_cons() + .get_contents(); +#endif + der.resize(ber.size()); + memcpy(&der[0], &ber[0], ber.size()); + return der; } // Decode from PKCS#8 BER -bool BotanGOSTPrivateKey::PKCS8Decode(const ByteString& /*ber*/) +bool BotanGOSTPrivateKey::PKCS8Decode(const ByteString& ber) { - return false; + Botan::DataSource_Memory source(ber.const_byte_str(), ber.size()); + if (source.end_of_data()) return false; +#if BOTAN_VERSION_CODE >= BOTAN_VERSION_CODE_FOR(1,11,0) + Botan::secure_vector<Botan::byte> keydata; +#else + Botan::SecureVector<Botan::byte> keydata; +#endif + Botan::AlgorithmIdentifier alg_id; + Botan::GOST_3410_PrivateKey* key = NULL; + try + { + Botan::BER_Decoder(source) + .start_cons(Botan::SEQUENCE) + .decode_and_check<size_t>(0, "Unknown PKCS #8 version number") + .decode(alg_id) + .decode(keydata, Botan::OCTET_STRING) + .discard_remaining() + .end_cons(); + if (keydata.empty()) + throw Botan::Decoding_Error("PKCS #8 private key decoding failed"); + if (Botan::OIDS::lookup(alg_id.oid).compare("GOST-34.10")) + { + ERROR_MSG("Decoded private key not GOST-34.10"); + + return false; + } + key = new Botan::GOST_3410_PrivateKey(alg_id, keydata); + if (key == NULL) return false; + + setFromBotan(key); + + delete key; + } + catch (std::exception& e) + { + ERROR_MSG("Decode failed on %s", e.what()); + + return false; + } + + return true; } // Retrieve the Botan representation of the key |