crypto: support multiple ECDH curves and auto · nodejs/node@bd07574 · GitHub
Skip to content

Commit bd07574

Browse files
rogapsjasnell
authored andcommitted
crypto: support multiple ECDH curves and auto
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 <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Tobias Nießen <tniessen@tnie.de>
1 parent b9a9290 commit bd07574

4 files changed

Lines changed: 159 additions & 19 deletions

File tree

doc/api/tls.md

Lines changed: 9 additions & 7 deletions

src/node_crypto.cc

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -923,20 +923,14 @@ void SecureContext::SetECDHCurve(const FunctionCallbackInfo<Value>& args) {
923923

924924
node::Utf8Value curve(env->isolate(), args[0]);
925925

926-
int nid = OBJ_sn2nid(*curve);
927-
928-
if (nid == NID_undef)
929-
return env->ThrowTypeError("First argument should be a valid curve name");
930-
931-
EC_KEY* ecdh = EC_KEY_new_by_curve_name(nid);
932-
933-
if (ecdh == nullptr)
934-
return env->ThrowTypeError("First argument should be a valid curve name");
935-
936926
SSL_CTX_set_options(sc->ctx_, SSL_OP_SINGLE_ECDH_USE);
937-
SSL_CTX_set_tmp_ecdh(sc->ctx_, ecdh);
927+
SSL_CTX_set_ecdh_auto(sc->ctx_, 1);
928+
929+
if (strcmp(*curve, "auto") == 0)
930+
return;
938931

939-
EC_KEY_free(ecdh);
932+
if (!SSL_CTX_set1_curves_list(sc->ctx_, *curve))
933+
return env->ThrowError("Failed to set ECDH curve");
940934
}
941935

942936

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
'use strict';
2+
const common = require('../common');
3+
4+
// This test ensures that the value "auto" on ecdhCurve option is
5+
// supported to enable automatic curve selection in TLS server.
6+
7+
if (!common.hasCrypto)
8+
common.skip('missing crypto');
9+
10+
if (!common.opensslCli)
11+
common.skip('missing openssl-cli');
12+
13+
const assert = require('assert');
14+
const tls = require('tls');
15+
const spawn = require('child_process').spawn;
16+
const fixtures = require('../common/fixtures');
17+
18+
function loadPEM(n) {
19+
return fixtures.readKey(`${n}.pem`);
20+
}
21+
22+
const options = {
23+
key: loadPEM('agent2-key'),
24+
cert: loadPEM('agent2-cert'),
25+
ciphers: '-ALL:ECDHE-RSA-AES128-SHA256',
26+
ecdhCurve: 'auto'
27+
};
28+
29+
const reply = 'I AM THE WALRUS'; // something recognizable
30+
31+
const server = tls.createServer(options, function(conn) {
32+
conn.end(reply);
33+
});
34+
35+
let gotReply = false;
36+
37+
server.listen(0, function() {
38+
const args = ['s_client',
39+
'-cipher', `${options.ciphers}`,
40+
'-connect', `127.0.0.1:${this.address().port}`];
41+
42+
// for the performance and stability issue in s_client on Windows
43+
if (common.isWindows)
44+
args.push('-no_rand_screen');
45+
46+
const client = spawn(common.opensslCli, args);
47+
48+
client.stdout.on('data', function(data) {
49+
const message = data.toString();
50+
if (message.includes(reply))
51+
gotReply = true;
52+
});
53+
54+
client.on('exit', function(code) {
55+
assert.strictEqual(0, code);
56+
server.close();
57+
});
58+
59+
client.on('error', assert.ifError);
60+
});
61+
62+
process.on('exit', function() {
63+
assert.ok(gotReply);
64+
});
Lines changed: 80 additions & 0 deletions

0 commit comments

Comments
 (0)