From b789c87b7c96dbdb00839996c9603a3f0921b25b Mon Sep 17 00:00:00 2001
From: lloyd <lloyd@randombit.net>
Date: Mon, 1 Mar 2010 22:53:42 +0000
Subject: Clean up EC_Domain_Params

---
 checks/cvc_tests.cpp               |  12 +--
 src/cert/cvc/cvc_self.cpp          |   6 +-
 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 +-
 8 files changed, 153 insertions(+), 193 deletions(-)

diff --git a/checks/cvc_tests.cpp b/checks/cvc_tests.cpp
index 8ca00e048..454ed0b36 100644
--- a/checks/cvc_tests.cpp
+++ b/checks/cvc_tests.cpp
@@ -93,7 +93,7 @@ void test_enc_gen_selfsigned(RandomNumberGenerator& rng)
    // creating a non sense selfsigned cert w/o dom pars
    EC_Domain_Params dom_pars(get_EC_Dom_Pars_by_oid("1.3.36.3.3.2.8.1.1.11"));
    ECDSA_PrivateKey key(rng, dom_pars);
-   key.set_parameter_encoding(ENC_IMPLICITCA);
+   key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
    EAC1_1_CVC cert = CVC_EAC::create_self_signed_cert(key, opts, rng);
 
    SecureVector<byte> der(cert.BER_encode());
@@ -169,7 +169,7 @@ void test_enc_gen_selfsigned(RandomNumberGenerator& rng)
    // let´s see if encoding is truely implicitca, because this is what the key should have
    // been set to when decoding (see above)(because it has no domain params):
    //cout << "encoding = " << p_ecdsa_pk->get_parameter_encoding() << std::endl;
-   CHECK(p_ecdsa_pk->get_parameter_encoding() == ENC_IMPLICITCA);
+   CHECK(p_ecdsa_pk->get_parameter_encoding() == EC_DOMPAR_ENC_IMPLICITCA);
    bool exc = false;
    try
       {
@@ -203,7 +203,7 @@ void test_enc_gen_req(RandomNumberGenerator& rng)
    // creating a non sense selfsigned cert w/o dom pars
    EC_Domain_Params dom_pars(get_EC_Dom_Pars_by_oid("1.3.132.0.8"));
    ECDSA_PrivateKey key(rng, dom_pars);
-   key.set_parameter_encoding(ENC_IMPLICITCA);
+   key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
    EAC1_1_Req req = CVC_EAC::create_cvc_req(key, opts.chr, opts.hash_alg, rng);
    SecureVector<byte> der(req.BER_encode());
    std::ofstream req_file(TEST_DATA_DIR "/my_cv_req.ber", std::ios::binary);
@@ -259,7 +259,7 @@ void test_cvc_ado_creation(RandomNumberGenerator& rng)
    EC_Domain_Params dom_pars(get_EC_Dom_Pars_by_oid("1.3.36.3.3.2.8.1.1.11"));
    //cout << "mod = " << hex << dom_pars.get_curve().get_p() << std::endl;
    ECDSA_PrivateKey req_key(rng, dom_pars);
-   req_key.set_parameter_encoding(ENC_IMPLICITCA);
+   req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
    //EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts);
    EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, rng);
    SecureVector<byte> der(req.BER_encode());
@@ -302,7 +302,7 @@ void test_cvc_ado_comparison(RandomNumberGenerator& rng)
    // creating a non sense selfsigned cert w/o dom pars
    EC_Domain_Params dom_pars(get_EC_Dom_Pars_by_oid("1.3.36.3.3.2.8.1.1.11"));
    ECDSA_PrivateKey req_key(rng, dom_pars);
-   req_key.set_parameter_encoding(ENC_IMPLICITCA);
+   req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
    //EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts);
    EAC1_1_Req req = CVC_EAC::create_cvc_req(req_key, opts.chr, opts.hash_alg, rng);
 
