diff options
author | lloyd <[email protected]> | 2011-04-08 18:13:41 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2011-04-08 18:13:41 +0000 |
commit | 8b543e804375a788ae71d461c0f8cf5d4193fc25 (patch) | |
tree | 6177931cd84a9be204cdab6e62729954e69e0421 /src/pubkey/ec_group | |
parent | 3b66bfd4da97189ec275e5f85b9f85009d3f8370 (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.cpp | 137 | ||||
-rw-r--r-- | src/pubkey/ec_group/ec_group.h | 143 | ||||
-rw-r--r-- | src/pubkey/ec_group/info.txt | 9 |
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> |