Skip to content

Commit 66cc032

Browse files
committed
add tests
1 parent 336468e commit 66cc032

File tree

2 files changed

+109
-0
lines changed

2 files changed

+109
-0
lines changed

src/util/tls.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ export async function generateCACertificate(options: {
110110
if(permittedDomains.length > 0) {
111111
extensions.push({
112112
critical: true,
113+
id: '2.5.29.30',
113114
name: 'nameConstraints',
114115
value: generateNameConstraints({
115116
permitted: permittedDomains,

test/ca.spec.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,80 @@ nodeOnly(() => {
2929
await expect(fetch('https://localhost:4430')).to.have.responseText('signed response!');
3030
});
3131

32+
describe("constrained CA", () => {
33+
let constrainedCA: CA;
34+
let constrainedCaCert: string;
35+
36+
beforeEach(async () => {
37+
const rootCa = await generateCACertificate({
38+
nameConstraints: { permitted: ["example.com"] },
39+
});
40+
constrainedCaCert = rootCa.cert;
41+
constrainedCA = new CA(rootCa);
42+
});
43+
44+
it("can generate a valid certificate for a domain included in a constrained CA", async () => {
45+
46+
const { cert, key } = constrainedCA.generateCertificate("hello.example.com");
47+
48+
server = https.createServer({ cert, key }, (req: any, res: any) => {
49+
res.writeHead(200);
50+
res.end("signed response!");
51+
});
52+
await new Promise<void>((resolve) => server.listen(4430, resolve));
53+
54+
await new Promise<void>((resolve) => {
55+
const req = https.request(
56+
{
57+
hostname: "hello.example.com",
58+
port: 4430,
59+
ca: [constrainedCaCert],
60+
lookup: (hostname, options, callback) => {
61+
callback(null, "127.0.0.1", 4);
62+
},
63+
},
64+
(res) => {
65+
expect(res.statusCode).to.equal(200);
66+
res.on("data", (data) => {
67+
expect(data.toString()).to.equal("signed response!");
68+
resolve();
69+
});
70+
}
71+
);
72+
req.end();
73+
});
74+
75+
});
76+
77+
it("can not generate a valid certificate for a domain not included in a constrained CA", async () => {
78+
const { cert, key } = constrainedCA.generateCertificate("hello.other.com");
79+
80+
server = https.createServer({ cert, key }, (req: any, res: any) => {
81+
res.writeHead(200);
82+
res.end("signed response!");
83+
});
84+
await new Promise<void>((resolve) => server.listen(4430, resolve));
85+
86+
await new Promise<void>((resolve) => {
87+
const req = https.request(
88+
{
89+
hostname: "hello.other.com",
90+
port: 4430,
91+
ca: [constrainedCaCert],
92+
lookup: (hostname, options, callback) => {
93+
callback(null, "127.0.0.1", 4);
94+
},
95+
},
96+
);
97+
req.on("error", (err) => {
98+
expect(err.message).to.equal("permitted subtree violation");
99+
resolve();
100+
})
101+
req.end();
102+
});
103+
});
104+
});
105+
32106
afterEach((done) => {
33107
if (server) server.close(done);
34108
});
@@ -176,5 +250,39 @@ nodeOnly(() => {
176250
expect(errors.join('\n')).to.equal('');
177251
});
178252

253+
it("should generate a CA cert constrained to a domain that pass lintcert checks", async function(){
254+
this.retries(3); // Remote server can be unreliable
255+
256+
const caCertificate = await generateCACertificate({
257+
nameConstraints: {
258+
permitted: ['example.com']
259+
}
260+
});
261+
262+
const { cert } = caCertificate;
263+
264+
const response = await ignoreNetworkError(
265+
fetch('https://crt.sh/lintcert', {
266+
method: 'POST',
267+
headers: { 'content-type': 'application/x-www-form-urlencoded' },
268+
body: new URLSearchParams({'b64cert': cert})
269+
}),
270+
{ context: this }
271+
);
272+
273+
const lintOutput = await response.text();
274+
275+
const lintResults = lintOutput
276+
.split('\n')
277+
.map(line => line.split('\t').slice(1))
278+
.filter(line => line.length > 1);
279+
280+
const errors = lintResults
281+
.filter(([level]) => level === 'ERROR')
282+
.map(([_level, message]) => message);
283+
284+
expect(errors.join('\n')).to.equal('');
285+
});
286+
179287
});
180288
});

0 commit comments

Comments
 (0)