aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-02-07 15:07:37 -0500
committerJack Lloyd <[email protected]>2018-02-07 15:07:37 -0500
commit08046d32318090bd6ef110c3e4bb0105453ef26f (patch)
tree609b4fa5bdbdd8e6107f661b3d474795c8e59b1f /src
parent7604dd4702ae61f74f37a91ab8f5177f04db8108 (diff)
parent2cb0fa04472f4bc60f02d822daa8f4f8ad487e7e (diff)
Merge GH #1441 Add a shared registry of EC_Group objects
Diffstat (limited to 'src')
-rw-r--r--src/lib/asn1/asn1_oid.cpp2
-rw-r--r--src/lib/asn1/asn1_oid.h18
-rw-r--r--src/lib/math/ec_gfp/point_gfp.cpp46
-rw-r--r--src/lib/math/ec_gfp/point_gfp.h15
-rw-r--r--src/lib/pubkey/ec_group/ec_group.cpp329
-rw-r--r--src/lib/pubkey/ec_group/ec_group.h34
-rw-r--r--src/lib/pubkey/ec_group/ec_named.cpp508
-rw-r--r--src/lib/utils/mem_ops.cpp7
-rw-r--r--src/lib/utils/mem_ops.h5
-rw-r--r--src/tests/unit_ecc.cpp26
-rw-r--r--src/tests/unit_x509.cpp3
11 files changed, 591 insertions, 402 deletions
diff --git a/src/lib/asn1/asn1_oid.cpp b/src/lib/asn1/asn1_oid.cpp
index 2aa453c2b..81450becf 100644
--- a/src/lib/asn1/asn1_oid.cpp
+++ b/src/lib/asn1/asn1_oid.cpp
@@ -47,7 +47,7 @@ void OID::clear()
/*
* Return this OID as a string
*/
-std::string OID::as_string() const
+std::string OID::to_string() const
{
std::string oid_str;
for(size_t i = 0; i != m_id.size(); ++i)
diff --git a/src/lib/asn1/asn1_oid.h b/src/lib/asn1/asn1_oid.h
index 8f3f20f2f..6198819ad 100644
--- a/src/lib/asn1/asn1_oid.h
+++ b/src/lib/asn1/asn1_oid.h
@@ -27,7 +27,13 @@ class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object
* Find out whether this OID is empty
* @return true is no OID value is set
*/
- bool empty() const { return m_id.size() == 0; }
+ bool empty() const { return m_id.empty(); }
+
+ /**
+ * Find out whether this OID has a value
+ * @return true is this OID has a value
+ */
+ bool has_value() const { return (m_id.empty() == false); }
/**
* Get this OID as list (vector) of its components.
@@ -39,7 +45,13 @@ class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object
* Get this OID as a string
* @return string representing this OID
*/
- std::string as_string() const;
+ std::string as_string() const { return this->to_string(); }
+
+ /**
+ * Get this OID as a string
+ * @return string representing this OID
+ */
+ std::string to_string() const;
/**
* Compare two OIDs.
@@ -64,6 +76,8 @@ class BOTAN_PUBLIC_API(2,0) OID final : public ASN1_Object
* @param str a string in the form "a.b.c" etc., where a,b,c are numbers
*/
OID(const std::string& str = "");
+
+ explicit OID(std::initializer_list<uint32_t> init) : m_id(init) {}
private:
std::vector<uint32_t> m_id;
};
diff --git a/src/lib/math/ec_gfp/point_gfp.cpp b/src/lib/math/ec_gfp/point_gfp.cpp
index 0b615b88b..f00f030d7 100644
--- a/src/lib/math/ec_gfp/point_gfp.cpp
+++ b/src/lib/math/ec_gfp/point_gfp.cpp
@@ -516,24 +516,24 @@ namespace {
BigInt decompress_point(bool yMod2,
const BigInt& x,
- const CurveGFp& curve)
+ const BigInt& curve_p,
+ const BigInt& curve_a,
+ const BigInt& curve_b)
{
BigInt xpow3 = x * x * x;
- const BigInt& p = curve.get_p();
-
- BigInt g = curve.get_a() * x;
+ BigInt g = curve_a * x;
g += xpow3;
- g += curve.get_b();
- g = g % p;
+ g += curve_b;
+ g = g % curve_p;
- BigInt z = ressol(g, p);
+ BigInt z = ressol(g, curve_p);
if(z < 0)
throw Illegal_Point("error during EC point decompression");
if(z.get_bit(0) != yMod2)
- z = p - z;
+ z = curve_p - z;
return z;
}
@@ -543,9 +543,28 @@ BigInt decompress_point(bool yMod2,
PointGFp OS2ECP(const uint8_t data[], size_t data_len,
const CurveGFp& curve)
{
+ // Should we really be doing this?
if(data_len <= 1)
return PointGFp(curve); // return zero
+ std::pair<BigInt, BigInt> xy = OS2ECP(data, data_len, curve.get_p(), curve.get_a(), curve.get_b());
+
+ PointGFp point(curve, xy.first, xy.second);
+
+ if(!point.on_the_curve())
+ throw Illegal_Point("OS2ECP: Decoded point was not on the curve");
+
+ return point;
+ }
+
+std::pair<BigInt, BigInt> OS2ECP(const uint8_t data[], size_t data_len,
+ const BigInt& curve_p,
+ const BigInt& curve_a,
+ const BigInt& curve_b)
+ {
+ if(data_len <= 1)
+ throw Decoding_Error("OS2ECP invalid point");
+
const uint8_t pc = data[0];
BigInt x, y;
@@ -556,7 +575,7 @@ PointGFp OS2ECP(const uint8_t data[], size_t data_len,
x = BigInt::decode(&data[1], data_len - 1);
const bool y_mod_2 = ((pc & 0x01) == 1);
- y = decompress_point(y_mod_2, x, curve);
+ y = decompress_point(y_mod_2, x, curve_p, curve_a, curve_b);
}
else if(pc == 4)
{
@@ -576,18 +595,13 @@ PointGFp OS2ECP(const uint8_t data[], size_t data_len,
const bool y_mod_2 = ((pc & 0x01) == 1);
- if(decompress_point(y_mod_2, x, curve) != y)
+ if(decompress_point(y_mod_2, x, curve_p, curve_a, curve_b) != y)
throw Illegal_Point("OS2ECP: Decoding error in hybrid format");
}
else
throw Invalid_Argument("OS2ECP: Unknown format type " + std::to_string(pc));
- PointGFp result(curve, x, y);
-
- if(!result.on_the_curve())
- throw Illegal_Point("OS2ECP: Decoded point was not on the curve");
-
- return result;
+ return std::make_pair(x, y);
}
}
diff --git a/src/lib/math/ec_gfp/point_gfp.h b/src/lib/math/ec_gfp/point_gfp.h
index 61239df80..2e1c626bd 100644
--- a/src/lib/math/ec_gfp/point_gfp.h
+++ b/src/lib/math/ec_gfp/point_gfp.h
@@ -279,7 +279,20 @@ inline PointGFp operator*(const PointGFp& point, const BigInt& scalar)
secure_vector<uint8_t> BOTAN_PUBLIC_API(2,0) EC2OSP(const PointGFp& point, uint8_t format);
PointGFp BOTAN_PUBLIC_API(2,0) OS2ECP(const uint8_t data[], size_t data_len,
- const CurveGFp& curve);
+ const CurveGFp& curve);
+
+/**
+* Perform point decoding
+* @param data the encoded point
+* @param data_len length of data in bytes
+* @param curve_p the curve equation prime
+* @param curve_a the curve equation a parameter
+* @param curve_b the curve equation b parameter
+*/
+std::pair<BigInt, BigInt> BOTAN_PUBLIC_API(2,5) OS2ECP(const uint8_t data[], size_t data_len,
+ const BigInt& curve_p,
+ const BigInt& curve_a,
+ const BigInt& curve_b);
template<typename Alloc>
PointGFp OS2ECP(const std::vector<uint8_t, Alloc>& data, const CurveGFp& curve)
diff --git a/src/lib/pubkey/ec_group/ec_group.cpp b/src/lib/pubkey/ec_group/ec_group.cpp
index 93747a166..0c2cd566c 100644
--- a/src/lib/pubkey/ec_group/ec_group.cpp
+++ b/src/lib/pubkey/ec_group/ec_group.cpp
@@ -2,7 +2,8 @@
* ECC Domain Parameters
*
* (C) 2007 Falko Strenzke, FlexSecure GmbH
-* 2008,2018 Jack Lloyd
+* (C) 2008,2018 Jack Lloyd
+* (C) 2018 Tobias Niemann
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -13,67 +14,201 @@
#include <botan/oids.h>
#include <botan/pem.h>
#include <botan/reducer.h>
+#include <botan/mutex.h>
+#include <vector>
namespace Botan {
-struct EC_Group_Data
+class EC_Group_Data final
{
- CurveGFp m_curve;
- PointGFp m_base_point;
- BigInt m_order;
- BigInt m_cofactor;
- OID m_oid;
- size_t m_p_bits, m_p_bytes;
- };
+ public:
+
+ EC_Group_Data(const BigInt& p,
+ const BigInt& a,
+ const BigInt& b,
+ const BigInt& g_x,
+ const BigInt& g_y,
+ const BigInt& order,
+ const BigInt& cofactor,
+ const OID& oid) :
+ m_curve(p, a, b),
+ m_base_point(m_curve, g_x, g_y),
+ m_order(order),
+ m_cofactor(cofactor),
+ m_oid(oid),
+ m_p_bits(p.bits()),
+ m_p_bytes(p.bytes())
+ {
+ }
-namespace {
+ bool match(const BigInt& p, const BigInt& a, const BigInt& b,
+ const BigInt& g_x, const BigInt& g_y,
+ const BigInt& order, const BigInt& cofactor) const
+ {
+ return (this->p() == p && this->a() == a && this->b() == b &&
+ this->order() == order && this->cofactor() == cofactor &&
+ this->g_x() == g_x && this->g_y() == g_y);
+ }
+
+ const OID& oid() const { return m_oid; }
+ const BigInt& p() const { return m_curve.get_p(); }
+ const BigInt& a() const { return m_curve.get_a(); }
+ const BigInt& b() const { return m_curve.get_b(); }
+ const BigInt& order() const { return m_order; }
+ const BigInt& cofactor() const { return m_cofactor; }
+ BigInt g_x() const { return m_base_point.get_affine_x(); }
+ BigInt g_y() const { return m_base_point.get_affine_y(); }
+
+ size_t p_bits() const { return m_p_bits; }
+ size_t p_bytes() const { return m_p_bytes; }
+
+ const CurveGFp& curve() const { return m_curve; }
+ const PointGFp& base_point() const { return m_base_point; }
+
+ private:
+ CurveGFp m_curve;
+ PointGFp m_base_point;
+ BigInt m_order;
+ BigInt m_cofactor;
+ OID m_oid;
+ size_t m_p_bits, m_p_bytes;
+ };
-std::shared_ptr<EC_Group_Data> new_EC_group_data(const BigInt& p,
- const BigInt& a,
- const BigInt& b,
- const BigInt& g_x,
- const BigInt& g_y,
- const BigInt& order,
- const BigInt& cofactor,
- const OID& oid = OID())
+class EC_Group_Data_Map final
{
- std::shared_ptr<EC_Group_Data> data = std::make_shared<EC_Group_Data>();
+ public:
+ EC_Group_Data_Map() {}
- data->m_curve = CurveGFp(p, a, b);
- data->m_base_point = PointGFp(data->m_curve, g_x, g_y);
- data->m_order = order;
- data->m_cofactor = cofactor;
- data->m_oid = oid;
+ std::shared_ptr<EC_Group_Data> lookup(const OID& oid)
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
- data->m_p_bits = p.bits();
- data->m_p_bytes = p.bytes();
- return data;
- }
+ for(auto i : m_registered_curves)
+ {
+ if(i->oid() == oid)
+ return i;
+ }
-std::shared_ptr<EC_Group_Data> new_EC_group_data(const BigInt& p,
- const BigInt& a,
- const BigInt& b,
- const std::vector<uint8_t>& base_point,
- const BigInt& order,
- const BigInt& cofactor,
- const OID& oid = OID())
- {
- std::shared_ptr<EC_Group_Data> data = std::make_shared<EC_Group_Data>();
+ // Not found, check hardcoded data
+ std::shared_ptr<EC_Group_Data> data = EC_Group::EC_group_info(oid);
+
+ if(data)
+ {
+ m_registered_curves.push_back(data);
+ return data;
+ }
+
+ // Nope, unknown curve
+ return std::shared_ptr<EC_Group_Data>();
+ }
- data->m_curve = CurveGFp(p, a, b);
- data->m_base_point = Botan::OS2ECP(base_point, data->m_curve);
- data->m_order = order;
- data->m_cofactor = cofactor;
- data->m_oid = oid;
+ std::shared_ptr<EC_Group_Data> lookup_or_create(const BigInt& p,
+ const BigInt& a,
+ const BigInt& b,
+ const BigInt& g_x,
+ const BigInt& g_y,
+ const BigInt& order,
+ const BigInt& cofactor,
+ const OID& oid)
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+
+ for(auto i : m_registered_curves)
+ {
+ if(oid.has_value())
+ {
+ if(i->oid() == oid)
+ return i;
+ else if(i->oid().has_value())
+ continue;
+ }
+
+ if(i->match(p, a, b, g_x, g_y, order, cofactor))
+ return i;
+ }
+
+ // Not found - if OID is set try looking up that way
+
+ if(oid.has_value())
+ {
+ // Not located in existing store - try hardcoded data set
+ std::shared_ptr<EC_Group_Data> data = EC_Group::EC_group_info(oid);
+
+ if(data)
+ {
+ m_registered_curves.push_back(data);
+ return data;
+ }
+ }
+
+ // Not found or no OID, add data and return
+ return add_curve(p, a, b, g_x, g_y, order, cofactor, oid);
+ }
+
+ private:
+
+ std::shared_ptr<EC_Group_Data> add_curve(const BigInt& p,
+ const BigInt& a,
+ const BigInt& b,
+ const BigInt& g_x,
+ const BigInt& g_y,
+ const BigInt& order,
+ const BigInt& cofactor,
+ const OID& oid)
+ {
+ std::shared_ptr<EC_Group_Data> d =
+ std::make_shared<EC_Group_Data>(p, a, b, g_x, g_y, order, cofactor, oid);
+
+ // This function is always called with the lock held
+ m_registered_curves.push_back(d);
+ return d;
+ }
+
+ mutex_type m_mutex;
+ std::vector<std::shared_ptr<EC_Group_Data>> m_registered_curves;
+ };
+
+//static
+EC_Group_Data_Map& EC_Group::ec_group_data()
+ {
+ /*
+ * This exists purely to ensure the allocator is constructed before g_ec_data,
+ * which ensures that its destructor runs after ~g_ec_data is complete.
+ */
+ class Allocator_Initializer
+ {
+ public:
+ Allocator_Initializer() { initialize_allocator(); }
+ };
- data->m_p_bits = p.bits();
- data->m_p_bytes = p.bytes();
- return data;
+ static Allocator_Initializer g_init_allocator;
+ static EC_Group_Data_Map g_ec_data;
+ return g_ec_data;
}
-std::shared_ptr<EC_Group_Data> lookup_EC_group_by_oid(const OID& oid);
+//static
+std::shared_ptr<EC_Group_Data>
+EC_Group::load_EC_group_info(const char* p_str,
+ const char* a_str,
+ const char* b_str,
+ const char* g_x_str,
+ const char* g_y_str,
+ const char* order_str,
+ const OID& oid)
+ {
+ const BigInt p(p_str);
+ const BigInt a(a_str);
+ const BigInt b(b_str);
+ const BigInt g_x(g_x_str);
+ const BigInt g_y(g_y_str);
+ const BigInt order(order_str);
+ const BigInt cofactor(1); // implicit
+
+ return std::make_shared<EC_Group_Data>(p, a, b, g_x, g_y, order, cofactor, oid);
+ }
-std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t len)
+//static
+std::shared_ptr<EC_Group_Data> EC_Group::BER_decode_EC_group(const uint8_t bits[], size_t len)
{
BER_Decoder ber(bits, len);
BER_Object obj = ber.get_next_object();
@@ -86,12 +221,12 @@ std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t
{
OID dom_par_oid;
BER_Decoder(bits, len).decode(dom_par_oid);
- return lookup_EC_group_by_oid(dom_par_oid);
+ return ec_group_data().lookup(dom_par_oid);
}
else if(obj.type() == SEQUENCE)
{
BigInt p, a, b, order, cofactor;
- std::vector<uint8_t> sv_base_point;
+ std::vector<uint8_t> base_pt;
BER_Decoder(bits, len)
.start_cons(SEQUENCE)
@@ -105,13 +240,15 @@ std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t
.decode_octet_string_bigint(a)
.decode_octet_string_bigint(b)
.end_cons()
- .decode(sv_base_point, OCTET_STRING)
+ .decode(base_pt, OCTET_STRING)
.decode(order)
.decode(cofactor)
.end_cons()
.verify_end();
- return new_EC_group_data(p, a, b, sv_base_point, order, cofactor);
+ std::pair<BigInt, BigInt> base_xy = Botan::OS2ECP(base_pt.data(), base_pt.size(), p, a, b);
+
+ return ec_group_data().lookup_or_create(p, a, b, base_xy.first, base_xy.second, order, cofactor, OID());
}
else
{
@@ -119,31 +256,6 @@ std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t
}
}
-std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const std::string& pem)
- {
- secure_vector<uint8_t> ber = PEM_Code::decode_check_label(pem, "EC PARAMETERS");
- return BER_decode_EC_group(ber.data(), ber.size());
- }
-
-std::shared_ptr<EC_Group_Data> lookup_EC_group_by_oid(const OID& oid)
- {
- if(oid.empty())
- throw Invalid_Argument("lookup_EC_group_by_oid with empty oid");
-
- const std::string oid_name = OIDS::oid2str(oid);
- if(oid_name.empty())
- throw Invalid_Argument("Unknown EC group OID " + oid.as_string());
-
- const std::string pem = EC_Group::PEM_for_named_group(oid_name);
- if(pem.empty())
- throw Invalid_Argument("EC group OID (" + oid_name + ") is not known");
- std::shared_ptr<EC_Group_Data> data = BER_decode_EC_group(pem);
- data->m_oid = oid;
- return data;
- }
-
-}
-
EC_Group::EC_Group()
{
}
@@ -155,7 +267,9 @@ EC_Group::~EC_Group()
EC_Group::EC_Group(const OID& domain_oid)
{
- this->m_data = lookup_EC_group_by_oid(domain_oid);
+ this->m_data = ec_group_data().lookup(domain_oid);
+ if(!this->m_data)
+ throw Invalid_Argument("Unknown EC_Group " + domain_oid.as_string());
}
EC_Group::EC_Group(const std::string& str)
@@ -167,7 +281,7 @@ EC_Group::EC_Group(const std::string& str)
{
OID oid = OIDS::lookup(str);
if(oid.empty() == false)
- m_data = lookup_EC_group_by_oid(oid);
+ m_data = ec_group_data().lookup(oid);
}
catch(Invalid_OID)
{
@@ -176,7 +290,22 @@ EC_Group::EC_Group(const std::string& str)
if(m_data == nullptr)
{
// OK try it as PEM ...
- this->m_data = BER_decode_EC_group(str);
+ secure_vector<uint8_t> ber = PEM_Code::decode_check_label(str, "EC PARAMETERS");
+ this->m_data = BER_decode_EC_group(ber.data(), ber.size());
+ }
+ }
+
+//static
+std::string EC_Group::PEM_for_named_group(const std::string& name)
+ {
+ try
+ {
+ EC_Group group(name);
+ return group.PEM_encode();
+ }
+ catch(...)
+ {
+ return "";
}
}
@@ -189,21 +318,7 @@ EC_Group::EC_Group(const BigInt& p,
const BigInt& cofactor,
const OID& oid)
{
- m_data = new_EC_group_data(p, a, b, base_x, base_y, order, cofactor, oid);
- }
-
-EC_Group::EC_Group(const CurveGFp& curve,
- const PointGFp& base_point,
- const BigInt& order,
- const BigInt& cofactor)
- {
- m_data = new_EC_group_data(curve.get_p(),
- curve.get_a(),
- curve.get_b(),
- base_point.get_affine_x(),
- base_point.get_affine_y(),
- order,
- cofactor);
+ m_data = ec_group_data().lookup_or_create(p, a, b, base_x, base_y, order, cofactor, oid);
}
EC_Group::EC_Group(const std::vector<uint8_t>& ber)
@@ -220,67 +335,67 @@ const EC_Group_Data& EC_Group::data() const
const CurveGFp& EC_Group::get_curve() const
{
- return data().m_curve;
+ return data().curve();
}
size_t EC_Group::get_p_bits() const
{
- return data().m_p_bits;
+ return data().p_bits();
}
size_t EC_Group::get_p_bytes() const
{
- return data().m_p_bytes;
+ return data().p_bytes();
}
const BigInt& EC_Group::get_p() const
{
- return data().m_curve.get_p();
+ return data().p();
}
const BigInt& EC_Group::get_a() const
{
- return data().m_curve.get_a();
+ return data().a();
}
const BigInt& EC_Group::get_b() const
{
- return data().m_curve.get_b();
+ return data().b();
}
const PointGFp& EC_Group::get_base_point() const
{
- return data().m_base_point;
+ return data().base_point();
}
const BigInt& EC_Group::get_order() const
{
- return data().m_order;
+ return data().order();
}
const BigInt& EC_Group::get_cofactor() const
{
- return data().m_cofactor;
+ return data().cofactor();
}
const OID& EC_Group::get_curve_oid() const
{
- return data().m_oid;
+ return data().oid();
}
PointGFp EC_Group::OS2ECP(const uint8_t bits[], size_t len) const
{
- return Botan::OS2ECP(bits, len, data().m_curve);
+ return Botan::OS2ECP(bits, len, data().curve());
}
PointGFp EC_Group::point(const BigInt& x, const BigInt& y) const
{
- return PointGFp(data().m_curve, x, y);
+ return PointGFp(data().curve(), x, y);
}
PointGFp EC_Group::zero_point() const
{
- return PointGFp(data().m_curve);
+ return PointGFp(data().curve());
}
std::vector<uint8_t>
diff --git a/src/lib/pubkey/ec_group/ec_group.h b/src/lib/pubkey/ec_group/ec_group.h
index 0e6b57b5a..1dc839540 100644
--- a/src/lib/pubkey/ec_group/ec_group.h
+++ b/src/lib/pubkey/ec_group/ec_group.h
@@ -27,7 +27,8 @@ enum EC_Group_Encoding {
EC_DOMPAR_ENC_OID = 2
};
-struct EC_Group_Data;
+class EC_Group_Data;
+class EC_Group_Data_Map;
/**
* Class representing an elliptic curve
@@ -47,7 +48,14 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
EC_Group(const CurveGFp& curve,
const PointGFp& base_point,
const BigInt& order,
- const BigInt& cofactor);
+ const BigInt& cofactor) :
+ EC_Group(curve.get_p(),
+ curve.get_a(),
+ curve.get_b(),
+ base_point.get_affine_x(),
+ base_point.get_affine_y(),
+ order,
+ cofactor) {}
/**
* Construct Domain paramers from specified parameters
@@ -200,17 +208,35 @@ class BOTAN_PUBLIC_API(2,0) EC_Group final
/**
* Return PEM representation of named EC group
+ * Deprecated: Use EC_Group(name).PEM_encode() if this is needed
*/
- static std::string PEM_for_named_group(const std::string& name);
+ static std::string BOTAN_DEPRECATED("See header comment") PEM_for_named_group(const std::string& name);
/**
* Return a set of known named EC groups
*/
static const std::set<std::string>& known_named_groups();
- static void add_named_group(const std::string& name, const OID& oid, const EC_Group& group);
+ /*
+ * For internal use only
+ */
+ static std::shared_ptr<EC_Group_Data> EC_group_info(const OID& oid);
private:
+ static EC_Group_Data_Map& ec_group_data();
+
+ static std::shared_ptr<EC_Group_Data> BER_decode_EC_group(const uint8_t bits[], size_t len);
+
+ static std::shared_ptr<EC_Group_Data>
+ load_EC_group_info(const char* p,
+ const char* a,
+ const char* b,
+ const char* g_x,
+ const char* g_y,
+ const char* order,
+ const OID& oid);
+
+ // Member data
const EC_Group_Data& data() const;
std::shared_ptr<EC_Group_Data> m_data;
};
diff --git a/src/lib/pubkey/ec_group/ec_named.cpp b/src/lib/pubkey/ec_group/ec_named.cpp
index 2a8e1a186..cfab1fafd 100644
--- a/src/lib/pubkey/ec_group/ec_named.cpp
+++ b/src/lib/pubkey/ec_group/ec_named.cpp
@@ -1,6 +1,6 @@
/*
* List of ECC groups
-* (C) 2013 Jack Lloyd
+* (C) 2013,2018 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -10,280 +10,250 @@
namespace Botan {
//static
-std::string EC_Group::PEM_for_named_group(const std::string& name)
+std::shared_ptr<EC_Group_Data> EC_Group::EC_group_info(const OID& oid)
{
- if(name == "secp160k1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGYAgEBMCAGByqGSM49AQECFQD////////////////////+//+sczAsBBQAAAAA"
- "AAAAAAAAAAAAAAAAAAAAAAQUAAAAAAAAAAAAAAAAAAAAAAAAAAcEKQQ7TDgs43qh"
- "kqQBnnYwNvT13U1+u5OM+TUxj9zta8KChlMXM8PwPE/uAhUBAAAAAAAAAAAAAbj6"
- "Ft+rmsoWtrMCAQE="
- "-----END EC PARAMETERS-----";
+ // P-256
+ if(oid == OID{1,2,840,10045,3,1,7})
+ return load_EC_group_info("0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
+ "0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
+ "0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
+ "0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
+ "0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
+ "0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
+ oid);
- if(name == "secp160r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGYAgEBMCAGByqGSM49AQECFQD/////////////////////f////zAsBBT/////"
- "////////////////f////AQUHJe+/FS9eotlrPifgdTUrcVl+kUEKQRKlrVojvVz"
- "KEZkaYlow4u5E8v8giOmKFUxaJR9WdzJEgQjUTd6xfsyAhUBAAAAAAAAAAAAAfTI"
- "+Seu08p1IlcCAQE="
- "-----END EC PARAMETERS-----";
+ // P-384
+ if(oid == OID{1,3,132,0,34})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
+ "0xB3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
+ "0xAA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
+ "0x3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
+ oid);
+ // P-521
+ if(oid == OID{1,3,132,0,35})
+ return load_EC_group_info("0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
+ "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
+ "0x51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
+ "0xC6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
+ "0x11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
+ "0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
+ oid);
- if(name == "secp160r2")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGYAgEBMCAGByqGSM49AQECFQD////////////////////+//+sczAsBBT/////"
- "///////////////+//+scAQUtOE00/tZ64urVydJBGZNWvUDiLoEKQRS3LA0KToR"
- "fh9P8Rsw9xmdMUTObf6v/vLjMfKW4HH6DfmYLP6n1D8uAhUBAAAAAAAAAAAAADUe"
- "54aoGPOhoWsCAQE="
- "-----END EC PARAMETERS-----";
+ // brainpool160r1
+ if(oid == OID{1,3,36,3,3,2,8,1,1,1})
+ return load_EC_group_info("0xE95E4A5F737059DC60DFC7AD95B3D8139515620F",
+ "0x340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
+ "0x1E589A8595423412134FAA2DBDEC95C8D8675E58",
+ "0xBED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
+ "0x1667CB477A1A8EC338F94741669C976316DA6321",
+ "0xE95E4A5F737059DC60DF5991D45029409E60FC09",
+ oid);
+ // brainpool192r1
+ if(oid == OID{1,3,36,3,3,2,8,1,1,3})
+ return load_EC_group_info("0xC302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
+ "0x6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
+ "0x469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
+ "0xC0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
+ "0x14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
+ "0xC302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
+ oid);
+ // brainpool224r1
+ if(oid == OID{1,3,36,3,3,2,8,1,1,5})
+ return load_EC_group_info("0xD7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
+ "0x68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
+ "0x2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
+ "0xD9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
+ "0x58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
+ "0xD7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
+ oid);
+ // brainpool256r1
+ if(oid == OID{1,3,36,3,3,2,8,1,1,7})
+ return load_EC_group_info("0xA9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
+ "0x7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
+ "0x26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
+ "0x8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
+ "0x547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
+ "0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
+ oid);
+ // brainpool320r1
+ if(oid == OID{1,3,36,3,3,2,8,1,1,9})
+ return load_EC_group_info("0xD35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
+ "0x3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
+ "0x520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
+ "0x43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
+ "0x14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
+ "0xD35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
+ oid);
+ // brainpool384r1
+ if(oid == OID{1,3,36,3,3,2,8,1,1,11})
+ return load_EC_group_info("0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
+ "0x7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
+ "0x4A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
+ "0x1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
+ "0x8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
+ "0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
+ oid);
+ // brainpool512r1
+ if(oid == OID{1,3,36,3,3,2,8,1,1,13})
+ return load_EC_group_info("0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
+ "0x7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
+ "0x3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
+ "0x81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
+ "0x7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
+ "0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
+ oid);
+ // frp256v1
+ if(oid == OID{1,2,250,1,223,101,256,1})
+ return load_EC_group_info("0xF1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C03",
+ "0xF1FD178C0B3AD58F10126DE8CE42435B3961ADBCABC8CA6DE8FCF353D86E9C00",
+ "0xEE353FCA5428A9300D4ABA754A44C00FDFEC0C9AE4B1A1803075ED967B7BB73F",
+ "0xB6B3D4C356C139EB31183D4749D423958C27D2DCAF98B70164C97A2DD98F5CFF",
+ "0x6142E0F7C8B204911F9271F0F3ECEF8C2701C307E8E4C9E183115A1554062CFB",
+ "0xF1FD178C0B3AD58F10126DE8CE42435B53DC67E140D2BF941FFDD459C6D655E1",
+ oid);
+ // gost_256A
+ if(oid == OID{1,2,643,2,2,35,1})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD97",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD94",
+ "0xA6",
+ "0x1",
+ "0x8D91E471E0989CDA27DF505A453F2B7635294F2DDF23E3B122ACC99C9E9F1E14",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6C611070995AD10045841B09B761B893",
+ oid);
+ // secp160k1
+ if(oid == OID{1,3,132,0,9})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+ "0x0",
+ "0x7",
+ "0x3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
+ "0x938CF935318FDCED6BC28286531733C3F03C4FEE",
+ "0x100000000000000000001B8FA16DFAB9ACA16B6B3",
+ oid);
+ // secp160r1
+ if(oid == OID{1,3,132,0,8})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
+ "0x1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
+ "0x4A96B5688EF573284664698968C38BB913CBFC82",
+ "0x23A628553168947D59DCC912042351377AC5FB32",
+ "0x100000000000000000001F4C8F927AED3CA752257",
+ oid);
+ // secp160r2
+ if(oid == OID{1,3,132,0,30})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
+ "0xB4E134D3FB59EB8BAB57274904664D5AF50388BA",
+ "0x52DCB034293A117E1F4FF11B30F7199D3144CE6D",
+ "0xFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
+ "0x100000000000000000000351EE786A818F3A1A16B",
+ oid);
+ // secp192k1
+ if(oid == OID{1,3,132,0,31})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
+ "0x0",
+ "0x3",
+ "0xDB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
+ "0x9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
+ oid);
+ // secp192r1
+ if(oid == OID{1,2,840,10045,3,1,1})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+ "0x64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
+ "0x188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+ "0x7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
+ oid);
+ // secp224k1
+ if(oid == OID{1,3,132,0,32})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
+ "0x0",
+ "0x5",
+ "0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
+ "0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
+ "0x10000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
+ oid);
+ // secp224r1
+ if(oid == OID{1,3,132,0,33})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
+ "0xB4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
+ "0xB70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
+ "0xBD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
+ oid);
+ // secp256k1
+ if(oid == OID{1,3,132,0,10})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
+ "0x0",
+ "0x7",
+ "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
+ "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
+ oid);
- if(name == "secp192k1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGwAgEBMCQGByqGSM49AQECGQD//////////////////////////v//7jcwNAQY"
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBgAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
- "AAMEMQTbT/EOwFfpriawfQKAt/Q0HaXRsergbH2bLy9tnFYop4RBY9AVvoY0QIKq"
- "iNleL50CGQD///////////////4m8vwXD2lGanTe/Y0CAQE="
- "-----END EC PARAMETERS-----";
+ // sm2p256v1
+ if(oid == OID{1,2,156,10197,1,301})
+ return load_EC_group_info("0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
+ "0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
+ "0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
+ "0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
+ "0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0",
+ "0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
+ oid);
+ // x962_p192v2
+ if(oid == OID{1,2,840,10045,3,1,2})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+ "0xCC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
+ "0xEEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
+ "0x6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",
+ oid);
+ // x962_p192v3
+ if(oid == OID{1,2,840,10045,3,1,3})
+ return load_EC_group_info("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
+ "0x22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
+ "0x7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
+ "0x38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
+ "0xFFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",
+ oid);
+ // x962_p239v1
+ if(oid == OID{1,2,840,10045,3,1,4})
+ return load_EC_group_info("0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+ "0x6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
+ "0xFFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
+ "0x7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",
+ oid);
+ // x962_p239v2
+ if(oid == OID{1,2,840,10045,3,1,5})
+ return load_EC_group_info("0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+ "0x617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
+ "0x38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
+ "0x5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",
+ oid);
+ // x962_p239v3
+ if(oid == OID{1,2,840,10045,3,1,6})
+ return load_EC_group_info("0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
+ "0x255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
+ "0x6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
+ "0x1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
+ "0x7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",
+ oid);
- if(name == "secp192r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY"
- "/////////////////////v/////////8BBhkIQUZ5ZyA5w+n6atyJDBJ/rje7MFG"
- "ubEEMQQYjagOsDCQ9ny/IOtDoYgA9P8K/YL/EBIHGSuV/8jaeGMQEe1rJM3Vc/l3"
- "oR55SBECGQD///////////////+Z3vg2FGvJsbTSKDECAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "secp224k1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHIAgEBMCgGByqGSM49AQECHQD///////////////////////////////7//+Vt"
- "MDwEHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEHAAAAAAAAAAAAAAAAAAA"
- "AAAAAAAAAAAAAAAAAAUEOQShRVszTfCZ3zD8KKFppGfp5HB1qQ9+ZQ62t6Rcfgif"
- "7X+6NEKCyvvW9+MZ98CwvVniykvbVW1hpQIdAQAAAAAAAAAAAAAAAAAB3OjS7GGE"
- "yvCpcXafsfcCAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "secp224r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHIAgEBMCgGByqGSM49AQECHQD/////////////////////AAAAAAAAAAAAAAAB"
- "MDwEHP////////////////////7///////////////4EHLQFCoUMBLOr9UEyVlBE"
- "sLfXv9i6Jws5QyNV/7QEOQS3Dgy9a7S/fzITkLlKA8HTVsIRIjQygNYRXB0hvTdj"
- "iLX3I/tMIt/mzUN1oFoHR2RE1YGZhQB+NAIdAP//////////////////FqLguPA+"
- "E90pRVxcKj0CAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "secp256k1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHgAgEBMCwGByqGSM49AQECIQD////////////////////////////////////+"
- "///8LzBEBCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQgAAAAAAAA"
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcEQQR5vmZ++dy7rFWgYpXOhwsHApv8"
- "2y3OKNlZ8oFbFvgXmEg62ncmo8RlXaT7/A4RCKj9F7RIpoVUGZxH0I/7ENS4AiEA"
- "/////////////////////rqu3OavSKA7v9JejNA2QUECAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "secp256r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHgAgEBMCwGByqGSM49AQECIQD/////AAAAAQAAAAAAAAAAAAAAAP//////////"
- "/////zBEBCD/////AAAAAQAAAAAAAAAAAAAAAP///////////////AQgWsY12Ko6"
- "k+ez671VdpiGvGUdBrDMU7D2O848PifSYEsEQQRrF9Hy4SxCR/i85uVjpEDydwN9"
- "gS3rM6D0oTlF2JjClk/jQuL+Gn+bjufrSnwPnhYrzjNXazFezsu2QGg3v1H1AiEA"
- "/////wAAAAD//////////7zm+q2nF56E87nKwvxjJVECAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "secp384r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIIBQAIBATA8BgcqhkjOPQEBAjEA////////////////////////////////////"
- "//////7/////AAAAAAAAAAD/////MGQEMP//////////////////////////////"
- "///////////+/////wAAAAAAAAAA/////AQwszEvp+I+5+SYjgVr4/gtGRgdnG7+"
- "gUESAxQIj1ATh1rGVjmNii7RnSqFyO3T7CrvBGEEqofKIr6LBTeOscce8yCtdG4d"
- "O2KLp5uYWfdB4IJUKjhVAvJdv1UpbDpUXjhydgq3NhfeSpYmLG9dnpi/kpLcKfj0"
- "Hb0omhR86doxE7XwuMAKYLHOHX6BnXpDHXyQ6g5fAjEA////////////////////"
- "////////////x2NNgfQ3Ld9YGg2ySLCneuzsGWrMxSlzAgEB"
- "-----END EC PARAMETERS-----";
-
- if(name == "secp521r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIIBrAIBATBNBgcqhkjOPQEBAkIB////////////////////////////////////"
- "//////////////////////////////////////////////////8wgYgEQgH/////"
- "////////////////////////////////////////////////////////////////"
- "/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ"
- "4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8ABIGFBADGhY4GtwQE6c2e"
- "PstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0izwYVqQpv5"
- "fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX7nKZXvQm"
- "QMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf//////////////////////////"
- "////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6ROGQJAgEB"
- "-----END EC PARAMETERS-----";
-
- if(name == "brainpool160r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGYAgEBMCAGByqGSM49AQECFQDpXkpfc3BZ3GDfx62Vs9gTlRViDzAsBBQ0Dnvi"
- "ooDrdOK+YbradF2X6PfDAAQUHliahZVCNBITT6otveyVyNhnXlgEKQS+1a8W6j9q"
- "T2KTjEYx61r3vbzbwxZny0d6Go7DOPlHQWacl2MW2mMhAhUA6V5KX3NwWdxg31mR"
- "1FApQJ5g/AkCAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "brainpool192r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGwAgEBMCQGByqGSM49AQECGQDDAvQdkyo2zaejRjCT0Y23j85HbeGoYpcwNAQY"
- "apEXQHax4OGcOcAx/oaFwcrgQOXGmijvBBhGmijvfCjMo9xyHQRPRJa8yn70FG+/"
- "JckEMQTAoGR+qrakh1OwM8VssPCQCi9cSFM3X9YUtpCGar1buItfSCjBSQAC5nc/"
- "ovopm48CGQDDAvQdkyo2zaejRi+enpFrW+jxAprErMECAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "brainpool224r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHIAgEBMCgGByqGSM49AQECHQDXwTSqJkNmhioYMCV10deHsJ8HV5faifV+yMD/"
- "MDwEHGil5iypzmwcKZgDpsFTC1FOGCrYsAQqWcrSn0MEHCWA9jzP5EE4hwcTsakj"
- "aeM+ITXSZtuzcjhsQAsEOQQNkCmtLH5c9DQII7KofcaMnkzjF0webv3uEsB9WKpW"
- "93LAcm8kxrieTs2sJDVLnpnKo/bTdhQCzQIdANfBNKomQ2aGKhgwJXXQ+5jRFrxL"
- "bd68o6Wnk58CAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "brainpool256r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHgAgEBMCwGByqGSM49AQECIQCp+1fboe6pvD5mCpCdg41ybjv2I9UmICggE0gd"
- "H25TdzBEBCB9Wgl1/CwwV+72dTBBev/n+4BVwSbcXGzpSktE8zC12QQgJtxcbOlK"
- "S0TzMLXZu9d8v5WEFilc9+HOa8zcGP+MB7YEQQSL0q65y35XyyxLSC/8gbevud4n"
- "4eO9I8I6RFO9ms4yYlR++DXD2sT9l/hGGhRhHcnCd0UTLe2OVFwdVMcvBGmXAiEA"
- "qftX26Huqbw+ZgqQnYONcYw5eqO1Yab3kB4OgpdIVqcCAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "brainpool320r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIIBEAIBATA0BgcqhkjOPQEBAikA015HIDa8T7fhPHhe0gHgZfmPz6b29A3vT5K5"
- "7HiT7Cj81BKx8bMuJzBUBCg+4wtWj7qw+IPM69RtPzu4oqc1E/XredpmGQ6whf+p"
- "9JLzdal9hg60BChSCIOUnf28QtOtGYZAaIpv4T9BNJVUtJrMMdzNiEU5gW9etKyP"
- "sfGmBFEEQ71+mvtT2LhSibzEjuW/5vIBN9EKCH6254ceKhClmccQr40NOeIGERT9"
- "0FVF7BzIq0CTJH93J14HQ//tEXGC6qnHeHeqrGrH01JF0WkujuECKQDTXkcgNrxP"
- "t+E8eF7SAeBl+Y/PpbaPEqMtSC7H7oZY6YaRVVtExZMRAgEB"
- "-----END EC PARAMETERS-----";
-
- if(name == "brainpool384r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIIBQAIBATA8BgcqhkjOPQEBAjEAjLkegqM4bSgPXW9+UOZB3xUvcQntVFa0ErHa"
- "GX+3ESOs06cpkB0acYdHABMxB+xTMGQEMHvDgsY9jBUMPHIICs4Fr6DCvqKOT7In"
- "hxORZe+6kfkPiqWBSlA61OsEqMfdIs4oJgQwBKjH3SLOKCaLObVUFvBEfC+3feEH"
- "3NKmLogOpT7rYtV8tDkCldvJlDq3hpb6UEwRBGEEHRxk8GjPRf+ipjqBt8E/a4hH"
- "o+d+8U/j23/K/gy9EOjoJuA0NtZGqu+HsuJH1K8eir4ddSD5wqRcseuOlc/VUmK3"
- "Cyn+7Fhk4ZwFT/mRKSgORkYhd5GBEUKCA0EmPFMVAjEAjLkegqM4bSgPXW9+UOZB"
- "3xUvcQntVFazHxZubKwEJafPOrava3/DEDuIMgLpBGVlAgEB"
- "-----END EC PARAMETERS-----";
-
- if(name == "brainpool512r1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIIBogIBATBMBgcqhkjOPQEBAkEAqt2duNvpxIs/1OauM8n8B8swjbOzydIO1mOc"
- "ynAzCHF9TZsAm8ZoQq7NoSrmo4DmKIH/Ly2CxoUoqmBWWDpI8zCBhARAeDCjMYtg"
- "O4niMnFFrCNMxZTL3Y09+RYQqDRByuqYY7wt7V1aqCU6oQou8cmLmsi1fxEXpyvy"
- "x7nnwaxNd/yUygRAPfkWEKg0QcrqmGO8Le1dWqglOqEKLvHJi5rItX8RF6cr8se5"
- "58GsTXf8lMrcCD5nmEBQt1665d0oCb1jgBb3IwSBgQSBruS92C7ZZFohMi6cTGqT"
- "he2fcLXZFsG0O2Lu9NAJjv87H3ji0NSNUNFoe5O5fV98bVBHQGpeaIs1Igm8ufgi"
- "fd44XVZjMuzA6r+pz3gi/fIJ9wAkpXsaoADFW4gfgRGy3N5JSl9IXlvKS9iKJ2Ou"
- "0corL6jwVAZ4zR4POtgIkgJBAKrdnbjb6cSLP9TmrjPJ/AfLMI2zs8nSDtZjnMpw"
- "MwhwVT5cQUypJhlBhmEZf6wQRx2x04EIXdrdtYeWgpypAGkCAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "x962_p192v2")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY"
- "/////////////////////v/////////8BBjMItbfuVxrJeScDWNkpOWYDDk6ohZo"
- "2VMEMQTuorrn4Ul4QvLed2nP6cmJwHKtaW9IA0pldNEdabbsemcruCoIPfLysIR9"
- "6XCy3hUCGQD///////////////5fsack3IBBhkjY3TECAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "x962_p192v3")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIGwAgEBMCQGByqGSM49AQECGQD////////////////////+//////////8wNAQY"
- "/////////////////////v/////////8BBgiEj3COVoFyqdCPa7MyUdgp9RiJWvV"
- "aRYEMQR9KXeBAMZaHaF4NxZYjc4ri0rujiKPGJY4qQ8iY3M3M0tJ3LZqbcj5l4rK"
- "dkipQ7ACGQD///////////////96YtAxyD9ClPZA7BMCAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "x962_p239v1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////"
- "/zBABB5///////////////9///////+AAAAAAAB///////wEHmsBbDvc8YlB0NZU"
- "khR1ynGp2y+yfR03eWGFwpQsCgQ9BA/6ljzcqIFszDO4ZCvt+QXD01hXPT8n+707"
- "PLmqr33r6OTpCl2ubkBUylMLoEZUs2gYziJrOfzLewLxrgIef///////////////"
- "f///nl6an12QcfvRUiaIkJ0LAgEB"
- "-----END EC PARAMETERS-----";
-
- if(name == "x962_p239v2")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////"
- "/zBABB5///////////////9///////+AAAAAAAB///////wEHmF/q2gyV2y7/tUN"
- "mfAknD/uWLlLoAOMeuhMjIMvLAQ9BDivCdmHJ3BRIMkhu16eJilqPNzy81dXoOr9"
- "h7gw51sBJeTb6g7HIG2g/AHZsIEyn7VV3m70YCN9/4vkugIef///////////////"
- "gAAAz6foWUN31BTAOCG8WCBjAgEB"
- "-----END EC PARAMETERS-----";
-
- if(name == "x962_p239v3")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHSAgEBMCkGByqGSM49AQECHn///////////////3///////4AAAAAAAH//////"
- "/zBABB5///////////////9///////+AAAAAAAB///////wEHiVXBfoqMGZUsfTL"
- "A9anUKMMJQEC1JiHF9m6FattPgQ9BGdoro4Yu5LPzwBclJqixtlIU9DmYLv4VLHJ"
- "UF/pWhYH5omPOQwGvB1VK60ibztvz+SLboGEma8Y4+1s8wIef///////////////"
- "f///l13rQbOmBXw8QyFGUmVRAgEB"
- "-----END EC PARAMETERS-----";
-
- if(name == "gost_256A")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHgAgEBMCwGByqGSM49AQECIQD/////////////////////////////////////"
- "///9lzBEBCD////////////////////////////////////////9lAQgAAAAAAAA"
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKYEQQQAAAAAAAAAAAAAAAAAAAAAAAAA"
- "AAAAAAAAAAAAAAAAAY2R5HHgmJzaJ99QWkU/K3Y1KU8t3yPjsSKsyZyenx4UAiEA"
- "/////////////////////2xhEHCZWtEARYQbCbdhuJMCAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "frp256v1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHgAgEBMCwGByqGSM49AQECIQDx/ReMCzrVjxASbejOQkNbOWGtvKvIym3o/PNT"
- "2G6cAzBEBCDx/ReMCzrVjxASbejOQkNbOWGtvKvIym3o/PNT2G6cAAQg7jU/ylQo"
- "qTANSrp1SkTAD9/sDJrksaGAMHXtlnt7tz8EQQS2s9TDVsE56zEYPUdJ1COVjCfS"
- "3K+YtwFkyXot2Y9c/2FC4PfIsgSRH5Jx8PPs74wnAcMH6OTJ4YMRWhVUBiz7AiEA"
- "8f0XjAs61Y8QEm3ozkJDW1PcZ+FA0r+UH/3UWcbWVeECAQE="
- "-----END EC PARAMETERS-----";
-
- if(name == "sm2p256v1")
- return
- "-----BEGIN EC PARAMETERS-----"
- "MIHgAgEBMCwGByqGSM49AQECIQD////+/////////////////////wAAAAD/////"
- "/////zBEBCD////+/////////////////////wAAAAD//////////AQgKOn6np2f"
- "XjRNWp5Lz2UJp/OXifUVq4+S3by9QU2UDpMEQQQyxK4sHxmBGV+ZBEZqOcmUj+ML"
- "v/JmC+FxWkWJM0x0x7w3NqL09necWb3O42tpIVPQqYd8xipHQALfMuUhOfCgAiEA"
- "/////v///////////////3ID32shxgUrU7v0CTnVQSMCAQE="
- "-----END EC PARAMETERS-----";
-
-#if defined(BOTAN_HOUSE_ECC_CURVE_NAME)
- if(name == BOTAN_HOUSE_ECC_CURVE_NAME)
- return BOTAN_HOUSE_ECC_CURVE_PEM;
-#endif
-
- return "";
+ return std::shared_ptr<EC_Group_Data>();
}
+//static
const std::set<std::string>& EC_Group::known_named_groups()
{
static const std::set<std::string> named_groups = {
@@ -317,6 +287,6 @@ const std::set<std::string>& EC_Group::known_named_groups()
,BOTAN_HOUSE_ECC_CURVE_NAME
#endif
};
- return named_groups;
+ return named_groups;
}
}
diff --git a/src/lib/utils/mem_ops.cpp b/src/lib/utils/mem_ops.cpp
index 3fd463195..b7ecd5326 100644
--- a/src/lib/utils/mem_ops.cpp
+++ b/src/lib/utils/mem_ops.cpp
@@ -41,6 +41,13 @@ void deallocate_memory(void* p, size_t elems, size_t elem_size)
std::free(p);
}
+void initialize_allocator()
+ {
+#if defined(BOTAN_HAS_LOCKING_ALLOCATOR)
+ mlock_allocator::instance();
+#endif
+ }
+
bool constant_time_compare(const uint8_t x[],
const uint8_t y[],
size_t len)
diff --git a/src/lib/utils/mem_ops.h b/src/lib/utils/mem_ops.h
index be75da655..5fb5752fc 100644
--- a/src/lib/utils/mem_ops.h
+++ b/src/lib/utils/mem_ops.h
@@ -33,6 +33,11 @@ BOTAN_PUBLIC_API(2,3) BOTAN_MALLOC_FN void* allocate_memory(size_t elems, size_t
BOTAN_PUBLIC_API(2,3) void deallocate_memory(void* p, size_t elems, size_t elem_size);
/**
+* Ensure the allocator is initialized
+*/
+void initialize_allocator();
+
+/**
* Scrub memory contents in a way that a compiler should not elide,
* using some system specific technique. Note that this function might
* not zero the memory (for example, in some hypothetical
diff --git a/src/tests/unit_ecc.cpp b/src/tests/unit_ecc.cpp
index 8d8cdb538..96e2438b3 100644
--- a/src/tests/unit_ecc.cpp
+++ b/src/tests/unit_ecc.cpp
@@ -806,6 +806,31 @@ Test::Result test_mult_sec_mass()
return result;
}
+Test::Result test_ecc_registration()
+ {
+ Test::Result result("ECC registration");
+
+ // secp112r1
+ const Botan::BigInt p("0xDB7C2ABF62E35E668076BEAD208B");
+ const Botan::BigInt a("0xDB7C2ABF62E35E668076BEAD2088");
+ const Botan::BigInt b("0x659EF8BA043916EEDE8911702B22");
+
+ const Botan::BigInt g_x("0x09487239995A5EE76B55F9C2F098");
+ const Botan::BigInt g_y("0xA89CE5AF8724C0A23E0E0FF77500");
+ const Botan::BigInt order("0xDB7C2ABF62E35E7628DFAC6561C5");
+
+ const Botan::OID oid("1.3.132.0.6");
+
+ // Creating this object implicitly registers the curve for future use ...
+ Botan::EC_Group reg_group(p, a, b, g_x, g_y, order, 1, oid);
+
+ Botan::EC_Group group(oid);
+
+ result.test_eq("Group registration worked", group.get_p(), p);
+
+ return result;
+ }
+
class ECC_Unit_Tests final : public Test
{
public:
@@ -836,6 +861,7 @@ class ECC_Unit_Tests final : public Test
results.push_back(test_mult_by_order());
results.push_back(test_point_swap());
results.push_back(test_mult_sec_mass());
+ results.push_back(test_ecc_registration());
return results;
}
diff --git a/src/tests/unit_x509.cpp b/src/tests/unit_x509.cpp
index 5ca5a2edc..94fa95392 100644
--- a/src/tests/unit_x509.cpp
+++ b/src/tests/unit_x509.cpp
@@ -1177,7 +1177,7 @@ class String_Extension final : public Botan::Certificate_Extension
Botan::OID oid_of() const override
{
- return m_oid;
+ return Botan::OID("1.2.3.4.5.6.7.8.9.1");
}
bool should_encode() const override
@@ -1205,7 +1205,6 @@ class String_Extension final : public Botan::Certificate_Extension
}
private:
- Botan::OID m_oid {"1.2.3.4.5.6.7.8.9.1"};
std::string m_contents;
};