|
|
|
## TLS (SSL)
|
|
|
|
|
|
|
|
Use `require('tls')` to access this module.
|
|
|
|
|
|
|
|
The `tls` module uses OpenSSL to provide Transport Layer Security and/or
|
|
|
|
Secure Socket Layer: encrypted stream communication.
|
|
|
|
|
|
|
|
TLS/SSL is a public/private key infrastructure. Each client and each
|
|
|
|
server must have a private key. A private key is created like this
|
|
|
|
|
|
|
|
openssl genrsa -out ryans-key.pem 1024
|
|
|
|
|
|
|
|
All severs and some clients need to have a certificate. Certificates are public
|
|
|
|
keys signed by a Certificate Authority or self-signed. The first step to
|
|
|
|
getting a certificate is to create a "Certificate Signing Request" (CSR)
|
|
|
|
file. This is done with:
|
|
|
|
|
|
|
|
openssl req -new -key ryans-key.pem -out ryans-csr.pem
|
|
|
|
|
|
|
|
To create a self-signed certificate with the CSR, do this:
|
|
|
|
|
|
|
|
openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem
|
|
|
|
|
|
|
|
Alternatively you can send the CSR to a Certificate Authority for signing.
|
|
|
|
|
|
|
|
(TODO: docs on creating a CA, for now interested users should just look at
|
|
|
|
`test/fixtures/keys/Makefile` in the Node source code)
|
|
|
|
|
|
|
|
|
|
|
|
### s = tls.connect(port, [host], [options], callback)
|
|
|
|
|
|
|
|
Creates a new client connection to the given `port` and `host`. (If `host`
|
|
|
|
defaults to `localhost`.) `options` should be an object which specifies
|
|
|
|
|
|
|
|
- `key`: A string or `Buffer` containing the private key of the server in
|
|
|
|
PEM format. (Required)
|
|
|
|
|
|
|
|
- `cert`: A string or `Buffer` containing the certificate key of the server in
|
|
|
|
PEM format.
|
|
|
|
|
|
|
|
- `ca`: An array of strings or `Buffer`s of trusted certificates. If this is
|
|
|
|
omitted several well known "root" CAs will be used, like VeriSign.
|
|
|
|
These are used to authorize connections.
|
|
|
|
|
|
|
|
`tls.connect()` returns a cleartext `CryptoStream` object.
|
|
|
|
|
|
|
|
After the TLS/SSL handshake the `callback` is called. The `callback` will be
|
|
|
|
called no matter if the server's certificate was authorized or not. It is up
|
|
|
|
to the user to test `s.authorized` to see if the server certificate was
|
|
|
|
signed by one of the specified CAs. If `s.authorized === false` then the error
|
|
|
|
can be found in `s.authorizationError`.
|
|
|
|
|
|
|
|
|
|
|
|
### STARTTLS
|
|
|
|
|
|
|
|
In the v0.4 branch no function exists for starting a TLS session on an
|
|
|
|
already existing TCP connection. This is possible it just requires a bit of
|
|
|
|
work. The technique is to use `tls.createSecurePair()` which returns two
|
|
|
|
streams: an encrypted stream and a plaintext stream. The encrypted stream is then
|
|
|
|
piped to the socket, the plaintext stream is what the user interacts with thereafter.
|
|
|
|
|
|
|
|
[Here is some code that does it.](http://gist.github.com/848444)
|
|
|
|
|
|
|
|
### pair = tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
|
|
|
|
|
|
|
|
Creates a new secure pair object with two streams, one of which reads/writes encrypted data, and one reads/writes cleartext data.
|
|
|
|
Generally the encrypted one is piped to/from an incoming encrypted data stream, and the cleartext one
|
|
|
|
is used as a replacement for the initial encrypted stream.
|
|
|
|
|
|
|
|
- `credentials`: A credentials object from crypto.createCredentials( ... )
|
|
|
|
|
|
|
|
- `isServer`: A boolean indicating whether this tls connection should be opened as a server or a client.
|
|
|
|
|
|
|
|
- `requestCert`: A boolean indicating whether a server should request a certificate from
|
|
|
|
a connecting client. Only applies to server connections.
|
|
|
|
|
|
|
|
- `rejectUnauthorized`: A boolean indicating whether a server should automatically
|
|
|
|
reject clients with invalid certificates. Only applies to servers with `requestCert` enabled.
|
|
|
|
|
|
|
|
`tls.createSecurePair()` returns a SecurePair object with `cleartext` and `encrypted` stream properties.
|
|
|
|
|
|
|
|
#### Event: 'secure'
|
|
|
|
|
|
|
|
The event is emitted from the SecurePair once the pair has successfully established a secure connection.
|
|
|
|
|
|
|
|
Similarly to the checking for the server 'secureConnection' event, pair.cleartext.authorized should be
|
|
|
|
checked to confirm whether the certificate used properly authorized.
|
|
|
|
|
|
|
|
### tls.Server
|
|
|
|
|
|
|
|
This class is a subclass of `net.Server` and has the same methods on it.
|
|
|
|
Instead of accepting just raw TCP connections, this accepts encrypted
|
|
|
|
connections using TLS or SSL.
|
|
|
|
|
|
|
|
Here is a simple example echo server:
|
|
|
|
|
|
|
|
var tls = require('tls');
|
|
|
|
var fs = require('fs');
|
|
|
|
|
|
|
|
var options = {
|
|
|
|
key: fs.readFileSync('server-key.pem'),
|
|
|
|
cert: fs.readFileSync('server-cert.pem')
|
|
|
|
};
|
|
|
|
|
|
|
|
tls.createServer(options, function (s) {
|
|
|
|
s.write("welcome!\n");
|
|
|
|
s.pipe(s);
|
|
|
|
}).listen(8000);
|
|
|
|
|
|
|
|
|
|
|
|
You can test this server by connecting to it with `openssl s_client`:
|
|
|
|
|
|
|
|
|
|
|
|
openssl s_client -connect 127.0.0.1:8000
|
|
|
|
|
|
|
|
|
|
|
|
#### tls.createServer(options, secureConnectionListener)
|
|
|
|
|
|
|
|
This is a constructor for the `tls.Server` class. The options object
|
|
|
|
has these possibilities:
|
|
|
|
|
|
|
|
- `key`: A string or `Buffer` containing the private key of the server in
|
|
|
|
PEM format. (Required)
|
|
|
|
|
|
|
|
- `cert`: A string or `Buffer` containing the certificate key of the server in
|
|
|
|
PEM format. (Required)
|
|
|
|
|
|
|
|
- `ca`: An array of strings or `Buffer`s of trusted certificates. If this is
|
|
|
|
omitted several well known "root" CAs will be used, like VeriSign.
|
|
|
|
These are used to authorize connections.
|
|
|
|
|
|
|
|
- `requestCert`: If `true` the server will request a certificate from
|
|
|
|
clients that connect and attempt to verify that certificate. Default:
|
|
|
|
`false`.
|
|
|
|
|
|
|
|
- `rejectUnauthorized`: If `true` the server will reject any connection
|
|
|
|
which is not authorized with the list of supplied CAs. This option only
|
|
|
|
has an effect if `requestCert` is `true`. Default: `false`.
|
|
|
|
|
|
|
|
|
|
|
|
#### Event: 'secureConnection'
|
|
|
|
|
|
|
|
`function (cleartextStream) {}`
|
|
|
|
|
|
|
|
This event is emitted after a new connection has been successfully
|
|
|
|
handshaked. The argument is a duplex instance of `stream.Stream`. It has all
|
|
|
|
the common stream methods and events.
|
|
|
|
|
|
|
|
`cleartextStream.authorized` is a boolean value which indicates if the
|
|
|
|
client has verified by one of the supplied certificate authorities for the
|
|
|
|
server. If `cleartextStream.authorized` is false, then
|
|
|
|
`cleartextStream.authorizationError` is set to describe how authorization
|
|
|
|
failed. Implied but worth mentioning: depending on the settings of the TLS
|
|
|
|
server, you unauthorized connections may be accepted.
|
|
|
|
|
|
|
|
|
|
|
|
#### server.listen(port, [host], [callback])
|
|
|
|
|
|
|
|
Begin accepting connections on the specified `port` and `host`. If the
|
|
|
|
`host` is omitted, the server will accept connections directed to any
|
|
|
|
IPv4 address (`INADDR_ANY`).
|
|
|
|
|
|
|
|
This function is asynchronous. The last parameter `callback` will be called
|
|
|
|
when the server has been bound.
|
|
|
|
|
|
|
|
See `net.Server` for more information.
|
|
|
|
|
|
|
|
|
|
|
|
#### server.close()
|
|
|
|
|
|
|
|
Stops the server from accepting new connections. This function is
|
|
|
|
asynchronous, the server is finally closed when the server emits a `'close'`
|
|
|
|
event.
|
|
|
|
|
|
|
|
|
|
|
|
#### server.maxConnections
|
|
|
|
|
|
|
|
Set this property to reject connections when the server's connection count gets high.
|
|
|
|
|
|
|
|
#### server.connections
|
|
|
|
|
|
|
|
The number of concurrent connections on the server.
|