Symptom
tools/uci/rig_https_local.py (U64E, uci-onchip, 48 MHz) fails with the client aborting at the Certificate stage and the listener seeing SSLEOFError: UNEXPECTED_EOF_WHILE_READING. Reproduced 3/3 on 2026-08-24 — twice on a #70 branch and once as a control on master ab5de2b (PRG 1af096e1…), identical state each time:
tls_state = $FF
tls_last_state = $04 (CERTIFICATE)
tls_recv_sub_progress = $31 (tls_deframe.s:271 — in-place dispatch into the cert handler)
tls_read_seq = 2
net_last_error = $00
listener: client_addr seen, request <none>, TLS handshake failed: UNEXPECTED_EOF
boot_check.py and phase2_check.py pass on the same device in the same session, and rig_https_live.py (github.com) is the control for the TLS path itself.
Cause
rig_https_local.py:1408:
host_str = host_ip_bytes + b"\x00"
The rig DMA-feeds the listener's dotted-quad IP as the hostname (UCI firmware resolves it, so it connects), and that same string is what tls_hostname carries into the v0.4.2 server-name validation (#135, 0673acb). The bundled certificate is:
tools/https_e2e/certs/server.pem SAN: DNS:foo.bar, DNS:www.foo.bar CN=www.foo.bar
An IP literal never matches a dNSName, and no-SAN-match is a reject — which is the correct behaviour of the check, and exactly why the rig now fails. The #135 hardware verification was done with rig_https_wiki.py (a real host, matching SAN), so this rig was never re-run after the check went live.
Only the UCI images are affected (X509_VERIFY_NAME is compiled out on ip65), which is the whole set this rig runs on.
Fix options (not done here — filed from the #70 alignment, which it blocks from using this rig as evidence)
- Rig-side, preferred: send a hostname the cert names and let the U64E resolve it — e.g. build the test PRG with
HTTPS_SNI=www.foo.bar (the knob added for exactly the connect-host ≠ name-check-host case) while the DMA'd host_str stays the IP; or point the U64E's resolver at www.foo.bar via the dnsmasq the VICE rig already uses.
- Cert-side: add
IP:<listener ip> to the SAN — but the parser is dNSName-only by design (RFC 6125), so that would mean extending src/x509_name.s, and the negative vectors in tools/test_x509_name.py would need an IP case.
- Same audit for
rig_https_print_body.py / rig_https_local_p384.py / rig_https_bad_finished.py, which share the host-string convention.
Until one of these lands, a rig_https_local FAIL on a UCI image is not evidence about the change under test.
Symptom
tools/uci/rig_https_local.py(U64E, uci-onchip, 48 MHz) fails with the client aborting at the Certificate stage and the listener seeingSSLEOFError: UNEXPECTED_EOF_WHILE_READING. Reproduced 3/3 on 2026-08-24 — twice on a #70 branch and once as a control on masterab5de2b(PRG1af096e1…), identical state each time:boot_check.pyandphase2_check.pypass on the same device in the same session, andrig_https_live.py(github.com) is the control for the TLS path itself.Cause
rig_https_local.py:1408:The rig DMA-feeds the listener's dotted-quad IP as the hostname (UCI firmware resolves it, so it connects), and that same string is what
tls_hostnamecarries into the v0.4.2 server-name validation (#135,0673acb). The bundled certificate is:An IP literal never matches a dNSName, and no-SAN-match is a reject — which is the correct behaviour of the check, and exactly why the rig now fails. The #135 hardware verification was done with
rig_https_wiki.py(a real host, matching SAN), so this rig was never re-run after the check went live.Only the UCI images are affected (
X509_VERIFY_NAMEis compiled out on ip65), which is the whole set this rig runs on.Fix options (not done here — filed from the #70 alignment, which it blocks from using this rig as evidence)
HTTPS_SNI=www.foo.bar(the knob added for exactly the connect-host ≠ name-check-host case) while the DMA'dhost_strstays the IP; or point the U64E's resolver atwww.foo.barvia the dnsmasq the VICE rig already uses.IP:<listener ip>to the SAN — but the parser is dNSName-only by design (RFC 6125), so that would mean extendingsrc/x509_name.s, and the negative vectors intools/test_x509_name.pywould need an IP case.rig_https_print_body.py/rig_https_local_p384.py/rig_https_bad_finished.py, which share the host-string convention.Until one of these lands, a
rig_https_localFAIL on a UCI image is not evidence about the change under test.