Name Types¶
Botan provides a small set of strongly-typed value classes for names that appear in network protocols and PKI artifacts: DNS host names, email addresses, IP addresses (v4 and v6), and URIs.
Although these types were introduced to model the GeneralName alternatives of an
X.509 certificate (RFC 5280 4.2.1.6), they are not specifically tied to X.509 and are
intended to be reusable wherever names over these forms are useful.
Construction of these name types goes through a static parser (from_string) that
returns std::optional; an empty optional signals a parse / validation failure.
Successfully constructed values are in a canonical form (for example, DNS names are
lowercased), so equality is defined on the canonical representation rather than on
the original input.
All of the types defined here are value types with equality comparison; all except
the subnet types additionally provide ordering via operator<=>.
DNS Names¶
Added in version 3.13.
Declared in botan/dns_name.h.
-
class DNSName¶
A DNS name (host name or wildcard pattern) in canonical form. Construction validates that the input conforms to the Preferred Name Syntax (RFC 1035 and RFC 1123 LDH labels, length limits, no leading or trailing dot). Entirely numeric names (
"1.2.3.4") are rejected. The stored form is lowercased ASCII.-
static std::optional<DNSName> from_string(std::string_view name)¶
Parse and canonicalize a literal hostname. Returns
std::nulloptif name is not a valid DNS name per RFCs 1035 / 1123, or if it contains a"*"character - usefrom_san_stringfor wildcards.
-
static std::optional<DNSName> from_san_string(std::string_view name)¶
Like
from_string, but additionally accepts the RFC 6125 Section 6.4.3 wildcard form: a single"*"anywhere within the leftmost label of an otherwise-valid DNS name (e.g."*.example.com","foo*.example.com"). Shapes that could never produce a match under the wildcard rules - multiple"*"("*.*.example.com"),"*"outside the leftmost label ("foo.*.example.com"), or patterns with fewer than three labels ("*","*.com") - are rejected, as are wildcards embedded within an IDNA A-label ("xn--f*.example.com"). Intended for parsing X.509 SANdnsNameentries.Note
In a future major release, Botan’s wildcard semantics will instead follow RFC 9525, at which time this function will only accept wildcards of the form
"*.example.com".
-
const std::string &name() const¶
-
const std::string &to_string() const¶
Return the canonicalized (lowercase ASCII) form of the name. Both accessors return the same value;
to_stringmatches the convention used by the other name types.
-
bool is_wildcard() const¶
True if this name is a wildcard pattern. Since
from_san_stringrejects any wildcard shape outside the leftmost label, any stored"*"is already in the leftmost label.
-
bool matches_wildcard(std::string_view wildcard) const¶
Test whether this name matches the wildcard pattern. Equivalent to
host_wildcard_match(wildcard, this->name()).
-
static bool host_wildcard_match(std::string_view issued, std::string_view host)¶
Test whether the issued name (possibly a wildcard pattern) matches host (which must be a complete and valid DNS name). Returns false if either input is invalid.
-
static std::optional<DNSName> from_string(std::string_view name)¶
Email Addresses¶
Added in version 3.13.
Declared in botan/email.h.
Botan distinguishes two mailbox name types:
EmailAddressmodels RFC 5280rfc822Name, in which the local-part is ASCII only.SmtpUtf8Mailboxmodels the RFC 9598 internationalized mailbox form, in which the local-part is UTF-8 and (per the RFC) MUST contain a non-ASCII character. Botan does not currently enforce the latter requirement when parsing; see below.
These types are intentionally not related to each other in the type system: name constraint processing rules apply differently to the two forms, and by a strict reading of the relevant RFCs their values should be entirely disjoint.
Both parsers accept only the unquoted dot-atom form of local-part; addresses that would
require quoting are currently rejected. The local-part is stored and compared verbatim
(case sensitively), while the domain is canonicalized as a DNSName.
-
class EmailAddress¶
A parsed email address in mailbox form
local-part@domain, modeling RFC 5280rfc822Name. The local-part is restricted to ASCII.-
static std::optional<EmailAddress> from_string(std::string_view addr)¶
Parse addr. Returns
std::nulloptif the input is not a valid mailbox, the local-part contains non-ASCII bytes, or the domain is not a valid DNS name.
-
const std::string &local_part() const¶
The local-part, ASCII only.
-
std::string to_string() const¶
The reassembled
local-part@domainform. Note that the domain name will be in canonicalized form.
-
static std::optional<EmailAddress> from_string(std::string_view addr)¶
-
class SmtpUtf8Mailbox¶
A parsed internationalized mailbox (
SmtpUTF8Mailbox) as defined by RFC 9598. The local-part is UTF-8, and the DNS name must be A-label form ASCII. Previous specifications of this type, from RFC 6531, also accepted U-label domain names, but RFC 9598 modifies it to only contain an A-label.-
static std::optional<SmtpUtf8Mailbox> from_string(std::string_view addr)¶
Parse addr. Returns
std::nulloptif the input is not a valid mailbox, is not valid UTF-8, or the domain is not a valid DNS name. The RFC 9598 requirement that the local-part contain at least one non-ASCII character is not currently enforced here; an all-ASCII mailbox also parses.
-
const std::string &local_part() const¶
-
std::string to_string() const¶
As for
EmailAddress.
-
static std::optional<SmtpUtf8Mailbox> from_string(std::string_view addr)¶
IP Addresses and Subnets¶
Added in version 3.12.
Declared in botan/ipv4_address.h and botan/ipv6_address.h.
Botan provides separate IPv4 and IPv6 address types, each paired with a CIDR subnet type. The subnet types are convenient for X.509 name constraints, which encode a network address paired with a netmask.
IPv4¶
-
class IPv4Address¶
A 32-bit IPv4 address.
-
explicit IPv4Address(uint32_t ip)¶
Construct from a 32-bit big-endian integer representation.
-
static std::optional<IPv4Address> from_string(std::string_view str)¶
Parse a dotted-decimal address (e.g.
"10.0.0.1"). Returnsstd::nullopton failure.Some libraries will accept strings like
"127.1","2130706433""0x7f000001", or “0177.0.0x1”` as valid encodings of the address"127.0.0.1". None of these alternate encodings are accepted by this function.
-
static IPv4Address netmask(size_t bits)¶
Return an address with the leading bits set to one and the remainder zero. Throws
Invalid_Argumentif bits > 32.
-
static IPv4Address host_mask()¶
Equivalent to
netmask(32).
-
uint32_t address() const¶
The address as a 32-bit big-endian integer.
-
std::array<uint8_t, 4> to_bytes() const¶
The address as four bytes in network-byte-order.
-
std::string to_string() const¶
Return the dotted-decimal form (e.g.
"10.0.0.1").
-
std::optional<size_t> prefix_length() const¶
If this value is a netmask consisting of a run of one bits followed by a run of zero bits, return the count of one bits; otherwise returns
std::nullopt.
-
IPv4Address operator&(const IPv4Address &other) const¶
Bitwise AND, useful for masking an address with a netmask.
-
explicit IPv4Address(uint32_t ip)¶
-
class IPv4Subnet¶
An IPv4 subnet in CIDR form: a network address paired with a prefix length.
-
IPv4Subnet(IPv4Address address, size_t prefix_length)¶
Construct from a network address and a prefix_length in
[0, 32]. Any set host bits of address are cleared. ThrowsInvalid_Argumentif prefix_length > 32.
-
static std::optional<IPv4Subnet> from_string(std::string_view str)¶
Parse the CIDR form
"10.0.0.0/8". The/Nsuffix is required; bare addresses should be parsed viaIPv4Address::from_stringand wrapped withIPv4Subnet::hostif needed.The input must already be canonical, such that
from_stringandto_stringare exact inverses: the prefix length is canonical decimal ("/8", not"/08") and the host bits are clear ("10.0.0.0/8", not"10.1.2.3/8").Unlike the constructor, which masks host bits away, a set host bit here is a parse failure. Returns
std::nullopton parse failure, non-canonical input, or out-of-range prefix length.
-
static std::optional<IPv4Subnet> from_address_and_mask(uint32_t addr, uint32_t mask)¶
-
static std::optional<IPv4Subnet> from_address_and_mask(std::span<const uint8_t, 8> addr_and_mask)¶
Construct a subnet from a network address and a contiguous-CIDR netmask. Returns
std::nulloptif the netmask has non-contiguous bits. Host bits are cleared.
-
static IPv4Subnet host(IPv4Address address)¶
A single-host subnet (prefix length 32) covering exactly address.
-
const IPv4Address &address() const¶
-
size_t prefix_length() const¶
-
bool is_host() const¶
-
bool contains(const IPv4Address &ip) const¶
-
std::string to_string() const¶
Accessors.
to_stringreturns the CIDR form.
-
IPv4Subnet(IPv4Address address, size_t prefix_length)¶
IPv6¶
-
class IPv6Address¶
A 128-bit IPv6 address.
-
explicit IPv6Address(std::array<uint8_t, 16> ip)¶
-
explicit IPv6Address(std::span<const uint8_t, 16> ip)¶
Construct from a 16-byte network-byte-order representation.
-
static std::optional<IPv6Address> from_string(std::string_view str)¶
Parse a textual IPv6 address. Accepts the full form (eight colon-separated hex groups), the
"::"-compressed form (exactly one run of zero groups elided), and combinations such as"2001:db8::1". The IPv4 dotted-decimal format (e.g."::ffff:192.0.2.1") is also accepted. Surrounding brackets and zone identifiers are not accepted.
-
static IPv6Address netmask(size_t bits)¶
Return an address with the leading bits set to one and the remainder zero. Throws
Invalid_Argumentif bits > 128.
-
static IPv6Address host_mask()¶
Equivalent to
netmask(128).
-
std::array<uint8_t, 16> address() const¶
Returns the 16 bytes of the address, in network-byte-order.
-
std::string to_string() const¶
Returns the RFC 5952 canonical text form: lowercase hex, leading zeros within a group suppressed, and the longest run of two or more zero groups compressed with
"::". The mixed hex/dotted notation is never produced, even for IPv4-mapped addresses.
-
std::optional<size_t> prefix_length() const¶
As for
IPv4Address::prefix_length.
-
std::optional<IPv4Address> as_ipv4() const¶
If this address is an IPv4-compatible IPv6 address (RFC 4291 2.5.5.1) or an IPv4-mapped IPv6 address (RFC 4291 2.5.5.2), return the embedded
IPv4Address. Otherwise returnstd::nullopt.
-
IPv6Address operator&(const IPv6Address &other) const¶
Bitwise AND.
-
explicit IPv6Address(std::array<uint8_t, 16> ip)¶
-
class IPv6Subnet¶
An IPv6 subnet in CIDR form. The interface mirrors
IPv4Subnet, with the prefix length valid in[0, 128].-
IPv6Subnet(IPv6Address address, size_t prefix_length)¶
-
static std::optional<IPv6Subnet> from_string(std::string_view str)¶
-
static std::optional<IPv6Subnet> from_address_and_mask(std::span<const uint8_t, 32> addr_and_mask)¶
-
static IPv6Subnet host(IPv6Address address)¶
-
const IPv6Address &address() const¶
-
size_t prefix_length() const¶
-
bool is_host() const¶
-
bool contains(const IPv6Address &ip) const¶
-
std::string to_string() const¶
As for the IPv4 counterparts. Note that
from_stringrequires canonical input: the address must be in RFC 5952 form with host bits clear, and in particular the IPv4-mapped dotted form ("::ffff:1.2.3.4/120") is rejected even thoughIPv6Address::from_stringaccepts that address.
-
IPv6Subnet(IPv6Address address, size_t prefix_length)¶
URIs¶
Added in version 3.13.
Declared in botan/uri.h.
-
class URI¶
A URI parsed as a subset of RFC 3986. The parser is intended to cover the shapes that appear in X.509
uniformResourceIdentifierGeneralName entries and similar PKI / network use; it is not a general-purpose URI library and does not perform pct-decoding or normalization beyond lowercasing the scheme. Percent escapes in the userinfo, path, query, and fragment components are validated for well-formedness (and"%00"is rejected outright) but are not decoded. Note that this non-canonicalization of the userinfo, path, query and fragment components implies that equality tests can be bypassed by varying pct encodings.The authority component is optional: URIs without one (e.g.
"mailto:user@example.com") parse successfully. When an authority is present, its host portion is held as a validatedDNSName,IPv4Address, orIPv6Address(seeHost).-
static std::optional<URI> from_string(std::string_view raw)¶
Parse a complete URI. Returns
std::nullopton any parse failure, including relative references (inputs without a scheme).
-
const std::string &scheme() const¶
Scheme, lowercase-normalized.
-
const std::optional<Authority> &authority() const¶
The parsed authority (
userinfo@host:port), if this URI has a non-empty one. SeeURI::Authority.
-
std::optional<std::string_view> raw_authority() const¶
The raw (unparsed) authority component, if this URI included one. This distinguishes an empty authority (
"ldap:///CN=x", empty string here whileauthorityisstd::nullopt) from an absent one ("mailto:user@example.com",std::nulloptfor both). Equality comparison also distinguishes these two cases.
-
std::optional<std::reference_wrapper<const Host>> host() const¶
The parsed host, if this URI has a non-empty authority.
-
const std::string &path() const¶
The path component, preserved verbatim. In a URI with an authority, a non-empty path always begins with
"/"; without an authority the path is whatever followed the scheme ("user@example.com"for"mailto:user@example.com"). Empty if the parsed URI had no path (e.g."http://example.com"or"http://example.com?q").
-
const std::optional<std::string> &query() const¶
The query component, without the leading
"?", orstd::nulloptif no query component was present.
-
const std::optional<std::string> &fragment() const¶
The fragment component, without the leading
"#", orstd::nulloptif no fragment component was present.
-
const std::string &original_input() const¶
The original input string that this URI was parsed from.
-
static std::optional<URI> from_string(std::string_view raw)¶
-
class URI::Authority¶
The authority component of a URI: a validated DNS name, IPv4 literal, or IPv6 literal, with an optional port and optional userinfo.
-
using Host = std::variant<DNSName, IPv4Address, IPv6Address>¶
Alternative types of the parsed host. Also accessible as
URI::Host.
-
enum class HostKind : uint8_t¶
Tag for the alternative held by
Host. Members:DNS,IPv4,IPv6. Also accessible asURI::HostKind.
-
static std::optional<Authority> from_string(std::string_view raw)¶
Parse a bare authority of the form
"host[:port]"or"[ipv6][:port]"(with optional"userinfo@"prefix). A port, if present, must be in[1, 65535], with no leading zeros. Returnsstd::nulloptfor any parse failure.
-
const Host &host() const¶
The parsed host, as one of
DNSName,IPv4Address, orIPv6Address.
-
std::string host_to_string() const¶
The host as a string, in the canonical
to_stringform of the held alternative: DNS names are lowercased, and IPv6 addresses are in RFC 5952 form without surrounding brackets.
-
std::optional<uint16_t> port() const¶
The port if present, or
std::nulloptif it was absent.
-
const std::string &original_input() const¶
The original input string that this authority was parsed from.
-
const std::optional<std::string> &userinfo() const¶
The
userinfocomponent, orstd::nulloptif no"@"was present. Note that a present-but-empty userinfo ("https://@example.com/") is represented as an empty string, which allows it to be distinguished from the absent case.
-
using Host = std::variant<DNSName, IPv4Address, IPv6Address>¶