Skip to content

nettrace: don't pin Let's Encrypt intermediate in TestTLSCertErrors - #91

Merged
milan-zededa merged 1 commit into
lf-edge:mainfrom
eriknordmark:nettrace-le-issuer
Aug 7, 2026
Merged

nettrace: don't pin Let's Encrypt intermediate in TestTLSCertErrors#91
milan-zededa merged 1 commit into
lf-edge:mainfrom
eriknordmark:nettrace-le-issuer

Conversation

@eriknordmark

Copy link
Copy Markdown
Contributor

TestTLSCertErrors/wrong_host reaches out to wrong.host.badssl.com and asserts that the certificate it gets back was issued by a Let's Encrypt intermediate named R followed by one or two digits. Let's Encrypt has moved to a new generation of intermediates — the currently active set is YE1, YE2, YR1, YR2 — and badssl.com renewed onto one of them on 2026-07-28. Every amd64 run since has failed:

Expected
    <string>: CN=YR2,O=Let's Encrypt,C=US
to match regular expression
    <string>: ^CN=R\d{1,2},O=Let's Encrypt,C=US$

The last green Build and Test on main was 2026-07-26, just before that renewal. This is not specific to any one PR — #88, #89 and #90 are all red on it, and every new PR will be until this lands.

Let's Encrypt says of its backup intermediates that it "may begin issuing Subscriber certificates from them at any time, without warning", so enumerating today's names would only defer the same breakage; a future rotation could also land on an ECDSA intermediate rather than an RSA one. The subtest exists to prove that a failed TLS handshake still surfaces a parsed issuer and subject in the trace — not to police Let's Encrypt's naming. So this matches only the portion of the issuer DN that survives rotation.

The assertion stays meaningful: it still requires a well-formed single-CN DN under O=Let's Encrypt,C=US, which distinguishes this endpoint from its two siblings, whose issuers are genuinely fixed (the expired-certificate case is COMODO-signed and never renewed; the untrusted-root case is self-signed by BadSSL).

Testing

Run against the live endpoint, since these subtests skip themselves when badssl.com resets the handshake before presenting a certificate:

  • Before the change, on runs where the endpoint was actually reachable: 3/3 FAIL, with exactly the CI signature above.
  • After the change, likewise reachable: 3/3 PASS.
  • The regex was also checked directly against real issuer DNs — it accepts YE1/YE2/YR1/YR2 and the retired R3/R10, and rejects the BadSSL and COMODO issuers used by the sibling subtests.

go build ./..., go vet ./nettrace/ and gofmt -l nettrace/ are all clean.

TestTLSCertErrors/wrong_host asserted that the certificate served by
wrong.host.badssl.com is issued by an intermediate whose common name
matches "R" followed by one or two digits. Let's Encrypt has since moved
to a new generation of intermediates (YE1, YE2, YR1, YR2), badssl.com
renewed onto one of them on 2026-07-28, and every run of the amd64 test
job has failed since:

    Expected
        <string>: CN=YR2,O=Let's Encrypt,C=US
    to match regular expression
        <string>: ^CN=R\d{1,2},O=Let's Encrypt,C=US$

Let's Encrypt states it may begin issuing from any of its backup
intermediates at any time without warning, so enumerating the current
names would only postpone the same breakage, and a future rotation could
just as well land on an ECDSA intermediate. What the subtest exists to
prove is that a failed TLS handshake still yields a parsed issuer and
subject in the trace, not that Let's Encrypt keeps a particular naming
scheme. Match only the stable portion of the issuer DN.

The assertion still distinguishes this endpoint from its two siblings,
whose issuers are fixed: the expired-certificate case is signed by
COMODO and never renewed, and the untrusted-root case is self-signed by
BadSSL.

Signed-off-by: eriknordmark <erik@zededa.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@milan-zededa
milan-zededa merged commit 6b30666 into lf-edge:main Aug 7, 2026
5 checks passed
@eriknordmark
eriknordmark deleted the nettrace-le-issuer branch August 15, 2026 20:30
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.

2 participants