You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
rig_https_local.py has failed on every UCI image since #135: it sends the listener's IP as the hostname, which the SAN check rejects #141
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:
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:
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.
Two controls isolate the name check as the sole cause:
build
result
X509_VERIFY_NAME compiled out
PASS — HELLO FROM TLS SERVER, carry=0
name check on + make clean && make BACKEND=uci USE_NISTCURVES_ONCHIP=1 HTTPS_SNI=www.foo.bar
PASS — same
So the cause is exactly as diagnosed, and fix option 1 works: the DMA'd host_str stays the listener IP (firmware still resolves and connects), while http_get's HTTPS_SNI_OVERRIDE prologue puts www.foo.bar into tls_hostname, which matches the bundled cert's DNS:www.foo.bar. The cert is valid to 2036, so no cert work is needed.
One trap for whoever implements this, which cost a false negative here first:
HTTPS_SNI= requires make clean. It is not in #128's no-clean-needed set. The generated build/https_host.inc content-compare invalidates boot.o + the PRG, but HTTPS_SNI= also adds -D HTTPS_SNI_OVERRIDE=1, which changes http.s. That is a flag change, so http.o goes stale. Without make clean you get a mixed link that embeds the SNI string via boot.o but never runs the override in http.o — the PRG hash changes, the string greps out of the image, and it still fails identically to no-SNI. The clean and dirty PRGs differ (a65fff60… vs d1b63508…); that hash difference is the only thing that gives it away.
Worth folding into the fix: if the rig grows a HTTPS_SNI build step it should force the clean, and the same applies to rig_https_print_body.py / rig_https_local_p384.py / rig_https_bad_finished.py per option 3.
Activity
JC-000 commentedon Aug 30, 2026
Hardware confirmation of the diagnosis, and fix option 1 verified working — U64E
601A96, quiet device, fw 3.15 preview, uci onchip @ 48 MHz, 2026-08-30 (taken while verifying #149).Default mode reproduces this issue exactly as filed:
Two controls isolate the name check as the sole cause:
X509_VERIFY_NAMEcompiled outHELLO FROM TLS SERVER, carry=0make clean && make BACKEND=uci USE_NISTCURVES_ONCHIP=1 HTTPS_SNI=www.foo.barSo the cause is exactly as diagnosed, and fix option 1 works: the DMA'd
host_strstays the listener IP (firmware still resolves and connects), whilehttp_get'sHTTPS_SNI_OVERRIDEprologue putswww.foo.barintotls_hostname, which matches the bundled cert'sDNS:www.foo.bar. The cert is valid to 2036, so no cert work is needed.One trap for whoever implements this, which cost a false negative here first:
HTTPS_SNI=requiresmake clean. It is not in #128's no-clean-needed set. The generatedbuild/https_host.inccontent-compare invalidatesboot.o+ the PRG, butHTTPS_SNI=also adds-D HTTPS_SNI_OVERRIDE=1, which changeshttp.s. That is a flag change, sohttp.ogoes stale. Withoutmake cleanyou get a mixed link that embeds the SNI string viaboot.obut never runs the override inhttp.o— the PRG hash changes, the string greps out of the image, and it still fails identically to no-SNI. The clean and dirty PRGs differ (a65fff60…vsd1b63508…); that hash difference is the only thing that gives it away.Worth folding into the fix: if the rig grows a
HTTPS_SNIbuild step it should force the clean, and the same applies torig_https_print_body.py/rig_https_local_p384.py/rig_https_bad_finished.pyper option 3.Merge pull request #163 from JC-000/fix/141-rig-sni-precondition
docs: retire the "make clean after any flag change" rule where it sur…