aboutsummaryrefslogtreecommitdiffstats
path: root/src/pubkey/ec_group
diff options
context:
space:
mode:
authorlloyd <[email protected]>2011-04-08 18:13:41 +0000
committerlloyd <[email protected]>2011-04-08 18:13:41 +0000
commit8b543e804375a788ae71d461c0f8cf5d4193fc25 (patch)
tree6177931cd84a9be204cdab6e62729954e69e0421 /src/pubkey/ec_group
parent3b66bfd4da97189ec275e5f85b9f85009d3f8370 (diff)
ECC private keys had two different constructors, one taking a group
and a random number generator, and the other taking a group and a preset private key value. The DL private keys instead have on constructor for this; if the x value is zero, then a new random key is created. For consistency, do this with ECC as well. ECDH actually didn't have one of these constructors, forcing you to either load from PKCS #8 or else use a random key. Rename EC_Domain_Params to EC_Group, with a typedef for compatability. More doc updates. Update mtn ignores for Sphinx output
Diffstat (limited to 'src/pubkey/ec_group')
-rw-r--r--src/pubkey/ec_group/ec_group.cpp137
-rw-r--r--src/pubkey/ec_group/ec_group.h143
-rw-r--r--src/pubkey/ec_group/info.txt9
3 files changed, 289 insertions, 0 deletions
diff --git a/src/pubkey/ec_group/ec_group.cpp b/src/pubkey/ec_group/ec_group.cpp
new file mode 100644
index 000000000..fe4fae885
--- /dev/null
+++ b/src/pubkey/ec_group/ec_group.cpp
@@ -0,0 +1,137 @@
+/*
+* ECC Domain Parameters
+*
+* (C) 2007 Falko Strenzke, FlexSecure GmbH
+* 2008 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/ec_group.h>
+#include <botan/ber_dec.h>
+#include <botan/der_enc.h>
+#include <botan/libstate.h>
+#include <botan/oids.h>
+#include <botan/pem.h>
+
+namespace Botan {
+
+EC_Group::EC_Group(const OID& domain_oid)
+ {
+ std::string pem =
+ global_state().get("ec", OIDS::lookup(domain_oid));
+
+ if(pem == "")
+ throw Lookup_Error("No ECC domain data for " + domain_oid.as_string());
+
+ *this = EC_Group(pem);
+ oid = domain_oid.as_string();
+ }
+
+EC_Group::EC_Group(const std::string& str)
+ {
+ if(str == "")
+ return; // no initialization / uninitialized
+
+ try
+ {
+ DataSource_Memory input(str);
+
+ SecureVector<byte> ber =
+ PEM_Code::decode_check_label(input, "EC PARAMETERS");
+
+ *this = EC_Group(ber);
+ }
+ catch(Decoding_Error) // hmm, not PEM?
+ {
+ *this = EC_Group(OIDS::lookup(str));
+ }
+ }
+
+EC_Group::EC_Group(const MemoryRegion<byte>& ber_data)
+ {
+ BER_Decoder ber(ber_data);
+ BER_Object obj = ber.get_next_object();
+
+ if(obj.type_tag == NULL_TAG)
+ throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters");
+ else if(obj.type_tag == OBJECT_ID)
+ {
+ OID dom_par_oid;
+ BER_Decoder(ber_data).decode(dom_par_oid);
+ *this = EC_Group(dom_par_oid);
+ }
+ else if(obj.type_tag == SEQUENCE)
+ {
+ BigInt p, a, b;
+ SecureVector<byte> sv_base_point;
+
+ BER_Decoder(ber_data)
+ .start_cons(SEQUENCE)
+ .decode_and_check<size_t>(1, "Unknown ECC param version code")
+ .start_cons(SEQUENCE)
+ .decode_and_check(OID("1.2.840.10045.1.1"),
+ "Only prime ECC fields supported")
+ .decode(p)
+ .end_cons()
+ .start_cons(SEQUENCE)
+ .decode_octet_string_bigint(a)
+ .decode_octet_string_bigint(b)
+ .end_cons()
+ .decode(sv_base_point, OCTET_STRING)
+ .decode(order)
+ .decode(cofactor)
+ .end_cons()
+ .verify_end();
+
+ curve = CurveGFp(p, a, b);
+ base_point = OS2ECP(sv_base_point, curve);
+ }
+ else
+ throw Decoding_Error("Unexpected tag while decoding ECC domain params");
+ }
+
+SecureVector<byte>
+EC_Group::DER_encode(EC_Group_Encoding form) const
+ {
+ if(form == EC_DOMPAR_ENC_EXPLICIT)
+ {
+ const size_t ecpVers1 = 1;
+ OID curve_type("1.2.840.10045.1.1");
+
+ const size_t p_bytes = curve.get_p().bytes();
+
+ return DER_Encoder()
+ .start_cons(SEQUENCE)
+ .encode(ecpVers1)
+ .start_cons(SEQUENCE)
+ .encode(curve_type)
+ .encode(curve.get_p())
+ .end_cons()
+ .start_cons(SEQUENCE)
+ .encode(BigInt::encode_1363(curve.get_a(), p_bytes),
+ OCTET_STRING)
+ .encode(BigInt::encode_1363(curve.get_b(), p_bytes),
+ OCTET_STRING)
+ .end_cons()
+ .encode(EC2OSP(base_point, PointGFp::UNCOMPRESSED), OCTET_STRING)
+ .encode(order)
+ .encode(cofactor)
+ .end_cons()
+ .get_contents();
+ }
+ else if(form == EC_DOMPAR_ENC_OID)
+ return DER_Encoder().encode(get_oid()).get_contents();
+ else if(form == EC_DOMPAR_ENC_IMPLICITCA)
+ return DER_Encoder().encode_null().get_contents();
+ else
+ throw Internal_Error("EC_Group::DER_encode: Unknown encoding");
+ }
+
+std::string EC_Group::PEM_encode() const
+ {
+ SecureVector<byte> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT);
+ return PEM_Code::encode(der, "EC PARAMETERS");
+ }
+
+}
diff --git a/src/pubkey/ec_group/ec_group.h b/src/pubkey/ec_group/ec_group.h
new file mode 100644
index 000000000..b7b09985e
--- /dev/null
+++ b/src/pubkey/ec_group/ec_group.h
@@ -0,0 +1,143 @@
+/*
+* ECC Domain Parameters
+*
+* (C) 2007 Falko Strenzke, FlexSecure GmbH
+* 2008-2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_ECC_DOMAIN_PARAMETERS_H__
+#define BOTAN_ECC_DOMAIN_PARAMETERS_H__
+
+#include <botan/point_gfp.h>
+#include <botan/curve_gfp.h>
+#include <botan/asn1_oid.h>
+
+namespace Botan {
+
+/**
+* This class represents elliptic curce domain parameters
+*/
+enum EC_Group_Encoding {
+ EC_DOMPAR_ENC_EXPLICIT = 0,
+ EC_DOMPAR_ENC_IMPLICITCA = 1,
+ EC_DOMPAR_ENC_OID = 2
+};
+
+/**
+* Class representing an elliptic curve
+*/
+class BOTAN_DLL EC_Group
+ {
+ public:
+
+ /**
+ * Construct Domain paramers from specified parameters
+ * @param curve elliptic curve
+ * @param base_point a base point
+ * @param order the order of the base point
+ * @param cofactor the cofactor
+ */
+ EC_Group(const CurveGFp& curve,
+ const PointGFp& base_point,
+ const BigInt& order,
+ const BigInt& cofactor) :
+ curve(curve),
+ base_point(base_point),
+ order(order),
+ cofactor(cofactor),
+ oid("")
+ {}
+
+ /**
+ * Decode a BER encoded ECC domain parameter set
+ * @param ber_encoding the bytes of the BER encoding
+ */
+ EC_Group(const MemoryRegion<byte>& ber_encoding);
+
+ /**
+ * Create an EC domain by OID (or throw if unknown)
+ * @param oid the OID of the EC domain to create
+ */
+ EC_Group(const OID& oid);
+
+ /**
+ * Create an EC domain from PEM encoding (as from PEM_encode),
+ * or from an OID name (eg "secp16r1", or "1.3.132.0.8")
+ * @param pem_or_oid PEM-encoded data, or an OID
+ */
+ EC_Group(const std::string& pem_or_oid = "");
+
+ /**
+ * Create the DER encoding of this domain
+ * @param form of encoding to use
+ * @returns bytes encododed as DER
+ */
+ SecureVector<byte> DER_encode(EC_Group_Encoding form) const;
+
+ /**
+ * Return the PEM encoding (always in explicit form)
+ * @return string containing PEM data
+ */
+ std::string PEM_encode() const;
+
+ /**
+ * Return domain parameter curve
+ * @result domain parameter curve
+ */
+ const CurveGFp& get_curve() const { return curve; }
+
+ /**
+ * Return domain parameter curve
+ * @result domain parameter curve
+ */
+ const PointGFp& get_base_point() const { return base_point; }
+
+ /**
+ * Return the order of the base point
+ * @result order of the base point
+ */
+ const BigInt& get_order() const { return order; }
+
+ /**
+ * Return the cofactor
+ * @result the cofactor
+ */
+ const BigInt& get_cofactor() const { return cofactor; }
+
+ bool initialized() const { return !base_point.is_zero(); }
+
+ /**
+ * Return the OID of these domain parameters
+ * @result the OID
+ */
+ std::string get_oid() const { return oid; }
+
+ bool operator==(const EC_Group& other) const
+ {
+ return ((get_curve() == other.get_curve()) &&
+ (get_base_point() == other.get_base_point()) &&
+ (get_order() == other.get_order()) &&
+ (get_cofactor() == other.get_cofactor()));
+ }
+
+ private:
+ CurveGFp curve;
+ PointGFp base_point;
+ BigInt order, cofactor;
+ std::string oid;
+ };
+
+inline bool operator!=(const EC_Group& lhs,
+ const EC_Group& rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+// For compatability with 1.8
+typedef EC_Group EC_Domain_Params;
+
+}
+
+#endif
diff --git a/src/pubkey/ec_group/info.txt b/src/pubkey/ec_group/info.txt
new file mode 100644
index 000000000..c611914e9
--- /dev/null
+++ b/src/pubkey/ec_group/info.txt
@@ -0,0 +1,9 @@
+define ECC_GROUP
+
+<requires>
+asn1
+numbertheory
+pem
+libstate
+oid_lookup
+</requires>