Skip to content

Commit c4d269f

Browse files
committed
test: cover tls multi-identity option mixtures
Prove that cert and key options do not have to be ordered, and that the pfx option can be used at the same time as the cert/key option (which was claimed to be impossible by some pre-existing documentation).
1 parent 0bc3166 commit c4d269f

1 file changed

Lines changed: 147 additions & 31 deletions

File tree

test/parallel/test-tls-multi-key.js

Lines changed: 147 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,52 +21,168 @@
2121

2222
'use strict';
2323
const common = require('../common');
24+
25+
// Test multi-identity ('key')/multi-algorithm scenarios.
26+
2427
if (!common.hasCrypto)
2528
common.skip('missing crypto');
2629

2730
const assert = require('assert');
2831
const tls = require('tls');
2932
const fs = require('fs');
3033

31-
const options = {
34+
// Key is ordered as ec, rsa, cert is ordered as rsa, ec.
35+
test({
3236
key: [
33-
fs.readFileSync(`${common.fixturesDir}/keys/ec-key.pem`),
37+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-key.pem`),
38+
fs.readFileSync(`${common.fixturesDir}/keys/agent1-key.pem`),
39+
],
40+
cert: [
41+
fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`),
42+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-cert.pem`)
43+
],
44+
eccCN: 'agent10.example.com',
45+
client: { ca: [
46+
fs.readFileSync(`${common.fixturesDir}/keys/ca5-cert.pem`),
47+
fs.readFileSync(`${common.fixturesDir}/keys/ca1-cert.pem`)
48+
]},
49+
});
50+
51+
// Key and cert are ordered as ec, rsa.
52+
test({
53+
key: [
54+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-key.pem`),
3455
fs.readFileSync(`${common.fixturesDir}/keys/agent1-key.pem`),
3556
],
3657
cert: [
3758
fs.readFileSync(`${common.fixturesDir}/keys/agent1-cert.pem`),
38-
fs.readFileSync(`${common.fixturesDir}/keys/ec-cert.pem`)
39-
]
40-
};
59+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-cert.pem`),
60+
],
61+
eccCN: 'agent10.example.com',
62+
client: { ca: [
63+
fs.readFileSync(`${common.fixturesDir}/keys/ca5-cert.pem`),
64+
fs.readFileSync(`${common.fixturesDir}/keys/ca1-cert.pem`),
65+
]},
66+
});
67+
68+
// Key, cert, and pfx options can be used simultaneously.
69+
test({
70+
key: [
71+
fs.readFileSync(`${common.fixturesDir}/keys/ec-key.pem`),
72+
],
73+
cert: [
74+
fs.readFileSync(`${common.fixturesDir}/keys/ec-cert.pem`),
75+
],
76+
pfx: fs.readFileSync(`${common.fixturesDir}/keys/agent1.pfx`),
77+
passphrase: 'sample',
78+
client: { ca: [
79+
fs.readFileSync(`${common.fixturesDir}/keys/ec-cert.pem`),
80+
fs.readFileSync(`${common.fixturesDir}/keys/ca1-cert.pem`),
81+
]},
82+
});
83+
84+
// Key and cert with mixed algorithms, and cert chains with intermediate CAs
85+
test({
86+
key: [
87+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-key.pem`),
88+
fs.readFileSync(`${common.fixturesDir}/keys/agent10-key.pem`),
89+
],
90+
cert: [
91+
fs.readFileSync(`${common.fixturesDir}/keys/agent10-cert.pem`),
92+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-cert.pem`),
93+
],
94+
rsaCN: 'agent10.example.com',
95+
eccCN: 'agent10.example.com',
96+
client: { ca: [
97+
fs.readFileSync(`${common.fixturesDir}/keys/ca2-cert.pem`),
98+
fs.readFileSync(`${common.fixturesDir}/keys/ca5-cert.pem`),
99+
]},
100+
});
101+
102+
// Key and cert with mixed algorithms, and cert chains with intermediate CAs,
103+
// using PFX for EC.
104+
test({
105+
key: [
106+
fs.readFileSync(`${common.fixturesDir}/keys/agent10-key.pem`),
107+
],
108+
cert: [
109+
fs.readFileSync(`${common.fixturesDir}/keys/agent10-cert.pem`),
110+
],
111+
pfx: fs.readFileSync(`${common.fixturesDir}/keys/ec10.pfx`),
112+
passphrase: 'sample',
113+
rsaCN: 'agent10.example.com',
114+
eccCN: 'agent10.example.com',
115+
client: { ca: [
116+
fs.readFileSync(`${common.fixturesDir}/keys/ca2-cert.pem`),
117+
fs.readFileSync(`${common.fixturesDir}/keys/ca5-cert.pem`),
118+
]},
119+
});
120+
121+
// Key and cert with mixed algorithms, and cert chains with intermediate CAs,
122+
// using PFX for RSA.
123+
test({
124+
key: [
125+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-key.pem`),
126+
],
127+
cert: [
128+
fs.readFileSync(`${common.fixturesDir}/keys/ec10-cert.pem`),
129+
],
130+
pfx: fs.readFileSync(`${common.fixturesDir}/keys/agent10.pfx`),
131+
passphrase: 'sample',
132+
rsaCN: 'agent10.example.com',
133+
eccCN: 'agent10.example.com',
134+
client: { ca: [
135+
fs.readFileSync(`${common.fixturesDir}/keys/ca2-cert.pem`),
136+
fs.readFileSync(`${common.fixturesDir}/keys/ca5-cert.pem`),
137+
]},
138+
});
41139

