-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
crypto: decode missing passphrase errors #25208
Conversation
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.
LGTM. Nice.
I would prefer to treat this as semver-minor.
Error message changes are normally semver-major. It would probably require an TSC exception to downgrade this to semver-minor.
Thanks, Ben. My primary concern is the difficulty of backporting other things, I guess having added key objects will make backporting difficult enough even without semver-major changes. (I am still unsure whether we can backport key objects to v10.x.) cc @nodejs/tsc for the semverity. |
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.
Code LGTM. According to our rules, those types of changes are semver-major.
Did Key objects ship into a release yet?
I’m +1 in shipping it as semver-minor in 11. IMHO this type of PR is the reason why I prefer new features to go out as experimental for a bit. |
CI: https://ci.nodejs.org/job/node-test-pull-request/19865/ @mcollina This would have changed existing errors with or without key objects, and making it experimental would not have helped with backporting. If we decide to treat this as semver-major, I would like to wait a little before landing it to make sure that we have a chance to backport all important semver-minor / patch commits first. |
To make things clear: is this changing the errors of other APIs apart from the new Key? In that case.. this should really be semver-major. |
@mcollina Yes, it does, consider this example which does not use key objects: const crypto = require('crypto');
const key = `
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIC2TBTBgkqhkiG9w0BBQ0wRjAlBgkqhkiG9w0BBQwwGAQSIFFvMaBFyBvqqhY6
yTV2fMVVAgIUczAdBglghkgBZQMEASoEEGRetyFtHhnJ7TZTM2qolWkEggKAFg/h
GERtM1loEd+u8VAtLwTzBiXE5pmRpp/hX/1HrbBnzFjAsNtWlEtzpSuxuCoXtMst
uKRB8qveHlfTQPzopkRZtljfOkD1DhdJz8BXSZrFmVkMrUq6m4Y/rnqTqI5JmtmQ
qAXTBbl7u8TwMnqIaoSInEHnc+aiFT3KJuIq6PZy2rGKWGW2WB/OML2gANvHBI9n
gyOo4VZHNsR6VBbCRJErUFhF5Wk2/YJD9ejnvXH6pJFqZYvnCFjkSlR+4MdCHBSo
Ld0IoFjQ6X1uLLglFf/rQGKEQruLjTKmz6oe8nZIzrOoLmArir0DGTakEt0K6mha
0M5s9zNkdMd7XRns0uvmYHzbpNVWpUP5YUmf1BJLjTHex51Msjoz6v6ixinel852
5lS2wtVwXp8MXG9iofvMEDocmvn60vuksmgwxMccRWX2zAt8ixFefzIjM0KzPRpt
ByJP0B733u+DI0Y5bsiJVAxl7Gr8Io5k6Uk0nZziVK8+vDXLF2BNetp4kRM/XBaM
N/DcosGiAxOeJqSA45ethV8cHGZVuNOsCXSVomVoKIxgWhkyBzXv9sIbRSSGWfJQ
edWEV9t4RTCgIu+622JZFzw1PbWtEu4R38v0JZQN3zxkYPC7nFIfmx9unUWucoup
ZYbvlzjyNZ6VI8jDvvqy+XmaY+FZcSgPTGCz/4KArxJuSvE8gJULUS7Y7JCuDjjL
h04pYsl8WMA3UH2/CxiFv75vXZI0q2HKUnNNawrQG83zPfBiVrDQARifCkPmzsCd
tHd8A/agDAeg9rmat6PRC4d0to6pUg7v5ZR9VZkRWMJiPMtuH4fh/2L/ys/9EihG
CZJe6XTZkgFAp9gzGg==
-----END ENCRYPTED PRIVATE KEY-----
`;
const message = Buffer.from('Hello world', 'utf8');
crypto.publicEncrypt(key, message); With node <= 11.6.0:
(And even weirder error messages for about 0.4% of all encrypted private keys due to PKCS padding, this caused issues such as #22978). With this patch, the error message is consistent when no passphrase was supplied:
Okay, then let's wait until we know about the backporting situation in crypto before landing this. Thanks for discussing this, Matteo! |
d2202aa
to
82e0fee
Compare
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.
Improving the error codes is a good idea. Its semver-major, though. Landing is OK IMO. I put a suggestion that, if possible, might make the changes less intrusive. Also, Tobias, just FYI, I I had to put aside some work I was doing to make all crypto errors have .code, .function, .library, .reason properties, like the tls_wrap/SSL errors now do. I'll pick it up again after TLS1.3. Its related, because sticking to the SSL error scheme would fit into that work (again, if possible).
len = len > buflen ? buflen : len; | ||
memcpy(buf, u, len); | ||
memcpy(buf, passphrase, len); |
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.
The existing code was like this, but looking at openssl source, couldn't we return -1 down below if there is no passphrase? That would cause openssl to immediately error with PEM_R_BAD_PASSWORD_READ, rather than try to decrypt the PEM with a zero-length passphrase, and then fail later with some semi-random decoding error because the decrypted data is garbage.
As long as the passphrase callback is only made if a passphrase is actually needed (isn't this the case?), that would be more direct, as it would make the returned SSL error actually be informative, so you wouldn't need to override it.
Just a thought, maybe it won't work, but it seems possible.
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.
And actually, perhaps we should be returning -1 if the passphrase is longer than the buffer openssl is giving us... if the passphrase is truncated its going to do a bad decrypt, and lead to strange error codes, seems to me that its better to fail immediately with -1.
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.
Based on the fact that we are not doing this already, I did not think there was a way to let OpenSSL know that there is no password. Sounds like a good idea though!
Thanks for letting me know! I just looked at the PR and so far, it seems to only affect SSL, not crypto, right? Generally, having such a code on all crypto errors would be desirable, as long as it does not become too OpenSSL specific. |
@tniessen Any chance of getting this landed so it can be in 12.x? |
@sam-github It's on my list, I assume it makes sense to wait for #26868 to land first? I'll try to get this into node 12! |
#26868 had an unrelated test failure so I resumed, I'm hopeful it can land within a couple hours. |
When a user attempts to load an encrypted key without supplying a passphrase, a cryptic OpenSSL error is thrown. This change intercepts the OpenSSL error and throws a nice error code instead.
82e0fee
to
36de9dc
Compare
@sam-github I rebased the changes. If I use your suggestion and return
What is your preference? I have a slight preference for returning |
BAD_PASSWORD_READ means specifically that the password could not be read, right? Not that the password was the wrong password? I like the Just for background, if you take a quick look at all the calls to ThrowCryptoError(), you can see that (usually) a default message is passed along with the error code. In existing code (before and after my change to decorate the Error), that message is only used when Aside: I'm a bit suspicious of this. ThrowCryptoError() is called only when an openssl API returned failure, so if Anyhow, I changed ThrowCryptoError() so that the user-supplied message string was used allways, not just as a default, thinking it would make more human-readable .message strings, but then backed that out:
What I think I'd prefer, longer term, is for ThrowCryptoError to essentially make As far as this PR goes, I think the way you have it now is reasonable. Its consistent with everything else in node_crypto.cc, and informative enough that users will understand what went wrong. |
Yes.
I agree. It's the inconsistency that bothers me.
Whenever I have to use
I am still not sure what's better... We could let OpenSSL deal with it and end up with an OpenSSL error code. That might be good because:
On the other hand,
Thinking about it a bit more, I think my preference is to land this after addressing your comments above and changing the error code to be more specific, and then adding the buffer size check separately, such that both conditions will have separate error codes. Is that okay? (Maybe I misunderstood your preference, feel free to correct me.) |
Your plan sounds sensible to me. |
@sam-github PTAL :) |
Landed in 2e2c015, thanks for reviewing thoroughly! |
When a user attempts to load an encrypted key without supplying a passphrase, a cryptic OpenSSL error is thrown. This change intercepts the OpenSSL error and throws a nice error code instead. PR-URL: #25208 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
This causes OpenSSL to fail early if the decryption passphrase is too long, and produces a somewhat helpful error message. Refs: nodejs#25208
This causes OpenSSL to fail early if the decryption passphrase is too long, and produces a somewhat helpful error message. PR-URL: nodejs#27010 Refs: nodejs#25208 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
When a user attempts to load an encrypted key without supplying a passphrase, a cryptic OpenSSL error is thrown. This change intercepts the OpenSSL error and throws a nice error code instead. PR-URL: #25208 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Notable changes: * assert: * improve performance to instantiate errors (Ruben Bridgewater) [#26738](#26738) * validate required arguments (Ruben Bridgewater) [#26641](#26641) * adjust loose assertions (Ruben Bridgewater) [#25008](#25008) * async_hooks: * remove deprecated emitBefore and emitAfter (Matteo Collina) [#26530](#26530) * remove promise object from resource (Andreas Madsen) [#23443](#23443) * bootstrap * make Buffer and process non-enumerable (Ruben Bridgewater) [#24874](#24874) * buffer: * use stricter range checks (Ruben Bridgewater) [#27045](#27045) * harden SlowBuffer creation (ZYSzys) [#26272](#26272) * harden validation of buffer allocation size (ZYSzys) [#26162](#26162) * do proper error propagation in addon methods (Anna Henningsen) [#23939](#23939) * child_process: * change the defaults maxBuffer size (kohta ito) [#27179](#27179) * harden fork arguments validation (ZYSzys) [#27039](#27039) * use non-infinite maxBuffer defaults (kohta ito) [#23027](#23027) * console: * don't use ANSI escape codes when TERM=dumb (Vladislav Kaminsky) [#26261](#26261) * crypto: * remove legacy native handles (Tobias Nießen) [#27011](#27011) * decode missing passphrase errors (Tobias Nießen) [#25208](#25208) * move DEP0113 to End-of-Life (Tobias Nießen) [#26249](#26249) * remove deprecated crypto.\_toBuf (Tobias Nießen) [#25338](#25338) * set `DEFAULT\_ENCODING` property to non-enumerable (Antoine du Hamel) [#23222](#23222) * deps: * silence irrelevant V8 warning (Michaël Zasso) [#26685](#26685) * update postmortem metadata generation script (cjihrig) [#26685](#26685) * V8: un-cherry-pick bd019bd (Refael Ackermann) [#26685](#26685) * V8: cherry-pick 6 commits (Michaël Zasso) [#26685](#26685) * V8: cherry-pick d82c9af (Anna Henningsen) [#26685](#26685) * V8: cherry-pick e5f01ba (Anna Henningsen) [#26685](#26685) * V8: cherry-pick d5f08e4 (Anna Henningsen) [#26685](#26685) * V8: cherry-pick 6b09d21 (Anna Henningsen) [#26685](#26685) * V8: cherry-pick f0bb5d2 (Anna Henningsen) [#26685](#26685) * V8: cherry-pick 5b0510d (Anna Henningsen) [#26685](#26685) * V8: cherry-pick 91f0cd0 (Anna Henningsen) [#26685](#26685) * V8: cherry-pick 392316d (Anna Henningsen) [#26685](#26685) * V8: cherry-pick 2f79d68 (Anna Henningsen) [#26685](#26685) * sync V8 gypfiles with 7.4 (Ujjwal Sharma) [#26685](#26685) * update V8 to 7.4.288.13 (Ujjwal Sharma) [#26685](#26685) * bump minimum icu version to 63 (Ujjwal Sharma) [#25852](#25852) * silence irrelevant V8 warnings (Michaël Zasso) [#25852](#25852) * V8: cherry-pick 7803fa6 (Jon Kunkee) [#25852](#25852) * V8: cherry-pick 58cefed (Jon Kunkee) [#25852](#25852) * V8: cherry-pick d3308d0 (Michaël Zasso) [#25852](#25852) * V8: cherry-pick 74571c8 (Michaël Zasso) [#25852](#25852) * cherry-pick fc0ddf5 from upstream V8 (Anna Henningsen) [#25852](#25852) * sync V8 gypfiles with 7.3 (Ujjwal Sharma) [#25852](#25852) * sync V8 gypfiles with 7.2 (Michaël Zasso) [#25852](#25852) * update V8 to 7.3.492.25 (Michaël Zasso) [#25852](#25852) * add s390 asm rules for OpenSSL-1.1.1 (Shigeki Ohtsu) [#19794](#19794) * sync V8 gypfiles with 7.1 (Refael Ackermann) [#23423](#23423) * update V8 to 7.1.302.28 (Michaël Zasso) [#23423](#23423) * doc: * update behaviour of fs.writeFile (Sakthipriyan Vairamani (thefourtheye)) [#25080](#25080) * add internal functionality details of util.inherits (Ruben Bridgewater) [#24755](#24755) * errors: * update error name (Ruben Bridgewater) [#26738](#26738) * fs: * use proper .destroy() implementation for SyncWriteStream (Matteo Collina) [#26690](#26690) * improve mode validation (Ruben Bridgewater) [#26575](#26575) * harden validation of start option in createWriteStream (ZYSzys) [#25579](#25579) * make writeFile consistent with readFile wrt fd (Sakthipriyan Vairamani (thefourtheye)) [#23709](#23709) * http: * validate timeout in ClientRequest() (cjihrig) [#26214](#26214) * return HTTP 431 on HPE\_HEADER\_OVERFLOW error (Albert Still) [#25605](#25605) * switch default parser to llhttp (Anna Henningsen) [#24870](#24870) * change DEP0066 to a runtime deprecation (Morgan Roderick) [#24167](#24167) * else case is not reachable (szabolcsit) [#24176](#24176) * lib: * move DEP0021 to end of life (cjihrig) [#27127](#27127) * remove Atomics.wake (Gus Caplan) [#27033](#27033) * validate Error.captureStackTrace() calls (Ruben Bridgewater) [#26738](#26738) * refactor Error.captureStackTrace() usage (Ruben Bridgewater) [#26738](#26738) * move DTRACE\_\* probes out of global scope (James M Snell) [#26541](#26541) * deprecate \_stream\_wrap (Sam Roberts) [#26245] (#26245) * don't use `util.inspect()` internals (Ruben Bridgewater) [#24971](#24971) * improve error message for MODULE\_NOT\_FOUND (Ali Ijaz Sheikh) [#25690](#25690) * requireStack property for MODULE\_NOT\_FOUND (Ali Ijaz Sheikh) [#25690](#25690) * move DEP0029 to end of life (cjihrig) [#25377](#25377) * move DEP0028 to end of life (cjihrig) [#25377](#25377) * move DEP0027 to end of life (cjihrig) [#25377](#25377) * move DEP0026 to end of life (cjihrig) [#25377](#25377) * move DEP0023 to end of life (cjihrig) [#25280](#25280) * move DEP0006 to end of life (cjihrig) [#25279](#25279) * remove unintended access to deps/ (Anna Henningsen) [#25138](#25138) * move DEP0120 to end of life (cjihrig) [#24862](#24862) * use ES6 class inheritance style (Ruben Bridgewater) [#24755](#24755) * remove `inherits()` usage (Ruben Bridgewater) [#24755](#24755) * module: * remove dead code (Ruben Bridgewater) [#26983](#26983) * mark DEP0019 as End-of-Life (Ruben Bridgewater) [#26973](#26973) * throw an error for invalid package.json main entries (Ruben Bridgewater) [#26823](#26823) * don't search in require.resolve.paths (cjihrig) [#23683](#23683) * n-api: * remove code from error name (Ruben Bridgewater) [#26738](#26738) * net: * do not manipulate potential user code (Ruben Bridgewater) [#26751](#26751) * emit "write after end" errors in the next tick (Ouyang Yadong) [#24457](#24457) * deprecate \_setSimultaneousAccepts() undocumented function (James M Snell) [#23760](#23760) * net,http2: * merge setTimeout code (ZYSzys) [#25084](#25084) * os: * implement os.type() using uv\_os\_uname() (cjihrig) [#25659](#25659) * process: * global.process, global.Buffer getters (Guy Bedford) [#26882](#26882) * move DEP0062 (node --debug) to end-of-life (Joyee Cheung) [#25828](#25828) * exit on --debug and --debug-brk after option parsing (Joyee Cheung) [#25828](#25828) * improve `--redirect-warnings` handling (Ruben Bridgewater) [#24965](#24965) * readline: * support TERM=dumb (Vladislav Kaminsky) [#26261](#26261) * repl: * add welcome message (gengjiawen) [#25947](#25947) * fix terminal default setting (Ruben Bridgewater) [#26518](#26518) * check colors with .getColorDepth() (Vladislav Kaminsky) [#26261](#26261) * deprecate REPLServer.rli (Ruben Bridgewater) [#26260](#26260) * src: * remove unused INT\_MAX constant (Sam Roberts) [#27078](#27078) * update NODE\_MODULE\_VERSION to 72 (Ujjwal Sharma) [#26685](#26685) * remove `AddPromiseHook()` (Anna Henningsen) [#26574](#26574) * update NODE\_MODULE\_VERSION to 71 (Michaël Zasso) [#25852](#25852) * clean up MultiIsolatePlatform interface (Anna Henningsen) [#26384](#26384) * properly configure default heap limits (Ali Ijaz Sheikh) [#25576](#25576) * remove icuDataDir from node config (GauthamBanasandra) [#24780](#24780) * explicitly allow JS in ReadHostObject (Yang Guo) [#23423](#23423) * update postmortem constant (cjihrig) [#23423](#23423) * update NODE\_MODULE\_VERSION to 68 (Michaël Zasso) [#23423](#23423) * tls: * support TLSv1.3 (Sam Roberts) [#26209](#26209) * return correct version from getCipher() (Sam Roberts) [#26625](#26625) * check arg types of renegotiate() (Sam Roberts) [#25876](#25876) * add code for ERR\_TLS\_INVALID\_PROTOCOL\_METHOD (Sam Roberts) [#24729](#24729) * emit a warning when servername is an IP address (Rodger Combs) [#23329](#23329) * disable TLS v1.0 and v1.1 by default (Ben Noordhuis) [#23814](#23814) * remove unused arg to createSecureContext() (Sam Roberts) [#24241](#24241) * deprecate Server.prototype.setOptions() (cjihrig)[ #23820](#23820) * load NODE\_EXTRA\_CA\_CERTS at startup (Ouyang Yadong) [#23354](#23354) * util: * change inspect compact and breakLength default (Ruben Bridgewater) [#27109](#27109) * improve inspect edge cases (Ruben Bridgewater) [#27109](#27109) * only the first line of the error message (Simon Zünd) [#26685](#26685) * don't set the prototype of callbackified functions (Ruben Bridgewater) [#26893](#26893) * rename callbackified function (Ruben Bridgewater) [#26893](#26893) * increase function length when using `callbackify()` (Ruben Bridgewater) [#26893](#26893) * prevent tampering with internals in `inspect()` (Ruben Bridgewater) [#26577](#26577) * fix proxy inspection (Ruben Bridgewater) [#26241](#26241) * prevent leaking internal properties (Ruben Bridgewater) [#24971](#24971) * protect against monkeypatched Object prototype for inspect() (Rich Trott) [#25953](#25953) * treat format arguments equally (Roman Reiss) [#23162](#23162) * win, fs: * detect if symlink target is a directory (Bartosz Sosnowski) [#23724](#23724) * zlib: * throw TypeError if callback is missing (Anna Henningsen)[ #24929](#24929) * make “bare” constants un-enumerable (Anna Henningsen) [#24824](#24824) PR-URL: #26930
Notable changes: * assert: * validate required arguments (Ruben Bridgewater) [#26641](#26641) * adjust loose assertions (Ruben Bridgewater) [#25008](#25008) * async_hooks: * remove deprecated `emitBefore` and `emitAfter` (Matteo Collina) [#26530](#26530) * remove promise object from resource (Andreas Madsen) [#23443](#23443) * bootstrap: make Buffer and process non-enumerable (Ruben Bridgewater) [#24874](#24874) * buffer: * use stricter range checks (Ruben Bridgewater) [#27045](#27045) * harden `SlowBuffer` creation (ZYSzys) [#26272](#26272) * harden validation of buffer allocation size (ZYSzys) [#26162](#26162) * do proper error propagation in addon methods (Anna Henningsen) [#23939](#23939) * child_process: * remove `options.customFds` (cjihrig) [#25279](#25279) * harden fork arguments validation (ZYSzys) [#27039](#27039) * use non-infinite `maxBuffer` defaults (kohta ito) [#23027](#23027) * console: * don't use ANSI escape codes when `TERM=dumb` (Vladislav Kaminsky) [#26261](#26261) * crypto: * remove legacy native handles (Tobias Nießen) [#27011](#27011) * decode missing passphrase errors (Tobias Nießen) [#25208](#25208) * remove `Cipher.setAuthTag()` and `Decipher.getAuthTag()` (Tobias Nießen) [#26249](#26249) * remove deprecated `crypto._toBuf()` (Tobias Nießen) [#25338](#25338) * set `DEFAULT\_ENCODING` property to non-enumerable (Antoine du Hamel) [#23222](#23222) * deps: * update V8 to 7.4.288.13 (Michaël Zasso, cjihrig, Refael Ackermann) (Anna Henningsen, Ujjwal Sharma) [#26685](#26685) * bump minimum icu version to 63 (Ujjwal Sharma) [#25852](#25852) * update OpenSSL to 1.1.1b (Sam Roberts, Shigeki Ohtsu) [#26327](#26327) * errors: * update error name (Ruben Bridgewater) [#26738](#26738) * fs: * use proper .destroy() implementation for SyncWriteStream (Matteo Collina) [#26690](#26690) * improve mode validation (Ruben Bridgewater) [#26575](#26575) * harden validation of start option in `createWriteStream()` (ZYSzys) [#25579](#25579) * make writeFile consistent with readFile wrt fd (Sakthipriyan Vairamani (thefourtheye)) [#23709](#23709) * http: * validate timeout in `ClientRequest()` (cjihrig) [#26214](#26214) * return HTTP 431 on `HPE_HEADER_OVERFLOW` error (Albert Still) [#25605](#25605) * switch default parser to llhttp (Anna Henningsen) [#24870](#24870) * Runtime-deprecate `outgoingMessage._headers` and `outgoingMessage._headerNames` (Morgan Roderick) [#24167](#24167) * lib: * remove `Atomics.wake()` (Gus Caplan) [#27033](#27033) * move DTRACE\_\* probes out of global scope (James M Snell) [#26541](#26541) * deprecate `_stream_wrap` (Sam Roberts) [#26245](#26245) * use ES6 class inheritance style (Ruben Bridgewater) [#24755](#24755) * module: * remove unintended access to deps/ (Anna Henningsen) [#25138](#25138) * improve error message for MODULE\_NOT\_FOUND (Ali Ijaz Sheikh) [#25690](#25690) * requireStack property for MODULE\_NOT\_FOUND (Ali Ijaz Sheikh) [#25690](#25690) * remove dead code (Ruben Bridgewater) [#26983](#26983) * make `require('.')` never resolve outside the current directory (Ruben Bridgewater) [#26973](#26973) * throw an error for invalid package.json main entries (Ruben Bridgewater) [#26823](#26823) * don't search in `require.resolve.paths` (cjihrig) [#23683](#23683) * net: * remove `Server.listenFD()` (cjihrig) [#27127](#27127) * do not add `.host` and `.port` properties to DNS error (Ruben Bridgewater) [#26751](#26751) * emit "write after end" errors in the next tick (Ouyang Yadong) [#24457](#24457) * deprecate `_setSimultaneousAccepts()` undocumented function (James M Snell) [#23760](#23760) * os: * implement `os.type()` using `uv_os_uname()` (cjihrig) [#25659](#25659) * remove `os.getNetworkInterfaces()` (cjihrig) [#25280](#25280) * process: * make global.process, global.Buffer getters (Guy Bedford) [#26882](#26882) * move DEP0062 (node --debug) to end-of-life (Joyee Cheung) [#25828](#25828) * exit on --debug and --debug-brk after option parsing (Joyee Cheung) [#25828](#25828) * improve `--redirect-warnings` handling (Ruben Bridgewater) [#24965](#24965) * readline: * support TERM=dumb (Vladislav Kaminsky) [#26261](#26261) * repl: * add welcome message (gengjiawen) [#25947](#25947) * fix terminal default setting (Ruben Bridgewater) [#26518](#26518) * check colors with `.getColorDepth()` (Vladislav Kaminsky) [#26261](#26261) * deprecate REPLServer.rli (Ruben Bridgewater) [#26260](#26260) * src: * remove unused `INT_MAX` constant (Sam Roberts) [#27078](#27078) * update `NODE_MODULE_VERSION` to 72 (Ujjwal Sharma) [#26685](#26685) * remove `AddPromiseHook()` (Anna Henningsen) [#26574](#26574) * clean up `MultiIsolatePlatform` interface (Anna Henningsen) [#26384](#26384) * properly configure default heap limits (Ali Ijaz Sheikh) [#25576](#25576) * remove `icuDataDir` from node config (GauthamBanasandra) [#24780](#24780) * tls: * support TLSv1.3 (Sam Roberts) [#26209](#26209) * return correct version from `getCipher()` (Sam Roberts) [#26625](#26625) * check arg types of renegotiate() (Sam Roberts) [#25876](#25876) * add code for `ERR_TLS_INVALID_PROTOCOL_METHOD` (Sam Roberts) [#24729](#24729) * emit a warning when servername is an IP address (Rodger Combs) [#23329](#23329) * disable TLS v1.0 and v1.1 by default (Ben Noordhuis) [#23814](#23814) * remove unused arg to createSecureContext() (Sam Roberts) [#24241](#24241) * deprecate `Server.prototype.setOptions()` (cjihrig) [#23820](#23820) * load `NODE_EXTRA_CA_CERTS` at startup (Ouyang Yadong) [#23354](#23354) * util: * remove `util.print()`, `util.puts()`, `util.debug()` and `util.error()` (cjihrig) [#25377](#25377) * change inspect compact and breakLength default (Ruben Bridgewater) [#27109](#27109) * improve inspect edge cases (Ruben Bridgewater) [#27109](#27109) * only the first line of the error message (Simon Zünd) [#26685](#26685) * don't set the prototype of callbackified functions (Ruben Bridgewater) [#26893](#26893) * rename callbackified function (Ruben Bridgewater) [#26893](#26893) * increase function length when using `callbackify()` (Ruben Bridgewater) [#26893](#26893) * prevent tampering with internals in `inspect()` (Ruben Bridgewater) [#26577](#26577) * prevent Proxy traps being triggered by `.inspect()` (Ruben Bridgewater) [#26241](#26241) * prevent leaking internal properties (Ruben Bridgewater) [#24971](#24971) * protect against monkeypatched Object prototype for inspect() (Rich Trott) [#25953](#25953) * treat format arguments equally (Roman Reiss) [#23162](#23162) * win, fs: * detect if symlink target is a directory (Bartosz Sosnowski) [#23724](#23724) * zlib: * throw TypeError if callback is missing (Anna Henningsen) [#24929](#24929) * make “bare” constants un-enumerable (Anna Henningsen) [#24824](#24824) PR-URL: #26930
Notable changes: * assert: * validate required arguments (Ruben Bridgewater) [#26641](#26641) * adjust loose assertions (Ruben Bridgewater) [#25008](#25008) * async_hooks: * remove deprecated `emitBefore` and `emitAfter` (Matteo Collina) [#26530](#26530) * remove promise object from resource (Andreas Madsen) [#23443](#23443) * bootstrap: make Buffer and process non-enumerable (Ruben Bridgewater) [#24874](#24874) * buffer: * use stricter range checks (Ruben Bridgewater) [#27045](#27045) * harden `SlowBuffer` creation (ZYSzys) [#26272](#26272) * harden validation of buffer allocation size (ZYSzys) [#26162](#26162) * do proper error propagation in addon methods (Anna Henningsen) [#23939](#23939) * child_process: * remove `options.customFds` (cjihrig) [#25279](#25279) * harden fork arguments validation (ZYSzys) [#27039](#27039) * use non-infinite `maxBuffer` defaults (kohta ito) [#23027](#23027) * console: * don't use ANSI escape codes when `TERM=dumb` (Vladislav Kaminsky) [#26261](#26261) * crypto: * remove legacy native handles (Tobias Nießen) [#27011](#27011) * decode missing passphrase errors (Tobias Nießen) [#25208](#25208) * remove `Cipher.setAuthTag()` and `Decipher.getAuthTag()` (Tobias Nießen) [#26249](#26249) * remove deprecated `crypto._toBuf()` (Tobias Nießen) [#25338](#25338) * set `DEFAULT\_ENCODING` property to non-enumerable (Antoine du Hamel) [#23222](#23222) * deps: * update V8 to 7.4.288.13 (Michaël Zasso, cjihrig, Refael Ackermann) (Anna Henningsen, Ujjwal Sharma) [#26685](#26685) * bump minimum icu version to 63 (Ujjwal Sharma) [#25852](#25852) * update OpenSSL to 1.1.1b (Sam Roberts, Shigeki Ohtsu) [#26327](#26327) * errors: * update error name (Ruben Bridgewater) [#26738](#26738) * fs: * use proper .destroy() implementation for SyncWriteStream (Matteo Collina) [#26690](#26690) * improve mode validation (Ruben Bridgewater) [#26575](#26575) * harden validation of start option in `createWriteStream()` (ZYSzys) [#25579](#25579) * make writeFile consistent with readFile wrt fd (Sakthipriyan Vairamani (thefourtheye)) [#23709](#23709) * http: * validate timeout in `ClientRequest()` (cjihrig) [#26214](#26214) * return HTTP 431 on `HPE_HEADER_OVERFLOW` error (Albert Still) [#25605](#25605) * switch default parser to llhttp (Anna Henningsen) [#24870](#24870) * Runtime-deprecate `outgoingMessage._headers` and `outgoingMessage._headerNames` (Morgan Roderick) [#24167](#24167) * lib: * remove `Atomics.wake()` (Gus Caplan) [#27033](#27033) * move DTRACE\_\* probes out of global scope (James M Snell) [#26541](#26541) * deprecate `_stream_wrap` (Sam Roberts) [#26245](#26245) * use ES6 class inheritance style (Ruben Bridgewater) [#24755](#24755) * module: * remove unintended access to deps/ (Anna Henningsen) [#25138](#25138) * improve error message for MODULE\_NOT\_FOUND (Ali Ijaz Sheikh) [#25690](#25690) * requireStack property for MODULE\_NOT\_FOUND (Ali Ijaz Sheikh) [#25690](#25690) * remove dead code (Ruben Bridgewater) [#26983](#26983) * make `require('.')` never resolve outside the current directory (Ruben Bridgewater) [#26973](#26973) * throw an error for invalid package.json main entries (Ruben Bridgewater) [#26823](#26823) * don't search in `require.resolve.paths` (cjihrig) [#23683](#23683) * net: * remove `Server.listenFD()` (cjihrig) [#27127](#27127) * do not add `.host` and `.port` properties to DNS error (Ruben Bridgewater) [#26751](#26751) * emit "write after end" errors in the next tick (Ouyang Yadong) [#24457](#24457) * deprecate `_setSimultaneousAccepts()` undocumented function (James M Snell) [#23760](#23760) * os: * implement `os.type()` using `uv_os_uname()` (cjihrig) [#25659](#25659) * remove `os.getNetworkInterfaces()` (cjihrig) [#25280](#25280) * process: * make global.process, global.Buffer getters (Guy Bedford) [#26882](#26882) * move DEP0062 (node --debug) to end-of-life (Joyee Cheung) [#25828](#25828) * exit on --debug and --debug-brk after option parsing (Joyee Cheung) [#25828](#25828) * improve `--redirect-warnings` handling (Ruben Bridgewater) [#24965](#24965) * readline: * support TERM=dumb (Vladislav Kaminsky) [#26261](#26261) * repl: * add welcome message (gengjiawen) [#25947](#25947) * fix terminal default setting (Ruben Bridgewater) [#26518](#26518) * check colors with `.getColorDepth()` (Vladislav Kaminsky) [#26261](#26261) * deprecate REPLServer.rli (Ruben Bridgewater) [#26260](#26260) * src: * remove unused `INT_MAX` constant (Sam Roberts) [#27078](#27078) * update `NODE_MODULE_VERSION` to 72 (Ujjwal Sharma) [#26685](#26685) * remove `AddPromiseHook()` (Anna Henningsen) [#26574](#26574) * clean up `MultiIsolatePlatform` interface (Anna Henningsen) [#26384](#26384) * properly configure default heap limits (Ali Ijaz Sheikh) [#25576](#25576) * remove `icuDataDir` from node config (GauthamBanasandra) [#24780](#24780) * tls: * support TLSv1.3 (Sam Roberts) [#26209](#26209) * return correct version from `getCipher()` (Sam Roberts) [#26625](#26625) * check arg types of renegotiate() (Sam Roberts) [#25876](#25876) * add code for `ERR_TLS_INVALID_PROTOCOL_METHOD` (Sam Roberts) [#24729](#24729) * emit a warning when servername is an IP address (Rodger Combs) [#23329](#23329) * disable TLS v1.0 and v1.1 by default (Ben Noordhuis) [#23814](#23814) * remove unused arg to createSecureContext() (Sam Roberts) [#24241](#24241) * deprecate `Server.prototype.setOptions()` (cjihrig) [#23820](#23820) * load `NODE_EXTRA_CA_CERTS` at startup (Ouyang Yadong) [#23354](#23354) * util: * remove `util.print()`, `util.puts()`, `util.debug()` and `util.error()` (cjihrig) [#25377](#25377) * change inspect compact and breakLength default (Ruben Bridgewater) [#27109](#27109) * improve inspect edge cases (Ruben Bridgewater) [#27109](#27109) * only the first line of the error message (Simon Zünd) [#26685](#26685) * don't set the prototype of callbackified functions (Ruben Bridgewater) [#26893](#26893) * rename callbackified function (Ruben Bridgewater) [#26893](#26893) * increase function length when using `callbackify()` (Ruben Bridgewater) [#26893](#26893) * prevent tampering with internals in `inspect()` (Ruben Bridgewater) [#26577](#26577) * prevent Proxy traps being triggered by `.inspect()` (Ruben Bridgewater) [#26241](#26241) * prevent leaking internal properties (Ruben Bridgewater) [#24971](#24971) * protect against monkeypatched Object prototype for inspect() (Rich Trott) [#25953](#25953) * treat format arguments equally (Roman Reiss) [#23162](#23162) * win, fs: * detect if symlink target is a directory (Bartosz Sosnowski) [#23724](#23724) * zlib: * throw TypeError if callback is missing (Anna Henningsen) [#24929](#24929) * make “bare” constants un-enumerable (Anna Henningsen) [#24824](#24824) PR-URL: #26930
When a user attempts to load an encrypted key without supplying a passphrase, a cryptic OpenSSL error is thrown. This change intercepts the OpenSSL error and throws a nice error code instead.
I would prefer to treat this as semver-minor.cc @nodejs/crypto
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes