Botan 3.9.0
Crypto and TLS for C&
Botan::OID Class Referencefinal

#include <asn1_obj.h>

Inheritance diagram for Botan::OID:
Botan::ASN1_Object

Public Member Functions

std::vector< uint8_t > BER_encode () const
void decode_from (BER_Decoder &from) override
bool empty () const
void encode_into (DER_Encoder &to) const override
const std::vector< uint32_t > & get_components () const
const std::vector< uint32_t > & get_id () const
bool has_value () const
uint64_t hash_code () const
std::string human_name_or_empty () const
bool matches (std::initializer_list< uint32_t > other) const
 OID ()=default
 OID (std::initializer_list< uint32_t > init)
 OID (std::string_view str)
 OID (std::vector< uint32_t > &&init)
bool operator== (const OID &other) const
bool registered_oid () const
std::string to_formatted_string () const
std::string to_string () const

Static Public Member Functions

static std::optional< OIDfrom_name (std::string_view name)
static OID from_string (std::string_view str)
static void register_oid (const OID &oid, std::string_view name)

Detailed Description

This class represents ASN.1 object identifiers.

Definition at line 215 of file asn1_obj.h.

Constructor & Destructor Documentation

◆ OID() [1/4]

Botan::OID::OID ( )
explicitdefault

Create an uninitialised OID object

References decode_from(), encode_into(), from_name(), from_string(), OID(), and register_oid().

Referenced by from_name(), from_string(), OID(), operator==(), and register_oid().

◆ OID() [2/4]

Botan::OID::OID ( std::string_view str)
explicit

Construct an OID from a string.

Parameters
stra string in the form "a.b.c" etc., where a,b,c are integers

Note: it is currently required that each integer fit into 32 bits

Definition at line 115 of file asn1_oid.cpp.

115 {
116 if(!oid_str.empty()) {
117 m_id = parse_oid_str(oid_str);
118 oid_valid_check(m_id);
119 }
120}

◆ OID() [3/4]

Botan::OID::OID ( std::initializer_list< uint32_t > init)

Initialize an OID from a sequence of integer values

Definition at line 104 of file asn1_oid.cpp.

104 : m_id(init) {
105 oid_valid_check(m_id);
106}

◆ OID() [4/4]

Botan::OID::OID ( std::vector< uint32_t > && init)
explicit

Initialize an OID from a vector of integer values

Definition at line 108 of file asn1_oid.cpp.

108 : m_id(std::move(init)) {
109 oid_valid_check(m_id);
110}

Member Function Documentation

◆ BER_encode()

std::vector< uint8_t > Botan::ASN1_Object::BER_encode ( ) const
inherited

Return the encoding of this object. This is a convenience method when just one object needs to be serialized. Use DER_Encoder for complicated encodings.

Definition at line 19 of file asn1_obj.cpp.

19 {
20 std::vector<uint8_t> output;
21 DER_Encoder der(output);
22 this->encode_into(der);
23 return output;
24}
virtual void encode_into(DER_Encoder &to) const =0

References encode_into().

Referenced by decode_from(), Botan::Certificate_Store_In_SQL::find_all_certs(), Botan::Certificate_Store_In_SQL::find_cert(), Botan::X509_Certificate::fingerprint(), Botan::Certificate_Store_In_SQL::insert_cert(), Botan::X509_Object::PEM_encode(), Botan::PSS_Params::PSS_Params(), and Botan::Certificate_Store_In_SQL::revoke_cert().

◆ decode_from()

void Botan::OID::decode_from ( BER_Decoder & from)
overridevirtual

Decode whatever this object is from from

Parameters
fromthe BER_Decoder that will be read from

Implements Botan::ASN1_Object.

Definition at line 222 of file asn1_oid.cpp.