42-
const ciphers = [];
140+
function test(options) {
141+
const rsaCN = options.rsaCN || 'agent1';
142+
const eccCN = options.eccCN || 'agent2';
143+
const clientTrustRoots = options.client.ca;
144+
delete options.rsaCN;
145+
delete options.eccCN;
146+
delete options.client;
147+
const server = tls.createServer(options, function(conn) {
148+
conn.end('ok');
149+
}).listen(0, common.mustCall(connectWithEcdsa));
43150

44-
const server = tls.createServer(options, function(conn) {
45-
conn.end('ok');
46-
}).listen(0, function() {
47-
const ecdsa = tls.connect(this.address().port, {
48-
ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384',
49-
rejectUnauthorized: false
50-
}, function() {
51-
ciphers.push(ecdsa.getCipher());
151+
function connectWithEcdsa() {
152+
const ecdsa = tls.connect(this.address().port, {
153+
ciphers: 'ECDHE-ECDSA-AES256-GCM-SHA384',
154+
rejectUnauthorized: true,
155+
ca: clientTrustRoots,
156+
checkServerIdentity: (_, c) => assert.strictEqual(c.subject.CN, eccCN),
157+
}, common.mustCall(function() {
158+
assert.deepStrictEqual(ecdsa.getCipher(), {
159+
name: 'ECDHE-ECDSA-AES256-GCM-SHA384',
160+
version: 'TLSv1/SSLv3'
161+
});
162+
assert.strictEqual(ecdsa.getPeerCertificate().subject.CN, eccCN);
163+
// XXX(sam) certs don't currently include EC key info, so depend on
164+
// absence of RSA key info to indicate key is EC.
165+
assert(!ecdsa.getPeerCertificate().exponent, 'not cert for an RSA key');
166+
ecdsa.end();
167+
connectWithRsa();
168+
}));
169+
}
170+
171+
function connectWithRsa() {
52172
const rsa = tls.connect(server.address().port, {
53173
ciphers: 'ECDHE-RSA-AES256-GCM-SHA384',
54-
rejectUnauthorized: false
55-
}, function() {
56-
ciphers.push(rsa.getCipher());
57-
ecdsa.end();
174+
rejectUnauthorized: true,
175+
ca: clientTrustRoots,
176+
checkServerIdentity: (_, c) => assert.strictEqual(c.subject.CN, rsaCN),
177+
}, common.mustCall(function() {
178+
assert.deepStrictEqual(rsa.getCipher(), {
179+
name: 'ECDHE-RSA-AES256-GCM-SHA384',
180+
version: 'TLSv1/SSLv3'
181+
});
182+
assert.strictEqual(rsa.getPeerCertificate().subject.CN, rsaCN);
183+
assert(rsa.getPeerCertificate().exponent, 'cert for an RSA key');
58184
rsa.end();
59185
server.close();
60-
});
61-
});
62-
});
63-
64-
process.on('exit', function() {
65-
assert.deepStrictEqual(ciphers, [{
66-
name: 'ECDHE-ECDSA-AES256-GCM-SHA384',
67-
version: 'TLSv1/SSLv3'
68-
}, {
69-
name: 'ECDHE-RSA-AES256-GCM-SHA384',
70-
version: 'TLSv1/SSLv3'
71-
}]);
72-
});
186+
}));
187+
}
188+
}

0 commit comments

Comments
 (0)