diff options
author | cjihrig <cjihrig@gmail.com> | 2018-10-13 14:18:31 -0400 |
---|---|---|
committer | cjihrig <cjihrig@gmail.com> | 2018-10-21 09:32:45 -0400 |
commit | 96a986d675fbc3ccc98832232b73b84ba5a4818d (patch) | |
tree | bf36dfe628dead7bd161580e9342e9f90ef3b027 /lib | |
parent | 517955a474877893751d71b33f9c02a21bc25000 (diff) | |
download | android-node-v8-96a986d675fbc3ccc98832232b73b84ba5a4818d.tar.gz android-node-v8-96a986d675fbc3ccc98832232b73b84ba5a4818d.tar.bz2 android-node-v8-96a986d675fbc3ccc98832232b73b84ba5a4818d.zip |
tls: support changing credentials dynamically
This commit adds a setSecureContext() method to TLS servers. In
order to maintain backwards compatibility, the method takes the
options needed to create a new SecureContext, rather than an
instance of SecureContext.
Fixes: https://github.com/nodejs/node/issues/4464
Refs: https://github.com/nodejs/node/issues/10349
Refs: https://github.com/nodejs/help/issues/603
Refs: https://github.com/nodejs/node/issues/15115
PR-URL: https://github.com/nodejs/node/pull/23644
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/_tls_wrap.js | 138 |
1 files changed, 114 insertions, 24 deletions
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js index b28e3b62b7..aa8b66b715 100644 --- a/lib/_tls_wrap.js +++ b/lib/_tls_wrap.js @@ -833,22 +833,11 @@ function Server(options, listener) { // Handle option defaults: this.setOptions(options); - this._sharedCreds = tls.createSecureContext({ - pfx: this.pfx, - key: this.key, - passphrase: this.passphrase, - cert: this.cert, - clientCertEngine: this.clientCertEngine, - ca: this.ca, - ciphers: this.ciphers, - ecdhCurve: this.ecdhCurve, - dhparam: this.dhparam, - secureProtocol: this.secureProtocol, - secureOptions: this.secureOptions, - honorCipherOrder: this.honorCipherOrder, - crl: this.crl, - sessionIdContext: this.sessionIdContext - }); + // setSecureContext() overlaps with setOptions() quite a bit. setOptions() + // is an undocumented API that was probably never intended to be exposed + // publicly. Unfortunately, it would be a breaking change to just remove it, + // and there is at least one test that depends on it. + this.setSecureContext(options); this[kHandshakeTimeout] = options.handshakeTimeout || (120 * 1000); this[kSNICallback] = options.SNICallback; @@ -863,14 +852,6 @@ function Server(options, listener) { 'options.SNICallback', 'function', options.SNICallback); } - if (this.sessionTimeout) { - this._sharedCreds.context.setSessionTimeout(this.sessionTimeout); - } - - if (this.ticketKeys) { - this._sharedCreds.context.setTicketKeys(this.ticketKeys); - } - // constructor call net.Server.call(this, tlsConnectionListener); @@ -886,6 +867,115 @@ exports.createServer = function createServer(options, listener) { }; +Server.prototype.setSecureContext = function(options) { + if (options === null || typeof options !== 'object') + throw new ERR_INVALID_ARG_TYPE('options', 'Object', options); + + if (options.pfx) + this.pfx = options.pfx; + else + this.pfx = undefined; + + if (options.key) + this.key = options.key; + else + this.key = undefined; + + if (options.passphrase) + this.passphrase = options.passphrase; + else + this.passphrase = undefined; + + if (options.cert) + this.cert = options.cert; + else + this.cert = undefined; + + if (options.clientCertEngine) + this.clientCertEngine = options.clientCertEngine; + else + this.clientCertEngine = undefined; + + if (options.ca) + this.ca = options.ca; + else + this.ca = undefined; + + if (options.secureProtocol) + this.secureProtocol = options.secureProtocol; + else + this.secureProtocol = undefined; + + if (options.crl) + this.crl = options.crl; + else + this.crl = undefined; + + if (options.ciphers) + this.ciphers = options.ciphers; + else + this.ciphers = undefined; + + if (options.ecdhCurve !== undefined) + this.ecdhCurve = options.ecdhCurve; + else + this.ecdhCurve = undefined; + + if (options.dhparam) + this.dhparam = options.dhparam; + else + this.dhparam = undefined; + + if (options.honorCipherOrder !== undefined) + this.honorCipherOrder = !!options.honorCipherOrder; + else + this.honorCipherOrder = true; + + const secureOptions = options.secureOptions || 0; + + if (secureOptions) + this.secureOptions = secureOptions; + else + this.secureOptions = undefined; + + if (options.sessionIdContext) { + this.sessionIdContext = options.sessionIdContext; + } else { + this.sessionIdContext = crypto.createHash('sha1') + .update(process.argv.join(' ')) + .digest('hex') + .slice(0, 32); + } + + this._sharedCreds = tls.createSecureContext({ + pfx: this.pfx, + key: this.key, + passphrase: this.passphrase, + cert: this.cert, + clientCertEngine: this.clientCertEngine, + ca: this.ca, + ciphers: this.ciphers, + ecdhCurve: this.ecdhCurve, + dhparam: this.dhparam, + secureProtocol: this.secureProtocol, + secureOptions: this.secureOptions, + honorCipherOrder: this.honorCipherOrder, + crl: this.crl, + sessionIdContext: this.sessionIdContext + }); + + if (this.sessionTimeout) + this._sharedCreds.context.setSessionTimeout(this.sessionTimeout); + + if (options.ticketKeys) { + this.ticketKeys = options.ticketKeys; + this.setTicketKeys(this.ticketKeys); + } else { + this.setTicketKeys(this.getTicketKeys()); + } +}; + + Server.prototype._getServerData = function() { return { ticketKeys: this.getTicketKeys().toString('hex') |