Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/std/tls/index.nct

index.nct

//! Authenticated TLS client byte streams.
//!
//! `TlsStream` uses the operating system trust store, verifies the requested server name, requires
//! TLS 1.2 or newer, and preserves the same unique stream ownership and timeout model as TCP.

use /io.{Reader, Writer}
use /net.{SocketAddress, TcpShutdown}
use /time.Duration
see ./trust_anchor.nct
see ./stream.nct
see ./async_stream.nct

/// One uniquely owned authenticated TLS client byte stream.
pub struct TlsStream

/// One owned DER certificate added to, rather than substituted for, the system trust store.
pub struct TrustAnchor

construct TrustAnchor {
    /// Copies one non-empty DER-encoded X.509 certificate.
    pub func from_der(certificate: &[u8]): Self!
}

instance TrustAnchor {
    pub(/) noalloc method &self.bytes(): &[u8] from self
}

construct TlsStream {
    /// Resolves `host` and connects to the first authenticated address in system order.
    pub func connect(host: &str, port: u16): Self!

    /// Resolves and authenticates candidates without restarting `timeout` for each address.
    pub func connect_with_timeout(host: &str, port: u16, timeout: Duration): Self!

    /// Authenticates with the system trust store plus one caller-supplied root certificate.
    pub func connect_with_trust_anchor(
        host: &str,
        port: u16,
        trust_anchor: &TrustAnchor,
    ): Self!

    /// Authenticates with an additional root without restarting the fixed timeout per address.
    pub func connect_with_trust_anchor_and_timeout(
        host: &str,
        port: u16,
        trust_anchor: &TrustAnchor,
        timeout: Duration,
    ): Self!
}

/// Resolves synchronously, then authenticates candidates without blocking the executor thread.
pub func connect_async(host: &str, port: u16): (async TlsStream!)!

/// Resolves synchronously, then authenticates candidates before one fixed timeout.
pub func connect_async_with_timeout(
    host: &str,
    port: u16,
    timeout: Duration,
): (async TlsStream!)!

/// Resolves synchronously, then authenticates asynchronously with one additional root.
pub func connect_async_with_trust_anchor(
    host: &str,
    port: u16,
    trust_anchor: &TrustAnchor,
): (async TlsStream!)!

/// Authenticates asynchronously with an additional root before one fixed timeout.
pub func connect_async_with_trust_anchor_and_timeout(
    host: &str,
    port: u16,
    trust_anchor: &TrustAnchor,
    timeout: Duration,
): (async TlsStream!)!

/// Opens one package-internal TLS stream that requires negotiated HTTP/1.1.
pub(/) func connect_http1(host: &str, port: u16): TlsStream!

/// Opens one package-internal HTTP/1.1 TLS stream before a fixed timeout.
pub(/) func connect_http1_with_timeout(
    host: &str,
    port: u16,
    timeout: Duration,
): TlsStream!

/// Opens one package-internal HTTP/1.1 stream with an additional trust root.
pub(/) func connect_http1_with_trust_anchor(
    host: &str,
    port: u16,
    trust_anchor: &TrustAnchor,
): TlsStream!

/// Opens one package-internal custom-trust HTTP/1.1 stream before a fixed timeout.
pub(/) func connect_http1_with_trust_anchor_and_timeout(
    host: &str,
    port: u16,
    trust_anchor: &TrustAnchor,
    timeout: Duration,
): TlsStream!

/// Resolves immediately and returns one package-internal HTTP/1.1 TLS computation.
pub(/) func connect_http1_async(host: &str, port: u16): (async TlsStream!)!

/// Resolves immediately and authenticates HTTP/1.1 TLS before a fixed timeout.
pub(/) func connect_http1_async_with_timeout(
    host: &str,
    port: u16,
    timeout: Duration,
): (async TlsStream!)!

/// Returns one package-internal HTTP/1.1 computation with an additional trust root.
pub(/) func connect_http1_async_with_trust_anchor(
    host: &str,
    port: u16,
    trust_anchor: &TrustAnchor,
): (async TlsStream!)!

/// Returns one custom-trust HTTP/1.1 computation bounded by a fixed timeout.
pub(/) func connect_http1_async_with_trust_anchor_and_timeout(
    host: &str,
    port: u16,
    trust_anchor: &TrustAnchor,
    timeout: Duration,
): (async TlsStream!)!

instance TlsStream {
    impl Reader
    impl Writer

    /// Returns the effective local socket address.
    pub noalloc method &self.local_address(): SocketAddress!

    /// Returns the authenticated peer socket address.
    pub noalloc method &self.peer_address(): SocketAddress!

    /// Replaces the read timeout; absence permits an unlimited wait.
    pub noalloc method &+self.set_read_timeout(timeout: Duration?): void

    /// Returns the configured read timeout.
    pub noalloc method &self.read_timeout(): Duration?

    /// Replaces the write timeout; absence permits an unlimited wait.
    pub noalloc method &+self.set_write_timeout(timeout: Duration?): void

    /// Returns the configured write timeout.
    pub noalloc method &self.write_timeout(): Duration?

    /// Shuts down selected local stream directions.
    pub noalloc method &+self.shutdown(direction: TcpShutdown): void!

    /// Cancels provider progress and releases the stream exactly once.
    pub noalloc method &+self.close(): void

    /// Reads one decrypted provider chunk without blocking the executor thread.
    pub method &+self.read_async(buffer: &+[u8]): async usize!

    /// Reads asynchronously until the fixed relative timeout expires.
    pub method &+self.read_async_with_timeout(
        buffer: &+[u8],
        timeout: Duration,
    ): async usize!

    /// Sends the complete plaintext view without blocking the executor thread.
    pub method &+self.write_async(bytes: &[u8]): async void!

    /// Sends asynchronously until completion or the fixed relative timeout expires.
    pub method &+self.write_async_with_timeout(
        bytes: &[u8],
        timeout: Duration,
    ): async void!
}