From 9b30bc4f81507ef812bbb52fd4355a8cda66a925 Mon Sep 17 00:00:00 2001 From: Shigeki Ohtsu Date: Wed, 25 Apr 2018 12:10:26 +0900 Subject: [PATCH] tls: fix getEphemeralKeyInfo to support X25519 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `EVP_PKEY_EC` only covers ANSI X9.62 curves not IETF ones(curve25519 and curve448). This fixes to add support of X25519 in `tlsSocket.getEphemeralKeyInfo()`. X448 should be added in the future upgrade to OpenSSL-1.1.1. PR-URL: https://github.com/nodejs/node/pull/20273 Fixes: https://github.com/nodejs/node/issues/20262 Reviewed-By: Daniel Bevenius Reviewed-By: Ben Noordhuis Reviewed-By: Tobias Nießen --- src/node_crypto.cc | 21 ++++++++++++++----- src/node_crypto.h | 2 ++ .../test-tls-client-getephemeralkeyinfo.js | 9 ++++++-- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index d9af0b4fa2f1b9..34018384eeeb75 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -2096,7 +2096,8 @@ void SSLWrap::GetEphemeralKeyInfo( EVP_PKEY* key; if (SSL_get_server_tmp_key(w->ssl_, &key)) { - switch (EVP_PKEY_id(key)) { + int kid = EVP_PKEY_id(key); + switch (kid) { case EVP_PKEY_DH: info->Set(context, env->type_string(), FIXED_ONE_BYTE_STRING(env->isolate(), "DH")).FromJust(); @@ -2104,19 +2105,29 @@ void SSLWrap::GetEphemeralKeyInfo( Integer::New(env->isolate(), EVP_PKEY_bits(key))).FromJust(); break; case EVP_PKEY_EC: + // TODO(shigeki) Change this to EVP_PKEY_X25519 and add EVP_PKEY_X448 + // after upgrading to 1.1.1. + case NID_X25519: { - EC_KEY* ec = EVP_PKEY_get1_EC_KEY(key); - int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); - EC_KEY_free(ec); + const char* curve_name; + if (kid == EVP_PKEY_EC) { + EC_KEY* ec = EVP_PKEY_get1_EC_KEY(key); + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec)); + curve_name = OBJ_nid2sn(nid); + EC_KEY_free(ec); + } else { + curve_name = OBJ_nid2sn(kid); + } info->Set(context, env->type_string(), FIXED_ONE_BYTE_STRING(env->isolate(), "ECDH")).FromJust(); info->Set(context, env->name_string(), OneByteString(args.GetIsolate(), - OBJ_nid2sn(nid))).FromJust(); + curve_name)).FromJust(); info->Set(context, env->size_string(), Integer::New(env->isolate(), EVP_PKEY_bits(key))).FromJust(); } + break; } EVP_PKEY_free(key); } diff --git a/src/node_crypto.h b/src/node_crypto.h index 31806b04434702..df7f47c82ab159 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -44,6 +44,8 @@ #endif // !OPENSSL_NO_ENGINE #include #include +// TODO(shigeki) Remove this after upgrading to 1.1.1 +#include #include #include #include diff --git a/test/parallel/test-tls-client-getephemeralkeyinfo.js b/test/parallel/test-tls-client-getephemeralkeyinfo.js index be6777b1ae0049..9432a277ac0fd0 100644 --- a/test/parallel/test-tls-client-getephemeralkeyinfo.js +++ b/test/parallel/test-tls-client-getephemeralkeyinfo.js @@ -82,7 +82,12 @@ function testECDHE256() { } function testECDHE512() { - test(521, 'ECDH', 'secp521r1', null); + test(521, 'ECDH', 'secp521r1', testX25519); + ntests++; +} + +function testX25519() { + test(253, 'ECDH', 'X25519', null); ntests++; } @@ -90,5 +95,5 @@ testNOT_PFS(); process.on('exit', function() { assert.strictEqual(ntests, nsuccess); - assert.strictEqual(ntests, 5); + assert.strictEqual(ntests, 6); });