Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit df9d8ee

Browse filesBrowse files
sam-githubMylesBorins
authored andcommitted
tls: allow obvious key/passphrase combinations
Passphrase is now used whether keys are provided singly, in an array of string/buffer, or an array of object, where it used to be ignored in some argument combinations. Specifically, these now work as expected: key: [encryptedPem], passphrase: 'passphrase' and key: [{pem: encryptedPem}] passphrase: 'passphrase' and key: [{pem: unencryptedPem}] PR-URL: #10294 Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
1 parent ae587f3 commit df9d8ee
Copy full SHA for df9d8ee

File tree

Expand file treeCollapse file tree

4 files changed

+97
-30
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

4 files changed

+97
-30
lines changed
Open diff view settings
Collapse file

‎doc/api/tls.md‎

Copy file name to clipboardExpand all lines: doc/api/tls.md
+7-6Lines changed: 7 additions & 6 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -891,12 +891,13 @@ added: v0.11.13
891891
individually. PFX is usually encrypted, if it is, `passphrase` will be used
892892
to decrypt it.
893893
* `key` {string|string[]|Buffer|Buffer[]|Object[]} Optional private keys in
894-
PEM format. Single keys will be decrypted with `passphrase` if necessary.
895-
Multiple keys, probably using different algorithms, can be provided either
896-
as an array of unencrypted key strings or buffers, or an array of objects in
897-
the form `{pem: <string|buffer>, passphrase: <string>}`. The object form can
898-
only occur in an array, and it _must_ include a passphrase, even if key is
899-
not encrypted.
894+
PEM format. PEM allows the option of private keys being encrypted. Encrypted
895+
keys will be decrypted with `options.passphrase`. Multiple keys using
896+
different algorithms can be provided either as an array of unencrypted key
897+
strings or buffers, or an array of objects in the form `{pem:
898+
<string|buffer>[, passphrase: <string>]}`. The object form can only occur in
899+
an array. `object.passphrase` is optional. Encrypted keys will be decrypted
900+
with `object.passphrase` if provided, or `options.passphrase` if it is not.
900901
* `passphrase` {string} Optional shared passphrase used for a single private
901902
key and/or a PFX.
902903
* `cert` {string|string[]|Buffer|Buffer[]} Optional cert chains in PEM format.
Collapse file

‎lib/_tls_common.js‎

Copy file name to clipboardExpand all lines: lib/_tls_common.js
+3-9Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,11 @@ exports.createSecureContext = function createSecureContext(options, context) {
7878
if (Array.isArray(options.key)) {
7979
for (i = 0; i < options.key.length; i++) {
8080
const key = options.key[i];
81-
if (key.passphrase)
82-
c.context.setKey(key.pem, key.passphrase);
83-
else
84-
c.context.setKey(key);
81+
const passphrase = key.passphrase || options.passphrase;
82+
c.context.setKey(key.pem || key, passphrase);
8583
}
8684
} else {
87-
if (options.passphrase) {
88-
c.context.setKey(options.key, options.passphrase);
89-
} else {
90-
c.context.setKey(options.key);
91-
}
85+
c.context.setKey(options.key, options.passphrase);
9286
}
9387
}
9488

Collapse file

‎src/node_crypto.cc‎

Copy file name to clipboardExpand all lines: src/node_crypto.cc
+4-1Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,10 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
446446
}
447447

448448
if (len == 2) {
449-
THROW_AND_RETURN_IF_NOT_STRING(args[1], "Pass phrase");
449+
if (args[1]->IsUndefined() || args[1]->IsNull())
450+
len = 1;
451+
else
452+
THROW_AND_RETURN_IF_NOT_STRING(args[1], "Pass phrase");
450453
}
451454

452455
BIO *bio = LoadBIO(env, args[0]);
Collapse file

