diff options
Diffstat (limited to 'ext/crypto/00_crypto.js')
-rw-r--r-- | ext/crypto/00_crypto.js | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index a503d316a..fdd0f612d 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -120,6 +120,10 @@ "decrypt": { "RSA-OAEP": "RsaOaepParams", }, + "wrapKey": { + // TODO(@littledivy): Enable this once implemented. + // "AES-KW": "AesKeyWrapParams", + }, }; // Decodes the unpadded base64 to the octet sequence containing key value `k` defined in RFC7518 Section 6.4 @@ -1525,6 +1529,104 @@ * @param {KeyUsage[]} keyUsages * @returns {Promise<any>} */ + async wrapKey(format, key, wrappingKey, wrapAlgorithm) { + webidl.assertBranded(this, SubtleCrypto); + const prefix = "Failed to execute 'wrapKey' on 'SubtleCrypto'"; + webidl.requiredArguments(arguments.length, 4, { prefix }); + format = webidl.converters.KeyFormat(format, { + prefix, + context: "Argument 1", + }); + key = webidl.converters.CryptoKey(key, { + prefix, + context: "Argument 2", + }); + wrappingKey = webidl.converters.CryptoKey(wrappingKey, { + prefix, + context: "Argument 3", + }); + wrapAlgorithm = webidl.converters.AlgorithmIdentifier(wrapAlgorithm, { + prefix, + context: "Argument 4", + }); + + let normalizedAlgorithm; + + try { + // 2. + normalizedAlgorithm = normalizeAlgorithm(wrapAlgorithm, "wrapKey"); + } catch (_) { + // 3. + normalizedAlgorithm = normalizeAlgorithm(wrapAlgorithm, "encrypt"); + } + + // 8. + if (normalizedAlgorithm.name !== wrappingKey[_algorithm].name) { + throw new DOMException( + "Wrapping algorithm doesn't match key algorithm.", + "InvalidAccessError", + ); + } + + // 9. + if (!ArrayPrototypeIncludes(wrappingKey[_usages], "wrapKey")) { + throw new DOMException( + "Key does not support the 'wrapKey' operation.", + "InvalidAccessError", + ); + } + + // 10. NotSupportedError will be thrown in step 12. + // 11. + if (key[_extractable] === false) { + throw new DOMException( + "Key is not extractable", + "InvalidAccessError", + ); + } + + // 12. + const exportedKey = await this.exportKey(format, key); + + let bytes; + // 13. + if (format !== "jwk") { + bytes = exportedKey; + } else { + // TODO(@littledivy): Implement JWK. + throw new DOMException( + "Not implemented", + "NotSupportedError", + ); + } + + // 14-15. + if ( + supportedAlgorithms["wrapKey"][normalizedAlgorithm.name] !== undefined + ) { + // TODO(@littledivy): Implement this for AES-KW. + throw new DOMException( + "Not implemented", + "NotSupportedError", + ); + } else if ( + supportedAlgorithms["encrypt"][normalizedAlgorithm.name] !== undefined + ) { + return this.encrypt(normalizedAlgorithm, wrappingKey, bytes); + } else { + throw new DOMException( + "Algorithm not supported", + "NotSupportedError", + ); + } + } + + /** + * @param {string} algorithm + * @param {boolean} extractable + * @param {KeyUsage[]} keyUsages + * @returns {Promise<any>} + */ async generateKey(algorithm, extractable, keyUsages) { webidl.assertBranded(this, SubtleCrypto); const prefix = "Failed to execute 'generateKey' on 'SubtleCrypto'"; |