Traversio

Implemented Features

A concrete feature matrix for the Traversio library.

Overview

The table below summarizes the current Traversio feature surface.

AreaSupportedDeferred / Missing
Transport and wireIdentification exchange, binary framing, encrypted packets for aes128-ctr / aes256-ctr with HMAC-SHA-2 and OpenSSH ETM or UMAC MACs, OpenSSH [email protected] / [email protected], OpenSSH [email protected], RFC 4253 zlib plus OpenSSH delayed [email protected] compression when explicitly requested, OpenSSH strict-kex sequencing and NEWKEYS sequence-number reset handling, packet-threshold and idle-time automatic local rekey, post-auth idle keepalive, parser state across partial reads, Apple 26+ TCP transportBroader algorithm matrix, reconnect policy, hardened long-session validation
Key exchange and authSSH_MSG_KEXINIT, curve25519-sha256, [email protected], ecdh-sha2-nistp256, Ed25519/RSA SHA-2/ECDSA host-key verification, explicit opt-in legacy ssh-rsa host-key and RSA auth compatibility through SSHLegacyAlgorithmOptions, Ed25519 and ECDSA P-256 OpenSSH host-certificate verification, password auth, keyboard-interactive callbacks, Ed25519/RSA/ECDSA public-key auth, OpenSSH Ed25519/ECDSA/RSA key-file loading with optional bcrypt + AES passphrase decryption, and OpenSSH key-pair generation for the same public-key algorithmsBroader host-key coverage and agent-backed auth
Host trustExplicit trust policy, exact raw-key pinning, trusted key sets, first-seen and changed-key helpers with caller-owned persistence, async trust callbacks, and OpenSSH known_hosts loading for exact, wildcard, negated, hashed, CIDR, @revoked, and @cert-authority entries, including optional host/IP-aware lookup namesBuilt-in trust-store persistence, broader host-certificate algorithm coverage beyond today's Ed25519 and ECDSA P-256 paths
Exec and shellSession-channel open, pre-start SSH env requests, exec, PTY plus shell startup, explicit connection ownership, explicit shell close, write support, PTY resize through SSH window-change, signal delivery through SSH signal, remote exit-signal event exposure, shell and streamed-exec event delivery through nextEvent() and events, transcript collection plus events iteration with best-effort channel-close on cancellation, receive-window replenishment, remote-window-aware chunked writes, and concurrent session-channel use on one connectionBroader cancellation semantics and a broader terminal-control surface
SFTPVersion exchange, metadata, concurrent request-id-routed path and handle operations, path and handle attribute mutation, path and handle filesystem queries, public file handles, directory listing, file reads including bounded concurrent whole-file reads on one handle plus cumulative progress callbacks, whole-file writes with optional bounded concurrent request windows, resumable whole-file uploads from the current remote size, cumulative progress callbacks, and optional fsync, rename, remove, mkdir/rmdir, symlink, readlink, extension-aware [email protected] useBroader resumable transfer coverage, deeper transfer-engine tuning, broader extension coverage, hardened recovery
ForwardingTyped TCP/IP forwarding coders, a public raw direct-tcpip channel wrapper, a public forwarding event stream through nextEvent() / events, best-effort channel-close on events-iterator cancellation for raw TCP/IP channel wrappers, an Apple 26+ local-forwarding helper, an Apple 26+ local dynamic SOCKS helper, an Apple 26+ raw remote-forward listener, an Apple 26+ remote-forwarding bridge helper, outermost-hop SOCKS5 / HTTP CONNECT transport proxies through SSHClientConfiguration.connectionProxy, explicit proxyJumpHosts hop chaining in SSHClientConfiguration, live OpenSSH forwarding validation for raw, local, dynamic, remote-bridge data paths plus ProxyJump, and a local Docker proxy matrix for connectionProxy validationFinalized shutdown/lifecycle semantics, broader interoperability coverage, and any broader routing or mailbox/dispatcher layer beyond the current helper model
Diagnostics and loggingStable SSHClientError wrappers for connection and post-auth failures, negotiated transport snapshots including effective integrity reporting, remote disconnect/debug context, structured SSHClientLogHandler sinks, a built-in bounded SSHClientLogRecorder export helper, OSLog helpers for the public connection entry points, explicit setup/reply timeout mapping including keepalive timeout failures, and direct SSH-port latency measurement through SSHClient.measurePortLatency(host:port:options:)Broader long-running retention/redaction guidance, proxy-aware latency utilities, and any later stability guarantees for additional diagnostic detail

Authentication