@@ -321,7 +321,7 @@ void test_cvc_ado_comparison(RandomNumberGenerator& rng)
    opts2.chr = ASN1_Chr("my_opt_chr");
    opts2.hash_alg = "SHA-160"; // this is the only difference
    ECDSA_PrivateKey req_key2(rng, dom_pars);
-   req_key.set_parameter_encoding(ENC_IMPLICITCA);
+   req_key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
    //EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2, rng);
    EAC1_1_Req req2 = CVC_EAC::create_cvc_req(req_key2, opts2.chr, opts2.hash_alg, rng);
    ECDSA_PrivateKey ado_key2(rng, dom_pars);
diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp
index deef351b9..5319caf10 100644
--- a/src/cert/cvc/cvc_self.cpp
+++ b/src/cert/cvc/cvc_self.cpp
@@ -217,7 +217,7 @@ EAC1_1_CVC link_cvca(EAC1_1_CVC const& signer,
    std::auto_ptr<Botan::PK_Signer> pk_signer(get_pk_signer(*priv_key, padding_and_hash));
    std::auto_ptr<Public_Key> pk = signee.subject_public_key();
    ECDSA_PublicKey*  subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get());
-   subj_pk->set_parameter_encoding(ENC_EXPLICIT);
+   subj_pk->set_parameter_encoding(EC_DOMPAR_ENC_EXPLICIT);
 
 #if 0 // FIXME
    std::auto_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder());
@@ -263,7 +263,7 @@ EAC1_1_CVC sign_request(EAC1_1_CVC const& signer_cert,
    // (we use those from the signer because they must fit)
    subj_pk->set_domain_parameters(priv_key->domain_parameters());
 
-   subj_pk->set_parameter_encoding(ENC_IMPLICITCA);
+   subj_pk->set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
 
 #if 0 // FIXME
    std::auto_ptr<EAC1_1_CVC_Encoder> enc(subj_pk->cvc_eac1_1_encoder());
@@ -322,7 +322,7 @@ EAC1_1_Req create_cvc_req(Private_Key const& prkey,
       throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
       }
    ECDSA_PrivateKey key(*priv_key);
-   key.set_parameter_encoding(ENC_IMPLICITCA);
+   key.set_parameter_encoding(EC_DOMPAR_ENC_IMPLICITCA);
    return Botan::CVC_EAC::create_cvc_req(key, chr, hash_alg, rng);
    }
 
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<byte> encode_der_ec_dompar_explicit(const EC_Domain_Params& dom_pars)
+EC_Domain_Params::EC_Domain_Params(const MemoryRegion<byte>& 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<byte> sv_a;
+      SecureVector<byte> sv_b;
+      BigInt p;
+      SecureVector<byte> 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<byte>& encoded)
-   {
-   BigInt ecpVers1(1);
-   OID curve_type_oid;
-   SecureVector<byte> sv_a;
-   SecureVector<byte> sv_b;
-   BigInt p;
-   SecureVector<byte> 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<byte> encode_der_ec_dompar(const EC_Domain_Params& dom_pars, EC_dompar_enc enc_type)
+SecureVector<byte>
+EC_Domain_Params::DER_encode(EC_Domain_Params_Encoding form) const
      {
-     SecureVector<byte> 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<byte>& 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<byte>& ber_encoding);
+
+      /**
+      * Create the DER encoding of this domain
+      * @param form of encoding to use
+      * @returns bytes encododed as DER
+      */
+      SecureVector<byte> 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<byte>
-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<byte> 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<byte> 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<byte> 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<byte>& 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<byte> 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<byte> 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<byte>& 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<EC_Domain_Params> mp_dom_pars;
       std::auto_ptr<PointGFp> 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<EC_Domain_Params>(new EC_Domain_Params(dom_par));
    mp_public_point = std::auto_ptr<PointGFp>(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<byte> 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<byte> 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<EC_Domain_Params>(new EC_Domain_Params(dom_par));
    mp_public_point = std::auto_ptr<PointGFp>(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