Skip to content

Add TLS-ALPN-01 challenge solver - #8

Merged
Shine-neko merged 1 commit into
mainfrom
feat/tls-alpn-01
Jul 20, 2026
Merged

Add TLS-ALPN-01 challenge solver#8
Shine-neko merged 1 commit into
mainfrom
feat/tls-alpn-01

Conversation

@Shine-neko

Copy link
Copy Markdown
Contributor

Adds a TLS-ALPN-01 challenge solver (RFC 8737), mirroring the existing DNS-01 solver so a downstream crate can provision certificates over the ALPN challenge with the same shape it already uses for DNS-01.

What's new

  • TlsAlpn01Solver<R: ChallengeResponder> — drives an ACME order through the TLS-ALPN-01 challenge to a certificate, the counterpart to Dns01Solver.
  • ChallengeResponder trait — the counterpart to DnsProvider. The library builds the challenge certificate; the implementer arranges for it to be served on acme-tls/1 handshakes. How the certificate reaches port 443 is the consumer's architecture, not this library's.
  • build_challenge_certificate(domain, digest) — a pure function that builds the RFC 8737 challenge certificate: a single dNSName SAN and a critical id-pe-acmeIdentifier extension wrapping the 32-byte key-authorization digest in an OCTET STRING. Uses rcgen's new_acme_identifier, which is why rcgen moves from a dev-dependency to a normal one (the only dependency change).
  • MockChallengeResponder in the testing feature — the counterpart to MockDnsProvider, so a downstream crate can integration-test its TLS-ALPN-01 wiring without a real TLS responder.

Design

The order-driving tail — poll ready, finalize, fetch the chain — is identical to DNS-01, so finalize_order reproduces it. The one structural difference from Dns01Solver: challenges are collected up front (domain, digest, URL) before any set_ready, because instant-acme's authorization stream and set_ready both borrow the order. The digest is copied into an owned buffer, so nothing depends on the stream afterward.

Cleanup is best-effort and documented as such: cheti carries no logger (matching the DNS-01 solver), a present that fails after installing the cert still gets that domain torn down, and a responder needing a hard guarantee should lease its presentations.

Scope note

This is the generic half of TLS-ALPN-01. The consumer-specific half — a rustls responder that serves the certificate on acme-tls/1, and routing that protocol to it on port 443 — lives in the downstream proxy, not here.

@Shine-neko
Shine-neko merged commit dca6075 into main Jul 20, 2026
5 checks passed
@Shine-neko
Shine-neko deleted the feat/tls-alpn-01 branch July 20, 2026 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant