ddn.api.net.tls

DDN TLS API.

This module provides interfaces for TLS (Transport Layer Security) connections. Implementations may be provided by:

  • Pure D implementation (ddn-tls-native)
  • OpenSSL backend (ddn-tls-openssl)
  • GnuTLS backend (ddn-tls-gnutls)

Example:

import ddn.api.net.tls;

// Create context (implementation-specific factory)
auto ctx = createTlsContext();
ctx.trustStore.loadSystemCerts();
ctx.setMinVersion(TlsVersion.TLS_1_2);

// Create client stream
auto stream = ctx.clientStream(transport, "example.com");
stream.handshake();

// Use the encrypted stream
stream.write(cast(const(ubyte)[])"Hello, TLS!");

Types 25

TLS protocol versions.

TLS_1_2
TLS_1_3

TLS connection role.

CLIENT
SERVER

TLS handshake state.

Distinguishes between different lifecycle stages of a TLS connection.

NOT_STARTEDHandshake has not been initiated
IN_PROGRESSHandshake is in progress (may need multiple calls for non-blocking I/O)
COMPLETEHandshake completed successfully
FAILEDHandshake failed (connection unusable)
SHUTDOWNConnection was gracefully shut down after successful handshake

Certificate verification mode. Peer certificate verification mode.

Normative default: contexts start in REQUIRED mode for clients and NONE mode for servers; implementations MUST use these defaults when setVerifyMode is never called, so no backend can silently ship an unverified client connection.

NONEDo not verify peer certificate (insecure, use only for testing)
OPTIONALVerify peer certificate if presented
REQUIREDRequire and verify peer certificate
enumIoResult : ptrdiff_t

Result of a non-blocking I/O operation.

WOULD_BLOCK = - 1Operation would block, try again later
CLOSED = - 2Connection closed by peer (mid-stream closure, not clean EOF)
ERROR = - 3An error occurred

Progress indicator for non-blocking TLS operations.

Every potentially-blocking operation returns TlsProgress instead of blocking. The caller checks the result and re-drives the operation when I/O is possible.

DONEOperation completed successfully
NEED_READNeed to read from the transport before continuing
NEED_WRITENeed to write to the transport before continuing
NEED_IONeed to read or write (both possible)
ERRORA fatal error occurred; connection must be closed
structTlsError

Typed error information for non-blocking TLS operations.

Used by TlsResult and TlsStream.lastError to report errors without throwing exceptions. This is the preferred error reporting mechanism for non-blocking I/O.

Fields
TlsErrorType typeThe error category
ubyte alertDescriptionAlert description (valid when type == ALERT_RECEIVED or ALERT_SENT). TLS alerts are single-byte values (0-255) as per RFC 5246/8446.
string messageHuman-readable error message
Methods
bool isNone() const pure nothrow @safe @nogcReturns: true if no error has occurred.
Nested Templates
TlsErrorTypeCategories of TLS errors.
structTlsResult

Result of a TLS read or write operation.

Combines byte count with progress information and optional error details. The eof field distinguishes between "no data yet" (bytes=0, eof=false) and "connection closed" (bytes=0, eof=true).

Fields
ptrdiff_t bytesBytes transferred (positive), or 0 on EOF/error
TlsProgress progressProgress indicator
TlsError errorError details (valid when progress == ERROR)
bool eofTrue when the peer closed the connection gracefully (received close_notify).
Methods
bool done() const pure nothrow @safe @nogcContract for "no data": a read that produced nothing because the stream is idle returns `NEED_READ` — never `DONE` with zero bytes. `DONE` with `bytes == 0` unambiguously means EOF, which is also...
bool wouldBlock() const pure nothrow @safe @nogcReturns: true if the caller should retry after I/O readiness.
bool isEof() const pure nothrow @safe @nogcReturns: true if EOF was reached (peer closed connection gracefully).

Opaque handle for event loop registration.

Abstracts platform differences (POSIX fd, Windows SOCKET, etc.) so that TLS code remains platform-agnostic.

Methods
bool isValid() const pure nothrow @safe @nogcReturns: true if this handle is valid and can be registered.

Common TLS cipher suites for type-safe configuration.

