-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
tls: support changing credentials dynamically #23644
Conversation
.update(process.argv.join(' ')) | ||
.digest('hex') | ||
.slice(0, 32); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't you call this.setOptions(options)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did that originally, but setOptions()
doesn't unset values that might have been passed on the first call, but omitted on subsequent calls. I also didn't want to change the behavior of setOptions()
.
EDIT: I guess one option would be to call setOptions()
to set the options, and leave the undefined
assignments in this function to clear old values.
EDIT2: Actually, setOptions()
sets values unrelated to the secure context (requestCert
, rejectUnauthorized
, etc.), so I think I'd prefer to not call it from setSecureContext()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bnoordhuis long term, I'd prefer to deprecate/remove setOptions()
because it's undocumented and only used in the tls server constructor. The few fields that don't overlap with setSecureContext()
could be inlined in the constructor.
this.ticketKeys = options.ticketKeys; | ||
this.setTicketKeys(this.ticketKeys); | ||
} else { | ||
this.setTicketKeys(this.getTicketKeys()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my understanding: that means there is no way to disable ticket keys using .setSecureContext()
if they've been enabled before?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to focus on maintaining any keys that were already set, and figured the {set,get}TicketKeys()
APIs could be used for any additional configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cjihrig I'm somehow not understanding this code. get returns a buffer with the wrap->ticket_key_
data, and set copies its buffer argument into the wrap->ticket_key_
data... making this a no-op AFAICT. What am I missing? If the previous value of _sharedCreds (if any) had been saved, and that was used for the get, then I would understand @bnoordhuis's comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sam-github I think it is just a mistake on my part. I just ran the test suite locally with that line commented out and everything passed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, thanks for looking into it. I'm doing some session/ticket work, I'll remove the code in that PR, unless you want to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to include it in #25713, I think that would be fine.
doc/api/tls.md
Outdated
`ca`, etc). | ||
|
||
The `server.setSecureContext()` method replaces the secure context of an | ||
existing server. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the effect on current connections? Will those that have completed handshaking continue to be valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sam-github existing connections should not be impacted. I've updated the docs to specify this, and updated the tests to validate it.
b105ef4
to
44be199
Compare
if (options.pfx) | ||
this.pfx = options.pfx; | ||
else | ||
this.pfx = undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could get a bit messy with so many options, but the following pattern may save a bit of boilerplate code in this method...
Server.prototype.setSecureContext = function({
pfx = undefined,
key = undefined,
passphrase = undefined,
cert = undefined,
clientCertEngine = undefined,
ca = undefined,
secureProtocol = undefined,
crl = undefined,
ciphers = undefined,
ecdhCurve = undefined,
dhparam = undefined,
honorCipherOrder = false,
secureOptions,
sessionIdContext
} = {}) {
this.pfx = pfx;
this.key = key;
// ...
}
Not sure it's actually that much better tho ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasnell I like that pattern, because I think it would be helpful for code coverage purposes. But I'm a little worried that it's just slightly different enough from the existing options handling (setOptions()
) to cause problems. For example, right now falsy values get filtered out in most cases, but that would no longer be the case. The current structure also allows us to make the validation stricter, because right now it seems rather loose.
I already plan to follow this up with a deprecation PR for setOptions()
. I'd like to also revisit the argument validation here, but that will be semver-major.
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: nodejs#4464 Refs: nodejs#10349 Refs: nodejs/help#603 Refs: nodejs#15115 PR-URL: nodejs#23644 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
44be199
to
96a986d
Compare
It looks like the new test |
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: #4464 Refs: #10349 Refs: nodejs/help#603 Refs: #15115 PR-URL: #23644 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Would it be reasonable to allow Either: server.setSecureContext(secureContext); Or: server.setSecureContext({ secureContext: secureContext }); |
Backported in #27432, to reduce TLS1.3 conflicts. PTAL if I did it correctly. EDIT: I had to add min/maxversion back into the options (I guess due to out-of-order landing of features), and to remove a semver-major SNICallback type check. |
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: nodejs#4464 Refs: nodejs#10349 Refs: nodejs/help#603 Refs: nodejs#15115 PR-URL: nodejs#23644 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit adds a
setSecureContext()
method to TLS servers. In order to maintain backwards compatibility, the method takes the options needed to create a newSecureContext
, rather than an instance ofSecureContext
.Fixes: #4464
Refs: #10349
Refs: nodejs/help#603
Refs: #15115
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesGreen CI: https://ci.nodejs.org/job/node-test-pull-request/17941/