Botan 3.13.0
Crypto and TLS for C&
Botan::Extensions Class Referencefinal

#include <pkix_types.h>

Inheritance diagram for Botan::Extensions:
Botan::ASN1_Object

Public Member Functions

void add (std::unique_ptr< Certificate_Extension > extn, bool critical=false)
bool add_new (std::unique_ptr< Certificate_Extension > extn, bool critical=false)
std::vector< uint8_t > BER_encode () const
size_t count () const
bool critical_extension_set (const OID &oid) const
std::vector< OIDcritical_extensions () const
void decode_from (BER_Decoder &from) override
void decode_from (BER_Decoder &from, std::optional< Extension_Context > context)
void encode_into (DER_Encoder &to) const override
bool extension_set (const OID &oid) const
 Extensions ()=default
 Extensions (const Extensions &)=default
 Extensions (Extensions &&)=default
std::vector< std::pair< std::unique_ptr< Certificate_Extension >, bool > > extensions () const
std::map< OID, std::pair< std::vector< uint8_t >, bool > > extensions_raw () const
std::unique_ptr< Certificate_Extensionget (const OID &oid) const
std::vector< uint8_t > get_extension_bits (const OID &oid) const
const Certificate_Extensionget_extension_object (const OID &oid) const
template<typename T>
const T * get_extension_object_as (const OID &oid=T::static_oid()) const
const std::vector< OID > & get_extension_oids () const
template<typename T>
std::unique_ptr< T > get_raw (const OID &oid) const
bool has_unknown_critical_extension () const
Extensionsoperator= (const Extensions &)=default
Extensionsoperator= (Extensions &&)=default
bool remove (const OID &oid)
void replace (std::unique_ptr< Certificate_Extension > extn, bool critical=false)
void validate (const X509_Certificate &subject, const std::optional< X509_Certificate > &issuer, const std::vector< X509_Certificate > &cert_path, std::vector< std::set< Certificate_Status_Code > > &cert_status, size_t pos) const
 ~Extensions () override=default

Detailed Description

X.509 Certificate Extension List

Definition at line 872 of file pkix_types.h.

Constructor & Destructor Documentation

◆ Extensions() [1/3]

Botan::Extensions::Extensions ( )
default

◆ Extensions() [2/3]

Botan::Extensions::Extensions ( const Extensions & )
default

References Extensions().

◆ Extensions() [3/3]

Botan::Extensions::Extensions ( Extensions && )
default

References Extensions().

◆ ~Extensions()

Botan::Extensions::~Extensions ( )
overridedefault

References BOTAN_UNSTABLE_API.

Member Function Documentation

◆ add()

void Botan::Extensions::add ( std::unique_ptr< Certificate_Extension > extn,
bool critical = false )

Adds a new extension to the list.

Parameters
extnpointer to the certificate extension (Extensions takes ownership)
criticalwhether this extension should be marked as critical
Exceptions
Invalid_Argumentif the extension is already present in the list

Definition at line 190 of file x509_ext.cpp.

190 {
191 // sanity check: we don't want to have the same extension more than once
192 if(m_extension_info.contains(extn->oid_of())) {
193 const std::string name = extn->oid_name();
194 throw Invalid_Argument("Extension " + name + " already present in Extensions::add");
195 }
196
197 const OID oid = extn->oid_of();
198 Extensions_Info info(critical, std::move(extn));
199 m_extension_oids.push_back(oid);
200 m_extension_info.emplace(oid, info);
201}

◆ add_new()

bool Botan::Extensions::add_new ( std::unique_ptr< Certificate_Extension > extn,
bool critical = false )

Adds a new extension to the list unless it already exists. If the extension already exists within the Extensions object, the extn pointer will be deleted.

Parameters
extnpointer to the certificate extension (Extensions takes ownership)
criticalwhether this extension should be marked as critical
Returns
true if the object was added false if the extension was already used

Definition at line 203 of file x509_ext.cpp.

203 {
204 if(m_extension_info.contains(extn->oid_of())) {
205 return false; // already exists
206 }
207
208 const OID oid = extn->oid_of();
209 Extensions_Info info(critical, std::move(extn));
210 m_extension_oids.push_back(oid);
211 m_extension_info.emplace(oid, info);
212 return true;
213}

