Browse Source

doc: rework tls for accuracy and clarity

Document all TLSSocket options:

- All the secure context options are valid options
  to a secureContext
- isServer modifies the default value of requestCert

Describe all tls.connect() variants:

- tls.connect(path) was undocumented
- tls.connect(port) was underdocumented, and its relationship to
  tls.connect(options) was obscure

Socket passed to tls.connect is user managed:

- Replace https://github.com/nodejs/node/pull/8996

Add documentation to:

- describe and add tests for the pfx and key variants, and describe how
  and when passphrase is used.
- describe tls cert and ca options
- describe buffer forms of tls crl option
- describe tls cipher option and defaults
- fix link to Crypto Constants
- describe that honorCipherOrder sets SSL_OP_CIPHER_SERVER_PREFERENCE.
- describe tls ecdhCurve/dhparam options
- describe tls secureProtocol option
- describe tls secureOptions
- describe tls sessionIdContext

De-deduplicate secure context docs:

The secure context options were documented 4 times, making it difficult
to understand where the options come from, where they are supported,
and under what conditions they are used.

The multiple copies were inconsistent and contradictory in their
descriptions of the options, and also inconsistent in whether the
options would be documented at all.

Cut through this gordian knot by linking all APIs that use the
secureContext options to the single source of truth about the options.

PR-URL: https://github.com/nodejs/node/pull/9800
Reviewed-By: Roman Reiss <me@silverwind.io>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
v6
Sam Roberts 8 years ago
parent
commit
caa7fa982a
  1. 33
      doc/api/crypto.md
  2. 361
      doc/api/tls.md
  3. 15
      test/fixtures/raw-key.pem
  4. 190
      test/parallel/test-tls-passphrase.js

33
doc/api/crypto.md

@ -1082,26 +1082,15 @@ deprecated: v0.11.13
> Stability: 0 - Deprecated: Use [`tls.createSecureContext()`][] instead. > Stability: 0 - Deprecated: Use [`tls.createSecureContext()`][] instead.
The `crypto.createCredentials()` method is a deprecated alias for creating - `details` {Object} Identical to [`tls.createSecureContext()`][].
and returning a `tls.SecureContext` object. The `crypto.createCredentials()`
method should not be used.
The optional `details` argument is a hash object with keys: The `crypto.createCredentials()` method is a deprecated function for creating
and returning a `tls.SecureContext`. It should not be used. Replace it with
[`tls.createSecureContext()`][] which has the exact same arguments and return
value.
* `pfx` : {String|Buffer} - PFX or PKCS12 encoded private Returns a `tls.SecureContext`, as-if [`tls.createSecureContext()`][] had been
key, certificate and CA certificates called.
* `key` : {String} - PEM encoded private key
* `passphrase` : {String} - passphrase for the private key or PFX
* `cert` : {String} - PEM encoded certificate
* `ca` : {String|Array} - Either a string or array of strings of PEM encoded CA
certificates to trust.
* `crl` : {String|Array} - Either a string or array of strings of PEM encoded CRLs
(Certificate Revocation List)
* `ciphers`: {String} using the [OpenSSL cipher list format][] describing the
cipher algorithms to use or exclude.
If no 'ca' details are given, Node.js will use Mozilla's default
[publicly trusted list of CAs][].
### crypto.createDecipher(algorithm, password) ### crypto.createDecipher(algorithm, password)
<!-- YAML <!-- YAML
@ -1653,8 +1642,8 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
</tr> </tr>
<tr> <tr>
<td><code>SSL_OP_CIPHER_SERVER_PREFERENCE</code></td> <td><code>SSL_OP_CIPHER_SERVER_PREFERENCE</code></td>
<td>Uses the server's preferences instead of the clients when selecting a <td>Attempts to use the server's preferences instead of the client's when
cipher. See selecting a cipher. Behaviour depends on protocol version. See
https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_options.html.</td> https://www.openssl.org/docs/man1.0.2/ssl/SSL_CTX_set_options.html.</td>
</tr> </tr>
<tr> <tr>
@ -1682,7 +1671,7 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
</tr> </tr>
<tr> <tr>
<td><code>SSL_OP_LEGACY_SERVER_CONNECT</code></td> <td><code>SSL_OP_LEGACY_SERVER_CONNECT</code></td>
<td>Allow initial connection to servers that do not support RI.</td> <td>Allows initial connection to servers that do not support RI.</td>
</tr> </tr>
<tr> <tr>
<td><code>SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER</code></td> <td><code>SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER</code></td>
@ -1980,4 +1969,4 @@ the `crypto`, `tls`, and `https` modules and are generally specific to OpenSSL.
[RFC 3526]: https://www.rfc-editor.org/rfc/rfc3526.txt [RFC 3526]: https://www.rfc-editor.org/rfc/rfc3526.txt
[stream]: stream.html [stream]: stream.html
[stream-writable-write]: stream.html#stream_writable_write_chunk_encoding_callback [stream-writable-write]: stream.html#stream_writable_write_chunk_encoding_callback
[Crypto Constants]: #crypto_crypto_constants [Crypto Constants]: #crypto_crypto_constants_1

