From cb3b0ec4fcbef9d77bcb66338ca048b69ca2a31b Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Mon, 25 Jan 2021 14:18:27 +0100 Subject: [PATCH] crypto: generateKeyPair('ec') should not support NODE-ED* and NODE-X* MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes https://github.com/nodejs/node/issues/37055 PR-URL: https://github.com/nodejs/node/pull/37063 Reviewed-By: James M Snell Reviewed-By: Tobias Nießen Reviewed-By: Juan José Arboleda --- lib/internal/crypto/ec.js | 22 +++++++++++++++++++++- src/crypto/crypto_ec.cc | 28 ++++++++++++++++------------ src/crypto/crypto_ec.h | 1 + src/crypto/crypto_keys.cc | 2 +- test/parallel/test-crypto-keygen.js | 16 ++++++++++++++++ 5 files changed, 55 insertions(+), 14 deletions(-) diff --git a/lib/internal/crypto/ec.js b/lib/internal/crypto/ec.js index 248bba57ad2c3f..88079707367b5d 100644 --- a/lib/internal/crypto/ec.js +++ b/lib/internal/crypto/ec.js @@ -166,7 +166,27 @@ async function ecGenerateKey(algorithm, extractable, keyUsages) { // Fall through } return new Promise((resolve, reject) => { - generateKeyPair('ec', { namedCurve }, (err, pubKey, privKey) => { + let genKeyType; + let genOpts; + switch (namedCurve) { + case 'NODE-ED25519': + genKeyType = 'ed25519'; + break; + case 'NODE-ED448': + genKeyType = 'ed448'; + break; + case 'NODE-X25519': + genKeyType = 'x25519'; + break; + case 'NODE-X448': + genKeyType = 'x448'; + break; + default: + genKeyType = 'ec'; + genOpts = { namedCurve }; + break; + } + generateKeyPair(genKeyType, genOpts, (err, pubKey, privKey) => { if (err) { return reject(lazyDOMException( 'The operation failed for an operation-specific reason', diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc index c764124bdd0d6f..1dd3b317633cdd 100644 --- a/src/crypto/crypto_ec.cc +++ b/src/crypto/crypto_ec.cc @@ -36,17 +36,21 @@ int GetCurveFromName(const char* name) { int nid = EC_curve_nist2nid(name); if (nid == NID_undef) nid = OBJ_sn2nid(name); - // If there is still no match, check manually for known curves - if (nid == NID_undef) { - if (strcmp(name, "NODE-ED25519") == 0) { - nid = EVP_PKEY_ED25519; - } else if (strcmp(name, "NODE-ED448") == 0) { - nid = EVP_PKEY_ED448; - } else if (strcmp(name, "NODE-X25519") == 0) { - nid = EVP_PKEY_X25519; - } else if (strcmp(name, "NODE-X448") == 0) { - nid = EVP_PKEY_X448; - } + return nid; +} + +int GetOKPCurveFromName(const char* name) { + int nid; + if (strcmp(name, "NODE-ED25519") == 0) { + nid = EVP_PKEY_ED25519; + } else if (strcmp(name, "NODE-ED448") == 0) { + nid = EVP_PKEY_ED448; + } else if (strcmp(name, "NODE-X25519") == 0) { + nid = EVP_PKEY_X25519; + } else if (strcmp(name, "NODE-X448") == 0) { + nid = EVP_PKEY_X448; + } else { + nid = NID_undef; } return nid; } @@ -443,7 +447,7 @@ Maybe ECDHBitsTraits::AdditionalConfig( return Nothing(); } - params->id_ = GetCurveFromName(*name); + params->id_ = GetOKPCurveFromName(*name); params->private_ = private_key->Data(); params->public_ = public_key->Data(); diff --git a/src/crypto/crypto_ec.h b/src/crypto/crypto_ec.h index a6ec85947bfd99..00d9d0087b0989 100644 --- a/src/crypto/crypto_ec.h +++ b/src/crypto/crypto_ec.h @@ -17,6 +17,7 @@ namespace node { namespace crypto { int GetCurveFromName(const char* name); +int GetOKPCurveFromName(const char* name); class ECDH final : public BaseObject { public: diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index cb548d10cf45b7..6a4d7950c8629c 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -1058,7 +1058,7 @@ void KeyObjectHandle::InitEDRaw(const FunctionCallbackInfo& args) { ? EVP_PKEY_new_raw_private_key : EVP_PKEY_new_raw_public_key; - int id = GetCurveFromName(*name); + int id = GetOKPCurveFromName(*name); switch (id) { case EVP_PKEY_X25519: diff --git a/test/parallel/test-crypto-keygen.js b/test/parallel/test-crypto-keygen.js index c27d5fe166220e..b80b35135743d9 100644 --- a/test/parallel/test-crypto-keygen.js +++ b/test/parallel/test-crypto-keygen.js @@ -1283,3 +1283,19 @@ const sec1EncExp = (cipher) => getRegExpForPEM('EC PRIVATE KEY', cipher); })); } } + +{ + // Proprietary Web Cryptography API ECDH/ECDSA namedCurve parameters + // should not be recognized in this API. + // See https://github.com/nodejs/node/issues/37055 + const curves = ['NODE-ED25519', 'NODE-ED448', 'NODE-X25519', 'NODE-X448']; + for (const namedCurve of curves) { + assert.throws( + () => generateKeyPair('ec', { namedCurve }, common.mustNotCall()), + { + name: 'TypeError', + message: 'Invalid EC curve name' + } + ); + } +}