Botan
1.11.15
|
00001 /* 00002 * ECC Domain Parameters 00003 * 00004 * (C) 2007 Falko Strenzke, FlexSecure GmbH 00005 * 2008 Jack Lloyd 00006 * 00007 * Botan is released under the Simplified BSD License (see license.txt) 00008 */ 00009 00010 #include <botan/ec_group.h> 00011 #include <botan/ber_dec.h> 00012 #include <botan/der_enc.h> 00013 #include <botan/oids.h> 00014 #include <botan/pem.h> 00015 00016 namespace Botan { 00017 00018 EC_Group::EC_Group(const OID& domain_oid) 00019 { 00020 const char* pem = PEM_for_named_group(OIDS::lookup(domain_oid)); 00021 00022 if(!pem) 00023 throw Lookup_Error("No ECC domain data for " + domain_oid.as_string()); 00024 00025 *this = EC_Group(pem); 00026 oid = domain_oid.as_string(); 00027 } 00028 00029 EC_Group::EC_Group(const std::string& str) 00030 { 00031 if(str == "") 00032 return; // no initialization / uninitialized 00033 00034 try 00035 { 00036 std::vector<byte> ber = 00037 unlock(PEM_Code::decode_check_label(str, "EC PARAMETERS")); 00038 00039 *this = EC_Group(ber); 00040 } 00041 catch(Decoding_Error) // hmm, not PEM? 00042 { 00043 *this = EC_Group(OIDS::lookup(str)); 00044 } 00045 } 00046 00047 EC_Group::EC_Group(const std::vector<byte>& ber_data) 00048 { 00049 BER_Decoder ber(ber_data); 00050 BER_Object obj = ber.get_next_object(); 00051 00052 if(obj.type_tag == NULL_TAG) 00053 throw Decoding_Error("Cannot handle ImplicitCA ECDSA parameters"); 00054 else if(obj.type_tag == OBJECT_ID) 00055 { 00056 OID dom_par_oid; 00057 BER_Decoder(ber_data).decode(dom_par_oid); 00058 *this = EC_Group(dom_par_oid); 00059 } 00060 else if(obj.type_tag == SEQUENCE) 00061 { 00062 BigInt p, a, b; 00063 std::vector<byte> sv_base_point; 00064 00065 BER_Decoder(ber_data) 00066 .start_cons(SEQUENCE) 00067 .decode_and_check<size_t>(1, "Unknown ECC param version code") 00068 .start_cons(SEQUENCE) 00069 .decode_and_check(OID("1.2.840.10045.1.1"), 00070 "Only prime ECC fields supported") 00071 .decode(p) 00072 .end_cons() 00073 .start_cons(SEQUENCE) 00074 .decode_octet_string_bigint(a) 00075 .decode_octet_string_bigint(b) 00076 .end_cons() 00077 .decode(sv_base_point, OCTET_STRING) 00078 .decode(order) 00079 .decode(cofactor) 00080 .end_cons() 00081 .verify_end(); 00082 00083 curve = CurveGFp(p, a, b); 00084 base_point = OS2ECP(sv_base_point, curve); 00085 } 00086 else 00087 throw Decoding_Error("Unexpected tag while decoding ECC domain params"); 00088 } 00089 00090 std::vector<byte> 00091 EC_Group::DER_encode(EC_Group_Encoding form) const 00092 { 00093 if(form == EC_DOMPAR_ENC_EXPLICIT) 00094 { 00095 const size_t ecpVers1 = 1; 00096 OID curve_type("1.2.840.10045.1.1"); 00097 00098 const size_t p_bytes = curve.get_p().bytes(); 00099 00100 return DER_Encoder() 00101 .start_cons(SEQUENCE) 00102 .encode(ecpVers1) 00103 .start_cons(SEQUENCE) 00104 .encode(curve_type) 00105 .encode(curve.get_p()) 00106 .end_cons() 00107 .start_cons(SEQUENCE) 00108 .encode(BigInt::encode_1363(curve.get_a(), p_bytes), 00109 OCTET_STRING) 00110 .encode(BigInt::encode_1363(curve.get_b(), p_bytes), 00111 OCTET_STRING) 00112 .end_cons() 00113 .encode(EC2OSP(base_point, PointGFp::UNCOMPRESSED), OCTET_STRING) 00114 .encode(order) 00115 .encode(cofactor) 00116 .end_cons() 00117 .get_contents_unlocked(); 00118 } 00119 else if(form == EC_DOMPAR_ENC_OID) 00120 return DER_Encoder().encode(OID(get_oid())).get_contents_unlocked(); 00121 else if(form == EC_DOMPAR_ENC_IMPLICITCA) 00122 return DER_Encoder().encode_null().get_contents_unlocked(); 00123 else 00124 throw Internal_Error("EC_Group::DER_encode: Unknown encoding"); 00125 } 00126 00127 std::string EC_Group::PEM_encode() const 00128 { 00129 const std::vector<byte> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT); 00130 return PEM_Code::encode(der, "EC PARAMETERS"); 00131 } 00132 00133 }