361
doc/api/tls.md

@ -89,8 +89,9 @@ Ephemeral methods may have some performance drawbacks, because key generation
is expensive. is expensive.
To use Perfect Forward Secrecy using `DHE` with the `tls` module, it is required To use Perfect Forward Secrecy using `DHE` with the `tls` module, it is required
to generate Diffie-Hellman parameters. The following illustrates the use of the to generate Diffie-Hellman parameters and specify them with the `dhparam`
OpenSSL command-line interface to generate such parameters: option to [`tls.createSecureContext()`][]. The following illustrates the use of
the OpenSSL command-line interface to generate such parameters:
```sh ```sh
openssl dhparam -outform PEM -out dhparam.pem 2048 openssl dhparam -outform PEM -out dhparam.pem 2048
@ -179,11 +180,31 @@ line switch. For instance, the following makes
node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4" node --tls-cipher-list="ECDHE-RSA-AES128-GCM-SHA256:!RC4"
``` ```
The default can also be replaced on a per client or server basis using the
`ciphers` option from [`tls.createSecureContext()`][], which is also available
in [`tls.createServer()`], [`tls.connect()`], and when creating new
[`tls.TLSSocket`]s.
Consult [OpenSSL cipher list format documentation][] for details on the format.
*Note*: The default cipher suite included within Node.js has been carefully *Note*: The default cipher suite included within Node.js has been carefully
selected to reflect current security best practices and risk mitigation. selected to reflect current security best practices and risk mitigation.
Changing the default cipher suite can have a significant impact on the security Changing the default cipher suite can have a significant impact on the security
of an application. The `--tls-cipher-list` switch should by used only if of an application. The `--tls-cipher-list` switch and `ciphers` option should by
absolutely necessary. used only if absolutely necessary.
The default cipher suite prefers GCM ciphers for [Chrome's 'modern
cryptography' setting] and also prefers ECDHE and DHE ciphers for Perfect
Forward Secrecy, while offering *some* backward compatibility.
128 bit AES is preferred over 192 and 256 bit AES in light of [specific
attacks affecting larger AES key sizes].
Old clients that rely on insecure and deprecated RC4 or DES-based ciphers
(like Internet Explorer 6) cannot complete the handshaking process with
the default configuration. If these clients _must_ be supported, the
[TLS recommendations] may offer a compatible cipher suite. For more details
on the format, see the [OpenSSL cipher list format documentation].
## Class: tls.Server ## Class: tls.Server
<!-- YAML <!-- YAML
@ -444,12 +465,14 @@ added: v0.11.4
* `socket` {net.Socket} An instance of [`net.Socket`][] * `socket` {net.Socket} An instance of [`net.Socket`][]
* `options` {Object} * `options` {Object}
* `secureContext`: An optional TLS context object from * `isServer`: The SSL/TLS protocol is asymetrical, TLSSockets must know if
[`tls.createSecureContext()`][] they are to behave as a server or a client. If `true` the TLS socket will be
* `isServer`: If `true` the TLS socket will be instantiated in server-mode. instantiated as a server. Defaults to `false`.
Defaults to `false`.
* `server` {net.Server} An optional [`net.Server`][] instance. * `server` {net.Server} An optional [`net.Server`][] instance.
* `requestCert`: Optional, see [`tls.createServer()`][] * `requestCert`: Whether to authenticate the remote peer by requesting a
certificate. Clients always request a server certificate. Servers
(`isServer` is true) may optionally set `requestCert` to true to request a
client certificate.
* `rejectUnauthorized`: Optional, see [`tls.createServer()`][] * `rejectUnauthorized`: Optional, see [`tls.createServer()`][]
* `NPNProtocols`: Optional, see [`tls.createServer()`][] * `NPNProtocols`: Optional, see [`tls.createServer()`][]
* `ALPNProtocols`: Optional, see [`tls.createServer()`][] * `ALPNProtocols`: Optional, see [`tls.createServer()`][]
@ -458,7 +481,14 @@ added: v0.11.4
* `requestOCSP` {boolean} If `true`, specifies that the OCSP status request * `requestOCSP` {boolean} If `true`, specifies that the OCSP status request
extension will be added to the client hello and an `'OCSPResponse'` event extension will be added to the client hello and an `'OCSPResponse'` event
will be emitted on the socket before establishing a secure communication will be emitted on the socket before establishing a secure communication
* `secureContext`: Optional TLS context object created with
[`tls.createSecureContext()`][]. If a `secureContext` is _not_ provided, one
will be created by passing the entire `options` object to
`tls.createSecureContext()`. *Note*: In effect, all
[`tls.createSecureContext()`][] options can be provided, but they will be
_completely ignored_ unless the `secureContext` option is missing.
* ...: Optional [`tls.createSecureContext()`][] options can be provided, see
the `secureContext` option for more information.
Construct a new `tls.TLSSocket` object from an existing TCP socket. Construct a new `tls.TLSSocket` object from an existing TCP socket.
### Event: 'OCSPResponse' ### Event: 'OCSPResponse'
@ -708,111 +738,54 @@ and their processing can be delayed due to packet loss or reordering. However,
smaller fragments add extra TLS framing bytes and CPU overhead, which may smaller fragments add extra TLS framing bytes and CPU overhead, which may
decrease overall server throughput. decrease overall server throughput.
## tls.connect(port[, host][, options][, callback])
## tls.connect(options[, callback])
<!-- YAML <!-- YAML
added: v0.11.3 added: v0.11.3
--> -->
* `options` {Object} * `port` {number} Default value for `options.port`.
* `host` {string} Host the client should connect to. * `host` {string} Optional default value for `options.host`.
* `port` {number} Port the client should connect to. * `options` {Object} See [`tls.connect()`][].
* `socket` {net.Socket} Establish secure connection on a given socket rather * `callback` {Function} See [`tls.connect()`][].
than creating a new socket. If this option is specified, `host` and `port`
are ignored.
* `path` {string} Creates unix socket connection to path. If this option is
specified, `host` and `port` are ignored.
* `pfx` {string|Buffer} A string or `Buffer` containing the private key,
certificate, and CA certs of the client in PFX or PKCS12 format.
* `key` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of
strings, or array of `Buffer`s containing the private key of the client in
PEM format.
* `passphrase` {string} A string containing the passphrase for the private key
or pfx.
* `cert` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of
strings, or array of `Buffer`s containing the certificate key of the client
in PEM format.
* `ca` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of strings,
or array of `Buffer`s of trusted certificates in PEM format. If this is
omitted several well known "root" CAs (like VeriSign) will be used. These
are used to authorize connections.
* `ciphers` {string} A string describing the ciphers to use or exclude,
separated by `:`. Uses the same default cipher suite as
[`tls.createServer()`][].
* `rejectUnauthorized` {boolean} If `true`, the server certificate is verified
against the list of supplied CAs. An `'error'` event is emitted if
verification fails; `err.code` contains the OpenSSL error code. Defaults to
`true`.
* `NPNProtocols` {string[]|Buffer[]} An array of strings or `Buffer`s
containing supported NPN protocols. `Buffer`s should have the format
`[len][name][len][name]...` e.g. `0x05hello0x05world`, where the first
byte is the length of the next protocol name. Passing an array is usually
much simpler, e.g. `['hello', 'world']`.
* `ALPNProtocols`: {string[]|Buffer[]} An array of strings or `Buffer`s
containing the supported ALPN protocols. `Buffer`s should have the format
`[len][name][len][name]...` e.g. `0x05hello0x05world`, where the first byte
is the length of the next protocol name. Passing an array is usually much
simpler: `['hello', 'world']`.)
* `servername`: {string} Server name for the SNI (Server Name Indication) TLS
extension.
* `checkServerIdentity(servername, cert)` {Function} A callback function
to be used when checking the server's hostname against the certificate.
This should throw an error if verification fails. The method should return
`undefined` if the `servername` and `cert` are verified.
* `secureProtocol` {string} The SSL method to use, e.g. `SSLv3_method` to
force SSL version 3. The possible values depend on the version of OpenSSL
installed in the environment and are defined in the constant
[SSL_METHODS][].
* `secureContext` {object} An optional TLS context object as returned by from
`tls.createSecureContext( ... )`. It can be used for caching client
certificates, keys, and CA certificates.
* `session` {Buffer} A `Buffer` instance, containing TLS session.
* `minDHSize` {number} Minimum size of the DH parameter in bits to accept a
TLS connection. When a server offers a DH parameter with a size less
than `minDHSize`, the TLS connection is destroyed and an error is thrown.
Defaults to `1024`.
* `callback` {Function}
Creates a new client connection to the given `options.port` and `options.host` Same as [`tls.connect()`][] except that `port` and `host` can be provided
If `options.host` is omitted, it defaults to `localhost`. as arguments instead of options.
The `callback` function, if specified, will be added as a listener for the *Note*: A port or host option, if specified, will take precedence over any port
[`'secureConnect'`][] event. or host argument.
`tls.connect()` returns a [`tls.TLSSocket`][] object. ## tls.connect(path[, options][, callback])
<!-- YAML
added: v0.11.3
-->
## tls.connect(port[, host][, options][, callback]) * `path` {string} Default value for `options.path`.
* `options` {Object} See [`tls.connect()`][].
* `callback` {Function} See [`tls.connect()`][].
Same as [`tls.connect()`][] except that `path` can be provided
as an argument instead of an option.
*Note*: A path option, if specified, will take precedence over the path
argument.
## tls.connect(options[, callback])
<!-- YAML <!-- YAML
added: v0.11.3 added: v0.11.3
--> -->
* `port` {number}
* `host` {string}
* `options` {Object} * `options` {Object}
* `host` {string} Host the client should connect to. * `host` {string} Host the client should connect to, defaults to 'localhost'.
* `port` {number} Port the client should connect to. * `port` {number} Port the client should connect to.
* `socket` {net.Socket} Establish secure connection on a given socket rather
than creating a new socket. If this option is specified, `host` and `port`
are ignored.
* `path` {string} Creates unix socket connection to path. If this option is * `path` {string} Creates unix socket connection to path. If this option is
specified, `host` and `port` are ignored. specified, `host` and `port` are ignored.
* `pfx` {string|Buffer} A string or `Buffer` containing the private key, * `socket` {net.Socket} Establish secure connection on a given socket rather
certificate, and CA certs of the client in PFX or PKCS12 format. than creating a new socket. If this option is specified, `path`, `host` and
* `key` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of `port` are ignored. Usually, a socket is already connected when passed to
strings, or array of `Buffer`s containing the private key of the client in `tls.connect()`, but it can be connected later. Note that
PEM format. connection/disconnection/destruction of `socket` is the user's
* `passphrase` {string} A string containing the passphrase for the private key responsibility, calling `tls.connect()` will not cause `net.connect()` to be
or pfx. called.
* `cert` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of
strings, or array of `Buffer`s containing the certificate key of the client
in PEM format.
* `ca` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of strings,
or array of `Buffer`s of trusted certificates in PEM format. If this is
omitted several well known "root" CAs (like VeriSign) will be used. These
are used to authorize connections.
* `ciphers` {string} A string describing the ciphers to use or exclude,
separated by `:`. Uses the same default cipher suite as
[`tls.createServer()`][].
* `rejectUnauthorized` {boolean} If `true`, the server certificate is verified * `rejectUnauthorized` {boolean} If `true`, the server certificate is verified
against the list of supplied CAs. An `'error'` event is emitted if against the list of supplied CAs. An `'error'` event is emitted if
verification fails; `err.code` contains the OpenSSL error code. Defaults to verification fails; `err.code` contains the OpenSSL error code. Defaults to
@ -833,24 +806,21 @@ added: v0.11.3
to be used when checking the server's hostname against the certificate. to be used when checking the server's hostname against the certificate.
This should throw an error if verification fails. The method should return This should throw an error if verification fails. The method should return
`undefined` if the `servername` and `cert` are verified. `undefined` if the `servername` and `cert` are verified.
* `secureProtocol` {string} The SSL method to use, e.g. `SSLv3_method` to
force SSL version 3. The possible values depend on the version of OpenSSL
installed in the environment and are defined in the constant
[SSL_METHODS][].
* `secureContext` {object} An optional TLS context object as returned by from
`tls.createSecureContext( ... )`. It can be used for caching client
certificates, keys, and CA certificates.
* `session` {Buffer} A `Buffer` instance, containing TLS session. * `session` {Buffer} A `Buffer` instance, containing TLS session.
* `minDHSize` {number} Minimum size of the DH parameter in bits to accept a * `minDHSize` {number} Minimum size of the DH parameter in bits to accept a
TLS connection. When a server offers a DH parameter with a size less TLS connection. When a server offers a DH parameter with a size less
than `minDHSize`, the TLS connection is destroyed and an error is thrown. than `minDHSize`, the TLS connection is destroyed and an error is thrown.
Defaults to `1024`. Defaults to `1024`.
* `secureContext`: Optional TLS context object created with
[`tls.createSecureContext()`][]. If a `secureContext` is _not_ provided, one
will be created by passing the entire `options` object to
`tls.createSecureContext()`. *Note*: In effect, all
[`tls.createSecureContext()`][] options can be provided, but they will be
_completely ignored_ unless the `secureContext` option is missing.
* ...: Optional [`tls.createSecureContext()`][] options can be provided, see
the `secureContext` option for more information.
* `callback` {Function} * `callback` {Function}
Creates a new client connection to the given `port` and `host` or
`options.port` and `options.host`. (If `host` is omitted, it defaults to
`localhost`.)
The `callback` function, if specified, will be added as a listener for the The `callback` function, if specified, will be added as a listener for the
[`'secureConnect'`][] event. [`'secureConnect'`][] event.
@ -918,31 +888,72 @@ added: v0.11.13
--> -->
* `options` {Object} * `options` {Object}
* `pfx` {string|Buffer} A string or `Buffer` holding the PFX or PKCS12 encoded * `pfx` {string|Buffer} Optional PFX or PKCS12 encoded private key and
private key, certificate, and CA certificates. certificate chain. `pfx` is an alternative to providing `key` and `cert`
* `key` {string|string[]|Buffer|Object[]} The private key of the server in individually. PFX is usually encrypted, if it is, `passphrase` will be used
PEM format. To support multiple keys using different algorithms, an array to decrypt it.
can be provided either as an array of key strings or as an array of objects * `key` {string|string[]|Buffer|Buffer[]|Object[]} Optional private keys in
in the format `{pem: key, passphrase: passphrase}`. This option is PEM format. Single keys will be decrypted with `passphrase` if necessary.
*required* for ciphers that make use of private keys. Multiple keys, probably using different algorithms, can be provided either
* `passphrase` {string} A string containing the passphrase for the private key as an array of unencrypted key strings or buffers, or an array of objects in
or pfx. the form `{pem: <string|buffer>, passphrase: <string>}`. The object form can
* `cert` {string} A string containing the PEM encoded certificate only occur in an array, and it _must_ include a passphrase, even if key is
* `ca`{string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of strings, not encrypted.
or array of `Buffer`s of trusted certificates in PEM format. If omitted, * `passphrase` {string} Optional shared passphrase used for a single private
several well known "root" CAs (like VeriSign) will be used. These are used key and/or a PFX.
to authorize connections. * `cert` {string|string[]|Buffer|Buffer[]} Optional cert chains in PEM format.
* `crl` {string|string[]} Either a string or array of strings of PEM encoded One cert chain should be provided per private key. Each cert chain should
CRLs (Certificate Revocation List). consist of the PEM formatted certificate for a provided private `key`,
* `ciphers` {string} A string describing the ciphers to use or exclude. followed by the PEM formatted intermediate certificates (if any), in order,
Consult and not including the root CA (the root CA must be pre-known to the peer,
<https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT> see `ca`). When providing multiple cert chains, they do not have to be in
for details on the format. the same order as their private keys in `key`. If the intermediate
* `honorCipherOrder` {boolean} If `true`, when a cipher is being selected, certificates are not provided, the peer will not be able to validate the
the server's preferences will be used instead of the client preferences. certificate, and the handshake will fail.
* `ca`{string|string[]|Buffer|Buffer[]} Optional CA certificates to trust.
Default is the well-known CAs from Mozilla. When connecting to peers that
use certificates issued privately, or self-signed, the private root CA or
self-signed certificate must be provided to verify the peer.
* `crl` {string|string[]|Buffer|Buffer[]} Optional PEM formatted
CRLs (Certificate Revocation Lists).
* `ciphers` {string} Optional cipher suite specification, replacing the
default. For more information, see [modifying the default cipher suite][].
* `honorCipherOrder` {boolean} Attempt to use the server's cipher suite
preferences instead of the client's. When `true`, causes
`SSL_OP_CIPHER_SERVER_PREFERENCE` to be set in `secureOptions`, see
[OpenSSL Options][] for more information.
*Note*: [`tls.createServer()`][] sets the default value to `true`, other
APIs that create secure contexts leave it unset.
* `ecdhCurve` {string} A string describing a named curve to use for ECDH key
agreement or `false` to disable ECDH. Defaults to `prime256v1` (NIST P-256).
Use [`crypto.getCurves()`][] to obtain a list of available curve names. On
recent releases, `openssl ecparam -list_curves` will also display the name
and description of each available elliptic curve.
* `dhparam` {string|Buffer} Diffie Hellman parameters, required for
[Perfect Forward Secrecy][]. Use `openssl dhparam` to create the parameters.
The key length must be greater than or equal to 1024 bits, otherwise an
error will be thrown. It is strongly recommended to use 2048 bits or larger
for stronger security. If omitted or invalid, the parameters are silently
discarded and DHE ciphers will not be available.
* `secureProtocol` {string} Optional SSL method to use, default is
`"SSLv23_method"`. The possible values are listed as [SSL_METHODS][], use
the function names as strings. For example, `"SSLv3_method"` to force SSL
version 3.
* `secureOptions` {number} Optionally affect the OpenSSL protocol behaviour,
which is not usually necessary. This should be used carefully if at all!
Value is a numeric bitmask of the `SSL_OP_*` options from
[OpenSSL Options][].
* `sessionIdContext` {string} Optional opaque identifier used by servers to
ensure session state is not shared between applications. Unused by clients.
*Note*: [`tls.createServer()`][] uses a 128 bit truncated SHA1 hash value
generated from `process.argv`, other APIs that create secure contexts
have no default value.
The `tls.createSecureContext()` method creates a credentials object. The `tls.createSecureContext()` method creates a credentials object.
A key is *required* for ciphers that make use of certificates. Either `key` or
`pfx` can be used to provide it.
If the 'ca' option is not given, then Node.js will use the default If the 'ca' option is not given, then Node.js will use the default
publicly trusted list of CAs as given in publicly trusted list of CAs as given in
<http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt>. <http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt>.
@ -954,45 +965,10 @@ added: v0.3.2
--> -->
* `options` {Object} * `options` {Object}
* `pfx` {string|Buffer} A string or `Buffer` containing the private key,
certificate and CA certs of the server in PFX or PKCS12 format. (Mutually
exclusive with the `key`, `cert`, and `ca` options.)
* `key` {string|string[]|Buffer|Object[]} The private key of the server in
PEM format. To support multiple keys using different algorithms an array can
be provided either as a plain array of key strings or an array of objects
in the format `{pem: key, passphrase: passphrase}`. This option is
*required* for ciphers that make use of private keys.
* `passphrase` {string} A string containing the passphrase for the private
key or pfx.
* `cert` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of
strings, or array of `Buffer`s containing the certificate key of the server
in PEM format. (Required)
* `ca` {string|string[]|Buffer|Buffer[]} A string, `Buffer`, array of strings,
or array of `Buffer`s of trusted certificates in PEM format. If this is
omitted several well known "root" CAs (like VeriSign) will be used. These
are used to authorize connections.
* `crl` {string|string[]} Either a string or array of strings of PEM encoded
CRLs (Certificate Revocation List).
* `ciphers` {string} A string describing the ciphers to use or exclude,
separated by `:`.
* `ecdhCurve` {string} A string describing a named curve to use for ECDH key
agreement or `false` to disable ECDH. Defaults to `prime256v1` (NIST P-256).
Use [`crypto.getCurves()`][] to obtain a list of available curve names. On
recent releases, `openssl ecparam -list_curves` will also display the name
and description of each available elliptic curve.
* `dhparam` {string|Buffer} A string or `Buffer` containing Diffie Hellman
parameters, required for [Perfect Forward Secrecy][]. Use
`openssl dhparam` to create the parameters. The key length must be greater
than or equal to 1024 bits, otherwise an error will be thrown. It is
strongly recommended to use 2048 bits or larger for stronger security. If
omitted or invalid, the parameters are silently discarded and DHE ciphers
will not be available.
* `handshakeTimeout` {number} Abort the connection if the SSL/TLS handshake * `handshakeTimeout` {number} Abort the connection if the SSL/TLS handshake
does not finish in the specified number of milliseconds. Defaults to `120` does not finish in the specified number of milliseconds. Defaults to `120`
seconds. A `'clientError'` is emitted on the `tls.Server` object whenever a seconds. A `'clientError'` is emitted on the `tls.Server` object whenever a
handshake times out. handshake times out.
* `honorCipherOrder` {boolean} When choosing a cipher, use the server's
preferences instead of the client preferences. Defaults to `true`.
* `requestCert` {boolean} If `true` the server will request a certificate from * `requestCert` {boolean} If `true` the server will request a certificate from
clients that connect and attempt to verify that certificate. Defaults to clients that connect and attempt to verify that certificate. Defaults to
`false`. `false`.
@ -1019,58 +995,13 @@ added: v0.3.2
a 16-byte HMAC key, and a 16-byte AES key. This can be used to accept TLS a 16-byte HMAC key, and a 16-byte AES key. This can be used to accept TLS
session tickets on multiple instances of the TLS server. *Note* that this is session tickets on multiple instances of the TLS server. *Note* that this is
automatically shared between `cluster` module workers. automatically shared between `cluster` module workers.
* `sessionIdContext` {string} A string containing an opaque identifier for * ...: Any [`tls.createSecureContext()`][] options can be provided. For
session resumption. If `requestCert` is `true`, the default is a 128 bit servers, the identity options (`pfx` or `key`/`cert`) are usually required.
truncated SHA1 hash value generated from the command-line. Otherwise, a
default is not provided.
* `secureProtocol` {string} The SSL method to use, e.g. `SSLv3_method` to
force SSL version 3. The possible values depend on the version of OpenSSL
installed in the environment and are defined in the constant
[SSL_METHODS][].
* `secureConnectionListener` {Function} * `secureConnectionListener` {Function}
Creates a new [tls.Server][]. The `secureConnectionListener`, if provided, is Creates a new [tls.Server][]. The `secureConnectionListener`, if provided, is
automatically set as a listener for the [`'secureConnection'`][] event. automatically set as a listener for the [`'secureConnection'`][] event.
For the `ciphers` option, the default cipher suite is:
```text
ECDHE-RSA-AES128-GCM-SHA256:
ECDHE-ECDSA-AES128-GCM-SHA256:
ECDHE-RSA-AES256-GCM-SHA384:
ECDHE-ECDSA-AES256-GCM-SHA384:
DHE-RSA-AES128-GCM-SHA256:
ECDHE-RSA-AES128-SHA256:
DHE-RSA-AES128-SHA256:
ECDHE-RSA-AES256-SHA384:
DHE-RSA-AES256-SHA384:
ECDHE-RSA-AES256-SHA256:
DHE-RSA-AES256-SHA256:
HIGH:
!aNULL:
!eNULL:
!EXPORT:
!DES:
!RC4:
!MD5:
!PSK:
!SRP:
!CAMELLIA
```
The default cipher suite prefers GCM ciphers for [Chrome's 'modern
cryptography' setting] and also prefers ECDHE and DHE ciphers for Perfect
Forward Secrecy, while offering *some* backward compatibility.
128 bit AES is preferred over 192 and 256 bit AES in light of [specific
attacks affecting larger AES key sizes].
Old clients that rely on insecure and deprecated RC4 or DES-based ciphers
(like Internet Explorer 6) cannot complete the handshaking process with
the default configuration. If these clients _must_ be supported, the
[TLS recommendations] may offer a compatible cipher suite. For more details
on the format, see the [OpenSSL cipher list format documentation].
The following illustrates a simple echo server: The following illustrates a simple echo server:
```js ```js
@ -1254,6 +1185,8 @@ where `secure_socket` has the same API as `pair.cleartext`.
[OpenSSL cipher list format documentation]: https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT [OpenSSL cipher list format documentation]: https://www.openssl.org/docs/man1.0.2/apps/ciphers.html#CIPHER-LIST-FORMAT
[Chrome's 'modern cryptography' setting]: https://www.chromium.org/Home/chromium-security/education/tls#TOC-Cipher-Suites [Chrome's 'modern cryptography' setting]: https://www.chromium.org/Home/chromium-security/education/tls#TOC-Cipher-Suites
[OpenSSL Options]: crypto.html#crypto_openssl_options
[modifying the default cipher suite]: #tls_modifying_the_default_tls_cipher_suite
[specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html [specific attacks affecting larger AES key sizes]: https://www.schneier.com/blog/archives/2009/07/another_new_aes.html
[`crypto.getCurves()`]: crypto.html#crypto_crypto_getcurves [`crypto.getCurves()`]: crypto.html#crypto_crypto_getcurves
[`tls.createServer()`]: #tls_tls_createserver_options_secureconnectionlistener [`tls.createServer()`]: #tls_tls_createserver_options_secureconnectionlistener

15
test/fixtures/raw-key.pem

@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQChmQeFwsaomtQbw9Nm55Dn6KSR9bkY8PDroQUeTNa90BlIbhGs
KYm4l7bERaasFgOrkcQpk45fdDVYPjKxraZiGXXKjSIDYeDAIC/+CkwQKrejgCPm
Js4gV4g+npvwi1gVr2NAg7fkJOyEW2TDp4dsAD8qtG8Aml0C1hJXwFYmBwIDAQAB
AoGAVgZpAsQVjVwe3kj5GSbc9Rfbw/fTeXuKRWWKm/67soA9dVli/wt9zU62dPW/
LIzrl0IZ8ygh+p6aZ0d1JTEUCPx7e0KocCmNg77i5AG0eK5i/KKjTWB4UGRDylfD
dnBXQc814bK+VB0mrcp46U/7tLGYkV2Kz/LiNpmxKwITS4ECQQDPoA6WIU87Eulq
OuVmJnFIQ2IR3SycVisO7TUq2MItq2U4BwsA3aQ4ehpP/uJdAfJEfwi2omRV5pGb
806pWkfPAkEAxz+igHS8tR11aLck71dD4BRBY7XZCUg6G4zmYYWsqj0yvM6c4Yn0
HRcrZqFvV/xuMFphWEmMBhrqLvgy66yUSQJBALkei4LeRid0sDswMhMHGaAFvG4T
FtB5n8CaTPpb854GoKP42521ANP+QnGq36dvsdPStDEqz20rvA4hPLSQs08CQCV8
eWxFikNg+XfsDQzilCiSZwMFcYHnjtckGSv75FJbFTKkhKuCMuVOOKIkeThKi8iZ
GHttyuRTKAASPjJM09ECQBrhlKJwYKuUDMp3qkLBgrXYqbFxZtkS2GeFMUfLcRlx
oMrTFEczz9lZ0huTuQYPeAAOY0Gd84mL0kQqTRTzNLs=
-----END RSA PRIVATE KEY-----

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

@ -1,21 +1,27 @@
'use strict'; 'use strict';
var common = require('../common'); const common = require('../common');
var assert = require('assert'); const assert = require('assert');
if (!common.hasCrypto) { if (!common.hasCrypto) {
common.skip('missing crypto'); common.skip('missing crypto');
return; return;
} }
var tls = require('tls'); const tls = require('tls');
var fs = require('fs'); const fs = require('fs');
var path = require('path'); const path = require('path');
var key = fs.readFileSync(path.join(common.fixturesDir, 'pass-key.pem')); const passKey = fs.readFileSync(path.join(common.fixturesDir, 'pass-key.pem'));
var cert = fs.readFileSync(path.join(common.fixturesDir, 'pass-cert.pem')); const rawKey = fs.readFileSync(path.join(common.fixturesDir, 'raw-key.pem'));
const cert = fs.readFileSync(path.join(common.fixturesDir, 'pass-cert.pem'));
var server = tls.Server({ assert(Buffer.isBuffer(passKey));
key: key, assert(Buffer.isBuffer(cert));
assert.strictEqual(typeof passKey.toString(), 'string');
assert.strictEqual(typeof cert.toString(), 'string');
const server = tls.Server({
key: passKey,
passphrase: 'passphrase', passphrase: 'passphrase',
cert: cert, cert: cert,
ca: [cert], ca: [cert],
@ -26,24 +32,174 @@ var server = tls.Server({
}); });
server.listen(0, common.mustCall(function() { server.listen(0, common.mustCall(function() {
var c = tls.connect({ // Buffer
tls.connect({
port: this.address().port, port: this.address().port,
key: key, key: passKey,
passphrase: 'passphrase', passphrase: 'passphrase',
cert: cert, cert: cert,
rejectUnauthorized: false rejectUnauthorized: false
}, common.mustCall(function() {})); }, common.mustCall(function() {}));
c.on('end', function() {
server.close(); tls.connect({
}); port: this.address().port,
})); key: rawKey,
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: rawKey,
passphrase: 'passphrase', // Ignored.
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
// Buffer[]
/* XXX(sam) Should work, but its unimplemented ATM.
tls.connect({
port: this.address().port,
key: [passKey],
passphrase: 'passphrase',
cert: [cert],
rejectUnauthorized: false
}, common.mustCall(function() {}));
*/
tls.connect({
port: this.address().port,
key: [rawKey],
cert: [cert],
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [rawKey],
passphrase: 'passphrase', // Ignored.
cert: [cert],
rejectUnauthorized: false
}, common.mustCall(function() {}));
// string
tls.connect({
port: this.address().port,
key: passKey.toString(),
passphrase: 'passphrase',
cert: cert.toString(),
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: rawKey.toString(),
cert: cert.toString(),
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: rawKey.toString(),
passphrase: 'passphrase', // Ignored.
cert: cert.toString(),
rejectUnauthorized: false
}, common.mustCall(function() {}));
// String[]
/* XXX(sam) Should work, but its unimplemented ATM.
tls.connect({
port: this.address().port,
key: [passKey.toString()],
passphrase: 'passphrase',
cert: [cert.toString()],
rejectUnauthorized: false
}, common.mustCall(function() {}));
*/
tls.connect({
port: this.address().port,
key: [rawKey.toString()],
cert: [cert.toString()],
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [rawKey.toString()],
passphrase: 'passphrase', // Ignored.
cert: [cert.toString()],
rejectUnauthorized: false
}, common.mustCall(function() {}));
// Object[]
tls.connect({
port: this.address().port,
key: [{pem: passKey, passphrase: 'passphrase'}],
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [{pem: passKey.toString(), passphrase: 'passphrase'}],
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [{pem: rawKey, passphrase: 'passphrase'}],
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [{pem: rawKey.toString(), passphrase: 'passphrase'}],
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
/* XXX(sam) Should work, but unimplemented ATM
tls.connect({
port: this.address().port,
key: [{pem: rawKey}],
passphrase: 'passphrase',
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [{pem: rawKey.toString()}],
passphrase: 'passphrase',
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [{pem: rawKey}],
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
tls.connect({
port: this.address().port,
key: [{pem: rawKey.toString()}],
cert: cert,
rejectUnauthorized: false
}, common.mustCall(function() {}));
*/
})).unref();
assert.throws(function() { assert.throws(function() {
tls.connect({ tls.connect({
port: server.address().port, port: server.address().port,
key: key, key: passKey,
passphrase: 'invalid', passphrase: 'invalid',
cert: cert, cert: cert,
rejectUnauthorized: false rejectUnauthorized: false
}); });
}); }, /bad decrypt/);

Loading…
Cancel
Save