hoike

OCSP responder

A pre-signed, replayable, multi-CA OCSP responder with keyless edge serving and post-quantum ML-DSA support. Built in Rust.

hoike (Hawaiian) — to show, to exhibit, to testify. An OCSP responder does exactly one thing: it testifies to the status of someone else's certificate.

Built for Private PKI

Signer/edge split architecture. The machine that signs status and the machine that serves it are never the same machine.

Pre-Signed Responses

Responses are batch-signed by the signer tier and sealed into ahu bundles. Edge nodes serve stored bytes verbatim — no keys, no signing, no HSM access on the hot path.

Keyless Edge Nodes

Edge nodes hold no signing keys. An edge compromise cannot produce a false good — only denial of service or stale replay within nextUpdate.

Multi-CA Routing

One responder instance serves many CAs. Routing uses the issuerKeyHash multimap from each OCSP request's CertID, handling re-keyed and cross-signed CAs correctly.

Post-Quantum Ready

ML-DSA-44, ML-DSA-65, and ML-DSA-87 signing as first-class configurations, not patches. Batching amortizes post-quantum signature size across certificate buckets.

ahu Bundle Format

Self-describing containers with CBOR manifest, CMS seal, and a sorted index for O(log n) binary search. Designed for zero-copy serving via mmap.

SWIM Gossip

Edge fleet coordination via the SWIM protocol (foca). Generation announcements, membership tracking, and urgent revocation notices — gossip is never authoritative for status.

Air-Gap Ready

Bundles are sealed files that cross air gaps on removable media. Enclave mode uses byte-identical code paths — only acquisition differs. No gossip, no upstream, full functionality.

Anti-Rollback

Epoch chain with persisted high-water marks prevents replay of older generations. Fork detection catches duplicate signers immediately. Stale-generation alerts before nextUpdate expires.

Zero-Copy Serving

Responses are mmap'd and written directly via writev. No parse, no copy, no re-encode on the hot path. Horizontal scaling limited only by network bandwidth.

Delta Bundles

Incremental updates distribute only changes since the last full generation. Steady-state mirrors receive deltas; full bundles only on join or chain-length exhaustion.

Nonce Policies

Per-CA nonce handling: ignore for pre-signed responses, forward to proxy to a signer. Configuring live signing on an edge is a startup error, not a runtime surprise.

Dual CertID

One BasicOCSPResponse carries both SHA-1 and SHA-256 CertID entries per RFC 9919. One signature, one payload, two index records. Log SHA-1 usage to track migration.


Up and Running in Minutes

Sign a bundle, inspect it, start the responder.

terminal
$ hoike sign --ca enterprise-ca --crl revoked.crl -o bundle.ahu INFO hoike::sign: reading CRL from 'revoked.crl' (42 entries) INFO hoike::sign: signing with ecdsa-p256, epoch 1 INFO hoike::sign: wrote bundle.ahu (42 good, 3 revoked, 84 index entries) $ ahu inspect bundle.ahu format : ahu v1 producer : hoike 0.1.0 epoch : 1 scope : enterprise-ca (partial) algorithm : ecdsa-p256 entries : 84 (42 good, 3 revoked, dual CertID) size : 48.2 KB (zstd compressed) $ hoike serve --config hoike.toml INFO hoike: loading config from 'hoike.toml' INFO hoike::core: loaded CA 'enterprise-ca' (45 entries, epoch 1) INFO hoike::server: OCSP responder listening on 0.0.0.0:2560
Read the full quickstart guide →

4

RFCs and standards implemented — 20 conformance assertions

Full OCSP protocol with pre-signed response production, HTTP caching profile, nonce handling rules, and AIA discovery. Every protocol claim validated by wire-format conformance tests against OpenSSL and Go clients.

View RFC compliance details →

Quick Start

Container

# Build the container image podman build -t hoike . podman run --rm \ -v ./hoike.toml:/etc/hoike/hoike.toml:ro \ -v ./bundles:/var/lib/hoike/bundles:ro \ -p 2560:2560 \ hoike

Build from source

git clone https://github.com/czinda/hoike cd hoike cargo build --release # Two binaries: hoike (~8 MB) and ahu (~1 MB) cargo run --release -p hoike-cli -- \ serve --config hoike.toml

Architecture

A Cargo workspace with six crates. The signer holds keys; the edge serves bytes.

revocation source SIGNER TIER (CRL, Dogtag, 389 DS) ────▶ batch signs produces .ahu │ ┌────────────────────────┼────────────────────────┐ │ │ │ ┌─────▼──────┐ ┌──────▼─────┐ ┌──────▼──────┐ │ EDGE NODE │◀──gossip──▶│ EDGE NODE │◀──gossip──▶│ EDGE NODE │ │ keyless │ │ keyless │ │ keyless │ └─────┬──────┘ └──────┬─────┘ └──────┬──────┘ │ │ │ └────────────── clients ─┴────────────────────────┘ ┌──────────────────────────────────────────────┐ │ AIR-GAPPED ENCLAVE │ │ edge node, bundle imported from media │ │ no gossip, no upstream, identical code │ └──────────────────────────────────────────────┘

Workspace

Six crates with clean dependency boundaries.

ahu

Bundle format: read, write, verify. Apache-2.0 OR MIT. No server dependencies.

hoike-core

CertID routing, request parsing, config, policy, state store.

hoike-sign

Signing, CRL adapter, OCSP response generation, batch production.

hoike-server

HTTP request path via axum. GET and POST handlers, RFC 9919 headers.

hoike-gossip

SWIM membership and generation announcements via foca.

hoike-cli

hoike + ahu binaries. The operator-facing surface.