From 5ee211017912bc0837cbce3b845e6ab4a7887885 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Sun, 29 Aug 2021 17:53:51 +0530 Subject: feat(ext/crypto): support JWK export for HMAC (#11864) --- ext/crypto/00_crypto.js | 49 +++++++++++++++++++++++++++++++++++++++-- ext/crypto/lib.deno_crypto.d.ts | 8 +++++-- 2 files changed, 53 insertions(+), 4 deletions(-) (limited to 'ext/crypto') diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 375170ad9..ab6347d41 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -12,7 +12,7 @@ const core = window.Deno.core; const webidl = window.__bootstrap.webidl; const { DOMException } = window.__bootstrap.domException; - const { atob } = window.__bootstrap.base64; + const { atob, btoa } = window.__bootstrap.base64; const { ArrayPrototypeFind, @@ -122,6 +122,13 @@ return keyBytes; } + function unpaddedBase64(bytes) { + const binaryString = core.decode(bytes); + const base64String = btoa(binaryString); + + return StringPrototypeReplace(base64String, /=/g, ""); + } + // See https://www.w3.org/TR/WebCryptoAPI/#dfn-normalize-an-algorithm // 18.4.4 function normalizeAlgorithm(algorithm, op) { @@ -970,10 +977,48 @@ // 4-5. return bits.buffer; } - // TODO(@littledivy): jwk + case "jwk": { + // 1-3. + const jwk = { + kty: "oct", + k: unpaddedBase64(innerKey.data), + }; + // 4. + const algorithm = key[_algorithm]; + // 5. + const hash = algorithm.hash; + // 6. + switch (hash.name) { + case "SHA-1": + jwk.alg = "HS1"; + break; + case "SHA-256": + jwk.alg = "HS256"; + break; + case "SHA-384": + jwk.alg = "HS384"; + break; + case "SHA-512": + jwk.alg = "HS512"; + break; + default: + throw new DOMException( + "Hash algorithm not supported", + "NotSupportedError", + ); + } + // 7. + jwk.key_ops = key.usages; + // 8. + jwk.ext = key[_extractable]; + // 9. + return jwk; + } default: throw new DOMException("Not implemented", "NotSupportedError"); } + // TODO(@littledivy): Redundant break but deno_lint complains without it + break; } // TODO(@littledivy): RSASSA-PKCS1-v1_5 // TODO(@littledivy): RSA-PSS diff --git a/ext/crypto/lib.deno_crypto.d.ts b/ext/crypto/lib.deno_crypto.d.ts index 2e8d2f8b2..5169e5c3b 100644 --- a/ext/crypto/lib.deno_crypto.d.ts +++ b/ext/crypto/lib.deno_crypto.d.ts @@ -25,7 +25,7 @@ type KeyUsage = | "unwrapKey" | "verify" | "wrapKey"; - +type KeyFormat = "jwk" | "pkcs8" | "raw" | "spki"; type NamedCurve = string; interface RsaOtherPrimesInfo { @@ -164,7 +164,11 @@ interface SubtleCrypto { extractable: boolean, keyUsages: KeyUsage[], ): Promise; - exportKey(format: "raw", key: CryptoKey): Promise; + exportKey(format: "jwk", key: CryptoKey): Promise; + exportKey( + format: Exclude, + key: CryptoKey, + ): Promise; sign( algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, -- cgit v1.2.3