Referenced by Botan::X509::create_cert_req(), and Botan::X509::create_self_signed_cert().

◆ 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 21 of file asn1_obj.cpp.

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

References encode_into().

Referenced by decode_from(), Botan::PKCS12::export_to(), 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(), and Botan::PSS_Params::PSS_Params().

◆ count()

size_t Botan::Extensions::count ( ) const
inline

Definition at line 1027 of file pkix_types.h.

1027{ return m_extension_oids.size(); }

◆ critical_extension_set()

bool Botan::Extensions::critical_extension_set ( const OID & oid) const

Return true if an extension was set and marked critical

Definition at line 239 of file x509_ext.cpp.

239 {
240 auto i = m_extension_info.find(oid);
241 if(i != m_extension_info.end()) {
242 return i->second.is_critical();
243 }
244 return false;
245}

Referenced by Botan::X509_Certificate::is_critical().

◆ critical_extensions()

std::vector< OID > Botan::Extensions::critical_extensions ( ) const

Return the set of critical extensions in the order they appeared in the extension list (This may be an empty vector)

Definition at line 128 of file x509_ext.cpp.

128 {
129 std::vector<OID> crit;
130
131 for(const auto& oid : m_extension_oids) {
132 auto ext_info = m_extension_info.find(oid);
133 BOTAN_ASSERT_NOMSG(ext_info != m_extension_info.end());
134 if(ext_info->second.is_critical()) {
135 crit.push_back(oid);
136 }
137 }
138
139 return crit;
140}
#define BOTAN_ASSERT_NOMSG(expr)
Definition assert.h:75

References BOTAN_ASSERT_NOMSG.

Referenced by Botan::OCSP::SingleResponse::decode_from(), and Botan::OCSP::Response::Response().

◆ decode_from() [1/2]

void Botan::Extensions::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 322 of file x509_ext.cpp.

322 {
323 decode_from(from_source, std::nullopt);
324}
void decode_from(BER_Decoder &from) override
Definition x509_ext.cpp:322

References decode_from().

Referenced by decode_from(), Botan::OCSP::SingleResponse::decode_from(), and Botan::OCSP::Response::Response().

◆ decode_from() [2/2]

void Botan::Extensions::decode_from ( BER_Decoder & from,
std::optional< Extension_Context > context )

Definition at line 326 of file x509_ext.cpp.

326 {
327 m_extension_oids.clear();
328 m_extension_info.clear();
329 m_has_unknown_critical_extension = false;
330
331 BER_Decoder sequence = from_source.start_sequence();
332
333 while(sequence.more_items()) {
334 OID oid;
335 bool critical = false;
336 std::vector<uint8_t> bits;
337
338 sequence.start_sequence()
339 .decode(oid)
340 .decode_optional(critical, ASN1_Type::Boolean, ASN1_Class::Universal, false)
341 .decode(bits, ASN1_Type::OctetString)
342 .end_cons();
343
344 auto obj = create_extn_obj(oid, critical, bits, context);
345 // Unknown_Extension is the only Certificate_Extension with an empty oid_name
346 if(critical && obj->oid_name().empty()) {
347 m_has_unknown_critical_extension = true;
348 }
349 Extensions_Info info(critical, bits, std::move(obj));
350
351 // RFC 5280 4.2: "A certificate MUST NOT include more than one
352 // instance of a particular extension."
353 if(!m_extension_info.emplace(oid, info).second) {
354 throw Decoding_Error("Duplicate certificate extension encountered");
355 }
356 m_extension_oids.push_back(oid);
357 }
358 sequence.verify_end();
359}

References Botan::Boolean, Botan::BER_Decoder::decode(), Botan::BER_Decoder::decode_optional(), Botan::BER_Decoder::end_cons(), Botan::BER_Decoder::more_items(), Botan::OctetString, Botan::BER_Decoder::start_sequence(), Botan::Universal, and Botan::BER_Decoder::verify_end().

◆ encode_into()

void Botan::Extensions::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 302 of file x509_ext.cpp.

