| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
@shigeki, how does this approach sound to you? |
Sorry, something went wrong.
|
/cc @nodejs/crypto |
Sorry, something went wrong.
|
/cc @nodejs/tsc |
Sorry, something went wrong.
|
@davidben do you have an insight into if there is planned fips support for openssl 1.1.0? I know that has been a reason for us to not upgrade in the past |
Sorry, something went wrong.
|
You'll have to ask OpenSSL folks about that one. But I don't think it makes sense to wait for it before supporting it at all, maybe just before shipping it in the bundled copy. Switching to 1.1.0 is a large change with deprecation consequences. You're better off getting things in sooner rather than later so you can plan for it before 1.0.2 goes EOL. (I intentionally did not switch the bundled copy in this PR.) Moreover, folks like Linux distributions may switch before you do. They may just pick up the old PR which would be problematic as it didn't work right. |
Sorry, something went wrong.
|
@MylesBorins I think we are at the point where regardless of FIPs validation status for 1.1.0 we will need to upgrade. I believe that version 8.x was the last one where openssl 1.0.2 would be supported long enough to use it in an LTS release. |
Sorry, something went wrong.
|
@davidben thanks for putting this together. It is important that we have a path to 1.1.0 sooner than later. Based on the size of change, this may take a bit of time for the reviewers to be able to comment. |
Sorry, something went wrong.
|
node 8.x and openssl 1.0.2 both go out of support in Dec, 2019 Interestingly, openssl 1.1.0 goes out of support in Aug, 2018, before 1.0.2. We can use openssl 1.1.0 for node 9.x, because 9.x will be short-lived. For node 10.x, which is LTS for us, we will want to use an openssl release that will be supported for its lifetime, I assume. They haven't released one yet, and I can't find anywhere where they commit to a release date for the next LTS openssl, though they say this:
Since 1.0.2 was released in jan 2015, if I understand correctly, there should be a LTS release of openssl by jan 2019. But hopefully they won't wait to the last minute, because node 10.x goes LTS in october 2018. What would be most awkward for us would be if openssl 1.1.0 goes out of support while we are using it for 10.x and getting ready for LTS, and there is no replacement yet. What would we do, go back to openssl 1.0.2? I strongly suspect that won't happen. That either 1.1.0 will become LTS by then, or that there will be a 1.2.0 by then and it will be called LTS, but I'm speculating. |
Sorry, something went wrong.
|
I'm adding the TSC-Agenda label. Specifically I think the TSC should create a interest group specifically focused around coming up with some suggestions around how we can deal with this. We only have 6 months before the 10.x cut |
Sorry, something went wrong.
|
I can't speak for OpenSSL, but I am sure either 1.1.1 will be released before 1.1.0 goes out of support or they will extend support for 1.1.0. It wouldn't make much sense for 1.0.2 to be the only supported OpenSSL release at any point. :-) |
Sorry, something went wrong.
|
OpenSSL 1.1.1's release is essentially waiting on a final version of the TLS 1.3 specification from the IETF. There is no hard deadline on this happening, but I agree with @davidben that it would be silly for 1.0.2 to be the only supported OpenSSL release. |
Sorry, something went wrong.
|
An important issue we need to consider here is how packagers are dynamically linking Node to their own versions of OpenSSL. Maximising the options for them to do that is going to be in our interests because we're not going to stop them from doing this (dynamic linking and separating out dependant packages is strict policy in Debian-land for instance) and they're already shipping Node in ways that are not strictly compatible with core since we do some patching of OpenSSL in our own statically linked version that is never picked up downstream. So, supporting both 1.0.2 and 1.1.0 as soon as possible makes a lot of sense, so I'd be keen to see this PR move forward even while we're tied primarily to 1.0.2. Packagers can then opt to compile against 1.1.0 if it suits their needs, or stick to 1.0.2 which is still going to be more common for Linux distros for a while yet. i.e. there's going to be an extended period where our downstream packagers are going to be (either forced to, or preferring to) opting for 1.1.x or 1.0.2 in their linking regardless of what we would prefer them to do and the less we help them the more they're going to be doing a hacky job of it. Given that we're about to hit 9.x, we're unlikely to get any breaking changes in there so the ideal might look something like this:
We can fire up at least one dedicated 1.1.0 node in Jenkins like we have for FIPS now, it'd be great to be testing it multiple ways (ideally we'd also have dynamic-linking nodes in there too, we've talked about that for a while but never done it). wrt to some of the specifics in OP:
Huge thanks to @davidben for this work and being so thorough in description and advice here! |
Sorry, something went wrong.
|
To add to the distro thing, another reason to get 1.1.0 support in sooner rather than later is this way the support won't bitrot and you can test out all the ramifications while you still have time for the 9.x deprecation cycle. Everything I wrote in the OP was stuff I only realized working on this PR.
Yup, the intent was that this PR has no user-visible changes when building against 1.0.2. (Though certainly this needs careful review to make sure I got it right!)
As far as I can tell, that's correct. The closest you all get to using some of it is in TLS tests used anonymous ciphers to avoid needing to configure certs. (This PR makes them configure certs instead.)
It's mostly that OpenSSL's errors are not very good at being stable. The most obvious change is that the function code switched from all caps to actually being the function code. And function codes existing at all mean renaming an internally OpenSSL function will change that part of the error string! And then there are some minor differences just because some of the SSL code was reworked and invalid things are detected differently. (Version negotiation in particular goes through a very different codepath. OpenSSL 1.0.x's version negotiation logic was kind of weird. OpenSSL 1.1.0 does it better.)
Not a problem in itself but the server.setTicketKeys API expects the caller just know 48 is the magic number. It's documented as such and whatnot. There's also no other way to find out the expected key length, so I expect anyone using this API is indeed just hardcoding 48. (Unless they're querying some other context's server.getTicketKeys and passing it in, in which case they wouldn't care.) It's possible the answer is just exposing some constant[*] which queries the key length and asking callers to use that rather than a hardcoded 48? In that case, you probably could avoid the relevant commit in this patch and do a deprecation cycle? (I can adjust this PR to drop the "compatibility hack" commits you all don't end up needing. I erred on the side on including them here so it'd be easier to see what the options were.) [*] Or something? The OpenSSL API to query it is per-SSL_CTX so, in theory, they could decide to make ticket key sizes differ based on SSL_METHOD or random configuration??? Though it's just a constant right now.
Yeah, there's no rush here. You get a mess of deprecated API warnings, but it builds fine. |
Sorry, something went wrong.
|
https://nodejs.org/api/tls.html#tls_server_setticketkeys_keys
I see the problem now, we've hardwired it in our API and docs, that's a bit unfortunate. I'm not seeing an obvious best way around this. A constant could be backported to 8.x and maybe even 6.x so users could start querying it. The awkward part is that we throw if ! 48 (env->ThrowTypeError("Ticket keys length must be 48 bytes")) and it seems to me from your patch that it'd be too late to insert the callback at setTicketKeys() only if we get 48 bytes because that'd be the nicer way to approach this and then we could more slowly deprecate 48-byte keys. So, unless we want to be stuck with the old behaviour then we're going to have to force a break here. This is an API we're not going to get good ecosystem usage numbers because it's most likely used in applications rather than libraries. My hunch is that it's got very limited usage. IIRC it was PayPal that drove interest in this and I haven't seen much of anyone else talk about ticket keys than @indutny. Next step would be some reviews by people with more of a clue. @indutny, @bnoordhuis, @shigeki, maybe @sam-github? Would you mind taking a look over the code? It's a surprisingly small diff and shouldn't take too long. I've had a look over it and will play more before I give a +1. It'll also need some testing actually compiling against 1.1.0 across our platforms so we'll have to come up with a strategy that's a little more comprehensive than just adding a single 1.1.0 box into the mix. @davidben would you mind rebasing off master so we can run this in CI? Currently having a problem with that: https://ci.nodejs.org/job/node-test-commit/13351/console |
Sorry, something went wrong.
There was a problem hiding this comment.
Mostly LGTM. I agree on deprecating ecdhCurve and that there probably isn't much risk in changing the ticket keys API (and defensible for v9.x because it's ultimately openssl that drives this change.)
Sorry, something went wrong.
There was a problem hiding this comment.
Can you explain in the commit log why this no longer works? X509_STORE_CTX_init() and X509_STORE_CTX_cleanup() still exist in 1.1.0, don't they?
Sorry, something went wrong.
There was a problem hiding this comment.
Yeah, I'm not really sure why they still exist TBH. Some weird form of reset I guess. The reason this is needed is X509_STORE_CTX is opaque and thus cannot be stack-allocated. (I can add a note in the commit message to clarify this.)
Sorry, something went wrong.
There was a problem hiding this comment.
Just curious, is the qualification necessary?
Sorry, something went wrong.
There was a problem hiding this comment.
It's not. I'm not sure what I was doing there. Removed. :-)
Sorry, something went wrong.
There was a problem hiding this comment.
Tiny style nit: method == nullptr
Sorry, something went wrong.
There was a problem hiding this comment.
Done.
Sorry, something went wrong.
There was a problem hiding this comment.
nullptr
Sorry, something went wrong.
There was a problem hiding this comment.
Done.
Sorry, something went wrong.
There was a problem hiding this comment.
Tiny nit: const char*
Sorry, something went wrong.
There was a problem hiding this comment.
Done.
Sorry, something went wrong.
There was a problem hiding this comment.
Tiny nit: can you indent by four spaces here and below? (Line continuation.)
Sorry, something went wrong.
There was a problem hiding this comment.
eslint gets unhappy and seems to really want this indent.
Sorry, something went wrong.
There was a problem hiding this comment.
2 spaces is the standard line continuation for our JS style guide. This seems fine to me but if you really, really wanted to make it a bit less awkward because of the length then maybe just put the RegExp into a variable... ?
Sorry, something went wrong.
There was a problem hiding this comment.
Somewhat amusingly, we only started doing that last month. Is there a better way of doing that with openssl 1.0.2? I couldn't find one.
Sorry, something went wrong.
There was a problem hiding this comment.
Nah, that's the way to do it. They added and deprecated APIs one release after another. :-) Both of those calls are no-ops in 1.1.0. The ifdef isn't needed, but it silences some build warnings, so I figured I'd clear them.
Sorry, something went wrong.
There was a problem hiding this comment.
Could be simplified to .on('error', common.mustNotCall()).
Sorry, something went wrong.
There was a problem hiding this comment.
Done.
Sorry, something went wrong.
There was a problem hiding this comment.
Not needed, available as common.fixtures
Sorry, something went wrong.
There was a problem hiding this comment.
Hrm. That doesn't seem to work. I also don't see common.fixtures in any other test. There's common.fixturesDir, though that just points to the directory. Is that plus fs.readFileSync plus path-munging preferred over fixtures.readKey?
Sorry, something went wrong.
There was a problem hiding this comment.
This seems fine as is. It matches what people were instructed to use in the latest Code & Learn.
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, you're both right. I thought (don't know why) that common.js re-exported everything from fixtures.js.
Sorry, something went wrong.
There was a problem hiding this comment.
You can DRY this like this:
const { OPENSSL_VERSION_NUMBER, SSL_OP_NO_TICKET } =
require('crypto').constants;
Sorry, something went wrong.
There was a problem hiding this comment.
Done.
Sorry, something went wrong.
|
I've addressed the comments, rebased to master, and removed the original ecdhCurve commit. Instead, I've added fd6658e99db128f4879cefa70630b98fe57b28aa to suppress the test in OpenSSL 1.1.0. I'm not sure how to make that as deprecated, so I'll probably need some help from one of you all there. (Or should that be done separately?) I've left the ticket one alone for the time being, since it sounds like that's still being discussed. I also realize now I missed the "DSS1" one... shall I remove that workaround in favor of a deprecation + test suppression like ecdhCurve? |
Sorry, something went wrong.
There was a problem hiding this comment.
Thanks, basically LGTM pending two questions.
I'm not sure how to make that as deprecated, so I'll probably need some help from one of you all there.
Untested but this diff shows the basic principle:
Detailsdiff --git a/doc/api/deprecations.md b/doc/api/deprecations.md
index 75c5c0feb5..62c0a7a0ce 100644
--- a/doc/api/deprecations.md
+++ b/doc/api/deprecations.md
@@ -737,6 +737,13 @@ Type: Runtime
internal mechanics of the `REPLServer` itself, and is therefore not
necessary in user space.
+<a id="DEP0083"></a>
+### DEP0083: Disabling ECDH with `{ ecdhCurve: false }`
+
+Type: Runtime
+
+Blurb goes here.
+
[`Buffer.allocUnsafeSlow(size)`]: buffer.html#buffer_class_method_buffer_allocunsafeslow_size
[`Buffer.from(array)`]: buffer.html#buffer_class_method_buffer_from_array
diff --git a/lib/_tls_wrap.js b/lib/_tls_wrap.js
index d7e349b239..ff2fa178d8 100644
--- a/lib/_tls_wrap.js
+++ b/lib/_tls_wrap.js
@@ -919,6 +919,15 @@ Server.prototype.setTicketKeys = function setTicketKeys(keys) {
};
+function ecdhCurveWarning() {
+ if (ecdhCurveWarning.emitted) return;
+ process.emitWarning('{ ecdhCurve: false } is a deprecated no-op.',
+ 'DeprecationWarning',
+ 'DEP0083');
+ ecdhCurveWarning.emitted = true;
+}
+ecdhCurveWarning.emitted = false;
+
Server.prototype.setOptions = function(options) {
this.requestCert = options.requestCert === true;
this.rejectUnauthorized = options.rejectUnauthorized !== false;
@@ -931,8 +940,10 @@ Server.prototype.setOptions = function(options) {
if (options.secureProtocol) this.secureProtocol = options.secureProtocol;
if (options.crl) this.crl = options.crl;
if (options.ciphers) this.ciphers = options.ciphers;
- if (options.ecdhCurve !== undefined)
+ if (options.ecdhCurve !== undefined) {
this.ecdhCurve = options.ecdhCurve;
+ if (this.ecdhCurve === false) ecdhCurveWarning();
+ }
if (options.dhparam) this.dhparam = options.dhparam;
if (options.sessionTimeout) this.sessionTimeout = options.sessionTimeout;
if (options.ticketKeys) this.ticketKeys = options.ticketKeys;I also realize now I missed the "DSS1" one... shall I remove that workaround in favor of a deprecation + test suppression like ecdhCurve?
No strong opinion. It doesn't cost much to keep around and logging deprecation warnings from C++ is kind of cumbersome because you have to thread through the node::Environment. The function you are looking for is ProcessEmitWarning() if you want to pursue that.
Sorry, something went wrong.
There was a problem hiding this comment.
Doesn't this leak the resources allocated by EVP_EncryptInit_ex() when HMAC_Init_ex() fails?
Sorry, something went wrong.
There was a problem hiding this comment.
It does not. hctx is owned by the caller, so it's meant to get cleaned up after this function returns.
Sorry, something went wrong.
There was a problem hiding this comment.
Ah, I found the corresponding logic in t1_lib.c and s3_srvr.c. Okay, thanks for clearing that up.
Sorry, something went wrong.
There was a problem hiding this comment.
Same question.
Sorry, something went wrong.
There was a problem hiding this comment.
(ditto.)
Sorry, something went wrong.
There was a problem hiding this comment.
Ideally, use explicit nullptr checks for clarity.
Sorry, something went wrong.
There was a problem hiding this comment.
Done. (In patch set that will be uploaded shortly.)
Sorry, something went wrong.
There was a problem hiding this comment.
Sorry, you're both right. I thought (don't know why) that common.js re-exported everything from fixtures.js.
Sorry, something went wrong.
There was a problem hiding this comment.
missing semicolon
Sorry, something went wrong.
There was a problem hiding this comment.
Done. (In patch set that will be uploaded shortly.)
Sorry, something went wrong.
|
FYI https://ci.nodejs.org/job/node-test-commit/13361/ CI is happy with this as is sans the linting problem in test/parallel/test-tls-ecdh-disable.js |
Sorry, something went wrong.
|
I'm playing with 1.1.0 as a local (non-global) build to test this out and I have a few notes. First, for @davidben, I'm getting 2 failures, not just parallel/test-http2-create-client-connect but also parallel/test-tls-close-notify on Linux and macOS. This is using the current HEAD of openssl/openssl: Error: 140737282147264:error:140E0197:SSL routines:SSL_shutdown:shutdown while in init:ssl/ssl_lib.c:1988:
140737282147264:error:140E0197:SSL routines:SSL_shutdown:shutdown while in init:ssl/ssl_lib.c:1988:
Notes, mainly for me and for anyone else wanting to test this out for themselves without having to install OpenSSL globally:
My thinking here is that we could test in bulk across most of our CI by either checking in a openssl-1.1.0g/ source directory or just downloading it and unpacking it, then testing with a modified Makefile that does all of these steps. That wouldn't require any CI modification or special machines. A step beyond that for a more permanent test-dynamically-linked-openssl might be to bake in these steps into CI somewhere so they can be run on any of our hosts without requiring a special host like we do for FIPS. Or perhaps it's sufficient to just have a sub-job that reuses some of the other hosts to do this work across a small subset of our platforms. I'll take this up with the Build WG because it'd be great to start testing dynamic linking in our CI. We could then conceivably extend to some of the other shared libs we support. |
Sorry, something went wrong.
|
I'll try to get to the other comments later today or this week, but to answer the immediate test issues real quick: So, OpenSSL master is slated to be 1.1.1, not 1.1.0g. I've been testing with the OpenSSL_1_1_0-stable branch, on the assumption that 1.1.1 adding TLS 1.3 might throw off others of your tests (though I see it's off by default) and dealing with that later would be simpler. But clearly I should have tested master too, given this new failure! The immediate cause for this is openssl/openssl#4574, however I think ultimately it's Node that's misbehaving. You all are calling into user code within the OpenSSL info callback, which might re-entrantly call into more code. OpenSSL, 1.1.x or 1.0.x, is unlikely to behave well in all scenarios where SSL_read calls the handshake calls info_callback calls Node calls SSL_read again. TLSWrap too is also unlikely to be happy if random methods are called reentrantly from ClearOut or ClearIn. Some part of the assembly leaking up to TLSSocket.prototype._finishInit calling this.emit('secure') should probably be deferred an event loop iteration. Though it would also be weird if some read or write callback runs just before the 'secure' event, rather than just after, so we may want to be a bit careful there. (Yeah, parallel/test-http2-create-client-connect failing is a known issue. Sorry I haven't gotten to writing up the details there yet. Just finished a much-needed vacation the past week, so I've got quite a backlog. :-) ) |
Sorry, something went wrong.
This is kind of hairy. OpenSSL 1.0.2 ignored the return value and always treated everything as SSL_TLSEXT_ERR_NOACK (so the comment was wrong and Node was never sending a warning alert). OpenSSL 1.1.0 honors SSL_TLSEXT_ERR_NOACK vs SSL_TLSEXT_ERR_FATAL_ALERT and treats everything unknown as SSL_TLSEXT_ERR_FATAL_ALERT. Since this is a behavior change (tests break too), start by aligning everything on SSL_TLSEXT_ERR_NOACK. If sending no_application_protocol is desirable in the future, this can by changed to SSL_TLSEXT_ERR_FATAL_ALERT with whatever deprecation process is appropriate. However, note that, contrary to https://rt.openssl.org/Ticket/Display.html?id=3463#txn-54498, SSL_TLSEXT_ERR_FATAL_ALERT is *not* useful to a server with no fallback protocol. Even if such mismatches were rejected, such a server must *still* account for the fallback protocol case when the client does not advertise ALPN at all. Thus this may not be worth bothering. PR-URL: #16130 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
Fixing the rest will be rather involved. I think the cleanest option is to deprecate the method string APIs which are weird to begin with. PR-URL: #16130 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
The first group of tests makes one more connection and leave the server alive for longer. Otherwise the test is just catching that the server has closed the socket, depending on timing. This does not quite make the test pass yet, however. There are some quirks with how the http2 code handles errors which actually affect 1.0.2 as well. PR-URL: #16130 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
This doesn't work in OpenSSL 1.1.0. Per discussion on the PR, it is preferable to just deprecate this setting. Deprecate it and skip the test in OpenSSL 1.1.0. PR-URL: #16130 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
The first group of tests makes one more connection and leave the server alive for longer. Otherwise the test is just catching that the server has closed the socket, depending on timing. This does not quite make the test pass yet, however. There are some quirks with how the http2 code handles errors which actually affect 1.0.2 as well. PR-URL: #16130 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
The first group of tests makes one more connection and leave the server alive for longer. Otherwise the test is just catching that the server has closed the socket, depending on timing. This does not quite make the test pass yet, however. There are some quirks with how the http2 code handles errors which actually affect 1.0.2 as well. PR-URL: #16130 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Rod Vagg <rod@vagg.org>
|
Release team were -1 on backporting to 6.x, but cautiously +1 on backporting to 8.x. It would be great to have feedback on:
For info on the backporting process, see the guide |
Sorry, something went wrong.
|
There is a working set of patches for 8.9.3 here the order of which can be found in this file. |
Sorry, something went wrong.
|
@kapouer does this mean that Debian is already using this for Node 8.x. If so that seems like a good reason to backport. |
Sorry, something went wrong.
Sorry, something went wrong.
|
I'm working on similar patch for fedora, though test/parallel/test-tls-no-sslv3 always fails, even v9.x/master fails. === release test-tls-no-sslv3 ===
Path: parallel/test-tls-no-sslv3
CONNECTED(00000003)
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 80 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : SSLv3
Cipher : 0000
Session-ID:
Session-ID-ctx:
Master-Key:
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1516204799
Timeout : 7200 (sec)
Verify return code: 0 (ok)
Extended master secret: no
---
140662277297984:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl/record/rec_layer_s3.c:1399:SSL alert number 40
assert.js:42
throw new errors.AssertionError({
^
AssertionError [ERR_ASSERTION]: false == true
at process.<anonymous> (/root/node/test/parallel/test-tls-no-sslv3.js:50:5)
at emitOne (events.js:121:20)
at process.emit (events.js:211:7)
Command: out/Release/node /root/node/test/parallel/test-tls-no-sslv3.js
|
Sorry, something went wrong.
|
Here are my patches for Fedora Rawhide for v8.9.4 |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
WARNING: This is a rather large change.
In a previous PR, it was suggested that Node was uninterested in incremental changes for OpenSSL 1.1.0 support, with the worry that OPENSSL_VERSION_NUMBER ifdefs in the code will appear as if you support 1.1.0 when you don't. However, doing it all in one commit is also not feasible as one cannot possibly review such a change. I've instead attempted a middle ground where there is one PR, but it is made up of many many individual commits. It's recommended that you review each commit individually and not use Github's combined diff UI.
Let me know if you would like the branch presented differently. (Go back to separate PRs, etc.)
This was partially adapted from PR #8491 but fixes some issues with it. This PR does not switch Node to OpenSSL 1.1.0, nor does it break support with OpenSSL 1.0.2. Two notes:
OpenSSL needs Allow DH_set0_key with only private key. openssl/openssl#4384 applied. This means OpenSSL 1.1.0g or later, which is not yet released. Since it would otherwise compile but not work, I've added a OPENSSL_VERSION_NUMBER check to catch this.
test-http2-create-client-connect does not work. I've fixed an issue with the test itself, but it still doesn't pass in 1.1.0. The HTTP/2 code bypasses the usual JS afterWrite code which, combined with some weird OpenSSL behaviors, causes the error-handling to be a little off. It actually affects 1.0.2, just not on that particular test's input. I'll file a separate ticket for all that, but since it affects 1.0.2 too, I figure that should be separate to this PR. I'll put together a report with details later.
Additionally, switching to OpenSSL 1.1.0 comes with a number of removals. OpenSSL has documentation here:
https://www.openssl.org/news/openssl-1.1.0-notes.html
https://www.openssl.org/news/changelog.html#x7
I've described what I did notice below. Where it was feasible, I added a change to retain compatibility in Node's API as much as possible. I'll let you all decide exactly which of those you wish to include. For instance, one could imagine adding 1.1.0 support (so it doesn't bitrot), but still shipping with 1.0.2 for a deprecation cycle, and then switching to 1.1.0 with all the breakages that entails. That would let you drop some of the commits in this branch.
DSS1
In OpenSSL 1.0.2, the digest name "DSS1" was a DSA alias for SHA-1, part of the EVP_Sign* legacy. This has been removed in OpenSSL 1.1.0. In crypto: add compatibility logic for "DSS1" and "dss1", I've added a compatibility knob for it, but it may be better to skip this commit and instead deprecate the name, since there are other unavoidable removals anyway.
Weak crypto
OpenSSL 1.1.0 disables a number of weak ciphers like RC4 or anonymous ciphers by default. You can build OpenSSL with enable-weak-ssl-ciphers if you wish to restore them. If you do, you probably want a deprecation cycle.
OpenSSL 1.1.0 also rejects RSA keys smaller than 1024 bits by default and other settings. See https://www.openssl.org/docs/man1.1.0/ssl/SSL_CTX_get_security_level.html
SHA-0
SHA-0 was removed in OpenSSL 1.1.0. This is an insecure and virtually unused early variant of SHA-1, but Node did nominally expose it via crypto.createHash('sha'). Short of adding a compatibility reimplementation of the hash, I think this is an unavoidable removal in OpenSSL 1.1.0.
tlsSocket.getCipher().version
The version field returned by tlsSocket.getCipher() did not do what was documented in 1.0.2 and always returned the string "TLSv1/SSLv3". I've retained that behavior in Node and fixed the documentation, but you all may wish to go through a deprecation cycle with that field. It's not useful anyway.
See the commit crypto: hard-code tlsSocket.getCipher().version for details.
Error messages
Some of the errors OpenSSL emits are slightly differnent. I had to fix a few strings in tests. Dunno how much you care about this sort of behavior change.
ecdhCurve
The ecdhCurve server setting in the TLS module is defined to disable ECDH. This is a remnant of an implementation quirk in OpenSSL where it lacked curve negotiation logic. That meant there exists an ECDH-less state for OpenSSL servers separate from the cipher list. (Note no such mode exists on the client.) They fixed this and added this "ecdh_auto" opt-in knob in 1.0.2. In 1.1.0, this opt-in knob was made always on. Unfortunately, Node exposed this state by setting ecdhCurve to false.
I've hacked it back in in the comment crypto: fix setting ecdhCurve to false with OpenSSL 1.1.0 by appending to the user's cipher list. Your call whether you wish to keep this. Since everything in TLS without ECDHE is insecure anyway, I would suggest taking a deprecation cycle to remove this instead and dropping the commit.
Ticket keys
OpenSSL 1.0.2 used a 16 byte key name, 16 byte AES-128-CBC key, and 16 byte HMAC-SHA256 key for session tickets. OpenSSL 1.1.0 switches this to a 16 byte key name, 32 byte AES-256-CBC key, and 32 byte HMAC-SHA256 key. One can query the size of the ticket key with SSL_CTX_get_tlsext_ticket_keys to avoid the hard-coded 48, but that doesn't really solve the problem. That ticket keys are 48 bytes are exposed in Node's public APIs.
In crypto: emulate OpenSSL 1.0.x ticket scheme in 1.1.x, I've implemented the callback to use the old scheme in OpenSSL 1.1.0. This works, but you may wish to think about alternate APIs (maybe expose a constant somewhere for the ticket key size) that allow the ticket scheme to change.
SSL_METHOD and protocol versions
OpenSSL's old SSL_METHODs are kind of a mess. You had methods like TLSv1_1_client_method which locked you to TLS 1.1 and only worked for clients. Then you had methods like TLSv1_1_method which were exactly the same as TLSv1_1_client_method except you could use them for either clients or server. Then you had SSLv23_method which was actually version-flexible and misnamed. Then, to configure versions, you had toggles like SSL_OP_NO_TLSv1_1.
This is a mess. In OpenSSL 1.1.0, things are much better. SSLv23_method is renamed to TLS_method and then you have APIs like SSL_CTX_set_min_proto_version and SSL_CTX_set_max_proto_version. TLS_client_method and TLS_server_method sadly still exist and are approximately as pointless as they always were. :-)
Unfortunately, Node's APIs thoroughly expose this and has the user specify the string name of the method to use, rather than min/max version configurations. OpenSSL 1.1.0 retains the old APIs but marks them as deprecated, so this still works but you have a lot oc compile warnings. I have not attempted to remove the deprecated APIs in this branch as I think you all need a better API first.
My suggestion:
Checklist
Affected core subsystem(s)
crypto