Skip to content

Commit e11fc67

Browse files
committed
tls: add getTicketKeys()/setTicketKeys()
Introduce two new APIs for getting/settings the TLS Server Ticket Keys. Fix: #1465 PR-URL: #2227 Reviewed-By: Ben Noordhuis <[email protected]>
1 parent 4ef2b5f commit e11fc67

File tree

3 files changed

+57
-7
lines changed

3 files changed

+57
-7
lines changed

doc/api/tls.markdown

+16
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,21 @@ Returns the bound address, the address family name and port of the
630630
server as reported by the operating system. See [net.Server.address()][] for
631631
more information.
632632

633+
### server.getTicketKeys()
634+
635+
Returns `Buffer` instance holding the keys currently used for
636+
encryption/decryption of the [TLS Session Tickets][]
637+
638+
### server.setTicketKeys(keys)
639+
640+
Updates the keys for encryption/decryption of the [TLS Session Tickets][].
641+
642+
NOTE: the buffer should be 48 bytes long. See server `ticketKeys` option for
643+
more information oh how it is going to be used.
644+
645+
NOTE: the change is effective only for the future server connections. Existing
646+
or currently pending server connections will use previous keys.
647+
633648
### server.addContext(hostname, context)
634649

635650
Add secure context that will be used if client request's SNI hostname is
@@ -835,3 +850,4 @@ The numeric representation of the local port.
835850
[asn1.js]: http://npmjs.org/package/asn1.js
836851
[OCSP request]: http://en.wikipedia.org/wiki/OCSP_stapling
837852
[TLS recommendations]: https://wiki.mozilla.org/Security/Server_Side_TLS
853+
[TLS Session Tickets]: https://www.ietf.org/rfc/rfc5077.txt

lib/_tls_wrap.js

+12-2
Original file line numberDiff line numberDiff line change
@@ -812,13 +812,23 @@ exports.createServer = function(options, listener) {
812812

813813
Server.prototype._getServerData = function() {
814814
return {
815-
ticketKeys: this._sharedCreds.context.getTicketKeys().toString('hex')
815+
ticketKeys: this.getTicketKeys().toString('hex')
816816
};
817817
};
818818

819819

820820
Server.prototype._setServerData = function(data) {
821-
this._sharedCreds.context.setTicketKeys(new Buffer(data.ticketKeys, 'hex'));
821+
this.setTicketKeys(new Buffer(data.ticketKeys, 'hex'));
822+
};
823+
824+
825+
Server.prototype.getTicketKeys = function getTicketKeys(keys) {
826+
return this._sharedCreds.context.getTicketKeys(keys);
827+
};
828+
829+
830+
Server.prototype.setTicketKeys = function setTicketKeys(keys) {
831+
this._sharedCreds.context.setTicketKeys(keys);
822832
};
823833

824834

test/parallel/test-tls-ticket.js

+29-5
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,39 @@ var serverCount = 0;
2020
function createServer() {
2121
var id = serverCount++;
2222

23+
var counter = 0;
24+
var previousKey = null;
25+
2326
var server = tls.createServer({
2427
key: fs.readFileSync(common.fixturesDir + '/keys/agent1-key.pem'),
2528
cert: fs.readFileSync(common.fixturesDir + '/keys/agent1-cert.pem'),
2629
ticketKeys: keys
2730
}, function(c) {
2831
serverLog.push(id);
2932
c.end();
33+
34+
counter++;
35+
36+
// Rotate ticket keys
37+
if (counter === 1) {
38+
previousKey = server.getTicketKeys();
39+
server.setTicketKeys(crypto.randomBytes(48));
40+
} else if (counter === 2) {
41+
server.setTicketKeys(previousKey);
42+
} else if (counter === 3) {
43+
// Use keys from counter=2
44+
} else {
45+
throw new Error('UNREACHABLE');
46+
}
3047
});
3148

3249
return server;
3350
}
3451

35-
var servers = [ createServer(), createServer(),
36-
createServer(), createServer(),
37-
createServer(), createServer() ];
52+
var naturalServers = [ createServer(), createServer(), createServer() ];
53+
54+
// 3x servers
55+
var servers = naturalServers.concat(naturalServers).concat(naturalServers);
3856

3957
// Create one TCP server and balance sockets to multiple TLS server instances
4058
var shared = net.createServer(function(c) {
@@ -54,7 +72,7 @@ function start(callback) {
5472
session: sess,
5573
rejectUnauthorized: false
5674
}, function() {
57-
sess = s.getSession() || sess;
75+
sess = sess || s.getSession();
5876
ticketLog.push(s.getTLSTicket().toString('hex'));
5977
});
6078
s.on('close', function() {
@@ -70,8 +88,14 @@ function start(callback) {
7088

7189
process.on('exit', function() {
7290
assert.equal(ticketLog.length, serverLog.length);
73-
for (var i = 0; i < serverLog.length - 1; i++) {
91+
for (var i = 0; i < naturalServers.length - 1; i++) {
7492
assert.notEqual(serverLog[i], serverLog[i + 1]);
7593
assert.equal(ticketLog[i], ticketLog[i + 1]);
94+
95+
// 2nd connection should have different ticket
96+
assert.notEqual(ticketLog[i], ticketLog[i + naturalServers.length]);
97+
98+
// 3rd connection should have the same ticket
99+
assert.equal(ticketLog[i], ticketLog[i + naturalServers.length * 2]);
76100
}
77101
});

0 commit comments

Comments
 (0)