Use setCipherSuites() with these enum values for compile-time checking. For custom or unlisted cipher suites, use setCipherSuiteStrings().

TLS_AES_128_GCM_SHA256
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
classTlsException : Exception

Base exception for TLS-related errors.

Constructors
this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)Constructs a TLS exception.

Exception thrown when the TLS handshake fails.

Constructors
this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)Constructs a TLS handshake exception.

Exception for certificate verification failures in throwing (blocking) API layers. The non-blocking stream API reports the same condition as TlsProgress.ERROR with TlsError.type == CERTIFICATE_ERROR.

Constructors
this(string msg, string file = __FILE__, size_t line = __LINE__, Throwable next = null)Constructs a TLS certificate exception.

Exception thrown when a TLS alert is received.

Fields
ubyte alertLevelThe TLS alert level (1 = warning, 2 = fatal)
ubyte alertDescriptionThe TLS alert description code
Constructors
this(string msg, ubyte level, ubyte description, string file = __FILE__, size_t line = __LINE__, Throwable next = null)Constructs a TLS alert exception.
interfaceTlsTransport

Abstract transport layer for TLS.

This interface abstracts the underlying byte stream (TCP socket, memory buffer, pipe, etc.) that TLS operates over. Implementations wrap the actual I/O mechanism.

This separation allows:

  • Testing TLS logic without real network I/O
  • Using TLS over different transport mechanisms
  • Implementing non-blocking I/O patterns

Return Value Convention:

  • Positive value: Number of bytes read/written
  • Zero (0): Clean end-of-file (EOF) - peer closed connection gracefully
  • Negative value: IoResult enum indicating error condition
Methods
ptrdiff_t read(ubyte[] buffer)Reads raw bytes from the underlying transport.
ptrdiff_t write(const(ubyte)[] data)Writes raw bytes to the underlying transport.
void flush()Flushes any buffered output data.
void close()Closes the underlying transport.
bool isOpen() @property const;Returns: Whether the transport is still open.
PollHandle pollHandle() @property const;Returns a handle suitable for event loop registration.

Represents an X.509 certificate for TLS operations.

Note

This interface is named TlsCertificate to avoid collision with the

planned ddn.api.crypto.cert.Certificate type from the X.509 module (PLAN3.md T3). Once the crypto certificate module is complete, this interface may be deprecated in favor of the unified certificate type.

Methods
string subjectCommonName() @property const;Returns: The certificate's subject common name (CN). May be empty if the certificate has no CN (use subjectDn() instead).
string issuerCommonName() @property const;Returns: The certificate's issuer common name (CN). May be empty if the issuer has no CN (use issuerDn() instead).
string subjectDn() @property const;Returns: Full subject distinguished name as RFC 4514 string. Example: "CN=example.com,O=Example Inc,C=US"
string issuerDn() @property const;Returns: Full issuer distinguished name as RFC 4514 string.
string[] subjectAltNames() @property const;Returns: The certificate's subject alternative names (SANs). These are typically DNS names or IP addresses.
string serialNumber() @property const;Returns: The certificate's serial number as a hex string.
long notBefore() @property const;Returns the certificate's "not before" validity timestamp.
long notAfter() @property const;Returns the certificate's "not after" validity timestamp.
bool isTimeValid() @property const;Checks if the certificate is valid at the current time.
bool isTimeValidAt(long atTime) const;Checks if the certificate is valid at a specific time.
string keyAlgorithm() @property const;Returns: Public key algorithm (e.g., "RSA", "ECDSA", "Ed25519").
size_t keySize() @property const;Returns: Public key size in bits.
string fingerprintSha256() @property const;Returns: SHA-256 fingerprint as colon-separated hex string. Example: "A1:B2:C3:..."
string[] extendedKeyUsage() @property const;Returns: Extended Key Usage OIDs (e.g., "1.3.6.1.5.5.7.3.1" for serverAuth).
bool isCa() @property const;Returns: Whether the Basic Constraints extension marks this as a CA certificate.
int pathLengthConstraint() @property const;Returns: Path length constraint from Basic Constraints, or -1 if absent.
const(ubyte)[] toDer() const;Returns: The DER-encoded certificate bytes.
string toPem() const;Returns: The PEM-encoded certificate string.
  • Represents a chain of certificates.
  • The first certificate is the end-entity (leaf) certificate, /
  • Represents a certificate chain as presented by a peer.
  • The getters are deliberately not const: inside a const method stored
  • interface references become const and cannot be returned as mutable
  • references without unsafe casts. Implementations return the live objects.
  • Chains obtained during verification must be treated as read-only by
  • convention. *
  • Certificates are ordered leaf-first, as received: the leaf certificate is
  • followed by intermediate certificates, and optionally the root CA.