222 {
223 BER_Object obj = decoder.get_next_object();
224 if(obj.tagging() != (ASN1_Class::Universal | ASN1_Type::ObjectId)) {
225 throw BER_Bad_Tag("Error decoding OID, unknown tag", obj.tagging());
226 }
227
228 if(obj.length() == 0) {
229 throw BER_Decoding_Error("OID encoding is too short");
230 }
231
232 auto consume = [](BufferSlicer& data) -> uint32_t {
233 BOTAN_ASSERT_NOMSG(!data.empty());
234 uint32_t b = data.take_byte();
235
236 if(b > 0x7F) {
237 b &= 0x7F;
238
239 // Even BER requires that the OID have minimal length, ie that
240 // the first byte of a multibyte encoding cannot be zero
241 // See X.690 section 8.19.2
242 if(b == 0) {
243 throw Decoding_Error("Leading zero byte in multibyte OID encoding");
244 }
245
246 while(true) {
247 if(data.empty()) {
248 throw Decoding_Error("Truncated OID value");
249 }
250
251 const uint8_t next = data.take_byte();
252 const bool more = (next & 0x80) == 0x80;
253 const uint8_t value = next & 0x7F;
254
255 if((b >> (32 - 7)) != 0) {
256 throw Decoding_Error("OID component overflow");
257 }
258
259 b = (b << 7) | value;
260
261 if(!more) {
262 break;
263 }
264 }
265 }
266
267 return b;
268 };
269
270 BufferSlicer data(obj.data());
271 std::vector<uint32_t> parts;
272 while(!data.empty()) {
273 const uint32_t comp = consume(data);
274
275 if(parts.empty()) {
276 // divide into root and second arc
277
278 const uint32_t root_arc = [](uint32_t b0) -> uint32_t {
279 if(b0 < 40) {
280 return 0;
281 } else if(b0 < 80) {
282 return 1;
283 } else {
284 return 2;
285 }
286 }(comp);
287
288 parts.push_back(root_arc);
289 BOTAN_ASSERT_NOMSG(comp >= 40 * root_arc);
290 parts.push_back(comp - 40 * root_arc);
291 } else {
292 parts.push_back(comp);
293 }
294 }
295
296 m_id = parts;
297}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG, Botan::BER_Object::data(), Botan::BufferSlicer::empty(), Botan::BER_Decoder::get_next_object(), Botan::BER_Object::length(), Botan::ObjectId, Botan::BER_Object::tagging(), and Botan::Universal.

Referenced by OID().

◆ empty()

bool Botan::OID::empty ( ) const
inline

Find out whether this OID is empty

Returns
true is no OID value is set

Definition at line 265 of file asn1_obj.h.

265{ return m_id.empty(); }

Referenced by has_value().

◆ encode_into()

void Botan::OID::encode_into ( DER_Encoder & to) const
overridevirtual

Encode whatever this object is into to

Parameters
tothe DER_Encoder that will be written to

Implements Botan::ASN1_Object.

Definition at line 183 of file asn1_oid.cpp.

183 {
184 if(m_id.size() < 2) {
185 throw Invalid_Argument("OID::encode_into: OID is invalid");
186 }
187
188 auto append = [](std::vector<uint8_t>& encoding, uint32_t z) {
189 if(z <= 0x7F) {
190 encoding.push_back(static_cast<uint8_t>(z));
191 } else {
192 size_t z7 = (high_bit(z) + 7 - 1) / 7;
193
194 for(size_t j = 0; j != z7; ++j) {
195 uint8_t zp = static_cast<uint8_t>(z >> (7 * (z7 - j - 1)) & 0x7F);
196
197 if(j != z7 - 1) {
198 zp |= 0x80;
199 }
200
201 encoding.push_back(zp);
202 }
203 }
204 };
205
206 std::vector<uint8_t> encoding;
207
208 // We know 40 * root can't overflow because root is between 0 and 2
209 auto first = BOTAN_ASSERT_IS_SOME(checked_add(40 * m_id[0], m_id[1]));
210
211 append(encoding, first);
212
213 for(size_t i = 2; i != m_id.size(); ++i) {
214 append(encoding, m_id[i]);
215 }
216 der.add_object(ASN1_Type::ObjectId, ASN1_Class::Universal, encoding);
217}
constexpr std::optional< T > checked_add(T a, T b)
Definition int_utils.h:19
BOTAN_FORCE_INLINE constexpr size_t high_bit(T n)
Definition bit_ops.h:56
#define BOTAN_ASSERT_IS_SOME(v)
Definition stl_util.h:391

