-
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: support multiple ECDH curves and auto #15206
Conversation
src/node_crypto.cc
Outdated
if (!SSL_CTX_set1_curves_list(sc->ctx_, *curve)) | ||
return env->ThrowError("Failed to set ECDH curve"); | ||
#else | ||
int nid = OBJ_sn2nid(strcmp(*curve, "auto") == 0 ? "prime256v1" : *curve); |
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'm not sure we should be implicitly selecting our own hardcoded curve in this case for "auto." If the intent is to use the value of tls.DEFAULT_ECDH_CURVE
, we would probably need to dynamically read that value since it could be changed by end users. However, we should probably throw an error instead when we see "auto" and the appropriate OpenSSL API is not available.
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.
My intention was to use tls.DEFAULT_ECDH_CURVE
's value but displaying error is perhaps better if auto is actually not supported the version of OpenSSL.
src/node_crypto.cc
Outdated
int nid = OBJ_sn2nid(*curve); | ||
SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE); | ||
|
||
#if (defined SSL_CTX_set1_curves_list || defined SSL_CTRL_SET_CURVES_LIST) |
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.
Minor nit: we use defined()
below but not here. I think we should be consistent.
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.
Sure. I will update it.
/cc @nodejs/crypto |
1e960c6
to
9636b1c
Compare
PTAL @nodejs/crypto |
test/parallel/test-tls-ecdh-auto.js
Outdated
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
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 copyright header block should not be added to new files
test/parallel/test-tls-ecdh-auto.js
Outdated
|
||
const options = { | ||
key: fs.readFileSync(`${common.fixturesDir}/keys/agent2-key.pem`), | ||
cert: fs.readFileSync(`${common.fixturesDir}/keys/agent2-cert.pem`), |
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.
Please make use of the new require('common/fixtures')
utility here.
test/parallel/test-tls-ecdh-auto.js
Outdated
conn.end(reply); | ||
})); | ||
|
||
server.listen(0, '127.0.0.1', common.mustCall(function() { |
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 127.0.0.1
host can be omitted
test/parallel/test-tls-ecdh-auto.js
Outdated
|
||
server.listen(0, '127.0.0.1', common.mustCall(function() { | ||
let cmd = `"${common.opensslCli}" s_client -cipher ${ | ||
options.ciphers} -connect 127.0.0.1:${this.address().port}`; |
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.
Not really a fan of multiline template literals and we've tried to avoid their use in the past.
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE | ||
// USE OR OTHER DEALINGS IN THE SOFTWARE. |
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.
Ditto here... the copyright header should not be included.
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.
Getting closer! Left a few comments.
Mostly LGTM, will do a review when @jasnell's comments were addressed. |
src/node_crypto.cc
Outdated
@@ -923,6 +923,22 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) { | |||
|
|||
node::Utf8Value curve(env->isolate(), args[0]); | |||
|
|||
SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE); | |||
|
|||
#if defined(SSL_CTX_set1_curves_list) || defined(SSL_CTRL_SET_CURVES_LIST) |
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 don't think you have to do this #define dance; the versions of openssl we support, support this API.
src/node_crypto.cc
Outdated
SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE); | ||
|
||
#if defined(SSL_CTX_set1_curves_list) || defined(SSL_CTRL_SET_CURVES_LIST) | ||
# if defined(SSL_CTX_set_ecdh_auto) |
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.
Likewise.
src/node_crypto.cc
Outdated
if (strcmp(*curve, "auto") == 0) | ||
return; | ||
|
||
if (!SSL_CTX_set1_curves_list(sc->ctx_, *curve)) |
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.
One (possibly academic) drawback to SSL_CTX_set1_curves_list()
is that it won't let you set more than ~30 curves.
I.e., options = { ecdhCurve: crypto.getCurves().join(':') }
won't work because there are over 80 different curves.
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.
Supported curves are listed here. Does the documentation need to mention the lists?
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.
Yes, I think that's a good idea. I was initially going to suggest to just refer readers to the relevant RFCs but on second thought, that would work okay for Brainpool (RFC 7027) but RFC 4492 is too much of a grab bag of different algorithms.
src/node_crypto.cc
Outdated
@@ -933,10 +949,10 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) { | |||
if (ecdh == nullptr) | |||
return env->ThrowTypeError("First argument should be a valid curve name"); | |||
|
|||
SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE); |
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.
Why was this removed?
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.
fwiw it was moved up
Thanks for the reviews. I will address them. |
9636b1c
to
a266edc
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.
LGTM if @bnoordhuis is happy also.
LGTM if CI passes: https://ci.nodejs.org/job/node-test-pull-request/10098/ |
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.
Thanks, LGTM.
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.
JS and doc LGTM
test/parallel/test-tls-ecdh-auto.js
Outdated
}); | ||
|
||
client.on('error', function(error) { | ||
assert.ifError(error); |
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.
Nit: (non blocking) assert.ifError
is actually meant as callback replacement. Therefore you do not have to wrap it in a function and can use it as client.on("error", assert.ifError)
instead. The same in the other test.
I am OK with this but in general - would it not be much nicer to use an |
Perhaps, but using the |
This is failing significantly on FIPS...
|
@jasnell I overlooked FIPS mode doesn't support |
a266edc
to
affa214
Compare
@rogaps I assume you are just going to update the tests so that they don't try to use brainpoolP256r1 when in FIPs mode. Although maybe you have already updated. |
@mhdawson Sure. I will update the tests for some unsupported curves. |
Using SSL_CTX_set1_curves_list() (OpenSSL 1.0.2+), this allows to set colon separated ECDH curve names in SecureContext's ecdhCurve option. The option can also be set to "auto" to select the curve automatically from list built in OpenSSL by enabling SSL_CTX_set_ecdh_auto() (OpenSSL 1.0.2+). PR-URL: #15206 Ref: #15054 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
Landed in 873e5bd |
Using SSL_CTX_set1_curves_list() (OpenSSL 1.0.2+), this allows to set colon separated ECDH curve names in SecureContext's ecdhCurve option. The option can also be set to "auto" to select the curve automatically from list built in OpenSSL by enabling SSL_CTX_set_ecdh_auto() (OpenSSL 1.0.2+). PR-URL: #15206 Ref: #15054 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
* **crypto** * Support for multiple ECDH curves. [#15206](#15206) * **dgram** * Added `setMulticastInterface()` API. [#7855](#7855) * **n-api** * The command-line flag is no longer required to use N-API. [#14902](#14902) * **tls** * Docs-only deprecation of `parseCertString()`. [#14245](#14245) * **New Contributors** * Welcome Sebastiaan Deckers (@sebdeckers) as a new Collaborator! [#15354](#15354)
* **crypto** * Support for multiple ECDH curves. [#15206](#15206) * **dgram** * Added `setMulticastInterface()` API. [#7855](#7855) * **n-api** * The command-line flag is no longer required to use N-API. [#14902](#14902) * **tls** * Docs-only deprecation of `parseCertString()`. [#14245](#14245) * **New Contributors** * Welcome Sebastiaan Deckers (@sebdeckers) as a new Collaborator! [#15354](#15354)
Using SSL_CTX_set1_curves_list() (OpenSSL 1.0.2+), this allows to set colon separated ECDH curve names in SecureContext's ecdhCurve option. The option can also be set to "auto" to select the curve automatically from list built in OpenSSL by enabling SSL_CTX_set_ecdh_auto() (OpenSSL 1.0.2+). PR-URL: nodejs/node#15206 Ref: nodejs/node#15054 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
Using SSL_CTX_set1_curves_list() (OpenSSL 1.0.2+), this allows to set colon separated ECDH curve names in SecureContext's ecdhCurve option. The option can also be set to "auto" to select the curve automatically from list built in OpenSSL by enabling SSL_CTX_set_ecdh_auto() (OpenSSL 1.0.2+). PR-URL: nodejs/node#15206 Ref: nodejs/node#15054 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Ruben Bridgewater <[email protected]> Reviewed-By: Tobias Nießen <[email protected]>
* **crypto** * Support for multiple ECDH curves. [#15206](#15206) * **dgram** * Added `setMulticastInterface()` API. [#7855](#7855) * **n-api** * The command-line flag is no longer required to use N-API. [#14902](#14902) * **tls** * Docs-only deprecation of `parseCertString()`. [#14245](#14245) * **New Contributors** * Welcome Sebastiaan Deckers (@sebdeckers) as a new Collaborator! [#15354](#15354)
* **crypto** * Support for multiple ECDH curves. [#15206](#15206) * **dgram** * Added `setMulticastInterface()` API. [#7855](#7855) * Custom lookup functions are now supported. [#14560](#14560) * **n-api** * The command-line flag is no longer required to use N-API. [#14902](#14902) * **tls** * Docs-only deprecation of `parseCertString()`. [#14245](#14245) * **New Contributors** * Welcome Sebastiaan Deckers (@sebdeckers) as a new Collaborator! [#15354](#15354)
* **crypto** * Support for multiple ECDH curves. [#15206](#15206) * **dgram** * Added `setMulticastInterface()` API. [#7855](#7855) * Custom lookup functions are now supported. [#14560](#14560) * **n-api** * The command-line flag is no longer required to use N-API. [#14902](#14902) * **tls** * Docs-only deprecation of `parseCertString()`. [#14245](#14245) * **New Contributors** * Welcome Sebastiaan Deckers (@sebdeckers) as a new Collaborator! [#15354](#15354)
* **crypto** * Support for multiple ECDH curves. [#15206](#15206) * **dgram** * Added `setMulticastInterface()` API. [#7855](#7855) * Custom lookup functions are now supported. [#14560](#14560) * **n-api** * The command-line flag is no longer required to use N-API. [#14902](#14902) * **tls** * Docs-only deprecation of `parseCertString()`. [#14245](#14245) * **New Contributors** * Welcome Sebastiaan Deckers (@sebdeckers) as a new Collaborator! [#15354](#15354)
* **crypto** * Support for multiple ECDH curves. [#15206](nodejs/node#15206) * **dgram** * Added `setMulticastInterface()` API. [#7855](nodejs/node#7855) * Custom lookup functions are now supported. [#14560](nodejs/node#14560) * **n-api** * The command-line flag is no longer required to use N-API. [#14902](nodejs/node#14902) * **tls** * Docs-only deprecation of `parseCertString()`. [#14245](nodejs/node#14245) * **New Contributors** * Welcome Sebastiaan Deckers (@sebdeckers) as a new Collaborator! [#15354](nodejs/node#15354)
For best out-of-the-box compatibility there should not be one default `ecdhCurve` for the tls client, OpenSSL should choose them automatically. See https://wiki.openssl.org/index.php/Manual:SSL_CTX_set1_curves(3) PR-URL: #16853 Refs: #16196 Refs: #1495 Refs: #15206 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Rich Trott <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Sam Roberts <[email protected]> Reviewed-By: Tobias Nießen <[email protected]> Reviewed-By: Luigi Pinca <[email protected]>
@nodejs/lts Post-mortem on this, it contained an accidental breaking change (which brought the code in line with the docs), changing the default curve setting from One thing that would help would be @sam-github 's suggestion in #16853 (comment), which is adding a Quite a few people have hit this, so IMO we should prioritize getting this fixed and backported to 8.x and 6.x. |
Using SSL_CTX_set1_curves_list() (OpenSSL 1.0.2+), this allows to set
colon separated ECDH curve names in SecureContext's ecdhCurve option.
The option can also be set to "auto" to select the curve automatically
from list built in OpenSSL by enabling SSL_CTX_set_ecdh_auto()
(OpenSSL 1.0.2+).
Refs: #15054
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
crypto