Methods
TlsCertificate leafCertificate() @propertyReturns: The end-entity (leaf) certificate.
TlsCertificate[] certificates() @propertyReturns: All certificates in the chain.
size_t length() @property const;Returns: The number of certificates in the chain.
interfaceTlsTrustStore

Certificate store for trusted CA certificates.

Methods
void addCertificate(TlsCertificate cert)Adds a trusted CA certificate.
void addFromPem(const(char)[] pemData)Adds certificates from PEM-encoded data (may contain multiple certs).
void addFromDer(const(ubyte)[] derData)Adds certificates from a DER-encoded certificate.
void loadSystemCerts()Loads the system's default trusted CA certificates.
size_t length() @property const;Returns: The number of trusted certificates.
interfaceTlsSession

Represents a resumable TLS session.

Sessions can be cached and reused to speed up subsequent connections to the same server by skipping the full handshake.

Methods
const(ubyte)[] sessionId() @property const;Returns: An opaque session identifier.
const(ubyte)[] sessionTicket() @property const;Returns: The session ticket data (for TLS 1.3 resumption).
long expirationTime() @property const;Returns: The Unix timestamp when this session expires.
bool isValid() @property const;Returns: Whether the session is still valid for resumption.
ubyte[] serialize() const;Serializes the session for external storage.

Cache for storing and retrieving TLS sessions.

Security Considerations: Implementations should:

  • Limit the maximum number of cached sessions to prevent memory exhaustion from attackers flooding the server with session resumption attempts.
  • Implement an eviction policy (e.g., LRU - Least Recently Used) when the limit is reached.
  • Periodically call pruneExpired() to remove stale sessions.

    See Also

    RECOMMENDED_MAX_SIZE for suggested default cache size.
Fields
size_t RECOMMENDED_MAX_SIZERecommended default maximum cache size for implementations.
Methods
void store(string serverName, ushort port, TlsSession session)Stores a session for later resumption.
TlsSession retrieve(string serverName, ushort port)Retrieves a session for resumption.
void remove(string serverName, ushort port)Removes a session from the cache.
void pruneExpired()Removes all expired sessions from the cache.
void clear()Clears all sessions from the cache.

Information provided to the verification callback during handshake. Outcome of the standard (built-in) certificate verification that ran before a TlsVerifyCallback is invoked.

OKStandard verification succeeded
FAILEDStandard verification failed (the callback may still accept)
NOT_PERFORMEDStandard verification did not run (mode NONE or no certificates)
Fields
TlsCertificateChain chainThe peer's certificate chain
string hostnameThe hostname being verified (from SNI or clientStream argument)
TlsVersion negotiatedVersionThe negotiated TLS version
string cipherSuiteThe negotiated cipher suite
TlsVerifyResult standardVerificationOutcome of standard verification before this callback runs
aliasTlsVerifyCallback = bool delegate(scope ref const TlsVerifyInfo info) @safe

Callback delegate for custom certificate verification.

Called after standard verification (if any) completes, with its outcome in TlsVerifyInfo.standardVerification. The callback is invoked even when standard verification failed, so pin-auditing can observe every chain.

Override semantics: returning true ACCEPTS the connection even when standardVerification == FAILED (this is what enables self-signed and pinning flows — use deliberately); returning false always rejects, failing the handshake as TlsProgress.ERROR with a CERTIFICATE_ERROR lastError (the handshake itself never throws).

Use cases:

  • Certificate pinning (SHA-256 fingerprint, public key pinning)
  • Corporate proxy environments with custom CAs
  • Development environments with self-signed certificates
  • Audit logging of the full certificate chain
interfaceTlsStream

Encrypted TLS stream for reading and writing application data.

A TLS stream wraps an underlying transport and provides transparent encryption/decryption of data. The handshake must complete before application data can be exchanged.

