-
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: Use SHA1 for sessionIdContext in FIPS mode #3755
Conversation
This should target |
2687e79
to
7a0d7d0
Compare
@mscdex I updated the commit message accordingly. Thanks. |
if (process.versions.openssl && process.versions.openssl.endsWith("-fips")) { | ||
return crypto.createHash('sha1') | ||
.update(defaultText) | ||
.digest('hex').substring(0,32); /* SSL_MAX_SID_CTX_LENGTH is 128 bits */ |
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.
Let's use .slice()
here, this is what we try to do everywhere else.
I think that in general it may be a good idea to use |
The main concern would be interoperability. Would changing to sha256 for non-FIPs mean that there would be problems inter-operating with with earlier Node.js releases ? |
I don't particularly like this commit. What's fed into the hash function is the process name and arguments. I maintained MD5 for non-FIPS because I was afraid someone somewhere might be serializing (caching) sessions across process lifetimes. I've looked a bit more into the OpenSSL caching mechanism, specifically: The only place where we provide external callbacks for session management is in node_crypto.cc GetSessionCallback and NewSessionCallback. In turn, these store data using CRYPTO_get_ex_data and CRYPTO_set_ex_data which I believe means the data only live as long as the process. Therefore, I suggest we don't use a hash at all, and instead simply call crypto.randomBytes(16) once in this file and use the resulting value for the lifetime of a given Node process, in both FIPS and non-FIPS mode. Edit: We still have to clarify why MD5 was mentioned in the docs, is that just internals leaking into the documentation or did it have some meaning to users? |
7a0d7d0
to
d3140c4
Compare
@stefanmb ... just a quick note, I see this PR has a few conflicts now, can you please take a moment to rebase and update. Thank you! |
d3140c4
to
2b01c3c
Compare
@jasnell Fixed, thanks! |
@indutny @shigeki
If so, I can update this PR. Thank you for your help and advice! |
@stefanmb the idea, originally was to provide the same session context to clustered processes (if I remember it right) |
@indutny Okay, that's what I started to suspect. It's kind of clunky to do it through argv though. Anyway, perhaps the simplest thing is to move to a truncated SHA1 for both FIPS and non-FIPS. OpenSSL requires 128 bits, so I don't think there's a point in using a bigger hash. |
Alright, this makes sense to me. |
.update(defaultText) | ||
.digest('hex').slice(0, 32); /* SSL_MAX_SID_CTX_LENGTH is 128 bits */ | ||
} else { | ||
return crypto.createHash('md5') |
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.
Hm... Let's use sha1
for both cases, and remove condition?
042f645
to
ab64b8b
Compare
@indutny Okay, changed this to do SHA1 in all cases, the change is now pretty trivial. |
@stefanmb I was thinking about it for a bit now, and I think we should handle it this way. Let's split this PR into two commits:
The best way to do it is probably to submit a second PR for the second half. @stefanmb does it sound reasonable? Thank you very much! |
FIPS 140-2 disallows use of MD5, which is used to derive the default sessionIdContext for tls.createServer().
ab64b8b
to
532857b
Compare
FIPS 140-2 disallows use of MD5, which is used to derive the default sessionIdContext for tls.createServer(). PR-URL: #3755 Reviewed-By: Fedor Indutny <fedor@indutny.com>
FIPS 140-2 disallows use of MD5, which is used to derive the default sessionIdContext for tls.createServer(). PR-URL: #3755 Reviewed-By: Fedor Indutny <fedor@indutny.com>
FIPS 140-2 disallows use of MD5, which is used to derive the default sessionIdContext for tls.createServer(). PR-URL: #3755 Reviewed-By: Fedor Indutny <fedor@indutny.com>
FIPS 140-2 disallows use of MD5, which is used to derive the default sessionIdContext for tls.createServer(). PR-URL: #3755 Reviewed-By: Fedor Indutny <fedor@indutny.com>
Notable changes: * buffer: The `noAssert` option for many buffer functions will now silently drop invalid write values rather than crashing (P.S.V.R) nodejs/node#3767. - This makes the behavior match what the docs suggest. * child_process: `child.send()` now properly returns a boolean like the docs suggest (Rich Trott) nodejs/node#3577. * doc: All of the API docs have been re-ordered so as to read in alphabetical order (Tristian Flanagan) nodejs/node#3662. * http_parser: update http-parser to 2.6.0 from 2.5.0 (James M Snell) nodejs/node#3569. - Now supports the following HTTP methods: `LINK`, `UNLINK`, `BIND`, `REBIND`, `UNBIND`. - Also added ACL and IPv6 Zone ID support. * npm: upgrade npm to 3.3.12 from v3.3.6 (Rebecca Turner) nodejs/node#3685. - See the release notes for https://github.com/npm/npm/releases/tag/v3.3.7, https://github.com/npm/npm/releases/tag/v3.3.8, https://github.com/npm/npm/releases/tag/v3.3.9, https://github.com/npm/npm/releases/tag/v3.3.10, https://github.com/npm/npm/releases/tag/v3.3.11, and https://github.com/npm/npm/releases/tag/v3.3.12 for more details. * repl: The REPL no longer crashes if the persistent history file cannot be opened (Evan Lucas) nodejs/node#3630. * tls: The default `sessionIdContext` now uses SHA1 in FIPS mode rather than MD5 (Stefan Budeanu) nodejs/node#3755. * v8: Added some more useful post-mortem data (Fedor Indutny) nodejs/node#3779. PR-URL: nodejs/node#3736
Notable changes: * buffer: The `noAssert` option for many buffer functions will now silently drop invalid write values rather than crashing (P.S.V.R) nodejs/node#3767. - This makes the behavior match what the docs suggest. * child_process: `child.send()` now properly returns a boolean like the docs suggest (Rich Trott) nodejs/node#3577. * doc: All of the API docs have been re-ordered so as to read in alphabetical order (Tristian Flanagan) nodejs/node#3662. * http_parser: update http-parser to 2.6.0 from 2.5.0 (James M Snell) nodejs/node#3569. - Now supports the following HTTP methods: `LINK`, `UNLINK`, `BIND`, `REBIND`, `UNBIND`. - Also added ACL and IPv6 Zone ID support. * npm: upgrade npm to 3.3.12 from v3.3.6 (Rebecca Turner) nodejs/node#3685. - See the release notes for https://github.com/npm/npm/releases/tag/v3.3.7, https://github.com/npm/npm/releases/tag/v3.3.8, https://github.com/npm/npm/releases/tag/v3.3.9, https://github.com/npm/npm/releases/tag/v3.3.10, https://github.com/npm/npm/releases/tag/v3.3.11, and https://github.com/npm/npm/releases/tag/v3.3.12 for more details. * repl: The REPL no longer crashes if the persistent history file cannot be opened (Evan Lucas) nodejs/node#3630. * tls: The default `sessionIdContext` now uses SHA1 in FIPS mode rather than MD5 (Stefan Budeanu) nodejs/node#3755. * v8: Added some more useful post-mortem data (Fedor Indutny) nodejs/node#3779. PR-URL: nodejs/node#3736
Notable changes: * buffer: The `noAssert` option for many buffer functions will now silently drop invalid write values rather than crashing (P.S.V.R) nodejs/node#3767. - This makes the behavior match what the docs suggest. * child_process: `child.send()` now properly returns a boolean like the docs suggest (Rich Trott) nodejs/node#3577. * doc: All of the API docs have been re-ordered so as to read in alphabetical order (Tristian Flanagan) nodejs/node#3662. * http_parser: update http-parser to 2.6.0 from 2.5.0 (James M Snell) nodejs/node#3569. - Now supports the following HTTP methods: `LINK`, `UNLINK`, `BIND`, `REBIND`, `UNBIND`. - Also added ACL and IPv6 Zone ID support. * npm: upgrade npm to 3.3.12 from v3.3.6 (Rebecca Turner) nodejs/node#3685. - See the release notes for https://github.com/npm/npm/releases/tag/v3.3.7, https://github.com/npm/npm/releases/tag/v3.3.8, https://github.com/npm/npm/releases/tag/v3.3.9, https://github.com/npm/npm/releases/tag/v3.3.10, https://github.com/npm/npm/releases/tag/v3.3.11, and https://github.com/npm/npm/releases/tag/v3.3.12 for more details. * repl: The REPL no longer crashes if the persistent history file cannot be opened (Evan Lucas) nodejs/node#3630. * tls: The default `sessionIdContext` now uses SHA1 in FIPS mode rather than MD5 (Stefan Budeanu) nodejs/node#3755. * v8: Added some more useful post-mortem data (Fedor Indutny) nodejs/node#3779. PR-URL: nodejs/node#3736
Notable changes: * buffer: The `noAssert` option for many buffer functions will now silently drop invalid write values rather than crashing (P.S.V.R) nodejs/node#3767. - This makes the behavior match what the docs suggest. * child_process: `child.send()` now properly returns a boolean like the docs suggest (Rich Trott) nodejs/node#3577. * doc: All of the API docs have been re-ordered so as to read in alphabetical order (Tristian Flanagan) nodejs/node#3662. * http_parser: update http-parser to 2.6.0 from 2.5.0 (James M Snell) nodejs/node#3569. - Now supports the following HTTP methods: `LINK`, `UNLINK`, `BIND`, `REBIND`, `UNBIND`. - Also added ACL and IPv6 Zone ID support. * npm: upgrade npm to 3.3.12 from v3.3.6 (Rebecca Turner) nodejs/node#3685. - See the release notes for https://github.com/npm/npm/releases/tag/v3.3.7, https://github.com/npm/npm/releases/tag/v3.3.8, https://github.com/npm/npm/releases/tag/v3.3.9, https://github.com/npm/npm/releases/tag/v3.3.10, https://github.com/npm/npm/releases/tag/v3.3.11, and https://github.com/npm/npm/releases/tag/v3.3.12 for more details. * repl: The REPL no longer crashes if the persistent history file cannot be opened (Evan Lucas) nodejs/node#3630. * tls: The default `sessionIdContext` now uses SHA1 in FIPS mode rather than MD5 (Stefan Budeanu) nodejs/node#3755. * v8: Added some more useful post-mortem data (Fedor Indutny) nodejs/node#3779. PR-URL: nodejs/node#3736
This broke my app:
It works on 4.2.3 but fails on 4.2.4. It still fails on 4.4.2 (current) and latest 5.x. Isn't the point of LTS to not add features and not break compatibility? |
@sneak are you 100% there isn't some monkey patching of the process object happening in your app? The error you are getting is suggesting that here is a screen shot of me sanity checking this in v4 |
I'm not; I have not read every line of the testing framework involved, I'm just letting you know that a test suite that passed on 4.2.3 now no longer runs on 4.2.4. I thought the point of LTS was to not break stuff and cost people time; why not keep this FIPS stuff to 5.x? I don't know what ill-advised stuff this app or its deps was doing, but I do now know that it doesn't work anymore and that this was the change that broke it. |
PS: When posting text snippets, you don't need to push bitmaps, simply wrapping them in triple backticks is sufficient. |
/cc @nodejs/crypto @nodejs/lts fwiw we extensively smoke test LTS, we do occasionally hit edges like this though. Thank you for reporting this, we'll dig in and see what we can find. |
FWIW:
I bumped the versions of the stuff mentioned in the stack trace to latest, but still no love. |
Yeah, the goal of LTS is to keep things as stable as absolutely possible but regressions do creep in from time to time. To help keep things easier to maintain we'll go ahead and pull certain changes back that appear innocuous but every once in a while we'll hit an edge case that needs to be looked at. For this, a quick existence check on |
There you go, a PR against 4.x. I haven't tried getting 5.x to work yet, I can do that next. |
It looks like the change is exactly the same in 5.x, but master has a different file without any FIPS stuff in it. (I haven't tested the breaking app against master, but can if you need me to.) |
By default, a call to tls.createServer() without a sessionIdContext will use a “MD5 hash value generated from command-line” as per documentation.
In FIPS mode MD5 is not allowed, however createServer is often called without specifying an explicit sessionIdContext. A significant number of test cases and applications break. The simple solution is to to use an allowed hash function. I have chosen SHA1 and truncated the output to 128 bits (which is the hardcoded length required by OpenSSL’s SSL_MAX_SID_CTX_LENGTH).
Note that I have opted to maintain the use of MD5 in non-FIPS mode, and updated the documentation accordingly.