Supported:

  • password authentication through .password(String)
  • generic keyboard-interactive authentication through .keyboardInteractive(submethods:responseProvider:)
  • Ed25519, RSA, and ECDSA public-key authentication through: .ed25519PrivateKey(rawRepresentation: [UInt8]), .rsaPrivateKey(pkcs1DERRepresentation: [UInt8]), .ecdsaP256PrivateKey(rawRepresentation: [UInt8]), .ecdsaP384PrivateKey(rawRepresentation: [UInt8]), .ecdsaP521PrivateKey(rawRepresentation: [UInt8]), try .ed25519PrivateKey(openSSHPrivateKey: String), try .ed25519PrivateKey(contentsOfOpenSSHPrivateKeyFile: String), try .rsaPrivateKey(openSSHPrivateKey: String), try .rsaPrivateKey(contentsOfOpenSSHPrivateKeyFile: String), try .ecdsaPrivateKey(openSSHPrivateKey: String), try .ecdsaPrivateKey(contentsOfOpenSSHPrivateKeyFile: String), and try SSHOpenSSHKeyPair.generate(...) with Ed25519, ECDSA P-256/P-384/P-521, or RSA
  • explicit per-connection and per-hop legacy RSA compatibility through SSHLegacyAlgorithmOptions.sshRSA, which appends ssh-rsa host-key negotiation and lets RSA auth retry the SHA-1 path when an older server still offers publickey

Deferred:

  • SSH agent support
  • keychain-backed credential loading or other product-owned credential stores

Transport profile:

Transport Algorithm Snapshot

This is the transport algorithm table for the documented implementation:

CategoryImplementedNotes
KexAlgorithmscurve25519-sha256, [email protected], ecdh-sha2-nistp256The initial proposal also advertises ext-info-c and [email protected], but those are OpenSSH/extension markers rather than real key-exchange methods. Rekey proposals omit those markers.
Ciphersaes128-ctr, aes256-ctr, [email protected], [email protected], [email protected]AES-CTR uses a separate MAC. OpenSSH AES-GCM and Chacha20-Poly1305 are AEAD paths.
MACs[email protected], [email protected], [email protected], [email protected], hmac-sha2-256, hmac-sha2-512, [email protected], [email protected]MAC negotiation matters only on the AES-CTR path. OpenSSH AES-GCM and Chacha20-Poly1305 do not use a separate negotiated MAC.
Compressionnone, zlib, [email protected]RFC 4253 zlib activates once encrypted transport is active after each key exchange. OpenSSH [email protected] waits until user authentication has completed.

Host Trust

Supported:

  • trust-any for disposable test environments and controlled tooling
  • exact single-key pinning
  • exact trusted key sets
  • trust-on-first-use helper with caller-owned load/store closures and compare-and-set store context
  • optional changed-key resolution through trustOnFirstUse(..., onStoredHostKeyMismatch: ...)
  • async callback-based trust evaluation under upper-layer control
  • known_hosts import from a file path for exact, wildcard, negated, hashed, CIDR, @revoked, and @cert-authority entries, with optional additional lookup names for host/IP-aware matching

Deferred:

  • built-in trust-store persistence
  • broader host-certificate algorithm coverage beyond the current Ed25519 and ECDSA P-256 certificate paths

Shell And Exec

Live validation:

  • command execution against OpenSSH
  • concurrent exec on one OpenSSH connection
  • monitoring-shaped concurrent exec batches on one OpenSSH connection
  • PTY-backed shell startup against OpenSSH
  • one shared OpenSSH connection carrying shell, exec, and SFTP at the same time
  • one shared OpenSSH connection carrying shell, SFTP, and monitoring exec batches at the same time
  • interleaved control traffic such as early CHANNEL_WINDOW_ADJUST
  • receive-window replenishment and outbound chunking

Practical limits:

  • the shell wrapper is intentionally small
  • the newer incremental surfaces are SSHConnection.openExec(_:) plus the unified SSHSession event stream
  • execute(_:environment:), openExec(_:environment:), and openShell(..., environment:) now send pre-start RFC 4254 env requests when you provide SSHSessionEnvironmentVariable values
  • SSHSession.resizePseudoTerminal(...) and SSHSession.sendSignal(_:) now exist for PTY-backed shells and streamed exec sessions, and Traversio now also exposes remote exit-signal events through SSHSessionEvent plus collected outputs
  • one SSHSession maps to one SSH session channel, so one channel is dedicated to one purpose
  • the older chunked reader covers stdout only
  • wrapper lifetime follows the owning SSHConnection

SFTP

Supported public methods:

  • close
  • realPath
  • lstat
  • stat
  • setAttributes
  • fileSystemAttributes
  • openFile
  • listDirectory
  • readFile
  • writeFile
  • makeDirectory
  • removeFile
  • removeDirectory
  • rename
  • readLink
  • createSymbolicLink

