11#ifndef BOTAN_PKIX_TYPES_H_
12#define BOTAN_PKIX_TYPES_H_
14#include <botan/asn1_obj.h>
16#include <botan/dns_name.h>
17#include <botan/email.h>
18#include <botan/ipv4_address.h>
19#include <botan/ipv6_address.h>
20#include <botan/pkix_enums.h>
23#include <initializer_list>
102 bool is_negative()
const;
107 bool is_zero()
const;
131 std::vector<uint8_t> magnitude()
const;
151 std::vector<uint8_t> m_contents;
161 X509_DN(std::initializer_list<std::pair<std::string_view, std::string_view>> args) {
162 for(
const auto& i : args) {
172 explicit
X509_DN(const std::multimap<
OID, std::
string>& args) {
173 for(
const auto& i : args) {
183 explicit
X509_DN(const std::multimap<std::
string, std::
string>& args) {
184 for(
const auto& i : args) {
192 bool has_field(
const OID& oid)
const;
198 const std::vector<uint8_t>&
get_bits()
const {
return m_dn_bits; }
200 std::vector<uint8_t> DER_encode()
const;
202 bool empty()
const {
return m_rdn.empty(); }
209 size_t count()
const {
return m_rdn.size(); }
222 static std::optional<X509_DN> parse(std::string_view str);
229 const std::vector<std::vector<std::pair<OID, ASN1_String>>>&
rdns()
const {
return m_rdn; }
238 std::multimap<
OID, std::
string> get_attributes() const;
239 std::multimap<std::
string, std::
string> contents() const;
241 bool has_field(std::string_view attr) const;
242 std::vector<std::
string> get_attribute(std::string_view attr) const;
243 std::
string get_first_attribute(std::string_view attr) const;
245 void add_attribute(std::string_view key, std::string_view val);
256 void add_rdn(std::vector<std::pair<OID, ASN1_String>> rdn);
258 static std::string deref_info_field(std::string_view key);
267 static size_t lookup_ub(
const OID& oid);
277 void update_canonical_bits();
281 std::vector<std::vector<std::pair<OID, ASN1_String>>> m_rdn;
282 std::vector<uint8_t> m_dn_bits;
283 std::vector<uint8_t> m_canonical_dn_bits;
286BOTAN_PUBLIC_API(2, 0) bool operator==(const X509_DN& dn1, const X509_DN& dn2);
287BOTAN_PUBLIC_API(2, 0)
bool operator!=(const X509_DN& dn1, const X509_DN& dn2);
293BOTAN_PUBLIC_API(2, 0)
bool operator<(const X509_DN& dn1, const X509_DN& dn2);
295BOTAN_PUBLIC_API(2, 0) std::ostream& operator<<(std::ostream& out, const X509_DN& dn);
301BOTAN_DEPRECATED_API(
"Use X509_DN::parse") std::istream& operator>>(std::istream& in, X509_DN& dn);
309 class OtherNameValue final {
313 std::span<const uint8_t>
value()
const {
return m_value; }
316 if(
oid() != other.
oid()) {
317 return oid() < other.
oid();
319 return m_value < other.m_value;
325 OtherNameValue(
const OID&
oid, std::vector<uint8_t>
value) : m_oid(
oid), m_value(std::move(
value)) {}
328 m_oid(oid), m_value(value.begin(), value.end()) {}
331 std::vector<uint8_t> m_value;
334 void encode_into(DER_Encoder& to)
const override;
335 void decode_from(BER_Decoder& from)
override;
341 void add_uri(std::string_view uri);
388 BOTAN_DEPRECATED(
"Use AlternativeName::uri_names") std::set<std::
string> uris() const;
397 BOTAN_DEPRECATED(
"Use AlternativeName::email_addresses") std::set<std::
string> email() const;
406 BOTAN_DEPRECATED(
"Use AlternativeName::dns_names") std::set<std::
string> dns() const;
412 BOTAN_DEPRECATED(
"Use ipv4_addresses") std::set<uint32_t> ipv4_address() const;
449 size_t count()
const;
452 bool has_items()
const;
455 bool is_empty()
const;
458 BOTAN_DEPRECATED(
"Use AlternativeName::{uris, email, dns, othernames, directory_names}")
459 std::multimap<std::
string, std::
string> contents() const;
461 BOTAN_DEPRECATED(
"Use AlternativeName::{uris, email, dns, othernames, directory_names}.empty()")
462 bool has_field(std::string_view attr) const;
464 BOTAN_DEPRECATED(
"Use AlternativeName::{uris, email, dns, othernames, directory_names}")
465 std::vector<std::
string> get_attribute(std::string_view attr) const;
467 BOTAN_DEPRECATED(
"Use AlternativeName::{uris, email, dns, othernames, directory_names}")
468 std::multimap<std::
string, std::
string, std::less<>> get_attributes() const;
470 BOTAN_DEPRECATED(
"Use AlternativeName::{uris, email, dns, othernames, directory_names}")
471 std::
string get_first_attribute(std::string_view attr) const;
474 void add_attribute(std::string_view type, std::string_view value);
477 void add_othername(const
OID& oid, std::string_view value,
ASN1_Type type);
489 BOTAN_DEPRECATED(
"Use plain constructor plus add_{uri,dns,email,ipv4_address}")
491 std::string_view uri =
"",
492 std::string_view
dns =
"",
493 std::string_view ip_address =
"");
505 std::set<
OID> m_registered_ids;
518 Attribute(std::string_view oid_str,
const std::vector<uint8_t>& params);
522 const std::vector<uint8_t>&
parameters()
const {
return m_parameters; }
530 std::vector<uint8_t> m_parameters;
611 BOTAN_DEPRECATED(
"Deprecated no replacement") std::vector<uint8_t> binary_name() const;
620 bool matches_dns(const std::
string& dns_name) const;
621 bool matches_dns(const
DNSName& dns_name) const;
623 bool matches_ipv4(uint32_t ip) const;
628 bool matches_dn(
const X509_DN& dn)
const;
629 bool matches_uri(
const URI& uri)
const;
636 class EmailConstraint final {
638 EmailConstraint() =
default;
640 static std::optional<EmailConstraint> from_string(std::string_view input);
642 const std::string& value()
const {
return m_value; }
644 auto operator<=>(
const EmailConstraint&)
const =
default;
647 explicit EmailConstraint(std::string value) : m_value(std::move(value)) {}
652 class DNSConstraint final {
654 DNSConstraint() =
default;
656 static std::optional<DNSConstraint> from_string(std::string_view input);
658 static std::optional<DNSConstraint> from_san_value(std::string_view input);
660 const std::string& value()
const {
return m_value; }
662 auto operator<=>(
const DNSConstraint&)
const =
default;
665 explicit DNSConstraint(std::string value) : m_value(std::move(value)) {}
670 class URIConstraint final {
672 URIConstraint() =
default;
674 static std::optional<URIConstraint> from_string(std::string_view input);
676 static std::optional<URIConstraint> from_san_value(std::string_view full_uri);
678 const std::string& value()
const {
return m_value; }
680 auto operator<=>(
const URIConstraint&)
const =
default;
683 explicit URIConstraint(std::string value) : m_value(std::move(value)) {}
692 using NameVariant = std::variant<EmailConstraint, DNSConstraint, URIConstraint, X509_DN, IPv4Subnet, IPv6Subnet>;
694 GeneralName(NameType type, NameVariant name) : m_type(type), m_name(std::move(name)) {}
696 NameType m_type = NameType::Unknown;
703 static bool matches_dn(
const X509_DN& name,
const X509_DN& constraint);
743BOTAN_DEPRECATED(
"Deprecated no replacement") std::ostream& operator<<(std::ostream& os, const GeneralSubtree& gs);
763 std::vector<GeneralSubtree>&& excluded_subtrees);
769 return m_permitted_subtrees;
776 return m_excluded_subtrees;
790 std::vector<GeneralSubtree> m_permitted_subtrees;
791 std::vector<GeneralSubtree> m_excluded_subtrees;
793 std::set<GeneralName::NameType> m_permitted_name_types;
794 std::set<GeneralName::NameType> m_excluded_name_types;
825 virtual std::unique_ptr<Certificate_Extension>
copy()
const = 0;
853 const std::optional<X509_Certificate>& issuer,
854 const std::vector<X509_Certificate>& cert_path,
855 std::vector<std::set<Certificate_Status_Code>>& cert_status,
883 template <
typename T>
887 if(extn->oid_name().empty()) {
889 }
else if(
const T* extn_as_T =
dynamic_cast<const T*
>(extn)) {
892 throw Decoding_Error(
"Exception::get_extension_object_as dynamic_cast failed");
909 std::vector<OID> critical_extensions()
const;
914 bool extension_set(
const OID& oid)
const;
919 bool critical_extension_set(
const OID& oid)
const;
925 std::vector<uint8_t> get_extension_bits(
const OID& oid)
const;
929 void decode_from(
BER_Decoder& from, std::optional<Extension_Context> context);
944 void add(std::unique_ptr<Certificate_Extension> extn,
bool critical =
false);
954 bool add_new(std::unique_ptr<Certificate_Extension> extn,
bool critical =
false);
961 void replace(std::unique_ptr<Certificate_Extension> extn,
bool critical =
false);
967 bool remove(
const OID& oid);
976 std::unique_ptr<Certificate_Extension> get(
const OID& oid)
const;
988 template <
typename T>
990 auto extn_info = m_extension_info.find(oid);
992 if(extn_info != m_extension_info.end()) {
994 if(extn_info->second.obj().oid_name().empty()) {
995 auto ext = std::make_unique<T>();
996 ext->decode_inner(extn_info->second.bits());
1009 std::vector<std::pair<std::unique_ptr<Certificate_Extension>,
bool>> extensions()
const;
1015 const std::optional<X509_Certificate>& issuer,
1016 const std::vector<X509_Certificate>& cert_path,
1017 std::vector<std::set<Certificate_Status_Code>>& cert_status,
1025 std::map<OID, std::pair<std::vector<uint8_t>,
bool>> extensions_raw()
const;
1027 size_t count()
const {
return m_extension_oids.size(); }
1040 static std::unique_ptr<Certificate_Extension> create_extn_obj(
const OID& oid,
1042 const std::vector<uint8_t>& body,
1043 std::optional<Extension_Context> context);
1047 Extensions_Info(
bool critical, std::unique_ptr<Certificate_Extension> ext) :
1048 m_obj(std::move(ext)), m_bits(m_obj->encode_inner()), m_critical(critical) {}
1050 Extensions_Info(
bool critical,
1051 const std::vector<uint8_t>& encoding,
1052 std::unique_ptr<Certificate_Extension> ext) :
1053 m_obj(std::move(ext)), m_bits(encoding), m_critical(critical) {}
1055 bool is_critical()
const {
return m_critical; }
1057 const std::vector<uint8_t>& bits()
const {
return m_bits; }
1059 const Certificate_Extension& obj()
const;
1062 std::shared_ptr<Certificate_Extension> m_obj;
1063 std::vector<uint8_t> m_bits;
1064 bool m_critical =
false;
1067 std::vector<OID> m_extension_oids;
1068 std::map<OID, Extensions_Info> m_extension_info;
1069 bool m_has_unknown_critical_extension =
false;
#define BOTAN_PUBLIC_API(maj, min)
#define BOTAN_UNSTABLE_API
#define BOTAN_DEPRECATED(msg)
#define BOTAN_FUTURE_EXPLICIT
#define BOTAN_DEPRECATED_API(msg)
An "OtherName" GeneralName entry: type-id OID and the inner ANY value as raw BER.
bool operator<(const OtherNameValue &other) const
std::span< const uint8_t > value() const
friend class AlternativeName
const std::set< IPv6Address > & ipv6_addresses() const
Return the set of IPv6 addresses included in this alternative name.
const std::set< DNSName > & dns_names() const
Return the set of DNS names included in this alternative name.
const std::set< X509_DN > & directory_names() const
Return the set of directory names included in this alternative name.
void add_dns(std::string_view dns)
Add a DNS name to this AlternativeName, parsing and validating the input.
std::set< std::string > dns() const
void add_ipv4_address(uint32_t ipv4)
Add an IP address to this alternative name.
void add_email(std::string_view addr)
Add an email address to this AlternativeName, parsing and validating the input.
const std::set< EmailAddress > & email_addresses() const
Return the set of email addresses included in this alternative name.
const std::set< std::pair< OID, ASN1_String > > & other_names() const
Return the set of "other names" whose value was a recognized ASN1_String type.
const std::set< SmtpUtf8Mailbox > & smtp_utf8_mailboxes() const
void add_uri(std::string_view uri)
Add a URI to this AlternativeName, parsing and validating the input.
void add_registered_id(const OID &oid)
Add a registeredID (RFC 5280 [8]).
const std::set< OtherNameValue > & other_name_values() const
Return all "OtherName" entries with their inner ANY value as raw BER.
void add_other_name_value(const OID &oid, std::span< const uint8_t > value)
void add_other_name(const OID &oid, const ASN1_String &value)
Add an "OtherName" identified by object identifier to this AlternativeName.
const std::set< IPv6Address > & ipv6_address() const
Return the set of IPv6 addresses included in this alternative name.
const std::set< IPv4Address > & ipv4_addresses() const
Return the set of IPv4 addresses included in this alternative name.
void add_dn(const X509_DN &dn)
Add a directory name to this AlternativeName.
const std::set< URI > & uri_names() const
Return the set of URIs included in this alternative name.
AlternativeName()=default
Create an empty name.
std::multimap< OID, ASN1_String > get_othernames() const
const std::set< OID > & registered_ids() const
Return the set of registeredID OIDs.
const std::vector< uint8_t > & parameters() const
void decode_from(BER_Decoder &from) override
const OID & object_identifier() const
void encode_into(DER_Encoder &to) const override
const std::vector< uint8_t > & get_parameters() const
virtual bool should_encode() const
virtual 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
virtual std::string oid_name() const =0
virtual OID oid_of() const =0
virtual std::unique_ptr< Certificate_Extension > copy() const =0
virtual bool is_appropriate_context(Extension_Context context) const =0
virtual std::vector< uint8_t > encode_inner() const =0
virtual ~Certificate_Extension()=default
virtual void decode_inner(const std::vector< uint8_t > &)=0
const Certificate_Extension * get_extension_object(const OID &oid) const
std::unique_ptr< T > get_raw(const OID &oid) const
Extensions & operator=(const Extensions &)=default
bool has_unknown_critical_extension() const
Extensions(const Extensions &)=default
~Extensions() override=default
Extensions(Extensions &&)=default
const std::vector< OID > & get_extension_oids() const
const T * get_extension_object_as(const OID &oid=T::static_oid()) const
Extensions & operator=(Extensions &&)=default
static GeneralName email(std::string_view email)
void decode_from(BER_Decoder &from) override
static GeneralName ipv4_address(uint32_t ipv4)
void encode_into(DER_Encoder &to) const override
static GeneralName uri(std::string_view uri)
static GeneralName _dns_san_value(std::string_view dns)
static GeneralName ipv6_address(const IPv6Address &ipv6)
friend class NameConstraints
NameType type_code() const
bool matches_ipv4(const IPv4Address &ip) const
bool matches_ipv4(uint32_t ip) const
static GeneralName dns(std::string_view dns)
static GeneralName _uri_san_value(std::string_view full_uri)
static GeneralName directory_name(Botan::X509_DN dn)
A single Name Constraint.
const GeneralName & base() const
NameConstraints()=default
const std::vector< GeneralSubtree > & permitted() const
const std::vector< GeneralSubtree > & excluded() const
const std::vector< std::vector< std::pair< OID, ASN1_String > > > & rdns() const
void add_attribute(const OID &oid, std::string_view val)
void add_attribute(std::string_view key, std::string_view val)
const std::vector< uint8_t > & _canonical_bytes() const
X509_DN(std::initializer_list< std::pair< std::string_view, std::string_view > > args)
const std::vector< uint8_t > & get_bits() const
size_t octet_length() const
bool conforms_to_rfc5280() const
std::span< const uint8_t > der_contents() const
bool operator==(const X509_Serial_Number &other) const
auto operator<=>(const Strong< T, Tags... > &lhs, const Strong< T, Tags... > &rhs)
std::string to_string(ErrorType type)
Convert an ErrorType to string.
std::string key_constraints_to_string(Key_Constraints c)