From b789c87b7c96dbdb00839996c9603a3f0921b25b Mon Sep 17 00:00:00 2001 From: lloyd Date: Mon, 1 Mar 2010 22:53:42 +0000 Subject: Clean up EC_Domain_Params --- src/pubkey/ec_dompar/ec_dompar.cpp | 201 +++++++++++++++---------------------- src/pubkey/ec_dompar/ec_dompar.h | 81 ++++++++------- src/pubkey/ecc_key/ecc_key.cpp | 30 +++--- src/pubkey/ecc_key/ecc_key.h | 6 +- src/pubkey/ecdsa/ecdsa.cpp | 2 +- src/pubkey/gost_3410/gost_3410.cpp | 8 +- 6 files changed, 144 insertions(+), 184 deletions(-) (limited to 'src/pubkey') diff --git a/src/pubkey/ec_dompar/ec_dompar.cpp b/src/pubkey/ec_dompar/ec_dompar.cpp index 30a121875..5ebf4932d 100644 --- a/src/pubkey/ec_dompar/ec_dompar.cpp +++ b/src/pubkey/ec_dompar/ec_dompar.cpp @@ -451,144 +451,101 @@ EC_Domain_Params get_ec_dompar(const std::string& oid) EC_Domain_Params get_EC_Dom_Pars_by_oid(std::string oid) { EC_Domain_Params result = get_ec_dompar(oid); - result.m_oid = oid; + result.oid = oid; return result; } -EC_Domain_Params::EC_Domain_Params(const CurveGFp& curve, const PointGFp& base_point, - const BigInt& order, const BigInt& cofactor) - : m_curve(curve), - m_base_point(base_point), - m_order(order), - m_cofactor(cofactor), - m_oid("") - { } - -namespace { - -SecureVector encode_der_ec_dompar_explicit(const EC_Domain_Params& dom_pars) +EC_Domain_Params::EC_Domain_Params(const MemoryRegion& ber_data) { - u32bit ecpVers1 = 1; - OID curve_type_oid("1.2.840.10045.1.1"); + BER_Decoder ber(ber_data); + BER_Object obj = ber.get_next_object(); - const u32bit p_bytes = dom_pars.get_curve().get_p().bytes(); - - return DER_Encoder() - .start_cons(SEQUENCE) - .encode(ecpVers1) - .start_cons(SEQUENCE) - .encode(curve_type_oid) - .encode(dom_pars.get_curve().get_p()) - .end_cons() + 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 = get_ec_dompar(dom_par_oid.as_string()); + } + else if(obj.type_tag == SEQUENCE) + { + BigInt ecpVers1(1); + OID curve_type; + SecureVector sv_a; + SecureVector sv_b; + BigInt p; + SecureVector sv_base_point; + + BER_Decoder(ber_data) .start_cons(SEQUENCE) - .encode(BigInt::encode_1363(dom_pars.get_curve().get_a(), p_bytes), OCTET_STRING) - .encode(BigInt::encode_1363(dom_pars.get_curve().get_b(), p_bytes), OCTET_STRING) + .decode(ecpVers1) + .start_cons(SEQUENCE) + .decode(curve_type) + .decode(p) + .end_cons() + .start_cons(SEQUENCE) + .decode(sv_a, OCTET_STRING) + .decode(sv_b, OCTET_STRING) + .end_cons() + .decode(sv_base_point, OCTET_STRING) + .decode(order) + .decode(cofactor) .end_cons() - .encode(EC2OSP ( dom_pars.get_base_point(), PointGFp::UNCOMPRESSED), OCTET_STRING) - .encode(dom_pars.get_order()) - .encode(dom_pars.get_cofactor()) - .end_cons() - .get_contents(); - } + .verify_end(); -EC_Domain_Params decode_ber_ec_dompar_explicit(const SecureVector& encoded) - { - BigInt ecpVers1(1); - OID curve_type_oid; - SecureVector sv_a; - SecureVector sv_b; - BigInt p; - SecureVector sv_base_point; - BigInt order; - BigInt cofactor; - - BER_Decoder(encoded) - .start_cons(SEQUENCE) - .decode(ecpVers1) - .start_cons(SEQUENCE) - .decode(curve_type_oid) - .decode(p) - .end_cons() - .start_cons(SEQUENCE) - .decode(sv_a, OCTET_STRING) - .decode(sv_b, OCTET_STRING) - .end_cons() - .decode(sv_base_point, OCTET_STRING) - .decode(order) - .decode(cofactor) - .end_cons() - .verify_end(); - - if(ecpVers1 != 1) - throw Decoding_Error("wrong ecpVers"); - - // Set the domain parameters - if(curve_type_oid.as_string() != "1.2.840.10045.1.1") // NOTE: hardcoded: prime field type - { - throw Decoding_Error("wrong curve type oid where prime field was expected"); - } + if(ecpVers1 != 1) + throw Decoding_Error("EC_Domain_Params: Unknown version code"); - CurveGFp curve(p, - BigInt::decode(sv_a, sv_a.size()), - BigInt::decode(sv_b, sv_b.size())); + // Only prime curves supported + if(curve_type.as_string() != "1.2.840.10045.1.1") + throw Decoding_Error("Unexpected curve type " + curve_type.as_string()); - PointGFp G = OS2ECP ( sv_base_point, curve ); - G.check_invariants(); - return EC_Domain_Params(curve, G, order, cofactor); - } + curve = CurveGFp(p, + BigInt::decode(sv_a, sv_a.size()), + BigInt::decode(sv_b, sv_b.size())); -} // end anonymous namespace + base_point = OS2ECP(sv_base_point, curve); + base_point.check_invariants(); + } + else + throw Decoding_Error("Unexpected tag while decoding ECC domain params"); + } -SecureVector encode_der_ec_dompar(const EC_Domain_Params& dom_pars, EC_dompar_enc enc_type) +SecureVector +EC_Domain_Params::DER_encode(EC_Domain_Params_Encoding form) const { - SecureVector result; - - if(enc_type == ENC_EXPLICIT) + if(form == EC_DOMPAR_ENC_EXPLICIT) { - result = encode_der_ec_dompar_explicit(dom_pars); + u32bit ecpVers1 = 1; + OID curve_type("1.2.840.10045.1.1"); + + const u32bit 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(enc_type == ENC_OID) - { - OID dom_par_oid(dom_pars.get_oid()); - result = DER_Encoder().encode(dom_par_oid).get_contents(); - } - else if(enc_type == ENC_IMPLICITCA) - { - result = DER_Encoder().encode_null().get_contents(); - } - else - { - throw Internal_Error("encountered illegal value for ec parameter encoding type"); - } - return result; - } + 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(); -EC_Domain_Params decode_ber_ec_dompar(const SecureVector& encoded) - { - BER_Decoder dec(encoded); - BER_Object obj = dec.get_next_object(); - - if(obj.type_tag == OBJECT_ID) - { - OID dom_par_oid; - BER_Decoder(encoded).decode(dom_par_oid); - return EC_Domain_Params(get_ec_dompar(dom_par_oid.as_string())); - } - else if(obj.type_tag == SEQUENCE) - return EC_Domain_Params(decode_ber_ec_dompar_explicit(encoded)); - else if(obj.type_tag == NULL_TAG) - throw Decoding_Error("cannot decode ECDSA parameters that are ImplicitCA"); - - throw Decoding_Error("encountered unexpected when trying to decode domain parameters"); - } - -bool operator==(const EC_Domain_Params& lhs, const EC_Domain_Params& rhs) - { - return ((lhs.get_curve() == rhs.get_curve()) && - (lhs.get_base_point() == rhs.get_base_point()) && - (lhs.get_order() == rhs.get_order()) && - (lhs.get_cofactor() == rhs.get_cofactor())); - } + throw Internal_Error("EC_Domain_Params::encode_DER: Unknown encoding"); + } } diff --git a/src/pubkey/ec_dompar/ec_dompar.h b/src/pubkey/ec_dompar/ec_dompar.h index f5f573ba9..cc55aa4df 100644 --- a/src/pubkey/ec_dompar/ec_dompar.h +++ b/src/pubkey/ec_dompar/ec_dompar.h @@ -2,7 +2,7 @@ * ECC Domain Parameters * * (C) 2007 Falko Strenzke, FlexSecure GmbH -* 2008 Jack Lloyd +* 2008-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -22,10 +22,15 @@ namespace Botan { /** * This class represents elliptic curce domain parameters */ +enum EC_Domain_Params_Encoding { + EC_DOMPAR_ENC_EXPLICIT = 0, + EC_DOMPAR_ENC_IMPLICITCA = 1, + EC_DOMPAR_ENC_OID = 2 +}; + class BOTAN_DLL EC_Domain_Params { public: - /** * Construct Domain paramers from specified parameters * @param curve elliptic curve @@ -36,78 +41,80 @@ class BOTAN_DLL EC_Domain_Params EC_Domain_Params(const CurveGFp& curve, const PointGFp& base_point, const BigInt& order, - const BigInt& cofactor); + 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_Domain_Params(const MemoryRegion& ber_encoding); + + /** + * Create the DER encoding of this domain + * @param form of encoding to use + * @returns bytes encododed as DER + */ + SecureVector DER_encode(EC_Domain_Params_Encoding form) const; /** * Return domain parameter curve * @result domain parameter curve */ - const CurveGFp& get_curve() const - { - return m_curve; - } + const CurveGFp& get_curve() const { return curve; } /** * Return domain parameter curve * @result domain parameter curve */ - const PointGFp& get_base_point() const - { - return m_base_point; - } + 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 m_order; - } + const BigInt& get_order() const { return order; } /** * Return the cofactor * @result the cofactor */ - const BigInt& get_cofactor() const - { - return m_cofactor; - } + const BigInt& get_cofactor() const { return cofactor; } /** * Return the OID of these domain parameters * @result the OID */ - std::string get_oid() const { return m_oid; } + std::string get_oid() const { return oid; } + + bool operator==(const EC_Domain_Params& 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: friend EC_Domain_Params get_EC_Dom_Pars_by_oid(std::string oid); - CurveGFp m_curve; - PointGFp m_base_point; - BigInt m_order; - BigInt m_cofactor; - std::string m_oid; + CurveGFp curve; + PointGFp base_point; + BigInt order, cofactor; + std::string oid; }; -bool BOTAN_DLL operator==(EC_Domain_Params const& lhs, - EC_Domain_Params const& rhs); - inline bool operator!=(const EC_Domain_Params& lhs, const EC_Domain_Params& rhs) { return !(lhs == rhs); } -enum EC_dompar_enc { ENC_EXPLICIT = 0, ENC_IMPLICITCA = 1, ENC_OID = 2 }; - -SecureVector -BOTAN_DLL encode_der_ec_dompar(EC_Domain_Params const& dom_pars, - EC_dompar_enc enc_type); - -EC_Domain_Params -BOTAN_DLL decode_ber_ec_dompar(SecureVector const& encoded); - /** * Factory function, the only way to obtain EC domain parameters with * an OID. The demanded OID has to be registered in the InSiTo diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index 6ed1fd9c6..c14617cfe 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -71,10 +71,8 @@ X509_Encoder* EC_PublicKey::x509_encoder() const { key->affirm_init(); - SecureVector params = - encode_der_ec_dompar(key->domain_parameters(), key->m_param_enc); - - return AlgorithmIdentifier(key->get_oid(), params); + return AlgorithmIdentifier(key->get_oid(), + key->domain_parameters().DER_encode(key->m_param_enc)); } MemoryVector key_bits() const @@ -98,7 +96,7 @@ X509_Decoder* EC_PublicKey::x509_decoder() public: void alg_id(const AlgorithmIdentifier& alg_id) { - key->mp_dom_pars.reset(new EC_Domain_Params(decode_ber_ec_dompar(alg_id.parameters))); + key->mp_dom_pars.reset(new EC_Domain_Params(alg_id.parameters)); } void key_bits(const MemoryRegion& bits) @@ -119,19 +117,21 @@ X509_Decoder* EC_PublicKey::x509_decoder() return new EC_Key_Decoder(this); } -void EC_PublicKey::set_parameter_encoding(EC_dompar_enc type) +void EC_PublicKey::set_parameter_encoding(EC_Domain_Params_Encoding form) { - if((type != ENC_EXPLICIT) && (type != ENC_IMPLICITCA) && (type != ENC_OID)) - throw Invalid_Argument("Invalid encoding type for EC-key object specified"); + if(form != EC_DOMPAR_ENC_EXPLICIT && + form != EC_DOMPAR_ENC_IMPLICITCA && + form != EC_DOMPAR_ENC_OID) + throw Invalid_Argument("Invalid encoding form for EC-key object specified"); affirm_init(); - if((type == ENC_OID) && (mp_dom_pars->get_oid() == "")) - throw Invalid_Argument("Invalid encoding type ENC_OID specified for " + if((form == EC_DOMPAR_ENC_OID) && (mp_dom_pars->get_oid() == "")) + throw Invalid_Argument("Invalid encoding form OID specified for " "EC-key object whose corresponding domain " "parameters are without oid"); - m_param_enc = type; + m_param_enc = form; } /* @@ -182,10 +182,8 @@ PKCS8_Encoder* EC_PrivateKey::pkcs8_encoder() const { key->affirm_init(); - SecureVector params = - encode_der_ec_dompar(key->domain_parameters(), ENC_EXPLICIT); - - return AlgorithmIdentifier(key->get_oid(), params); + return AlgorithmIdentifier(key->get_oid(), + key->domain_parameters().DER_encode(EC_DOMPAR_ENC_EXPLICIT)); } MemoryVector key_bits() const @@ -220,7 +218,7 @@ PKCS8_Decoder* EC_PrivateKey::pkcs8_decoder(RandomNumberGenerator&) public: void alg_id(const AlgorithmIdentifier& alg_id) { - key->mp_dom_pars.reset(new EC_Domain_Params(decode_ber_ec_dompar(alg_id.parameters))); + key->mp_dom_pars.reset(new EC_Domain_Params(alg_id.parameters)); } void key_bits(const MemoryRegion& bits) diff --git a/src/pubkey/ecc_key/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h index 76f3faf34..4e97a427f 100644 --- a/src/pubkey/ecc_key/ecc_key.h +++ b/src/pubkey/ecc_key/ecc_key.h @@ -58,7 +58,7 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key * Set the domain parameter encoding to be used when encoding this key. * @param enc the encoding to use */ - void set_parameter_encoding(EC_dompar_enc enc); + void set_parameter_encoding(EC_Domain_Params_Encoding enc); /** * Get the domain parameter encoding to be used when encoding this key. @@ -71,7 +71,7 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key //ctors EC_PublicKey() - : m_param_enc(ENC_EXPLICIT) + : m_param_enc(EC_DOMPAR_ENC_EXPLICIT) { //assert(mp_dom_pars.get() == 0); //assert(mp_public_point.get() == 0); @@ -104,7 +104,7 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key std::auto_ptr mp_dom_pars; std::auto_ptr mp_public_point; - EC_dompar_enc m_param_enc; + EC_Domain_Params_Encoding m_param_enc; }; /** diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 120efe99d..2e6efd609 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -135,7 +135,7 @@ ECDSA_PublicKey::ECDSA_PublicKey(const EC_Domain_Params& dom_par, { mp_dom_pars = std::auto_ptr(new EC_Domain_Params(dom_par)); mp_public_point = std::auto_ptr(new PointGFp(public_point)); - m_param_enc = ENC_EXPLICIT; + m_param_enc = EC_DOMPAR_ENC_EXPLICIT; m_ecdsa_core = ECDSA_Core(*mp_dom_pars, BigInt(0), *mp_public_point); } diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp index 24e078dca..8f6b56324 100644 --- a/src/pubkey/gost_3410/gost_3410.cpp +++ b/src/pubkey/gost_3410/gost_3410.cpp @@ -61,10 +61,8 @@ X509_Encoder* GOST_3410_PublicKey::x509_encoder() const { key->affirm_init(); - SecureVector params = - encode_der_ec_dompar(key->domain_parameters(), key->m_param_enc); - - return AlgorithmIdentifier(key->get_oid(), params); + return AlgorithmIdentifier(key->get_oid(), + key->domain_parameters().DER_encode(key->m_param_enc)); } MemoryVector key_bits() const @@ -242,7 +240,7 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const EC_Domain_Params& dom_par, { mp_dom_pars = std::auto_ptr(new EC_Domain_Params(dom_par)); mp_public_point = std::auto_ptr(new PointGFp(public_point)); - m_param_enc = ENC_EXPLICIT; + m_param_enc = EC_DOMPAR_ENC_EXPLICIT; } void GOST_3410_PublicKey::X509_load_hook() -- cgit v1.2.3