‎test/parallel/test-tls-passphrase.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-tls-passphrase.js
+83-14Lines changed: 83 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,19 @@ server.listen(0, common.mustCall(function() {
5151
tls.connect({
5252
port: this.address().port,
5353
key: rawKey,
54-
passphrase: 'passphrase', // Ignored.
54+
passphrase: 'ignored',
5555
cert: cert,
5656
rejectUnauthorized: false
5757
}, common.mustCall(function() {}));
5858

5959
// Buffer[]
60-
/* XXX(sam) Should work, but its unimplemented ATM.
6160
tls.connect({
6261
port: this.address().port,
6362
key: [passKey],
6463
passphrase: 'passphrase',
6564
cert: [cert],
6665
rejectUnauthorized: false
6766
}, common.mustCall(function() {}));
68-
*/
6967

7068
tls.connect({
7169
port: this.address().port,
@@ -77,7 +75,7 @@ server.listen(0, common.mustCall(function() {
7775
tls.connect({
7876
port: this.address().port,
7977
key: [rawKey],
80-
passphrase: 'passphrase', // Ignored.
78+
passphrase: 'ignored',
8179
cert: [cert],
8280
rejectUnauthorized: false
8381
}, common.mustCall(function() {}));
@@ -101,21 +99,19 @@ server.listen(0, common.mustCall(function() {
10199
tls.connect({
102100
port: this.address().port,
103101
key: rawKey.toString(),
104-
passphrase: 'passphrase', // Ignored.
102+
passphrase: 'ignored',
105103
cert: cert.toString(),
106104
rejectUnauthorized: false
107105
}, common.mustCall(function() {}));
108106

109107
// String[]
110-
/* XXX(sam) Should work, but its unimplemented ATM.
111108
tls.connect({
112109
port: this.address().port,
113110
key: [passKey.toString()],
114111
passphrase: 'passphrase',
115112
cert: [cert.toString()],
116113
rejectUnauthorized: false
117114
}, common.mustCall(function() {}));
118-
*/
119115

120116
tls.connect({
121117
port: this.address().port,
@@ -127,7 +123,7 @@ server.listen(0, common.mustCall(function() {
127123
tls.connect({
128124
port: this.address().port,
129125
key: [rawKey.toString()],
130-
passphrase: 'passphrase', // Ignored.
126+
passphrase: 'ignored',
131127
cert: [cert.toString()],
132128
rejectUnauthorized: false
133129
}, common.mustCall(function() {}));
@@ -140,6 +136,22 @@ server.listen(0, common.mustCall(function() {
140136
rejectUnauthorized: false
141137
}, common.mustCall(function() {}));
142138

139+
tls.connect({
140+
port: this.address().port,
141+
key: [{pem: passKey, passphrase: 'passphrase'}],
142+
passphrase: 'ignored',
143+
cert: cert,
144+
rejectUnauthorized: false
145+
}, common.mustCall(function() {}));
146+
147+
tls.connect({
148+
port: this.address().port,
149+
key: [{pem: passKey}],
150+
passphrase: 'passphrase',
151+
cert: cert,
152+
rejectUnauthorized: false
153+
}, common.mustCall(function() {}));
154+
143155
tls.connect({
144156
port: this.address().port,
145157
key: [{pem: passKey.toString(), passphrase: 'passphrase'}],
@@ -149,31 +161,30 @@ server.listen(0, common.mustCall(function() {
149161

150162
tls.connect({
151163
port: this.address().port,
152-
key: [{pem: rawKey, passphrase: 'passphrase'}],
164+
key: [{pem: rawKey, passphrase: 'ignored'}],
153165
cert: cert,
154166
rejectUnauthorized: false
155167
}, common.mustCall(function() {}));
156168

157169
tls.connect({
158170
port: this.address().port,
159-
key: [{pem: rawKey.toString(), passphrase: 'passphrase'}],
171+
key: [{pem: rawKey.toString(), passphrase: 'ignored'}],
160172
cert: cert,
161173
rejectUnauthorized: false
162174
}, common.mustCall(function() {}));
163175

164-
/* XXX(sam) Should work, but unimplemented ATM
165176
tls.connect({
166177
port: this.address().port,
167178
key: [{pem: rawKey}],
168-
passphrase: 'passphrase',
179+
passphrase: 'ignored',
169180
cert: cert,
170181
rejectUnauthorized: false
171182
}, common.mustCall(function() {}));
172183

173184
tls.connect({
174185
port: this.address().port,
175186
key: [{pem: rawKey.toString()}],
176-
passphrase: 'passphrase',
187+
passphrase: 'ignored',
177188
cert: cert,
178189
rejectUnauthorized: false
179190
}, common.mustCall(function() {}));
@@ -191,9 +202,37 @@ server.listen(0, common.mustCall(function() {
191202
cert: cert,
192203
rejectUnauthorized: false
193204
}, common.mustCall(function() {}));
194-
*/
195205
})).unref();
196206

207+
// Missing passphrase
208+
assert.throws(function() {
209+
tls.connect({
210+
port: server.address().port,
211+
key: passKey,
212+
cert: cert,
213+
rejectUnauthorized: false
214+
});
215+
}, /bad password read/);
216+
217+
assert.throws(function() {
218+
tls.connect({
219+
port: server.address().port,
220+
key: [passKey],
221+
cert: cert,
222+
rejectUnauthorized: false
223+
});
224+
}, /bad password read/);
225+
226+
assert.throws(function() {
227+
tls.connect({
228+
port: server.address().port,
229+
key: [{pem: passKey}],
230+
cert: cert,
231+
rejectUnauthorized: false
232+
});
233+
}, /bad password read/);
234+
235+
// Invalid passphrase
197236
assert.throws(function() {
198237
tls.connect({
199238
port: server.address().port,
@@ -203,3 +242,33 @@ assert.throws(function() {
203242
rejectUnauthorized: false
204243
});
205244
}, /bad decrypt/);
245+
246+
assert.throws(function() {
247+
tls.connect({
248+
port: server.address().port,
249+
key: [passKey],
250+
passphrase: 'invalid',
251+
cert: cert,
252+
rejectUnauthorized: false
253+
});
254+
}, /bad decrypt/);
255+
256+
assert.throws(function() {
257+
tls.connect({
258+
port: server.address().port,
259+
key: [{pem: passKey}],
260+
passphrase: 'invalid',
261+
cert: cert,
262+
rejectUnauthorized: false
263+
});
264+
}, /bad decrypt/);
265+
266+
assert.throws(function() {
267+
tls.connect({
268+
port: server.address().port,
269+
key: [{pem: passKey, passphrase: 'invalid'}],
270+
passphrase: 'passphrase', // Valid but unused
271+
cert: cert,
272+
rejectUnauthorized: false
273+
});
274+
}, /bad decrypt/);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.