From ac69b95e47f10179f0ab0cd79d6c9befee334594 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 1 Apr 2021 22:06:39 +0200 Subject: [PATCH] crypto: use correct webcrypto RSASSA-PKCS1-v1_5 algorithm name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/38029 Refs: https://www.w3.org/TR/WebCryptoAPI/#rsassa-pkcs1 Reviewed-By: James M Snell Reviewed-By: Tobias Nießen --- lib/internal/crypto/keygen.js | 4 +- lib/internal/crypto/rsa.js | 4 +- lib/internal/crypto/util.js | 57 ++++++++++--------- lib/internal/crypto/webcrypto.js | 12 ++-- src/crypto/crypto_rsa.cc | 2 +- src/crypto/crypto_rsa.h | 4 +- .../test-webcrypto-export-import-rsa.js | 2 +- test/parallel/test-webcrypto-keygen.js | 4 +- test/parallel/test-webcrypto-sign-verify.js | 8 +-- test/parallel/test-webcrypto-wrap-unwrap.js | 2 +- 10 files changed, 52 insertions(+), 47 deletions(-) diff --git a/lib/internal/crypto/keygen.js b/lib/internal/crypto/keygen.js index cb41b8c91fe42d..6fc06936a4fb03 100644 --- a/lib/internal/crypto/keygen.js +++ b/lib/internal/crypto/keygen.js @@ -16,7 +16,7 @@ const { kCryptoJobAsync, kCryptoJobSync, kKeyVariantRSA_PSS, - kKeyVariantRSA_SSA_PKCS1_V1_5, + kKeyVariantRSA_SSA_PKCS1_v1_5, EVP_PKEY_ED25519, EVP_PKEY_ED448, EVP_PKEY_X25519, @@ -183,7 +183,7 @@ function createJob(mode, type, options) { if (type === 'rsa') { return new RsaKeyPairGenJob( mode, - kKeyVariantRSA_SSA_PKCS1_V1_5, // Used also for RSA-OAEP + kKeyVariantRSA_SSA_PKCS1_v1_5, // Used also for RSA-OAEP modulusLength, publicExponent, ...encoding); diff --git a/lib/internal/crypto/rsa.js b/lib/internal/crypto/rsa.js index 06a9e802717c54..3a1599e2ac7ab6 100644 --- a/lib/internal/crypto/rsa.js +++ b/lib/internal/crypto/rsa.js @@ -14,7 +14,7 @@ const { kCryptoJobAsync, kSignJobModeSign, kSignJobModeVerify, - kKeyVariantRSA_SSA_PKCS1_V1_5, + kKeyVariantRSA_SSA_PKCS1_v1_5, kKeyVariantRSA_PSS, kKeyVariantRSA_OAEP, kKeyTypePrivate, @@ -66,7 +66,7 @@ const { } = require('internal/crypto/keygen'); const kRsaVariants = { - 'RSASSA-PKCS1-V1_5': kKeyVariantRSA_SSA_PKCS1_V1_5, + 'RSASSA-PKCS1-v1_5': kKeyVariantRSA_SSA_PKCS1_v1_5, 'RSA-PSS': kKeyVariantRSA_PSS, 'RSA-OAEP': kKeyVariantRSA_OAEP, }; diff --git a/lib/internal/crypto/util.js b/lib/internal/crypto/util.js index b0a903f03dd3b4..3c96f34f90e97e 100644 --- a/lib/internal/crypto/util.js +++ b/lib/internal/crypto/util.js @@ -6,9 +6,9 @@ const { BigInt, FunctionPrototypeBind, Number, + ObjectKeys, Promise, StringPrototypeToLowerCase, - StringPrototypeToUpperCase, Symbol, } = primordials; @@ -159,31 +159,32 @@ const kAesKeyLengths = [128, 192, 256]; // These are the only algorithms we currently support // via the Web Crypto API -const kAlgorithms = [ - 'rsassa-pkcs1-v1_5', - 'rsa-pss', - 'rsa-oaep', - 'ecdsa', - 'ecdh', - 'aes-ctr', - 'aes-cbc', - 'aes-gcm', - 'aes-kw', - 'hmac', - 'sha-1', - 'sha-256', - 'sha-384', - 'sha-512', - 'hkdf', - 'pbkdf2', +const kAlgorithms = { + 'rsassa-pkcs1-v1_5': 'RSASSA-PKCS1-v1_5', + 'rsa-pss': 'RSA-PSS', + 'rsa-oaep': 'RSA-OAEP', + 'ecdsa': 'ECDSA', + 'ecdh': 'ECDH', + 'aes-ctr': 'AES-CTR', + 'aes-cbc': 'AES-CBC', + 'aes-gcm': 'AES-GCM', + 'aes-kw': 'AES-KW', + 'hmac': 'HMAC', + 'sha-1': 'SHA-1', + 'sha-256': 'SHA-256', + 'sha-384': 'SHA-384', + 'sha-512': 'SHA-512', + 'hkdf': 'HKDF', + 'pbkdf2': 'PBKDF2', // Following here are Node.js specific extensions. All // should be prefixed with 'node-' - 'node-dsa', - 'node-dh', - 'node-scrypt', - 'node-ed25519', - 'node-ed448', -]; + 'node-dsa': 'NODE-DSA', + 'node-dh': 'NODE-DH', + 'node-scrypt': 'NODE-SCRYPT', + 'node-ed25519': 'NODE-ED25519', + 'node-ed448': 'NODE-ED448', +}; +const kAlgorithmsKeys = ObjectKeys(kAlgorithms); // These are the only export and import formats we currently // support via the Web Crypto API @@ -221,7 +222,7 @@ function normalizeAlgorithm(algorithm, label = 'algorithm') { let hash; if (typeof name !== 'string' || !ArrayPrototypeIncludes( - kAlgorithms, + kAlgorithmsKeys, StringPrototypeToLowerCase(name))) { throw lazyDOMException('Unrecognized name.', 'NotSupportedError'); } @@ -230,7 +231,11 @@ function normalizeAlgorithm(algorithm, label = 'algorithm') { if (!ArrayPrototypeIncludes(kHashTypes, hash.name)) throw lazyDOMException('Unrecognized name.', 'NotSupportedError'); } - return { ...algorithm, name: StringPrototypeToUpperCase(name), hash }; + return { + ...algorithm, + name: kAlgorithms[StringPrototypeToLowerCase(name)], + hash, + }; } } throw lazyDOMException('Unrecognized name.', 'NotSupportedError'); diff --git a/lib/internal/crypto/webcrypto.js b/lib/internal/crypto/webcrypto.js index 57e3ee3af11eb2..47c34b9ca0d665 100644 --- a/lib/internal/crypto/webcrypto.js +++ b/lib/internal/crypto/webcrypto.js @@ -71,7 +71,7 @@ async function generateKey( validateBoolean(extractable, 'extractable'); validateArray(keyUsages, 'keyUsages'); switch (algorithm.name) { - case 'RSASSA-PKCS1-V1_5': + case 'RSASSA-PKCS1-v1_5': // Fall through case 'RSA-PSS': // Fall through @@ -199,7 +199,7 @@ async function deriveKey( async function exportKeySpki(key) { switch (key.algorithm.name) { - case 'RSASSA-PKCS1-V1_5': + case 'RSASSA-PKCS1-v1_5': // Fall through case 'RSA-PSS': // Fall through @@ -242,7 +242,7 @@ async function exportKeySpki(key) { async function exportKeyPkcs8(key) { switch (key.algorithm.name) { - case 'RSASSA-PKCS1-V1_5': + case 'RSASSA-PKCS1-v1_5': // Fall through case 'RSA-PSS': // Fall through @@ -321,7 +321,7 @@ async function exportKeyJWK(key) { ext: key.extractable, }); switch (key.algorithm.name) { - case 'RSASSA-PKCS1-V1_5': + case 'RSASSA-PKCS1-v1_5': jwk.alg = normalizeHashName( key.algorithm.hash.name, normalizeHashName.kContextJwkRsa); @@ -461,7 +461,7 @@ async function importKey( validateBoolean(extractable, 'extractable'); validateArray(keyUsages, 'keyUsages'); switch (algorithm.name) { - case 'RSASSA-PKCS1-V1_5': + case 'RSASSA-PKCS1-v1_5': // Fall through case 'RSA-PSS': // Fall through @@ -588,7 +588,7 @@ function signVerify(algorithm, key, data, signature) { switch (algorithm.name) { case 'RSA-PSS': // Fall through - case 'RSASSA-PKCS1-V1_5': + case 'RSASSA-PKCS1-v1_5': return lazyRequire('internal/crypto/rsa') .rsaSignVerify(key, data, algorithm, signature); case 'NODE-ED25519': diff --git a/src/crypto/crypto_rsa.cc b/src/crypto/crypto_rsa.cc index 22c20a3031899c..a77ded918ebdda 100644 --- a/src/crypto/crypto_rsa.cc +++ b/src/crypto/crypto_rsa.cc @@ -559,7 +559,7 @@ void Initialize(Environment* env, Local target) { RSAKeyExportJob::Initialize(env, target); RSACipherJob::Initialize(env, target); - NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_SSA_PKCS1_V1_5); + NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_SSA_PKCS1_v1_5); NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_PSS); NODE_DEFINE_CONSTANT(target, kKeyVariantRSA_OAEP); } diff --git a/src/crypto/crypto_rsa.h b/src/crypto/crypto_rsa.h index fc2a9130389347..acc233ccbb36d2 100644 --- a/src/crypto/crypto_rsa.h +++ b/src/crypto/crypto_rsa.h @@ -15,7 +15,7 @@ namespace node { namespace crypto { enum RSAKeyVariant { - kKeyVariantRSA_SSA_PKCS1_V1_5, + kKeyVariantRSA_SSA_PKCS1_v1_5, kKeyVariantRSA_PSS, kKeyVariantRSA_OAEP }; @@ -53,7 +53,7 @@ struct RsaKeyGenTraits final { using RSAKeyPairGenJob = KeyGenJob>; struct RSAKeyExportConfig final : public MemoryRetainer { - RSAKeyVariant variant = kKeyVariantRSA_SSA_PKCS1_V1_5; + RSAKeyVariant variant = kKeyVariantRSA_SSA_PKCS1_v1_5; SET_NO_MEMORY_INFO() SET_MEMORY_INFO_NAME(RSAKeyExportConfig) SET_SELF_SIZE(RSAKeyExportConfig) diff --git a/test/parallel/test-webcrypto-export-import-rsa.js b/test/parallel/test-webcrypto-export-import-rsa.js index 1caf60f156c945..5deff132cb383a 100644 --- a/test/parallel/test-webcrypto-export-import-rsa.js +++ b/test/parallel/test-webcrypto-export-import-rsa.js @@ -457,7 +457,7 @@ const testVectors = [ publicUsages: ['verify'] }, { - name: 'RSASSA-PKCS1-V1_5', + name: 'RSASSA-PKCS1-v1_5', privateUsages: ['sign'], publicUsages: ['verify'] } diff --git a/test/parallel/test-webcrypto-keygen.js b/test/parallel/test-webcrypto-keygen.js index 4aa3cc4cf28401..9e18c871a169dd 100644 --- a/test/parallel/test-webcrypto-keygen.js +++ b/test/parallel/test-webcrypto-keygen.js @@ -65,7 +65,7 @@ const vectors = { ], mandatoryUsages: [] }, - 'RSASSA-PKCS1-V1_5': { + 'RSASSA-PKCS1-v1_5': { algorithm: { modulusLength: 1024, publicExponent: new Uint8Array([1, 0, 1]), @@ -317,7 +317,7 @@ const vectors = { const kTests = [ [ - 'RSASSA-PKCS1-V1_5', + 'RSASSA-PKCS1-v1_5', 1024, Buffer.from([1, 0, 1]), 'SHA-256', diff --git a/test/parallel/test-webcrypto-sign-verify.js b/test/parallel/test-webcrypto-sign-verify.js index 93fcdc17815f3e..71e357fedb7fc0 100644 --- a/test/parallel/test-webcrypto-sign-verify.js +++ b/test/parallel/test-webcrypto-sign-verify.js @@ -11,23 +11,23 @@ const { subtle } = require('crypto').webcrypto; // This is only a partial test. The WebCrypto Web Platform Tests // will provide much greater coverage. -// Test Sign/Verify RSASSA-PKCS1-V1_5 +// Test Sign/Verify RSASSA-PKCS1-v1_5 { async function test(data) { const ec = new TextEncoder(); const { publicKey, privateKey } = await subtle.generateKey({ - name: 'RSASSA-PKCS1-V1_5', + name: 'RSASSA-PKCS1-v1_5', modulusLength: 1024, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256' }, true, ['sign', 'verify']); const signature = await subtle.sign({ - name: 'RSASSA-PKCS1-V1_5' + name: 'RSASSA-PKCS1-v1_5' }, privateKey, ec.encode(data)); assert(await subtle.verify({ - name: 'RSASSA-PKCS1-V1_5' + name: 'RSASSA-PKCS1-v1_5' }, publicKey, signature, ec.encode(data))); } diff --git a/test/parallel/test-webcrypto-wrap-unwrap.js b/test/parallel/test-webcrypto-wrap-unwrap.js index d0c46737797a29..a28829b646f598 100644 --- a/test/parallel/test-webcrypto-wrap-unwrap.js +++ b/test/parallel/test-webcrypto-wrap-unwrap.js @@ -64,7 +64,7 @@ async function generateKeysToWrap() { const parameters = [ { algorithm: { - name: 'RSASSA-PKCS1-V1_5', + name: 'RSASSA-PKCS1-v1_5', modulusLength: 1024, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256'