leantls

package
v0.99.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package leantls is a standard-library-only TLS 1.3 client for networks you control: one version, cipher suite, key exchange, and a peer identified by a pinned Ed25519 key instead of a certificate chain.

Measured with the same tamago/riscv64 main (`-w -T 0x84010000`, 2026-08-12):

board + fmt baseline ...................... 1.69 MB
+ this package, pinned key ................ 2.51 MB (+0.82)
+ this package plus x509verify chain ...... 3.73 MB (+2.04)
+ crypto/tls with CA root bundle .......... 4.09 MB (+2.40)

Pinned mode saves 1.57 MB over crypto/tls. Chain mode alone saves 0.63 MB, but also unlocks leanhttp's larger saving. For the same HTTPS download:

net/http + crypto/tls ................. 5.53 MB
leanhttp + crypto/tls ................. 4.43 MB (-1.10)
leanhttp + leantls + x509verify ....... 3.80 MB (-1.73)

Pinned mode avoids crypto/x509, encoding/asn1, math/big, RSA, NIST curves, and the CA bundle. It uses X25519, AES-128-GCM, SHA-256, HMAC, HKDF, Ed25519, and crypto/rand, linking no crypto/tls, crypto/x509, or encoding/asn1.

Pinned identity

Ordinary HTTPS delegates identity to a CA chain. A pin instead distributes a known 32-byte Ed25519 public key with the node. The handshake requires the certificate key to equal it and verifies the transcript signature with that key. This removes CA, name, and validity ambiguity at the cost of distributing new pins when keys rotate, which fits a controlled fleet but not public hosts.

Deliberate limits

Pinned mode performs no chain, CA, name, or validity checks; Config.PeerKey is the identity. Config.VerifyPeer enables caller-supplied chain validation, with leantls/x509verify providing the standard form. Client rejects a missing or ambiguous trust model.

Only TLS 1.3, TLS_AES_128_GCM_SHA256, X25519, and Ed25519 are supported in pinned mode. There is no downgrade, session resumption, PSK, 0-RTT, client certificate, HelloRetryRequest, or renegotiation. Removing downgrade, compression, CBC, RSA-PKCS#1v1.5, and custom chain validation eliminates the usual dangerous TLS state space. RFC 8448 vectors test the key schedule; crypto/tls interoperability tests the transcript and record layer.

Usage

// A peer whose key is already known:
conn, err := leantls.Dial("tcp", "leader:7443", &leantls.Config{
    PeerKey: leaderKey, // 32 bytes from your own configuration
})

// A public certificate chain:
conn, err := leantls.Dial("tcp", "github.com:443", &leantls.Config{
    ServerName:          "github.com",
    VerifyPeer:          x509verify.Chain(nil),
    SignatureAlgorithms: x509verify.SignatureAlgorithms,
})

The result is an ordinary net.Conn. This package knows neither HTTP nor the underlying network stack.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// PeerKey is the Ed25519 public key the server must prove. This mode links no
	// PKI.
	PeerKey ed25519.PublicKey

	// VerifyPeer receives the wire certificate chain in leaf-first DER order and
	// the expected name, then returns a transcript-signature verifier. The hook
	// keeps crypto/x509's ~0.75 MB out of pinned builds; leantls/x509verify
	// provides standard HTTPS chain validation.
	VerifyPeer func(certs [][]byte, serverName string) (SignatureVerifier, error)

	// ServerName is sent as SNI and passed to VerifyPeer for certificate identity.
	// It is optional with PeerKey because the pin supplies identity.
	ServerName string

	// SignatureAlgorithms are offered for server CertificateVerify
	// (RFC 8446 §4.2.3). Empty means Ed25519 only. A VerifyPeer supporting more
	// should supply exactly those codes, such as x509verify.SignatureAlgorithms.
	SignatureAlgorithms []uint16
}

Config identifies the expected peer. Set exactly one trust model: PeerKey for a pin, or VerifyPeer for caller-supplied validation such as a certificate chain. Missing and ambiguous trust both fail.

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn is a TLS 1.3 connection implementing net.Conn.

func Client

func Client(conn net.Conn, cfg *Config) (*Conn, error)

Client performs the handshake over an existing connection. On error, the caller must close the unusable underlying connection. Handshake is eager so trust failures occur here instead of during later application I/O.

func Dial

func Dial(network, addr string, cfg *Config) (*Conn, error)

Dial opens TCP and performs the handshake with [dialTimeout]. For custom deadlines, dial separately and call Client; for cancellation use DialContext.

func DialContext added in v0.7.0

func DialContext(ctx context.Context, network, addr string, cfg *Config) (*Conn, error)

DialContext adds cancellation to Dial. An earlier context deadline also caps the handshake so a dial cannot outlive its caller.

func (*Conn) Close

func (c *Conn) Close() error

Close sends a best-effort close_notify before closing, allowing the peer to distinguish a complete stream from a truncated connection. It never waits behind an application Write: closing the transport is what releases such a writer. A close_notify that itself blocks is bounded by a write deadline and an independent transport-close timer.

func (*Conn) Grown added in v0.8.1

func (c *Conn) Grown() bool

Grown geeft de bulk-classificatie van het onderliggende transport door (zie leannet tcpSock.Grown): zo geldt de pool-regel "gegroeid = sluiten, niet poolen" ook voor TLS-verbindingen. Een transport zonder het begrip is per definitie niet gegroeid.

func (*Conn) LocalAddr

func (c *Conn) LocalAddr() net.Addr

func (*Conn) PeerKey

func (c *Conn) PeerKey() ed25519.PublicKey

PeerKey returns the configured key proven by certificate inclusion and the transcript signature.

func (*Conn) Read

func (c *Conn) Read(p []byte) (int, error)

Read returns application data and transparently handles post-handshake NewSessionTicket and KeyUpdate messages.

func (*Conn) RemoteAddr

func (c *Conn) RemoteAddr() net.Addr

func (*Conn) SetDeadline

func (c *Conn) SetDeadline(t time.Time) error

func (*Conn) SetReadDeadline

func (c *Conn) SetReadDeadline(t time.Time) error

func (*Conn) SetWriteDeadline

func (c *Conn) SetWriteDeadline(t time.Time) error

func (*Conn) Write

func (c *Conn) Write(p []byte) (int, error)

Write sends application data fragmented at the RFC record limit.

type SignatureVerifier

type SignatureVerifier = func(sigAlg uint16, signed, sig []byte) error

SignatureVerifier checks server CertificateVerify. sigAlg is the selected TLS code, signed is the exact transcript input, and sig is the signature. Nil means success. The alias lets helper packages provide verifiers without importing leantls.

Directories

Path Synopsis
Package x509verify provides ordinary HTTPS trust for leantls by validating a certificate chain through crypto/x509.
Package x509verify provides ordinary HTTPS trust for leantls by validating a certificate chain through crypto/x509.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL