aboutsummaryrefslogtreecommitdiffstats
path: root/src/pubkey/gost_3410
diff options
context:
space:
mode:
authorlloyd <[email protected]>2009-12-12 04:16:45 +0000
committerlloyd <[email protected]>2009-12-12 04:16:45 +0000
commitd1ce64bedee53f0050d44f86db070d87bf78926e (patch)
tree4b2236cab24157aa5fae0b4d110d113c0c8aab59 /src/pubkey/gost_3410
parent579b059c9310b98db90eb534fe09e024dcc4f94f (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.cpp89
-rw-r--r--src/pubkey/gost_3410/gost_3410.h21
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