Behavior notes:

  • one SFTPClient routes replies by request ID, so path and handle calls can overlap on the same subsystem channel
  • openFile returns a public SFTPFileHandle, and that handle shares the same request router and channel window as the parent SFTPClient
  • readFile(..., maxConcurrentReads:progress:), writeFile(..., maxConcurrentWrites:progress:), and SFTPFileHandle.readAll(...) can keep a bounded number of SFTP requests in flight on one handle while preserving whole-file convenience APIs
  • SFTPFileHandle.readChunks(...) now exposes handle-level streamed reads as an AsyncSequence, and SFTPFileHandle.write(contentsOf:startingAt:progress:) now consumes caller-provided chunk streams for offset-based uploads
  • resumeUploadFile(...) and resumeDownloadFile(...) now resume whole-file transfers from the server-reported remote file size and throw focused public errors when the caller's local and remote sizes are incompatible or the server omits size metadata
  • those same whole-file helpers now also emit cumulative SSHSFTPTransferProgress values during transfer work
  • writeFile truncates existing content by default
  • writeFile(syncAfterWrite: true) requires OpenSSH [email protected] support
  • rename prefers the OpenSSH extension when advertised

Forwarding

Supported public surface:

  • SSHConnection.openDirectTCPIPChannel(...) for expert raw byte streams over a direct-tcpip channel
  • SSHConnection.withLocalPortForwarding(...) on Apple 26+ for a closure-scoped local listener backed by the same channel path
  • SSHConnection.withDynamicPortForwarding(...) on Apple 26+ for a closure-scoped local SOCKS proxy which opens direct-tcpip channels on demand
  • SSHConnection.withRemotePortForwardListener(...) on Apple 26+ for a closure-scoped remote listener plus raw incoming forwarded-tcpip channels
  • SSHConnection.withRemotePortForwarding(...) on Apple 26+ for a closure-scoped remote listener that bridges back to one local TCP endpoint
  • SSHClientConfiguration.connectionProxy for an outermost-hop SOCKS5 or HTTP CONNECT transport proxy before the first SSH handshake starts
  • SSHClientConfiguration.proxyJumpHosts plus SSHProxyJumpHost for explicit multi-hop jump-host chaining
  • SSHDirectTCPIPChannel.nextEvent() / events and SSHForwardedTCPIPChannel.nextEvent() / events for incremental data plus EOF delivery without giving up the older chunk/transcript helpers

Limits:

  • the Apple 26+ local-forwarding helper uses a best-effort shutdown model: Traversio stops bridging data at scope exit and closes late accepted local connections, but does not promise that the bound port becomes immediately unconnectable
  • accepted local-forward, dynamic-forward, and fixed remote-forward bridge failures are now isolated per connection instead of poisoning the whole forwarding scope
  • the remote-forward listener and helper are closure-scoped helpers
  • live validation covers the raw-listener and fixed remote-bridge data paths against OpenSSH
  • the remote-forwarding helper keeps multiple accepted remote connections active and bridges them back to one fixed local TCP endpoint
  • dynamic forwarding is live-validated on the SOCKS5 path in both no-auth and username/password modes, while SOCKS4 and SOCKS4a keep deterministic-only coverage
  • ProxyJump has real OpenSSH live validation, and outer SOCKS5 / HTTP CONNECT connection proxies also have local Docker live-validation coverage
  • broader forwarding validation beyond OpenSSH-family servers and the local proxy matrix remains release work

Validation Snapshot

Already live-validated against the configured OpenSSH target:

  • shell and exec
  • baseline exec true against the local Ubuntu 24 OpenSSH 9.6p1 matrix target after enabling the client strict-kex marker
  • exec true against the local Ubuntu 24 OpenSSH 9.6p1 AEAD-only matrix target
  • exec true against the local Ubuntu 24 OpenSSH 9.6p1 ETM-only matrix target
  • exec true against the local Ubuntu 24 OpenSSH 9.6p1 UMAC-only matrix target
  • exec true against the local Ubuntu 24 OpenSSH 9.6p1 Chacha20-Poly1305-only matrix target
  • concurrent exec on one connection
  • monitoring exec batches on one connection
  • one shared connection carrying shell, exec, and SFTP
  • one shared connection carrying shell, SFTP, and monitoring exec batches
  • SFTP metadata
  • directory listing
  • file reads
  • sequential writes
  • rename, including [email protected]
  • symlink and readlink
  • password-authenticated authorized-key installation plus public-key re-login
  • ECDSA public-key auth
  • forwarding raw-listener, fixed local forwarding, dynamic SOCKS forwarding on the SOCKS5 path, and fixed-endpoint remote-bridge data paths
  • outer SOCKS5 / HTTP CONNECT connection proxies, including SOCKS5 username/password and HTTP CONNECT Basic auth, through the local Dante/Tinyproxy matrix
  • ProxyJump / explicit jump-host chaining
  • keyboard-interactive auth against a temporary local AsyncSSH server

Not yet live-validated:

  • SOCKS4 and SOCKS4a dynamic-forwarding paths
  • non-Docker / enterprise-style outer connection proxies for the SSH transport itself

On this page