TLS Support
Configuration
TlsConfiguration groups independent optional TlsClientConfiguration and TlsServerConfiguration parts.
Each part holds its own trust selection and shares an immutable identity.
TlsTrustConfiguration describes profile trust; TlsSettings supplies application-wide defaults and native
options.
See Configuring TLS Profiles for configuring services, loading identities, and reloading profiles.
Registration and Replacement
CryptologyConfiguration::setTlsConfiguration() replaces each supplied role completely, preserving the other role
already registered at that label.
It validates supplied roles against the installed shared settings and does not merge fields within a role.
CryptologyConfiguration::replaceTlsConfigurations() validates an entire TlsConfigurationSet before replacing its
shared settings and named profiles atomically.
A failed replacement leaves the installed set unchanged.
CryptologyConfiguration::hasTlsConfiguration() tests exact presence for one role.
CryptologyConfiguration::clearTlsConfiguration() removes one named role, or both when no role is specified.
CryptologyConfiguration::clearTlsConfigurations() preserves shared settings and built-in defaults.
CryptologyConfiguration::reset() also restores shared TLS defaults.
Connections retain their selected immutable profiles and effective policies across registry changes.
Label Resolution
CryptologyConfiguration::resolveTlsConfiguration() searches only the requested TlsRole at the exact label, its
slash-delimited ancestors, and finally the reserved empty label.
The returned TlsConfigurationResolution contains
requested and matched labels, the role, the immutable configuration, and its effective certificate policy.
Resolution performs no file access or native trust evaluation.
An invalid selected role fails without trying an ancestor.
CryptologyConfiguration::resolveTlsConfigurations() captures multiple labels from one registry state, allowing a
server to select its default and SNI profiles consistently.
Both built-in defaults always exist and cannot be registered, replaced, or individually cleared.
The client default has no identity and selects system trust subject to shared settings; all unresolved client labels
reach it.
The server default has no identity and fails synchronously when resolved.
Low-level TLS connections request tls and HTTP requests http in both roles.
Named labels contain at most 16 nonempty slash-separated segments and 255 bytes, using lowercase ASCII letters, digits, and interior hyphens. At most 256 named labels may be installed; a label containing both roles counts once and defaults consume no capacity.
ELCL Parsing and Validation
TlsConfigurationParser::parse() parses the complete optional TLS section into an owned TlsConfigurationSet.
The schema has shared [TLS] settings and optional *[TLS . Client]* and *[TLS . Server]* section lists.
A label may occur once per role; matching labels across the two lists combine into one configuration.
An absent TLS section returns a default set.
ELCL names are case-insensitive and treat spaces and underscores equivalently.
TlsConfigurationParser::validationRules() and TlsConfigurationParser::version() expose the compiled schema and
its version for a separate validation pass.
Parsing always repeats schema validation, then loads certificate and identity material and checks profile trust.
Validation alone does not load files or verify certificate/key matches.
Password fields receive secret annotations even when supplied as ordinary ELCL text.
Relative material paths resolve from the file defining the field, including fields supplied by an included file.
Absolute paths are accepted as written.
Text and stream sources require absolute paths.
Loading errors are reported as ConfError with the responsible source location
and the underlying error as a cause where available.
TLS Identities
TlsIdentity combines a leaf-first certificate chain with a signer backed by a software key or an operating-system
provider.
The software-key constructor takes a move-only SigningPrivateKey.
Construction rejects an empty chain, a leaf/key mismatch, or a key with no supported TLS 1.3 signature scheme.
Identity chains are limited to 16 certificates and a one-MiB encoded TLS Certificate message.
Mismatches and unsupported schemes report CryptologyError; empty components are caller precondition failures.
TlsConfiguration::setServer() and setClient() configure independent role parts.
Their identities use immutable shared ownership.
Configuration copies and connection snapshots share the identity without copying private key material.
Replacing or clearing a registry entry does not invalidate existing snapshots.
selectSignatureScheme() examines the peer’s offered schemes in order and returns the first compatible value.
Client Certificate Authentication
A client identity is sent only in response to an initial CertificateRequest, after the server’s certificate,
CertificateVerify, and Finished messages have authenticated it.
The identity must satisfy certificate validity, digital-signature key usage, client-authentication purpose, requested
issuer names, and signature-scheme requirements.
Unsupported nonempty OID filters suppress identity disclosure.
An absent or unsuitable identity produces an empty certificate list; the connection never searches a store for another
identity.
TlsServerConfiguration::setClientAuthentication() selects whether the server requests a client certificate during
the initial handshake:
Mode |
Behavior |
|---|---|
|
Send no certificate request. This is the default. |
|
Request a certificate and accept an empty certificate list as anonymous. |
|
Request a certificate and reject an empty certificate list with |
Both enabled modes reject invalid presented certificates or proofs of private-key possession. CertificateRequest uses an empty context and supported signature algorithms without CA-name hints or OID filters. Client path validation, CertificateVerify, and Finished must all succeed before authenticated peer metadata is published. See Network Connections for server connection metadata and its lifetime. Post-handshake authentication, PSK/resumption, and early data are not supported.
Native Identity Stores
SystemIdentityStore::list() returns public SystemIdentityInfo metadata.
load() selects an identity by its exact 32-byte SHA-256 leaf-certificate fingerprint and returns a
TlsIdentity that retains the native signer without exporting the
private key.
Public intermediate certificates are collected from locally available material, within the identity chain limit.
Enumeration is limited to 4,096 entries.
macOS uses identities from the current user’s Keychain.
Windows uses the current-user personal certificate store with CNG private keys; legacy CAPI keys and machine stores are
not supported.
isSupported() reports whether a native provider is available; Linux applications can use file-based identities.
Provisioning certificates and private keys remains a deployment task.
Store enumeration and identity loading are synchronous, so perform them during setup or on an appropriate worker.
Connection-triggered signing runs on background workers as described in Network Connections.
SystemIdentityStore{true} permits provider authorization dialogs; the default is silent access.
On macOS, Keychain interaction policy is process-wide.
The library serializes its own Keychain calls and restores the previous policy after each call; applications making
independent Security.framework calls must coordinate their use of that policy.
See Configuring TLS Profiles for configuring file-based and native identities in ELCL.
TLS 1.3 Record Protection
The record-protection API implements the authenticated TLS 1.3 record transformations from RFC 8446. A
TlsRecordEncryptor and TlsRecordDecryptor each retain one independent traffic-secret generation and sequence
number.
They operate on complete records so the exact wire header used as authenticated data cannot diverge from the header
returned to or received from the network layer.
Cipher Suites and Traffic Secrets
TlsCipherSuite represents exactly TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, and
TLS_CHACHA20_POLY1305_SHA256.
It maps each RFC 8446 wire value to its registry name, HKDF hash, and symmetric construction.
All supported constructions use a 96-bit nonce and a 128-bit authentication tag.
Create a move-only TlsTrafficSecret from exact SHA-256- or SHA-384-sized bytes.
The consuming factory erases its input allocation after copying the secret into ProtectedByteBlock.
An incorrect input length reports OutOfRangeError.
There is intentionally no plaintext accessor.
Record state resolves the secret only inside an erased callback while deriving a key, IV, or next-generation secret.
One Direction per Object
Construct a separate TlsRecordEncryptor and TlsRecordDecryptor for each protocol direction.
protect() returns one complete header-plus-ciphertext record.
unprotect() accepts exactly one complete record and returns a move-only TlsRecordPlaintext only after
authentication and inner-plaintext validation succeed.
Callers choose the inner content type and an explicit padding length.
This API deliberately defines no automatic padding policy.
Empty application data is supported; empty Alert and Handshake content is rejected.
Stream buffering, alert serialization, the record_size_limit extension, automatic padding strategies, and other
optional record extensions remain in the network protocol layer.
Failures and Terminal State
TlsRecordErrorCategory distinguishes decode errors, unexpected messages, authentication failure, record overflow,
and exhausted key usage.
This lets a network implementation select an alert without parsing diagnostic text.
A local protect() parameter error occurs before key or sequence use and leaves the encryptor usable.
Any failure after protection begins erases the sending generation so an uncertain nonce cannot be reused.
Every peer-record rejection or backend failure permanently erases the decryptor.
Authentication failure therefore exposes no plaintext and cannot be followed by another attempt with the same receiving
object.
Bounds and Key Usage
The implementation limits TLSInnerPlaintext to \(2^{14} + 1\) bytes and rejects an outer TLSCiphertext
length above \(2^{14} + 256\) bytes.
Supported records have the tighter construction bound of inner length plus the fixed 16-byte tag.
For AES-GCM, isKeyUpdateRequired() becomes true after \(2^{24}\) successful records.
Protection and deprotection refuse record number 23,726,566, the floor of \(2^{24.5}\).
For ChaCha20-Poly1305 the signal becomes true while one old-key record remains, and processing refuses before advancing
a 64-bit sequence would wrap.
updateApplicationTrafficKeys() performs only the caller-directed cryptographic transition from RFC 8446 Sections
4.6.3 and 7.2. Message parsing, serialization, and transition timing remain handshake responsibilities.
The method fully derives the next traffic secret, key, and IV before replacement, immediately erases the old generation,
and resets sequence and record counters to zero.
RFC 8446 Specification Mapping
The implementation follows the defining operations in review order:
Section 7.1 encodes
HkdfLabelas the requested network-order length,"tls13 "-prefixed label, and empty context before HKDF expansion.Section 7.3 derives
write_keyand the 96-bitwrite_ivfromSecretwith the"key"and"iv"labels.Section 5.3 encodes the 64-bit sequence in network byte order, left-pads it to 12 bytes, and XORs all 12 bytes with
write_ivto form the nonce.Sections 5.2 and 5.4 encode content, the nonzero inner type, and explicit zero padding as
TLSInnerPlaintext.Section 5.2 encodes outer type 23, legacy version
0x0303, and ciphertext length. Those exact five bytes areadditional_datafor AEAD.Section 5.2 performs AEAD protection or deprotection through the symmetric API. Tentative decryption storage remains sensitive and guarded until tag verification succeeds.
Section 5.4 reverse-scans authenticated plaintext over zero padding and validates the recovered inner type before copying content into its returned sensitive allocation.
Section 5.5 checks record and sequence usage before processing and advances counters exactly once after success.
Sections 4.6.3 and 7.2 derive
"traffic upd", construct a complete replacement generation, erase the old secret, key, and IV, then reset the sequence.
Validation
Focused tests include the RFC 8448 Section 3 AES-128-GCM application record and key derivation, plus pinned AES-256-GCM and ChaCha20-Poly1305 composition vectors independently generated with Node.js 24.4.1 and OpenSSL 3.5.0. Boundary tests cover sequences, content types, explicit padding, empty application data, maximum lengths, malformed framing, header and ciphertext tampering, terminal erasure, usage ceilings, and KeyUpdate. A bounded ASan/UBSan libFuzzer target seeds valid, malformed, oversized, and authentication-tampered records.
Specifications
Programmatic TLS profile registration and resolution raise CryptologyError for unusable profiles, conflicting trust
settings, duplicate roles, or registry capacity exhaustion.
Invalid label syntax and role values are caller precondition failures.
Linux trust-bundle discovery and unstable snapshots also raise CryptologyError; file access and certificate parsing
retain their documented path, stream, and parse errors.
Interface
-
struct SystemIdentityInfo
Public metadata identifying one current-user certificate without exposing a native handle.
Public Members
-
mem::ByteBlock fingerprint
Exact SHA-256 of the leaf certificate DER, used for unambiguous selection.
-
X509Certificate certificate
Public leaf certificate; listing does not sign or export a private key.
-
mem::ByteBlock fingerprint
-
class SystemIdentityStore
Explicit access to current-user OS certificate identities; Linux has no native provider.
See: TLS Support
Public Functions
-
explicit SystemIdentityStore(bool allowInteraction = false)
Create a store with explicit authorization-UI policy; no hidden worker threads are created.
- Parameters:
allowInteraction – Whether provider authorization UI is permitted.
-
bool isSupported() const noexcept
Test whether this platform implements native identities.
-
util::List<SystemIdentityInfo> list() const
List public certificate metadata from the current-user identity store.
- Throws:
CryptologyError – If native access fails or this platform is unsupported.
- Returns:
Available public identities, without selecting one for a connection.
-
TlsIdentity load(const mem::ByteBlock &fingerprint) const
Load exactly one identity by SHA-256 certificate fingerprint, retaining private keys in their provider.
- Parameters:
fingerprint – Exactly 32 fingerprint bytes.
- Throws:
CryptologyError – If no exact usable identity exists, access is denied, or interaction is required.
- Returns:
The identity and its available chain, ready for explicit TLS configuration.
-
explicit SystemIdentityStore(bool allowInteraction = false)
-
class TlsCipherSuite
A supported TLS 1.3 cipher suite from RFC 8446 section 9.1.
The suite binds one AEAD construction to the hash used by HKDF and the handshake transcript. Only the three cipher suites defined by RFC 8446 are represented.
See: TLS Support
Public Types
Public Functions
-
constexpr TlsCipherSuite() noexcept = default
Create the mandatory-to-implement TLS_AES_128_GCM_SHA256 suite.
-
inline constexpr TlsCipherSuite(const Value value) noexcept
Create a suite from a supported raw value.
-
inline constexpr uint16_t toRawValue() const noexcept
Get the exact unsigned 16-bit TLS wire value.
-
HashAlgorithm hashAlgorithm() const noexcept
Get the suite’s HKDF and transcript hash.
-
SymmetricEncryptionType encryptionType() const noexcept
Get the suite’s AEAD construction.
Public Static Functions
-
static std::optional<TlsCipherSuite> fromRawValue(uint16_t value) noexcept
Parse one supported unsigned 16-bit TLS wire value.
-
static TlsCipherSuite fromRawValueOrThrow(uint16_t value)
Parse one supported unsigned 16-bit TLS wire value.
- Throws:
err::ParseError – If the value is not supported.
-
static std::span<const TlsCipherSuite> all() noexcept
Get all supported TLS 1.3 cipher suites in preference order.
-
constexpr TlsCipherSuite() noexcept = default
-
enum class erbsland::cryptology::TlsClientAuthentication : uint8_t
Whether a TLS server requests and requires a client certificate.
Values:
-
enumerator Disabled
Do not request a certificate.
-
enumerator Optional
Accept absence, but verify every presented certificate.
-
enumerator Required
Require a verified certificate and proof of key possession.
-
enumerator Disabled
-
class TlsClientConfiguration
The independent client part of an application TLS profile.
Public Functions
-
TlsClientConfiguration() = default
Create a client configuration inheriting trust defaults and without an identity.
-
inline explicit TlsClientConfiguration(TlsTrustConfiguration trust, TlsIdentityConstPtr identity = {})
Create a client configuration with explicit trust settings and optional identity.
- Parameters:
trust – Profile trust settings.
identity – Optional immutable client identity.
-
inline explicit TlsClientConfiguration(TlsIdentity identity)
Create a client configuration with an identity and inherited trust.
- Parameters:
identity – The explicitly selected client identity.
-
inline const TlsTrustConfiguration &trust() const noexcept
Get profile trust settings.
-
inline void setTrust(TlsTrustConfiguration value)
Replace profile trust settings.
-
inline const TlsIdentityConstPtr &identity() const noexcept
Get the explicitly selected certificate identity, or null when absent.
-
inline void setIdentity(TlsIdentity value)
Set the certificate identity.
-
inline void setIdentity(TlsIdentityConstPtr value)
Share an immutable certificate identity.
-
TlsClientConfiguration() = default
-
class TlsConfiguration
Independent client and server parts sharing one application profile label.
Public Functions
-
TlsConfiguration() = default
Create a profile without either role.
-
inline explicit TlsConfiguration(TlsClientConfiguration client)
Create a client-only profile.
- Parameters:
client – Complete client configuration.
-
inline explicit TlsConfiguration(TlsServerConfiguration server)
Create a server-only profile.
- Parameters:
server – Complete server configuration.
-
inline const std::optional<TlsClientConfiguration> &client() const noexcept
Get the optional client part.
-
inline void setClient(TlsClientConfiguration value)
Replace the client part without modifying the server part.
-
inline const std::optional<TlsServerConfiguration> &server() const noexcept
Get the optional server part.
-
inline void setServer(TlsServerConfiguration value)
Replace the server part without modifying the client part.
-
inline bool hasRole(TlsRole role) const
Test whether this profile contains the requested local role.
- Parameters:
role – A valid local TLS role.
- Returns:
Whether that role is present.
-
inline void clearRole(TlsRole role)
Remove one role without modifying the other.
- Parameters:
role – A valid local TLS role.
-
inline void merge(const TlsConfiguration &value)
Replace only the role parts supplied by another profile.
- Parameters:
value – The supplied replacement parts.
-
TlsConfiguration() = default
-
class TlsConfigurationEntry
One labeled TLS configuration parsed from an external representation.
Public Functions
-
inline TlsConfigurationEntry(text::String label, TlsConfiguration configuration) noexcept
Create one labeled TLS configuration entry.
- Parameters:
label – The validated registry label.
configuration – The complete TLS configuration.
-
inline const TlsConfiguration &configuration() const noexcept
Get the parsed TLS configuration.
-
inline TlsConfiguration takeConfiguration() noexcept
Move the parsed TLS configuration out of this entry.
-
inline TlsConfigurationEntry(text::String label, TlsConfiguration configuration) noexcept
-
class TlsConfigurationParser
Parse shared TLS settings and role-specific profile lists.
Public Functions
-
TlsConfigurationSet parse(const conf::ValuePtr §ionValue) const
Validate and load a complete TLS section without modifying the application registry.
- Parameters:
sectionValue – The optional TLS section; null produces the default empty configuration set.
- Throws:
conf::ConfError – If validation or referenced-material loading fails.
- Returns:
Owned shared settings and grouped role profiles.
Public Static Functions
-
static const conf::vr::RulesPtr &validationRules()
Access the compiled validation rules shared by all parser instances.
- Returns:
The immutable compiled rules for the complete TLS section.
-
TlsConfigurationSet parse(const conf::ValuePtr §ionValue) const
-
class TlsConfigurationResolution
One coherently resolved immutable TLS configuration.
Public Functions
-
TlsConfigurationResolution() = default
Create an empty resolution.
-
inline TlsConfigurationResolution(text::String requestedLabel, text::String matchedLabel, TlsConfigurationConstPtr configuration, TlsRole role, std::optional<X509TlsCertificatePolicy> policy) noexcept
Create a successful resolution.
- Parameters:
requestedLabel – The label originally requested.
matchedLabel – The exact profile or built-in default selected by fallback.
role – The selected local role.
policy – The effective certificate policy.
configuration – The immutable configuration snapshot.
-
inline const text::String &requestedLabel() const noexcept
Get the label originally requested by the caller.
-
inline const text::String &matchedLabel() const noexcept
Get the exact profile label or empty built-in default label selected by fallback resolution.
-
inline const TlsConfigurationConstPtr &configuration() const noexcept
Get the immutable configuration snapshot.
-
inline const std::optional<X509TlsCertificatePolicy> &certificatePolicy() const noexcept
Get the effective certificate policy, absent when client authentication is disabled.
-
TlsConfigurationResolution() = default
-
class TlsConfigurationSet
Owned shared settings and named profiles published as one TLS registry update.
Public Functions
-
inline const TlsSettings &settings() const noexcept
Get shared settings.
-
inline void setSettings(TlsSettings value)
Replace shared settings.
-
inline const std::vector<TlsConfigurationEntry> &entries() const noexcept
Get the named profiles.
-
inline void add(text::String label, TlsConfiguration configuration)
Append a named profile; publication validates labels, duplicates, and roles.
- Parameters:
label – Nonempty application label.
configuration – The supplied role parts.
-
inline const TlsSettings &settings() const noexcept
-
class TlsIdentity
One immutable role-neutral TLS certificate chain and opaque software or native signer.
Matching follows RFC 8410 for Ed25519, RFC 5480 for P-256, and RFC 3279/RFC 4055 for RSA. Signature-scheme selection follows RFC 8446 section 4.2.3 in the peer-provided order and never permits certificate-only PKCS#1 schemes. The identity owns the move-only key; configurations share it only through a pointer to const.
See: TLS Support
Public Functions
-
TlsIdentity(X509CertificateBundle certificateChain, SigningPrivateKey signingKey)
Create a validated software identity usable in either TLS role.
- Parameters:
certificateChain – The leaf-first certificate chain. Must not be empty, and its leaf public key must match
signingKey.signingKey – The matching private key. Must not be empty and must support a usable TLS 1.3 signature scheme.
- Throws:
CryptologyError – If the certificate and key do not match or support no TLS 1.3 signature scheme.
-
auto selectSignatureScheme(const util::List<TlsSignatureScheme> &offeredSchemes) const noexcept -> std::optional<TlsSignatureScheme>
Select the first peer-offered scheme compatible with this identity.
- Parameters:
offeredSchemes – ClientHello or CertificateRequest
signature_algorithmsvalues in wire order.- Returns:
The first compatible TLS 1.3
CertificateVerifyscheme, or no value.
-
inline const X509CertificateBundle &certificateChain() const noexcept
Get the leaf-first certificate chain.
-
bool isNative() const noexcept
Test whether the private key remains in a native provider.
-
auto signTlsCertificateVerify(TlsSignatureScheme scheme, mem::ConstByteSpan message) const -> mem::ByteBlock
Sign RFC 8446 section 4.4.3 content using the owned provider; native operations may block.
- Parameters:
scheme – A compatible TLS CertificateVerify scheme.
message – Complete CertificateVerify content.
- Throws:
CryptologyError – If signing, provider access, or the signature fault check fails.
- Returns:
The verified signature, without exposing private key material.
-
TlsIdentity(X509CertificateBundle certificateChain, SigningPrivateKey signingKey)
-
enum class erbsland::cryptology::TlsRole : uint8_t
The local role used to select a TLS profile.
Values:
-
enumerator Client
Initiate a connection and authenticate a server.
-
enumerator Server
Accept a connection and optionally authenticate a client.
-
enumerator Client
-
class TlsServerConfiguration
The independent server part of an application TLS profile.
Public Functions
-
TlsServerConfiguration() = default
Create an incomplete server configuration requiring an identity before registration.
-
inline explicit TlsServerConfiguration(TlsIdentity identity)
Create a server configuration with client authentication disabled.
- Parameters:
identity – The explicitly selected server identity.
-
inline const TlsTrustConfiguration &trust() const noexcept
Get profile trust settings.
-
inline void setTrust(TlsTrustConfiguration value)
Replace profile trust settings.
-
inline const TlsIdentityConstPtr &identity() const noexcept
Get the explicitly selected certificate identity, or null when absent.
-
inline void setIdentity(TlsIdentity value)
Set the certificate identity.
-
inline void setIdentity(TlsIdentityConstPtr value)
Share an immutable certificate identity.
-
inline TlsClientAuthentication clientAuthentication() const noexcept
Get the client certificate authentication requirement.
-
inline void setClientAuthentication(TlsClientAuthentication value) noexcept
Set the client certificate authentication requirement.
-
TlsServerConfiguration() = default
-
class TlsSettings
Shared settings captured with an application TLS configuration set.
Public Functions
-
inline std::optional<bool> systemTrust() const noexcept
Get the shared trust selection, or no value for role defaults.
-
inline void setSystemTrust(std::optional<bool> value) noexcept
Set the shared trust selection; no value restores role defaults.
-
inline bool allowsTrustNetwork() const noexcept
Test whether native trust evaluation may retrieve certificates and revocation information.
-
inline void setTrustAllowNetwork(bool value) noexcept
Set native trust retrieval permission.
-
inline const path::Path &trustBundlePath() const noexcept
Get the Linux system trust bundle override.
-
inline bool allowsIdentityInteraction() const noexcept
Test whether loading and using native identities may display authorization dialogs.
-
inline void setIdentityAllowInteraction(bool value) noexcept
Set permission captured when native identities are loaded.
-
inline std::optional<bool> systemTrust() const noexcept
-
class TlsSignatureScheme
A supported TLS 1.3 signature scheme.
Code points and their permitted uses follow RFC 8446 section 4.2.3. The PKCS#1 v1.5 schemes are retained only for signatures appearing in certificates and are never allowed for TLS 1.3
CertificateVerifymessages. All values describe public verification inputs; this type creates and retains no secret state requiring erasure.See: X.509 Certificates
Public Types
-
enum Value
The supported RFC 8446 SignatureScheme values.
Values:
-
enumerator RsaPkcs1Sha256
Certificate-only RSASSA-PKCS1-v1_5 with SHA-256.
-
enumerator RsaPkcs1Sha384
Certificate-only RSASSA-PKCS1-v1_5 with SHA-384.
-
enumerator RsaPkcs1Sha512
Certificate-only RSASSA-PKCS1-v1_5 with SHA-512.
-
enumerator EcdsaSecp256r1Sha256
ECDSA with P-256 and SHA-256.
-
enumerator EcdsaSecp384r1Sha384
ECDSA with P-384 and SHA-384.
-
enumerator RsaPssRsaeSha256
RSASSA-PSS/SHA-256 with an rsaEncryption public key.
-
enumerator RsaPssRsaeSha384
RSASSA-PSS/SHA-384 with an rsaEncryption public key.
-
enumerator RsaPssRsaeSha512
RSASSA-PSS/SHA-512 with an rsaEncryption public key.
-
enumerator Ed25519
Pure Ed25519.
-
enumerator RsaPssPssSha256
RSASSA-PSS/SHA-256 with an id-RSASSA-PSS public key.
-
enumerator RsaPssPssSha384
RSASSA-PSS/SHA-384 with an id-RSASSA-PSS public key.
-
enumerator RsaPssPssSha512
RSASSA-PSS/SHA-512 with an id-RSASSA-PSS public key.
-
enumerator RsaPkcs1Sha256
Public Functions
-
constexpr TlsSignatureScheme() noexcept = default
Create the mandatory-to-implement RSA-PSS-RSAE/SHA-256 scheme.
-
inline constexpr TlsSignatureScheme(const Value value) noexcept
Create a scheme from its supported raw value.
- Parameters:
value – The supported raw scheme value.
-
bool isAllowedForCertificateVerify() const noexcept
Test whether this scheme may verify a TLS 1.3
CertificateVerifysignature.
-
bool isAllowedForCertificateSignature() const noexcept
Test whether this scheme may describe a signature appearing in an X.509 certificate.
-
inline constexpr uint16_t toRawValue() const noexcept
Get the exact unsigned 16-bit TLS wire value.
-
X509AlgorithmIdentifier signatureAlgorithmIdentifier() const
Map this scheme to the complete X.509 signature AlgorithmIdentifier.
Public Static Functions
-
static std::optional<TlsSignatureScheme> fromRawValue(uint16_t value) noexcept
Parse one supported unsigned 16-bit TLS wire value.
- Parameters:
value – The raw wire value.
- Returns:
The matching scheme, or no value when unsupported.
-
static TlsSignatureScheme fromRawValueOrThrow(uint16_t value)
Parse one supported unsigned 16-bit TLS wire value.
- Parameters:
value – The raw wire value.
- Throws:
err::ParseError – If the value is not supported.
- Returns:
The matching scheme.
-
enum Value
-
class TlsTrustConfiguration
A profile trust selection resolved against shared TLS settings.
Public Functions
-
TlsTrustConfiguration() = default
Create a trust configuration inheriting application and role defaults.
-
inline explicit TlsTrustConfiguration(X509CertificateBundle anchors, X509CertificateBundle intermediates = {})
Create an explicit-anchor trust configuration.
- Parameters:
anchors – Trusted root or directly trusted leaf certificates.
intermediates – Untrusted issuer candidates.
-
inline std::optional<bool> systemTrust() const noexcept
Get the profile override, or no value for inherited selection.
-
inline void setSystemTrust(std::optional<bool> value) noexcept
Set the profile override.
-
inline const X509CertificateBundle &trustAnchors() const noexcept
Get explicit anchors.
-
inline void setTrustAnchors(X509CertificateBundle value)
Set explicit anchors, implicitly selecting explicit trust unless overridden.
-
inline const X509CertificateBundle &intermediates() const noexcept
Get additional untrusted intermediate certificates.
-
inline void setIntermediates(X509CertificateBundle value)
Set additional untrusted intermediate certificates.
-
inline auto resolve(const TlsSettings &settings, TlsRole role, bool required = true) const -> std::optional<X509TlsCertificatePolicy>
Resolve a complete policy without native work or file access.
- Parameters:
settings – Shared application settings.
role – Local connection role.
required – Whether a usable trust source is required.
- Throws:
CryptologyError – If trust settings conflict or required trust is missing.
- Returns:
The effective policy, or no policy when verification is disabled.
-
TlsTrustConfiguration() = default
-
enum class erbsland::cryptology::TlsRecordContentType : uint8_t
An authenticated TLS 1.3 inner-plaintext content type from RFC 8446 sections 5.1 and 5.2.
Values:
-
enumerator Alert
One TLS alert message.
-
enumerator Handshake
One or more TLS handshake-message fragments.
-
enumerator ApplicationData
Opaque application data.
-
enumerator Alert
-
class TlsRecordDecryptor
A move-only TLS 1.3 record decryptor implementing RFC 8446 sections 5.2—5.5 and 7.2—7.3.
It authenticates one complete TLSCiphertext record before returning sensitive plaintext. Any malformed record, authentication failure, overflow, or exhausted key makes this state terminal and erases all retained secrets.
See: TLS Support
Public Functions
-
TlsRecordDecryptor() noexcept
Create an empty record-decryptor placeholder.
-
TlsRecordDecryptor(TlsCipherSuite suite, TlsTrafficSecret &&trafficSecret)
Create RFC 8446 Sections 5.3 and 7.3 receiving state by consuming a matching traffic secret.
- Parameters:
trafficSecret – The traffic secret to consume. Its hash algorithm must match the cipher suite.
suite – The selected TLS cipher suite.
- Throws:
CryptologyError – If key derivation or protected storage fails.
-
~TlsRecordDecryptor()
Securely erase record-protection state.
-
TlsRecordPlaintext unprotect(mem::ConstByteSpan record)
Authenticate and deprotect one exact complete TLS 1.3 record under RFC 8446 Sections 5.2—5.5.
- Parameters:
record – The complete five-byte header and encrypted body.
- Throws:
TlsRecordError – For malformed, unauthenticated, overflowing, or exhausted input.
CryptologyError – If the cryptographic backend fails independently of peer authentication.
- Returns:
Authenticated sensitive content and its inner content type.
-
void updateApplicationTrafficKeys()
Derive and install the next application traffic-secret generation under RFC 8446 Sections 4.6.3 and 7.2.
The caller must invoke this only after authenticating the RFC 8446 section 4.6.3 KeyUpdate message.
-
void secureErase() noexcept
Securely erase all retained secret state and restore the empty state.
-
inline bool isEmpty() const noexcept
Test whether no record-protection state is retained.
-
bool isKeyUpdateRequired() const noexcept
Test the RFC 8446 Section 5.5 signal that the peer should update before more application data.
-
TlsCipherSuite suite() const
Get the configured cipher suite.
This decryptor must not be empty.
-
TlsRecordDecryptor() noexcept
-
class TlsRecordEncryptor
A move-only TLS 1.3 record encryptor implementing RFC 8446 sections 5.2—5.5 and 7.2—7.3.
It constructs complete TLSCiphertext records, maintains one sending sequence, enforces key-usage limits, and keeps traffic secrets protected outside scoped derivation. Padding length is explicit; no padding policy is implied.
See: TLS Support
Public Functions
-
TlsRecordEncryptor() noexcept
Create an empty record-encryptor placeholder.
-
TlsRecordEncryptor(TlsCipherSuite suite, TlsTrafficSecret &&trafficSecret)
Create RFC 8446 Sections 5.3 and 7.3 sending state by consuming a matching traffic secret.
- Parameters:
trafficSecret – The traffic secret to consume. Its hash algorithm must match the cipher suite.
suite – The selected TLS cipher suite.
- Throws:
CryptologyError – If key derivation or protected storage fails.
-
~TlsRecordEncryptor()
Securely erase record-protection state.
-
auto protect(TlsRecordContentType type, mem::ConstByteSpan content, unit::ByteCount paddingLength = unit::ByteCount::zero()) -> mem::ByteBlock
Protect one complete TLS 1.3 record under RFC 8446 Sections 5.2—5.5.
- Parameters:
type – The authenticated inner content type. Must be Alert, Handshake, or ApplicationData.
content – The exact content bytes. Must contain at most 16,384 bytes; only ApplicationData may be empty.
paddingLength – The number of zero padding octets. Content plus padding must contain at most 16,384 bytes.
- Throws:
TlsRecordError – If key usage is exhausted.
CryptologyError – If encryption fails.
- Returns:
A complete TLSCiphertext header and encrypted body.
-
void updateApplicationTrafficKeys()
Derive and install the next application traffic-secret generation under RFC 8446 Sections 4.6.3 and 7.2.
The caller must invoke this only at the RFC 8446 section 4.6.3 protocol transition.
-
void secureErase() noexcept
Securely erase all retained secret state and restore the empty state.
-
inline bool isEmpty() const noexcept
Test whether no record-protection state is retained.
-
bool isKeyUpdateRequired() const noexcept
Test the RFC 8446 Section 5.5 signal for sending KeyUpdate before more application data.
-
TlsCipherSuite suite() const
Get the configured cipher suite.
This encryptor must not be empty.
-
TlsRecordEncryptor() noexcept
-
class TlsRecordError : public erbsland::err::RuntimeError
A categorized failure from TLS 1.3 record protection or deprotection.
Categories preserve the RFC 8446 alert distinction required by sections 5 and 6 without coupling cryptology to network alert serialization.
See: TLS Support
Public Functions
-
TlsRecordError(TlsRecordErrorCategory category, text::String reason) noexcept
Create a categorized record error.
-
inline TlsRecordErrorCategory category() const noexcept
Get the stable failure category.
-
TlsRecordError(TlsRecordErrorCategory category, text::String reason) noexcept
-
enum class erbsland::cryptology::TlsRecordErrorCategory : uint8_t
A stable TLS 1.3 record-protection failure category.
Values:
-
enumerator DecodeError
The complete record framing or encoded length is malformed.
-
enumerator UnexpectedMessage
The outer or authenticated inner record semantics are invalid.
-
enumerator BadRecordMac
AEAD authentication or decryption failed.
-
enumerator RecordOverflow
A ciphertext or authenticated plaintext exceeds its RFC bound.
-
enumerator KeyUsageExhausted
The sequence number or cipher-specific record limit is exhausted.
-
enumerator DecodeError
-
class TlsRecordPlaintext
Authenticated content recovered from one TLS 1.3 record.
The content type is the final nonzero TLSInnerPlaintext octet from RFC 8446 section 5.2. Content is retained in sensitive storage and is never constructed until AEAD authentication succeeds.
See: TLS Support
Public Functions
-
TlsRecordPlaintext(TlsRecordContentType type, mem::ByteBlock content) noexcept
Create authenticated record content.
-
~TlsRecordPlaintext()
Securely erase retained plaintext.
-
void secureErase() noexcept
Securely erase content and restore an empty payload.
-
inline bool isEmpty() const noexcept
Test whether the authenticated content is empty.
-
inline TlsRecordContentType type() const noexcept
Get the authenticated inner content type.
-
TlsRecordPlaintext(TlsRecordContentType type, mem::ByteBlock content) noexcept
-
class TlsTrafficSecret
A move-only TLS 1.3 traffic secret retained in application-protected storage.
The secret length is the selected SHA-256 or SHA-384 digest length required by RFC 8446 sections 7.1—7.3. There is no public plaintext accessor; record protection resolves the secret only for scoped derivation and erasure.
See: TLS Support
Public Functions
-
TlsTrafficSecret() noexcept = default
Create an empty traffic-secret placeholder.
-
~TlsTrafficSecret()
Securely erase the protected envelope.
-
void secureErase() noexcept
Securely erase the protected envelope and restore the empty state.
-
inline bool isEmpty() const noexcept
Test whether no traffic secret is stored.
-
inline HashAlgorithm hashAlgorithm() const noexcept
Get the traffic-secret hash algorithm.
Public Static Functions
-
static TlsTrafficSecret fromBytes(HashAlgorithm algorithm, mem::ConstByteSpan data)
Protect a copy of RFC 8446 Sections 7.1—7.3 exact digest-sized traffic-secret bytes.
The caller retains ownership and erasure responsibility for the borrowed bytes.
- Parameters:
algorithm – The traffic-secret hash algorithm. Must be SHA-256 or SHA-384.
data – The traffic-secret bytes. Length must equal the selected hash digest size.
- Throws:
err::OutOfRangeError – If the secret length does not match the selected hash digest size.
-
static TlsTrafficSecret fromBytes(HashAlgorithm algorithm, mem::ByteBlock &&data)
Protect and then erase an owning RFC 8446 Sections 7.1—7.3 exact digest-sized traffic-secret block.
- Parameters:
algorithm – The traffic-secret hash algorithm. Must be SHA-256 or SHA-384.
data – The traffic-secret block to erase after protection. Length must equal the selected hash digest size.
- Throws:
err::OutOfRangeError – If the secret length does not match the selected hash digest size.
-
TlsTrafficSecret() noexcept = default