server as reported by the operating system. See [net.Server.address()][] for
more information.
+### server.getTicketKeys()
+
+Returns `Buffer` instance holding the keys currently used for
+encryption/decryption of the [TLS Session Tickets][]
+
+### server.setTicketKeys(keys)
+
+Updates the keys for encryption/decryption of the [TLS Session Tickets][].
+
+NOTE: the buffer should be 48 bytes long. See server `ticketKeys` option for
+more information oh how it is going to be used.
+
+NOTE: the change is effective only for the future server connections. Existing
+or currently pending server connections will use previous keys.
+
### server.addContext(hostname, context)
Add secure context that will be used if client request's SNI hostname is
[asn1.js]: http://npmjs.org/package/asn1.js
[OCSP request]: http://en.wikipedia.org/wiki/OCSP_stapling
[TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS
+[TLS Session Tickets]: https://www.ietf.org/rfc/rfc5077.txt
Server.prototype._getServerData = function() {
return {
- ticketKeys: this._sharedCreds.context.getTicketKeys().toString('hex')
+ ticketKeys: this.getTicketKeys().toString('hex')
};
};
Server.prototype._setServerData = function(data) {
- this._sharedCreds.context.setTicketKeys(new Buffer(data.ticketKeys, 'hex'));
+ this.setTicketKeys(new Buffer(data.ticketKeys, 'hex'));
+};
+
+
+Server.prototype.getTicketKeys = function getTicketKeys(keys) {
+ return this._sharedCreds.context.getTicketKeys(keys);
+};
+
+
+Server.prototype.setTicketKeys = function setTicketKeys(keys) {
+ this._sharedCreds.context.setTicketKeys(keys);
};
function createServer() {
var id = serverCount++;
+ var counter = 0;
+ var previousKey = null;
+
var server = tls.createServer({
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'),
}, function(c) {
serverLog.push(id);
c.end();
+
+ counter++;
+
+ // Rotate ticket keys
+ if (counter === 1) {
+ previousKey = server.getTicketKeys();
+ server.setTicketKeys(crypto.randomBytes(48));
+ } else if (counter === 2) {
+ server.setTicketKeys(previousKey);
+ } else if (counter === 3) {
+ // Use keys from counter=2
+ } else {
+ throw new Error('UNREACHABLE');
+ }
});
return server;
}
-var servers = [ createServer(), createServer(),
- createServer(), createServer(),
- createServer(), createServer() ];
+var naturalServers = [ createServer(), createServer(), createServer() ];
+
+// 3x servers
+var servers = naturalServers.concat(naturalServers).concat(naturalServers);
// Create one TCP server and balance sockets to multiple TLS server instances
var shared = net.createServer(function(c) {
session: sess,
rejectUnauthorized: false
}, function() {
- sess = s.getSession() || sess;
+ sess = sess || s.getSession();
ticketLog.push(s.getTLSTicket().toString('hex'));
});
s.on('close', function() {
process.on('exit', function() {
assert.equal(ticketLog.length, serverLog.length);
- for (var i = 0; i < serverLog.length - 1; i++) {
+ for (var i = 0; i < naturalServers.length - 1; i++) {
assert.notEqual(serverLog[i], serverLog[i + 1]);
assert.equal(ticketLog[i], ticketLog[i + 1]);
+
+ // 2nd connection should have different ticket
+ assert.notEqual(ticketLog[i], ticketLog[i + naturalServers.length]);
+
+ // 3rd connection should have the same ticket
+ assert.equal(ticketLog[i], ticketLog[i + naturalServers.length * 2]);
}
});