Skip to content

TLS13-C10: a TLS 1.3 responder, and the consumer path proven against it - #1290

Merged
drawmeanelephant merged 1 commit into
mainfrom
agent/autocoder/tls13-c10
Sep 15, 2026
Merged

drawmeanelephant merged 1 commit into
mainfrom
agent/autocoder/tls13-c10

Conversation

@drawmeanelephant

Copy link
Copy Markdown
Owner

The consumer criterion had no runtime evidence. FETCHS.BIN compiles and installs, but nothing had driven the client along the consumer path — the bytes of the vendored root blob, and the exact identity the guest is built to expect.

This adds the peer that closes that gap.

What

  • tlsresponder.py — a TLS 1.3-only Python ssl responder. A fifth kind of implementation for the matrix (a different binding over a possibly different OpenSSL build), and the artifact a class-B gate would drive. TLS 1.3 is mandatory in it and --timeout bounds its life, so a lost peer cannot hang a runner.
  • run_consumer_interop.sh — drives the real client against it, positive and negative.
  • interop/consumer_ledger.jsonl — the machine-readable result.
  • INTEGRATION.md — the gate's runner-side half is now a named artifact instead of a plan.

Evidence

python-tls13           127.0.0.1:24533  leaf.example.com   -> ok
python-tls13-wronghost 127.0.0.1:24534  wrong.example.com  -> handshake_failed

The responder's own log corroborates both directions:

responder: served TLSv1.3 TLS_AES_128_GCM_SHA256: GET / HTTP/1.0
responder: refused: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol

So the client completed a TLS 1.3 handshake with an independent stack, negotiated the mandatory suite, sent an HTTP/1.0 GET, read a 200 response, and failed closed when the name did not match.

Honest scope

This exercises the consumer's trust path and request/response logic on the host, not the kernel seams beneath it. The guest's live handshake still needs a boot — which is why the gate spec itself is deliberately not committed here (an unvalidated spec reddens the fleet). What changes is that the runner-side half now exists in-tree, so INTEGRATION.md names the artifact rather than describing one.

zig build test unchanged: 198/198 steps, 3585/3585 tests.

The consumer criterion had no runtime evidence: FETCHS.BIN compiles and
installs, but nothing had ever driven the client along the *consumer* path --
the bytes of the vendored root blob, and the exact identity FETCHS.BIN is
built to expect.

This adds the peer that closes that gap. tlsresponder.py is a TLS 1.3-only
Python `ssl` responder: a fifth kind of implementation in the matrix (a
different binding over a possibly different OpenSSL build), and the artifact a
class-B gate would drive. TLS 1.3 is mandatory in it and `--timeout` bounds its
life, so a lost peer cannot hang a runner.

run_consumer_interop.sh drives the real client against it:

  python-tls13          127.0.0.1:24533  leaf.example.com   -> ok
  python-tls13-wronghost 127.0.0.1:24534  wrong.example.com -> handshake_failed

The responder's own log corroborates both directions:

  served TLSv1.3 TLS_AES_128_GCM_SHA256: GET / HTTP/1.0
  refused: [SSL: UNEXPECTED_EOF_WHILE_READING] ...

So the client completed a TLS 1.3 handshake with an independent stack,
negotiated the mandatory suite, sent an HTTP/1.0 GET, and read a 200 response
whose body it verified -- and failed closed when the name did not match.

Honest scope: this exercises the consumer's trust path and request/response
logic on the host, not the kernel seams beneath it. The guest's live handshake
still needs a boot. What changes is that the runner-side half of that gate now
exists in-tree instead of being a plan, so INTEGRATION.md can name the artifact
rather than describe one.

Evidence:
  bash run_consumer_interop.sh <driver> <fx> interop/consumer_ledger.jsonl
    -> exit 0, two rows (1 ok, 1 handshake_failed)
  zig build test -> 198/198 steps, 3585/3585 tests (unchanged)
@drawmeanelephant
drawmeanelephant merged commit 7f2cbe4 into main Sep 15, 2026
9 checks passed
@drawmeanelephant
drawmeanelephant deleted the agent/autocoder/tls13-c10 branch September 15, 2026 03:00
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