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: https://github.com/nodejs/node/pull/10294 Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
parent
793d8719eb
commit
0b44384561
@ -893,12 +893,13 @@ added: v0.11.13
|
|||||||
individually. PFX is usually encrypted, if it is, `passphrase` will be used
|
individually. PFX is usually encrypted, if it is, `passphrase` will be used
|
||||||
to decrypt it.
|
to decrypt it.
|
||||||
* `key` {string|string[]|Buffer|Buffer[]|Object[]} Optional private keys in
|
* `key` {string|string[]|Buffer|Buffer[]|Object[]} Optional private keys in
|
||||||
PEM format. Single keys will be decrypted with `passphrase` if necessary.
|
PEM format. PEM allows the option of private keys being encrypted. Encrypted
|
||||||
Multiple keys, probably using different algorithms, can be provided either
|
keys will be decrypted with `options.passphrase`. Multiple keys using
|
||||||
as an array of unencrypted key strings or buffers, or an array of objects in
|
different algorithms can be provided either as an array of unencrypted key
|
||||||
the form `{pem: <string|buffer>, passphrase: <string>}`. The object form can
|
strings or buffers, or an array of objects in the form `{pem:
|
||||||
only occur in an array, and it _must_ include a passphrase, even if key is
|
<string|buffer>[, passphrase: <string>]}`. The object form can only occur in
|
||||||
not encrypted.
|
an array. `object.passphrase` is optional. Encrypted keys will be decrypted
|
||||||
|
with `object.passphrase` if provided, or `options.passphrase` if it is not.
|
||||||
* `passphrase` {string} Optional shared passphrase used for a single private
|
* `passphrase` {string} Optional shared passphrase used for a single private
|
||||||
key and/or a PFX.
|
key and/or a PFX.
|
||||||
* `cert` {string|string[]|Buffer|Buffer[]} Optional cert chains in PEM format.
|
* `cert` {string|string[]|Buffer|Buffer[]} Optional cert chains in PEM format.
|
||||||
|
@ -78,17 +78,11 @@ exports.createSecureContext = function createSecureContext(options, context) {
|
|||||||
if (Array.isArray(options.key)) {
|
if (Array.isArray(options.key)) {
|
||||||
for (i = 0; i < options.key.length; i++) {
|
for (i = 0; i < options.key.length; i++) {
|
||||||
const key = options.key[i];
|
const key = options.key[i];
|
||||||
if (key.passphrase)
|
const passphrase = key.passphrase || options.passphrase;
|
||||||
c.context.setKey(key.pem, key.passphrase);
|
c.context.setKey(key.pem || key, passphrase);
|
||||||
else
|
|
||||||
c.context.setKey(key);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (options.passphrase) {
|
c.context.setKey(options.key, options.passphrase);
|
||||||
c.context.setKey(options.key, options.passphrase);
|
|
||||||
} else {
|
|
||||||
c.context.setKey(options.key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,7 +442,10 @@ void SecureContext::SetKey(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (len == 2) {
|
if (len == 2) {
|
||||||
THROW_AND_RETURN_IF_NOT_STRING(args[1], "Pass phrase");
|
if (args[1]->IsUndefined() || args[1]->IsNull())
|
||||||
|
len = 1;
|
||||||
|
else
|
||||||
|
THROW_AND_RETURN_IF_NOT_STRING(args[1], "Pass phrase");
|
||||||
}
|
}
|
||||||
|
|
||||||
BIO *bio = LoadBIO(env, args[0]);
|
BIO *bio = LoadBIO(env, args[0]);
|
||||||
|
@ -51,13 +51,12 @@ server.listen(0, common.mustCall(function() {
|
|||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: rawKey,
|
key: rawKey,
|
||||||
passphrase: 'passphrase', // Ignored.
|
passphrase: 'ignored',
|
||||||
cert: cert,
|
cert: cert,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
|
|
||||||
// Buffer[]
|
// Buffer[]
|
||||||
/* XXX(sam) Should work, but its unimplemented ATM.
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [passKey],
|
key: [passKey],
|
||||||
@ -65,7 +64,6 @@ server.listen(0, common.mustCall(function() {
|
|||||||
cert: [cert],
|
cert: [cert],
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
*/
|
|
||||||
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
@ -77,7 +75,7 @@ server.listen(0, common.mustCall(function() {
|
|||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [rawKey],
|
key: [rawKey],
|
||||||
passphrase: 'passphrase', // Ignored.
|
passphrase: 'ignored',
|
||||||
cert: [cert],
|
cert: [cert],
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
@ -101,13 +99,12 @@ server.listen(0, common.mustCall(function() {
|
|||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: rawKey.toString(),
|
key: rawKey.toString(),
|
||||||
passphrase: 'passphrase', // Ignored.
|
passphrase: 'ignored',
|
||||||
cert: cert.toString(),
|
cert: cert.toString(),
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
|
|
||||||
// String[]
|
// String[]
|
||||||
/* XXX(sam) Should work, but its unimplemented ATM.
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [passKey.toString()],
|
key: [passKey.toString()],
|
||||||
@ -115,7 +112,6 @@ server.listen(0, common.mustCall(function() {
|
|||||||
cert: [cert.toString()],
|
cert: [cert.toString()],
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
*/
|
|
||||||
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
@ -127,7 +123,7 @@ server.listen(0, common.mustCall(function() {
|
|||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [rawKey.toString()],
|
key: [rawKey.toString()],
|
||||||
passphrase: 'passphrase', // Ignored.
|
passphrase: 'ignored',
|
||||||
cert: [cert.toString()],
|
cert: [cert.toString()],
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
@ -140,6 +136,22 @@ server.listen(0, common.mustCall(function() {
|
|||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
|
|
||||||
|
tls.connect({
|
||||||
|
port: this.address().port,
|
||||||
|
key: [{pem: passKey, passphrase: 'passphrase'}],
|
||||||
|
passphrase: 'ignored',
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
}, common.mustCall(function() {}));
|
||||||
|
|
||||||
|
tls.connect({
|
||||||
|
port: this.address().port,
|
||||||
|
key: [{pem: passKey}],
|
||||||
|
passphrase: 'passphrase',
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
}, common.mustCall(function() {}));
|
||||||
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [{pem: passKey.toString(), passphrase: 'passphrase'}],
|
key: [{pem: passKey.toString(), passphrase: 'passphrase'}],
|
||||||
@ -149,23 +161,22 @@ server.listen(0, common.mustCall(function() {
|
|||||||
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [{pem: rawKey, passphrase: 'passphrase'}],
|
key: [{pem: rawKey, passphrase: 'ignored'}],
|
||||||
cert: cert,
|
cert: cert,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [{pem: rawKey.toString(), passphrase: 'passphrase'}],
|
key: [{pem: rawKey.toString(), passphrase: 'ignored'}],
|
||||||
cert: cert,
|
cert: cert,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
|
|
||||||
/* XXX(sam) Should work, but unimplemented ATM
|
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [{pem: rawKey}],
|
key: [{pem: rawKey}],
|
||||||
passphrase: 'passphrase',
|
passphrase: 'ignored',
|
||||||
cert: cert,
|
cert: cert,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
@ -173,7 +184,7 @@ server.listen(0, common.mustCall(function() {
|
|||||||
tls.connect({
|
tls.connect({
|
||||||
port: this.address().port,
|
port: this.address().port,
|
||||||
key: [{pem: rawKey.toString()}],
|
key: [{pem: rawKey.toString()}],
|
||||||
passphrase: 'passphrase',
|
passphrase: 'ignored',
|
||||||
cert: cert,
|
cert: cert,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
@ -191,9 +202,37 @@ server.listen(0, common.mustCall(function() {
|
|||||||
cert: cert,
|
cert: cert,
|
||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
}, common.mustCall(function() {}));
|
}, common.mustCall(function() {}));
|
||||||
*/
|
|
||||||
})).unref();
|
})).unref();
|
||||||
|
|
||||||
|
// Missing passphrase
|
||||||
|
assert.throws(function() {
|
||||||
|
tls.connect({
|
||||||
|
port: server.address().port,
|
||||||
|
key: passKey,
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
}, /bad password read/);
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
tls.connect({
|
||||||
|
port: server.address().port,
|
||||||
|
key: [passKey],
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
}, /bad password read/);
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
tls.connect({
|
||||||
|
port: server.address().port,
|
||||||
|
key: [{pem: passKey}],
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
}, /bad password read/);
|
||||||
|
|
||||||
|
// Invalid passphrase
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
tls.connect({
|
tls.connect({
|
||||||
port: server.address().port,
|
port: server.address().port,
|
||||||
@ -203,3 +242,33 @@ assert.throws(function() {
|
|||||||
rejectUnauthorized: false
|
rejectUnauthorized: false
|
||||||
});
|
});
|
||||||
}, /bad decrypt/);
|
}, /bad decrypt/);
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
tls.connect({
|
||||||
|
port: server.address().port,
|
||||||
|
key: [passKey],
|
||||||
|
passphrase: 'invalid',
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
}, /bad decrypt/);
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
tls.connect({
|
||||||
|
port: server.address().port,
|
||||||
|
key: [{pem: passKey}],
|
||||||
|
passphrase: 'invalid',
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
}, /bad decrypt/);
|
||||||
|
|
||||||
|
assert.throws(function() {
|
||||||
|
tls.connect({
|
||||||
|
port: server.address().port,
|
||||||
|
key: [{pem: passKey, passphrase: 'invalid'}],
|
||||||
|
passphrase: 'passphrase', // Valid but unused
|
||||||
|
cert: cert,
|
||||||
|
rejectUnauthorized: false
|
||||||
|
});
|
||||||
|
}, /bad decrypt/);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user