From 69d3813ae1cfb49111e73bb07167d8de184718b0 Mon Sep 17 00:00:00 2001 From: jochen Date: Mon, 21 Sep 2026 22:11:01 +0200 Subject: [PATCH] The certificate bed reads the names a certificate is for from its alternative names Pebble, like the public authority it stands in for, leaves the subject empty; the bed read the subject and refused a valid certificate. --- test/integration/certificates.test.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/integration/certificates.test.ts b/test/integration/certificates.test.ts index 59a32f7..96a9fd6 100644 --- a/test/integration/certificates.test.ts +++ b/test/integration/certificates.test.ts @@ -194,12 +194,16 @@ test("a public name is served with a certificate the mesh did not issue", { assert.match(served.out, /hello/); // And it is the authority's certificate, not something self-signed that happens to work. - const issuer = await must( + // The issuer, and the names the certificate is FOR — its alternative names, not its subject: + // Pebble, like the public authority it stands in for, leaves the subject empty and puts the + // name in the alternative names alone. The first version of this read the subject and refused + // a valid certificate. + const issued = await must( `echo | openssl s_client -connect ${NAME}:443 -servername ${NAME} 2>/dev/null ` + - `| openssl x509 -noout -issuer -subject`, + `| openssl x509 -noout -issuer -ext subjectAltName`, ); - assert.match(issuer, /Pebble/i, `the certificate was not issued by the ACME server:\n${issuer}`); - assert.match(issuer, new RegExp(NAME), `the certificate is not for the name asked for:\n${issuer}`); + assert.match(issued, /Pebble/i, `the certificate was not issued by the ACME server:\n${issued}`); + assert.match(issued, new RegExp(`DNS:${NAME.replace(".", "\\.")}`), `the certificate is not for the name asked for:\n${issued}`); }); test("the same order against a second authority: the catalogue's own certificate authority", { @@ -247,12 +251,12 @@ test("the same order against a second authority: the catalogue's own certificate `── the proxy tried:\n${proxyLog}\n── the authority heard:\n${authority}\n`); } assert.match(served.out, /hello/); - const issuer = await must( + const issued = await must( `echo | openssl s_client -connect ${NAME}:443 -servername ${NAME} 2>/dev/null ` + - `| openssl x509 -noout -issuer -subject`, + `| openssl x509 -noout -issuer -ext subjectAltName`, ); - assert.match(issuer, /Lab CA/, `the certificate was not issued by the second authority:\n${issuer}`); - assert.match(issuer, new RegExp(NAME), `the certificate is not for the name asked for:\n${issuer}`); + assert.match(issued, /Lab CA/, `the certificate was not issued by the second authority:\n${issued}`); + assert.match(issued, new RegExp(`DNS:${NAME.replace(".", "\\.")}`), `the certificate is not for the name asked for:\n${issued}`); }); test("no certificate is ordered for a name the mesh does not route", {