References Botan::DER_Encoder::add_object(), BOTAN_ASSERT_IS_SOME, Botan::checked_add(), Botan::high_bit(), Botan::ObjectId, and Botan::Universal.

Referenced by OID().

◆ from_name()

std::optional< OID > Botan::OID::from_name ( std::string_view name)
static

Construct an OID from a name

Parameters
nameany known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")

Definition at line 72 of file asn1_oid.cpp.

72 {
73 if(name.empty()) {
74 throw Invalid_Argument("OID::from_name argument must be non-empty");
75 }
76
78 if(o.has_value()) {
79 return std::optional(o);
80 }
81
82 return std::nullopt;
83}
static OID_Map & global_registry()
Definition oid_map.cpp:16
OID str2oid(std::string_view str)
Definition oid_map.cpp:84
OID()=default

References Botan::OID_Map::global_registry(), has_value(), OID(), and Botan::OID_Map::str2oid().

Referenced by Botan::EC_Group::from_name(), Botan::OIDS::lookup(), OID(), and Botan::OIDS::str2oid_or_empty().

◆ from_string()

OID Botan::OID::from_string ( std::string_view str)
static

Construct an OID from a string.

Parameters
stra string in the form "a.b.c" etc., where a,b,c are numbers or any known OID name (for example "RSA" or "X509v3.SubjectKeyIdentifier")

Definition at line 86 of file asn1_oid.cpp.

86 {
87 if(str.empty()) {
88 throw Invalid_Argument("OID::from_string argument must be non-empty");
89 }
90
92 if(o.has_value()) {
93 return o;
94 }
95
96 // Try to parse as a dotted decimal
97 try {
98 return OID(str);
99 } catch(...) {}
100
101 throw Lookup_Error(fmt("No OID associated with name '{}'", str));
102}
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53

References Botan::fmt(), Botan::OID_Map::global_registry(), has_value(), OID(), and Botan::OID_Map::str2oid().

Referenced by Botan::X509_DN::add_attribute(), Botan::X509_Cert_Options::add_ex_constraint(), Botan::TLS::Signature_Scheme::algorithm_identifier(), Botan::XMSS_Signature_Operation::algorithm_identifier(), Botan::X509_Certificate::allowed_extended_usage(), botan_oid_from_string(), Botan::PKCS10_Request::constraints(), Botan::EC_Group::EC_Group(), Botan::PKCS10_Request::ex_constraints(), Botan::X509_DN::get_attribute(), Botan::X509_DN::get_first_attribute(), Botan::X509_Certificate::has_ex_constraint(), Botan::X509_DN::has_field(), Botan::X509_Certificate::is_critical(), Botan::Asymmetric_Key::object_identifier(), Botan::Classic_McEliece_Parameters::object_identifier(), Botan::DilithiumMode::object_identifier(), Botan::FrodoKEMMode::object_identifier(), Botan::HSS_LMS_PublicKeyInternal::object_identifier(), Botan::KyberMode::object_identifier(), Botan::Sphincs_Parameters::object_identifier(), OID(), and Botan::HSS_LMS_PrivateKey::pkcs8_algorithm_identifier().

◆ get_components()

const std::vector< uint32_t > & Botan::OID::get_components ( ) const
inline

Get this OID as list (vector) of its components.

Returns
vector representing this OID

Definition at line 321 of file asn1_obj.h.

321 {
322 return m_id;
323 }

References get_components().

Referenced by get_components(), Botan::is_sub_element_of(), and Botan::operator<().

◆ get_id()

const std::vector< uint32_t > & Botan::OID::get_id ( ) const
inline

Definition at line 326 of file asn1_obj.h.

326 {
327 return m_id;
328 }

References get_id().

Referenced by get_id().

◆ has_value()

bool Botan::OID::has_value ( ) const
inline

Find out whether this OID has a value

Returns
true is this OID has a value

Definition at line 271 of file asn1_obj.h.

271{ return !empty(); }
bool empty() const
Definition asn1_obj.h:265

References empty().

Referenced by Botan::X509::create_self_signed_cert(), Botan::EC_Group::EC_Group(), Botan::EC_Group::EC_Group(), Botan::EC_Group::EC_Group(), from_name(), from_string(), and Botan::X509_DN::has_field().

