diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2021-09-14 18:51:20 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-14 15:21:20 +0200 |
commit | c41460ecc421ac7730cc5455542e5e05f7366c4a (patch) | |
tree | 18b7ac8683d6543b0610c25d42df089e2bf7d183 /ext/crypto/00_crypto.js | |
parent | d36b01ff6956930b51a80cd773f618b708a5f595 (diff) |
feat(ext/crypto): import RSA pkcs#8 keys (#11891)
Diffstat (limited to 'ext/crypto/00_crypto.js')
-rw-r--r-- | ext/crypto/00_crypto.js | 181 |
1 files changed, 178 insertions, 3 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index b3131a4f8..5eb283b22 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -68,6 +68,7 @@ }, Pbkdf2Params: { hash: "HashAlgorithmIdentifier", salt: "BufferSource" }, RsaOaepParams: { label: "BufferSource" }, + RsaHashedImportParams: { hash: "HashAlgorithmIdentifier" }, }; const supportedAlgorithms = { @@ -102,6 +103,9 @@ "HMAC": null, }, "importKey": { + "RSASSA-PKCS1-v1_5": "RsaHashedImportParams", + "RSA-PSS": "RsaHashedImportParams", + "RSA-OAEP": "RsaHashedImportParams", "HMAC": "HmacImportParams", "HKDF": null, "PBKDF2": null, @@ -664,7 +668,6 @@ * @param {KeyUsages[]} keyUsages * @returns {Promise<any>} */ - // deno-lint-ignore require-await async importKey(format, keyData, algorithm, extractable, keyUsages) { webidl.assertBranded(this, SubtleCrypto); const prefix = "Failed to execute 'importKey' on 'SubtleCrypto'"; @@ -898,8 +901,180 @@ return key; } - // TODO(@littledivy): RSASSA-PKCS1-v1_5 - // TODO(@littledivy): RSA-PSS + case "RSASSA-PKCS1-v1_5": { + switch (format) { + case "pkcs8": { + // 1. + if ( + ArrayPrototypeFind( + keyUsages, + (u) => !ArrayPrototypeIncludes(["sign"], u), + ) !== undefined + ) { + throw new DOMException("Invalid key usages", "SyntaxError"); + } + + if (keyUsages.length == 0) { + throw new DOMException("Key usage is empty", "SyntaxError"); + } + + // 2-9. + const { modulusLength, publicExponent, data } = await core + .opAsync( + "op_crypto_import_key", + { + algorithm: "RSASSA-PKCS1-v1_5", + format: "pkcs8", + // Needed to perform step 7 without normalization. + hash: normalizedAlgorithm.hash.name, + }, + keyData, + ); + + const handle = {}; + WeakMapPrototypeSet(KEY_STORE, handle, { + // PKCS#1 for RSA + type: "raw", + data, + }); + + const algorithm = { + name: "RSASSA-PKCS1-v1_5", + modulusLength, + publicExponent, + hash: normalizedAlgorithm.hash, + }; + + const key = constructKey( + "private", + extractable, + usageIntersection(keyUsages, recognisedUsages), + algorithm, + handle, + ); + + return key; + } + default: + throw new DOMException("Not implemented", "NotSupportedError"); + } + } + case "RSA-PSS": { + switch (format) { + case "pkcs8": { + // 1. + if ( + ArrayPrototypeFind( + keyUsages, + (u) => !ArrayPrototypeIncludes(["sign"], u), + ) !== undefined + ) { + throw new DOMException("Invalid key usages", "SyntaxError"); + } + + if (keyUsages.length == 0) { + throw new DOMException("Key usage is empty", "SyntaxError"); + } + + // 2-9. + const { modulusLength, publicExponent, data } = await core + .opAsync( + "op_crypto_import_key", + { + algorithm: "RSA-PSS", + format: "pkcs8", + // Needed to perform step 7 without normalization. + hash: normalizedAlgorithm.hash.name, + }, + keyData, + ); + + const handle = {}; + WeakMapPrototypeSet(KEY_STORE, handle, { + // PKCS#1 for RSA + type: "raw", + data, + }); + + const algorithm = { + name: "RSA-PSS", + modulusLength, + publicExponent, + hash: normalizedAlgorithm.hash, + }; + + const key = constructKey( + "private", + extractable, + usageIntersection(keyUsages, recognisedUsages), + algorithm, + handle, + ); + + return key; + } + default: + throw new DOMException("Not implemented", "NotSupportedError"); + } + } + case "RSA-OAEP": { + switch (format) { + case "pkcs8": { + // 1. + if ( + ArrayPrototypeFind( + keyUsages, + (u) => !ArrayPrototypeIncludes(["decrypt", "unwrapKey"], u), + ) !== undefined + ) { + throw new DOMException("Invalid key usages", "SyntaxError"); + } + + if (keyUsages.length == 0) { + throw new DOMException("Key usage is empty", "SyntaxError"); + } + + // 2-9. + const { modulusLength, publicExponent, data } = await core + .opAsync( + "op_crypto_import_key", + { + algorithm: "RSA-OAEP", + format: "pkcs8", + // Needed to perform step 7 without normalization. + hash: normalizedAlgorithm.hash.name, + }, + keyData, + ); + + const handle = {}; + WeakMapPrototypeSet(KEY_STORE, handle, { + // PKCS#1 for RSA + type: "raw", + data, + }); + + const algorithm = { + name: "RSA-OAEP", + modulusLength, + publicExponent, + hash: normalizedAlgorithm.hash, + }; + + const key = constructKey( + "private", + extractable, + usageIntersection(keyUsages, recognisedUsages), + algorithm, + handle, + ); + + return key; + } + default: + throw new DOMException("Not implemented", "NotSupportedError"); + } + } // TODO(@littledivy): ECDSA case "HKDF": { if (format !== "raw") { |