Usage:

auto stream = context.clientStream(transport, "example.com");
stream.handshake();  // Perform TLS handshake
stream.write(cast(const(ubyte)[])"GET / HTTP/1.1\r\n\r\n");
ubyte[4096] buffer;
auto n = stream.read(buffer[]);
stream.close();

Methods
TlsProgress handshake()Performs or continues the TLS handshake.
TlsHandshakeState handshakeState() @property const;Returns: The current handshake state.
TlsResult read(ubyte[] buffer)Reads decrypted application data.
TlsResult write(const(ubyte)[] data)Writes application data (will be encrypted).
TlsProgress flush()Flushes any buffered data through the TLS layer.
TlsProgress shutdown()Initiates graceful TLS shutdown (sends close_notify).
TlsError lastError() @property const;Returns: The last error that occurred. Valid after any operation returns `TlsProgress.ERROR`.
bool isOpen() @property const;Returns: Whether the stream is open and handshake is complete.
bool isHandshakeComplete() @property const;Returns: Whether the handshake has completed successfully.
bool receivedCloseNotify() @property const;Returns: Whether a close_notify has been received from the peer.
void close()Closes the underlying transport immediately. For graceful shutdown, use `shutdown()` instead.
TlsVersion negotiatedVersion() @property const;Returns: The negotiated TLS protocol version. Only valid after handshake completes.
string cipherSuite() @property const;Returns: The negotiated cipher suite name. Only valid after handshake completes.
string alpnProtocol() @property const;Returns: The negotiated ALPN protocol, or null if none. Only valid after handshake completes.
TlsCertificateChain peerCertificates() @propertyReturns: The peer's certificate chain, or null if none presented. Only valid after handshake completes. Not `const` because a const method cannot hand out the stored mutable chain without casts.
TlsRole role() @property const;Returns: The role of this endpoint (client or server).
string serverName() @property const;Returns: The server name (SNI) for this connection. For clients, this is the name that was sent. For servers, this is the name received from the client.
TlsSession session() @propertyReturns: The current session for potential resumption. Only valid after handshake completes. Not `const` because a const method cannot hand out the stored mutable session without casts.
interfaceTlsContext

TLS context for configuring and creating TLS connections.

A context holds configuration that can be shared across multiple connections:

  • Certificate chain and private key (for servers, or client authentication)
  • Trusted CA certificates
  • Protocol version constraints
  • Cipher suite preferences

Contexts are typically created once and reused for many connections.

Methods
void setCertificateChain(const(char)[] pemData)Sets the certificate chain for this endpoint.
void setCertificateChainDer(const(ubyte[])[] derCertificates)Sets the certificate chain from DER-encoded certificates.
void setPrivateKey(const(char)[] pemData, const(char)[] password = null)Sets the private key for the certificate.
void setPrivateKeyDer(const(ubyte)[] derData, const(char)[] password = null)Sets the private key from DER-encoded data.
TlsTrustStore trustStore() @propertyReturns: The trust store for adding trusted CA certificates.
void setVerifyMode(TlsVerifyMode mode)Sets the certificate verification mode.
void setVerifyCallback(TlsVerifyCallback callback)Sets a custom peer verification callback.
void setMinVersion(TlsVersion ver)Sets the minimum TLS protocol version.
void setMaxVersion(TlsVersion ver)Sets the maximum TLS protocol version.
void setCipherSuites(const(TlsCipherSuite)[] cipherSuites)Sets the list of allowed cipher suites using type-safe enum values.
void setCipherSuiteStrings(const(string)[] cipherSuites)Sets the list of allowed cipher suites using string names.
void setSniEnabled(bool enabled)Enables or disables Server Name Indication (SNI) for clients.
void setAlpnProtocols(const(string)[] protocols)Sets Application-Layer Protocol Negotiation (ALPN) protocols.
void setSessionCache(TlsSessionCache cache)Sets a session cache for session resumption.
TlsSession deserializeSession(const(ubyte)[] data)Reconstructs a session from serialized bytes.
TlsStream clientStream(TlsTransport transport, string serverName)Creates a client-side TLS stream.
TlsStream serverStream(TlsTransport transport)Creates a server-side TLS stream.