◆ hash_code()

uint64_t Botan::OID::hash_code ( ) const

Return a hash code for this OID

This value is only meant as a std::unordered_map hash and can change value from release to release.

Definition at line 160 of file asn1_oid.cpp.

160 {
161 // If this is changed also update gen_oids.py to match
162 uint64_t hash = 0x621F302327D9A49A;
163 for(auto id : m_id) {
164 hash *= 193;
165 hash += id;
166 }
167 return hash;
168}

◆ human_name_or_empty()

std::string Botan::OID::human_name_or_empty ( ) const

If there is a known name associated with this OID, return that. Otherwise return the empty string.

Definition at line 147 of file asn1_oid.cpp.

147 {
148 return OID_Map::global_registry().oid2str(*this);
149}
std::string oid2str(const OID &oid)
Definition oid_map.cpp:69

References Botan::OID_Map::global_registry(), and Botan::OID_Map::oid2str().

Referenced by Botan::pbes2_decrypt(), registered_oid(), and to_formatted_string().

◆ matches()

bool Botan::OID::matches ( std::initializer_list< uint32_t > other) const

Check if this OID matches the provided value

Definition at line 155 of file asn1_oid.cpp.

155 {
156 // TODO: once all target compilers support it, use std::ranges::equal
157 return std::equal(m_id.begin(), m_id.end(), other.begin(), other.end());
158}

◆ operator==()

bool Botan::OID::operator== ( const OID & other) const
inline

Compare two OIDs.

Returns
true if they are equal, false otherwise

Definition at line 301 of file asn1_obj.h.

301{ return m_id == other.m_id; }

References OID().

◆ register_oid()

void Botan::OID::register_oid ( const OID & oid,
std::string_view name )
static

Register a new OID in the internal table

Definition at line 67 of file asn1_oid.cpp.

67 {
69}
void add_oid(const OID &oid, std::string_view str)
Definition oid_map.cpp:21

References Botan::OID_Map::add_oid(), Botan::OID_Map::global_registry(), and OID().

Referenced by Botan::OIDS::add_oid(), Botan::OIDS::add_oidstr(), botan_oid_register(), and OID().

◆ registered_oid()

bool Botan::OID::registered_oid ( ) const

Return true if the OID in *this is registered in the internal set of constants as a known OID.

Definition at line 151 of file asn1_oid.cpp.

151 {
152 return !human_name_or_empty().empty();
153}
std::string human_name_or_empty() const
Definition asn1_oid.cpp:147

References human_name_or_empty().

Referenced by Botan::PKIX::check_chain().

◆ to_formatted_string()

std::string Botan::OID::to_formatted_string ( ) const

If there is a known name associated with this OID, return that. Otherwise return the result of to_string

Definition at line 139 of file asn1_oid.cpp.

139 {
140 std::string s = this->human_name_or_empty();
141 if(!s.empty()) {
142 return s;
143 }
144 return this->to_string();
145}
std::string to_string() const
Definition asn1_oid.cpp:125

References human_name_or_empty(), and to_string().

Referenced by Botan::Dilithium_PublicKey::algo_name(), Botan::Sphincs_Parameters::create(), Botan::Classic_McEliece_Parameter_Set::from_oid(), Botan::TPM2::get_tpm2_curve_id(), Botan::load_private_key(), Botan::load_public_key(), Botan::X509_Certificate::to_string(), and Botan::PK_Ops::Verification_with_Hash::Verification_with_Hash().

◆ to_string()

std::string Botan::OID::to_string ( ) const

Get this OID as a dotted-decimal string

Returns
string representing this OID

Definition at line 125 of file asn1_oid.cpp.

125 {
126 std::ostringstream out;
127
128 for(size_t i = 0; i != m_id.size(); ++i) {
129 // avoid locale issues with integer formatting
130 out << std::to_string(m_id[i]);
131 if(i != m_id.size() - 1) {
132 out << ".";
133 }
134 }
135
136 return out.str();
137}

Referenced by Botan::EC_Group::from_OID(), Botan::operator<<(), and to_formatted_string().


The documentation for this class was generated from the following files: