0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-04 01:44:26 -05:00

feat(ext/crypto): support JWK export for HMAC (#11864)

This commit is contained in:
Divy Srivastava 2021-08-29 17:53:51 +05:30 committed by GitHub
parent 8a097410a8
commit 5ee2110179
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 7 deletions

View file

@ -254,6 +254,8 @@ const jwk: JsonWebKey = {
// unpadded base64 for rawKey. // unpadded base64 for rawKey.
k: "AQIDBAUGBwgJCgsMDQ4PEA", k: "AQIDBAUGBwgJCgsMDQ4PEA",
alg: "HS256", alg: "HS256",
ext: true,
"key_ops": ["sign"],
}; };
unitTest(async function subtleCryptoHmacImportExport() { unitTest(async function subtleCryptoHmacImportExport() {
@ -297,7 +299,10 @@ unitTest(async function subtleCryptoHmacImportExport() {
new Uint8Array(actual2), new Uint8Array(actual2),
expected, expected,
); );
// TODO(@littledivy): Add a test for exporting JWK key when supported.
const exportedKey = await crypto.subtle.exportKey("raw", key1); const exportedKey1 = await crypto.subtle.exportKey("raw", key1);
assertEquals(new Uint8Array(exportedKey), rawKey); assertEquals(new Uint8Array(exportedKey1), rawKey);
const exportedKey2 = await crypto.subtle.exportKey("jwk", key2);
assertEquals(exportedKey2, jwk);
}); });

View file

@ -12,7 +12,7 @@
const core = window.Deno.core; const core = window.Deno.core;
const webidl = window.__bootstrap.webidl; const webidl = window.__bootstrap.webidl;
const { DOMException } = window.__bootstrap.domException; const { DOMException } = window.__bootstrap.domException;
const { atob } = window.__bootstrap.base64; const { atob, btoa } = window.__bootstrap.base64;
const { const {
ArrayPrototypeFind, ArrayPrototypeFind,
@ -122,6 +122,13 @@
return keyBytes; 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 // See https://www.w3.org/TR/WebCryptoAPI/#dfn-normalize-an-algorithm
// 18.4.4 // 18.4.4
function normalizeAlgorithm(algorithm, op) { function normalizeAlgorithm(algorithm, op) {
@ -970,10 +977,48 @@
// 4-5. // 4-5.
return bits.buffer; 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: default:
throw new DOMException("Not implemented", "NotSupportedError"); 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): RSASSA-PKCS1-v1_5
// TODO(@littledivy): RSA-PSS // TODO(@littledivy): RSA-PSS

View file

@ -25,7 +25,7 @@ type KeyUsage =
| "unwrapKey" | "unwrapKey"
| "verify" | "verify"
| "wrapKey"; | "wrapKey";
type KeyFormat = "jwk" | "pkcs8" | "raw" | "spki";
type NamedCurve = string; type NamedCurve = string;
interface RsaOtherPrimesInfo { interface RsaOtherPrimesInfo {
@ -164,7 +164,11 @@ interface SubtleCrypto {
extractable: boolean, extractable: boolean,
keyUsages: KeyUsage[], keyUsages: KeyUsage[],
): Promise<CryptoKey>; ): Promise<CryptoKey>;
exportKey(format: "raw", key: CryptoKey): Promise<ArrayBuffer>; exportKey(format: "jwk", key: CryptoKey): Promise<JsonWebKey>;
exportKey(
format: Exclude<KeyFormat, "jwk">,
key: CryptoKey,
): Promise<ArrayBuffer>;
sign( sign(
algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams,
key: CryptoKey, key: CryptoKey,