diff options
author | lloyd <[email protected]> | 2009-12-12 04:16:45 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-12-12 04:16:45 +0000 |
commit | d1ce64bedee53f0050d44f86db070d87bf78926e (patch) | |
tree | 4b2236cab24157aa5fae0b4d110d113c0c8aab59 /src/pubkey/gost_3410 | |
parent | 579b059c9310b98db90eb534fe09e024dcc4f94f (diff) |
Of _course_, GOST 34.10 uses a non-standard X.509 encoding, and _of course_
it's ridiculously poorly thought out.
The PKCS #8 format isn't documented anywhere I can find, so I'm declaring
the standard GOST-34.10-2001 to be identical to the ECDSA/ECDH format,
thus defining the problem away. :)
Diffstat (limited to 'src/pubkey/gost_3410')
-rw-r--r-- | src/pubkey/gost_3410/gost_3410.cpp | 89 | ||||
-rw-r--r-- | src/pubkey/gost_3410/gost_3410.h | 21 |
2 files changed, 105 insertions, 5 deletions
diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp index e4eb88307..0569dc8f0 100644 --- a/src/pubkey/gost_3410/gost_3410.cpp +++ b/src/pubkey/gost_3410/gost_3410.cpp @@ -1,5 +1,5 @@ /* -* GOST 34.10 implemenation +* GOST 34.10-2001 implemenation * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH * (C) 2008-2009 Jack Lloyd @@ -55,6 +55,93 @@ GOST_3410_PrivateKey::GOST_3410_PrivateKey(const EC_Domain_Params& domain, } } +X509_Encoder* GOST_3410_PublicKey::x509_encoder() const + { + class GOST_3410_Key_Encoder : public X509_Encoder + { + public: + AlgorithmIdentifier alg_id() const + { + key->affirm_init(); + + SecureVector<byte> params = + encode_der_ec_dompar(key->domain_parameters(), key->m_param_enc); + + return AlgorithmIdentifier(key->get_oid(), params); + } + + MemoryVector<byte> key_bits() const + { + key->affirm_init(); + + // Trust CryptoPro to come up with something obnoxious + const BigInt x = key->mp_public_point->get_affine_x().get_value(); + const BigInt y = key->mp_public_point->get_affine_y().get_value(); + + SecureVector<byte> bits(2*std::max(x.bytes(), y.bytes())); + + y.binary_encode(bits + (bits.size() / 2 - y.bytes())); + x.binary_encode(bits + (bits.size() - y.bytes())); + + return DER_Encoder().encode(bits, OCTET_STRING).get_contents(); + } + + GOST_3410_Key_Encoder(const GOST_3410_PublicKey* k): key(k) {} + private: + const GOST_3410_PublicKey* key; + }; + + return new GOST_3410_Key_Encoder(this); + } + +X509_Decoder* GOST_3410_PublicKey::x509_decoder() + { + class GOST_3410_Key_Decoder : public X509_Decoder + { + public: + void alg_id(const AlgorithmIdentifier& alg_id) + { + // Also includes hash and cipher OIDs... brilliant design guys + OID ecc_param_id; + + BER_Decoder ber(alg_id.parameters); + ber.start_cons(SEQUENCE).decode(ecc_param_id); + + EC_Domain_Params ecc_params = get_EC_Dom_Pars_by_oid(ecc_param_id.as_string()); + + key->mp_dom_pars.reset(new EC_Domain_Params(ecc_params)); + } + + void key_bits(const MemoryRegion<byte>& bits) + { + + SecureVector<byte> key_bits; + BER_Decoder ber(bits); + ber.decode(key_bits, OCTET_STRING); + + const u32bit part_size = key_bits.size() / 2; + + BigInt y(key_bits, part_size); + BigInt x(key_bits + part_size, part_size); + + const BigInt p = key->domain_parameters().get_curve().get_p(); + + key->mp_public_point.reset( + new PointGFp(key->domain_parameters().get_curve(), + GFpElement(x, p), + GFpElement(y, p))); + + key->X509_load_hook(); + } + + GOST_3410_Key_Decoder(GOST_3410_PublicKey* k): key(k) {} + private: + GOST_3410_PublicKey* key; + }; + + return new GOST_3410_Key_Decoder(this); + } + /* * GOST_3410_PublicKey */ diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h index f053091ca..460aca9bf 100644 --- a/src/pubkey/gost_3410/gost_3410.h +++ b/src/pubkey/gost_3410/gost_3410.h @@ -1,5 +1,5 @@ /* -* GOST_3410 +* GOST 34.10-2001 * (C) 2007 Falko Strenzke, FlexSecure GmbH * Manuel Hartl, FlexSecure GmbH * (C) 2008-2009 Jack Lloyd @@ -87,6 +87,19 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, */ virtual void affirm_init() const; + /** + * Get an x509_encoder that can be used to encode this key. + * @result an x509_encoder for this key + */ + X509_Encoder* x509_encoder() const; + + /** + * Get an x509_decoder that can be used to decode a stored key into + * this key. + * @result an x509_decoder for this key + */ + X509_Decoder* x509_decoder(); + protected: void X509_load_hook(); void set_all_values(const GOST_3410_PublicKey& other); @@ -96,8 +109,8 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey, * This class represents GOST_3410 Private Keys */ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, - public EC_PrivateKey, - public PK_Signing_Key + public EC_PrivateKey, + public PK_Signing_Key { public: /** @@ -111,7 +124,7 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, * @param the domain parameters to used for this key */ GOST_3410_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& domain); + const EC_Domain_Params& domain); /** * Load a private key |