302 {
303 for(const auto& [oid, extn] : m_extension_info) {
304 const bool should_encode = extn.obj().should_encode();
305
306 if(should_encode) {
307 const auto is_critical = extn.is_critical() ? std::optional<bool>{true} : std::nullopt;
308 const std::vector<uint8_t>& ext_value = extn.bits();
309
310 to_object.start_sequence()
311 .encode(oid)
312 .encode_optional(is_critical)
313 .encode(ext_value, ASN1_Type::OctetString)
314 .end_cons();
315 }
316 }
317}

References Botan::DER_Encoder::encode(), Botan::DER_Encoder::encode_optional(), Botan::DER_Encoder::end_cons(), Botan::OctetString, and Botan::DER_Encoder::start_sequence().

◆ extension_set()

bool Botan::Extensions::extension_set ( const OID & oid) const

Return true if an extension was set

Definition at line 235 of file x509_ext.cpp.

235 {
236 return m_extension_info.contains(oid);
237}

Referenced by botan_x509_cert_issuer_alternative_names(), botan_x509_cert_subject_alternative_names(), and Botan::Cert_Extension::NoRevocationAvailable::validate().

◆ extensions()

std::vector< std::pair< std::unique_ptr< Certificate_Extension >, bool > > Botan::Extensions::extensions ( ) const

Returns a copy of the list of extensions together with the corresponding criticality flag. All extensions are encoded as some object, falling back to Unknown_Extension class which simply allows reading the bytes as well as the criticality flag.

Definition at line 272 of file x509_ext.cpp.

272 {
273 std::vector<std::pair<std::unique_ptr<Certificate_Extension>, bool>> exts;
274 exts.reserve(m_extension_info.size());
275 for(auto&& ext : m_extension_info) {
276 exts.push_back(std::make_pair(ext.second.obj().copy(), ext.second.is_critical()));
277 }
278 return exts;
279}

◆ extensions_raw()

std::map< OID, std::pair< std::vector< uint8_t >, bool > > Botan::Extensions::extensions_raw ( ) const

Returns the list of extensions as raw, encoded bytes together with the corresponding criticality flag. Contains all extensions, including any extensions encoded as Unknown_Extension

Definition at line 291 of file x509_ext.cpp.

291 {
292 std::map<OID, std::pair<std::vector<uint8_t>, bool>> out;
293 for(auto&& ext : m_extension_info) {
294 out.emplace(ext.first, std::make_pair(ext.second.bits(), ext.second.is_critical()));
295 }
296 return out;
297}

◆ get()

std::unique_ptr< Certificate_Extension > Botan::Extensions::get ( const OID & oid) const

Searches for an extension by OID and returns the result. Only the known extensions types declared in this header are searched for by this function.

Returns
Copy of extension with oid, nullptr if not found. Can avoid creating a copy by using get_extension_object function

Definition at line 265 of file x509_ext.cpp.

265 {
266 if(const Certificate_Extension* ext = this->get_extension_object(oid)) {
267 return ext->copy();
268 }
269 return nullptr;
270}
const Certificate_Extension * get_extension_object(const OID &oid) const
Definition x509_ext.cpp:256

References get_extension_object().

◆ get_extension_bits()

std::vector< uint8_t > Botan::Extensions::get_extension_bits ( const OID & oid) const

Return the raw bytes of the extension Will throw if OID was not set as an extension.

Definition at line 247 of file x509_ext.cpp.

247 {
248 auto i = m_extension_info.find(oid);
249 if(i == m_extension_info.end()) {
250 throw Invalid_Argument("Extensions::get_extension_bits no such extension set");
251 }
252
253 return i->second.bits();
254}

◆ get_extension_object()

const Certificate_Extension * Botan::Extensions::get_extension_object ( const OID & oid) const

Look up an object in the extensions, based on OID Returns nullptr if not set, if the extension was either absent or not handled. The pointer returned is owned by the Extensions object. This would be better with an optional<T> return value

Definition at line 256 of file x509_ext.cpp.

256 {
257 auto extn = m_extension_info.find(oid);
258 if(extn == m_extension_info.end()) {
259 return nullptr;
260 }
261
262 return &extn->second.obj();
263}

Referenced by get(), and get_extension_object_as().

◆ get_extension_object_as()

template<typename T>
const T * Botan::Extensions::get_extension_object_as ( const OID & oid = T::static_oid()) const
inline

Definition at line 884 of file pkix_types.h.

884 {
885 if(const Certificate_Extension* extn = get_extension_object(oid)) {
886 // Unknown_Extension oid_name is empty
887 if(extn->oid_name().empty()) {
888 return nullptr;
889 } else if(const T* extn_as_T = dynamic_cast<const T*>(extn)) {
890 return extn_as_T;
891 } else {
892 throw Decoding_Error("Exception::get_extension_object_as dynamic_cast failed");
893 }
894 }
895
896 return nullptr;
897 }

References get_extension_object().

Referenced by Botan::distribution_point_match(), and Botan::Cert_Extension::NoRevocationAvailable::validate().

◆ get_extension_oids()

const std::vector< OID > & Botan::Extensions::get_extension_oids ( ) const
inline

Return the set of extensions in the order they appeared in the certificate (or as they were added, if constructed)

Definition at line 903 of file pkix_types.h.

903{ return m_extension_oids; }

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

◆ get_raw()

template<typename T>
std::unique_ptr< T > Botan::Extensions::get_raw ( const OID & oid) const
inline

Searches for an extension by OID and returns the result decoding it to some arbitrary extension type chosen by the application.

Only the unknown extensions, that is, extensions types that are not declared in this header, are searched for by this function.

Returns
Pointer to new extension with oid, nullptr if not found.

Definition at line 989 of file pkix_types.h.

989 {
990 auto extn_info = m_extension_info.find(oid);
991
992 if(extn_info != m_extension_info.end()) {
993 // Unknown_Extension oid_name is empty
994 if(extn_info->second.obj().oid_name().empty()) {
995 auto ext = std::make_unique<T>();
996 ext->decode_inner(extn_info->second.bits());
997 return ext;
998 }
999 }
1000 return nullptr;
1001 }

◆ has_unknown_critical_extension()

bool Botan::Extensions::has_unknown_critical_extension ( ) const
inline

Return true if an unrecognized critical extension was encountered during the most recent decode_from. Resets on each call to decode_from and is not affected by subsequent calls to add/replace/remove.

Definition at line 936 of file pkix_types.h.

936{ return m_has_unknown_critical_extension; }

◆ operator=() [1/2]

Extensions & Botan::Extensions::operator= ( const Extensions & )
default

References Extensions().

◆ operator=() [2/2]

Extensions & Botan::Extensions::operator= ( Extensions && )
default

References Extensions().

◆ remove()

bool Botan::Extensions::remove ( const OID & oid)

Remove an extension from the list. Returns true if the extension had been set, false otherwise.

Definition at line 215 of file x509_ext.cpp.

215 {
216 const bool erased = m_extension_info.erase(oid) > 0;
217
218 if(erased) {
219 m_extension_oids.erase(std::find(m_extension_oids.begin(), m_extension_oids.end(), oid));
220 }
221
222 return erased;
223}

Referenced by replace().

◆ replace()

void Botan::Extensions::replace ( std::unique_ptr< Certificate_Extension > extn,
bool critical = false )

Adds an extension to the list or replaces it.

Parameters
extnthe certificate extension
criticalwhether this extension should be marked as critical

Definition at line 225 of file x509_ext.cpp.

225 {
226 // Remove it if it existed
227 remove(extn->oid_of());
228
229 const OID oid = extn->oid_of();
230 Extensions_Info info(critical, std::move(extn));
231 m_extension_oids.push_back(oid);
232 m_extension_info.emplace(oid, info);
233}
bool remove(const OID &oid)
Definition x509_ext.cpp:215

References remove().

Referenced by Botan::X509_CA::choose_extensions(), Botan::X509::create_cert_req(), and Botan::X509::create_self_signed_cert().

◆ validate()

void Botan::Extensions::validate ( const X509_Certificate & subject,
const std::optional< X509_Certificate > & issuer,
const std::vector< X509_Certificate > & cert_path,
std::vector< std::set< Certificate_Status_Code > > & cert_status,
size_t pos ) const

Invoke the validation callback for each extension.

Definition at line 281 of file x509_ext.cpp.

285 {
286 for(const auto& ext : m_extension_info) {
287 ext.second.obj().validate(subject, issuer, cert_path, cert_status, pos);
288 }
289}

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


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