diff options
author | Luca Casonato <hello@lcas.dev> | 2021-12-14 17:02:14 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-14 17:02:14 +0100 |
commit | b220a58d1a678ffd46a42567909d0b0d59731d99 (patch) | |
tree | 423a9c086696e77b58a71317e005a713903fb7f5 /ext/crypto/00_crypto.js | |
parent | 5fe4d5c818d598abfdfc9ef1db0b00f56cf03c20 (diff) |
feat(ext/crypto): support exporting RSA JWKs (#13081)
This commit adds support for exporting RSA JWKs in the Web Crypto API.
It also does some minor fixes for RSA JWK imports.
Co-authored-by: Sean Michael Wykes <sean.wykes@nascent.com.br>
Diffstat (limited to 'ext/crypto/00_crypto.js')
-rw-r--r-- | ext/crypto/00_crypto.js | 204 |
1 files changed, 170 insertions, 34 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 99efde2d4..0e09197a8 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -15,31 +15,32 @@ const { btoa } = window.__bootstrap.base64; const { - ArrayPrototypeFind, - ArrayPrototypeEvery, - ArrayPrototypeIncludes, ArrayBuffer, ArrayBufferIsView, + ArrayPrototypeEvery, + ArrayPrototypeFind, + ArrayPrototypeIncludes, BigInt64Array, + Int16Array, + Int32Array, + Int8Array, + ObjectAssign, + StringFromCharCode, + StringPrototypeReplace, StringPrototypeToLowerCase, StringPrototypeToUpperCase, - StringPrototypeReplace, - StringFromCharCode, Symbol, SymbolFor, SyntaxError, - WeakMap, - WeakMapPrototypeGet, - WeakMapPrototypeSet, - Int8Array, - Uint8Array, TypedArrayPrototypeSlice, - Int16Array, + TypeError, Uint16Array, - Int32Array, Uint32Array, + Uint8Array, Uint8ClampedArray, - TypeError, + WeakMap, + WeakMapPrototypeGet, + WeakMapPrototypeSet, } = window.__bootstrap.primordials; // P-521 is not yet supported. @@ -2464,27 +2465,75 @@ let hash; // 8. - switch (jwk.alg) { - case undefined: - hash = undefined; - break; - case "RS1": - hash = "SHA-1"; - break; - case "RS256": - hash = "SHA-256"; - break; - case "RS384": - hash = "SHA-384"; - break; - case "RS512": - hash = "SHA-512"; - break; - default: - throw new DOMException( - `'alg' property of JsonWebKey must be one of 'RS1', 'RS256', 'RS384', 'RS512'`, - "DataError", - ); + if (normalizedAlgorithm.name === "RSASSA-PKCS1-v1_5") { + switch (jwk.alg) { + case undefined: + hash = undefined; + break; + case "RS1": + hash = "SHA-1"; + break; + case "RS256": + hash = "SHA-256"; + break; + case "RS384": + hash = "SHA-384"; + break; + case "RS512": + hash = "SHA-512"; + break; + default: + throw new DOMException( + `'alg' property of JsonWebKey must be one of 'RS1', 'RS256', 'RS384', 'RS512'`, + "DataError", + ); + } + } else if (normalizedAlgorithm.name === "RSA-PSS") { + switch (jwk.alg) { + case undefined: + hash = undefined; + break; + case "PS1": + hash = "SHA-1"; + break; + case "PS256": + hash = "SHA-256"; + break; + case "PS384": + hash = "SHA-384"; + break; + case "PS512": + hash = "SHA-512"; + break; + default: + throw new DOMException( + `'alg' property of JsonWebKey must be one of 'PS1', 'PS256', 'PS384', 'PS512'`, + "DataError", + ); + } + } else { + switch (jwk.alg) { + case undefined: + hash = undefined; + break; + case "RSA-OAEP": + hash = "SHA-1"; + break; + case "RSA-OAEP-256": + hash = "SHA-256"; + break; + case "RSA-OAEP-384": + hash = "SHA-384"; + break; + case "RSA-OAEP-512": + hash = "SHA-512"; + break; + default: + throw new DOMException( + `'alg' property of JsonWebKey must be one of 'RSA-OAEP', 'RSA-OAEP-256', 'RSA-OAEP-384', or 'RSA-OAEP-512'`, + "DataError", + ); + } } // 9. @@ -2822,6 +2871,93 @@ // 3. return data.buffer; } + case "jwk": { + // 1-2. + const jwk = { + kty: "RSA", + }; + + // 3. + const hash = key[_algorithm].hash.name; + + // 4. + if (key[_algorithm].name === "RSASSA-PKCS1-v1_5") { + switch (hash) { + case "SHA-1": + jwk.alg = "RS1"; + break; + case "SHA-256": + jwk.alg = "RS256"; + break; + case "SHA-384": + jwk.alg = "RS384"; + break; + case "SHA-512": + jwk.alg = "RS512"; + break; + default: + throw new DOMException( + "Hash algorithm not supported", + "NotSupportedError", + ); + } + } else if (key[_algorithm].name === "RSA-PSS") { + switch (hash) { + case "SHA-1": + jwk.alg = "PS1"; + break; + case "SHA-256": + jwk.alg = "PS256"; + break; + case "SHA-384": + jwk.alg = "PS384"; + break; + case "SHA-512": + jwk.alg = "PS512"; + break; + default: + throw new DOMException( + "Hash algorithm not supported", + "NotSupportedError", + ); + } + } else { + switch (hash) { + case "SHA-1": + jwk.alg = "RSA-OAEP"; + break; + case "SHA-256": + jwk.alg = "RSA-OAEP-256"; + break; + case "SHA-384": + jwk.alg = "RSA-OAEP-384"; + break; + case "SHA-512": + jwk.alg = "RSA-OAEP-512"; + break; + default: + throw new DOMException( + "Hash algorithm not supported", + "NotSupportedError", + ); + } + } + + // 5-6. + const data = core.opSync("op_crypto_export_key", { + format: key[_type] === "private" ? "jwkprivate" : "jwkpublic", + algorithm: key[_algorithm].name, + }, innerKey); + ObjectAssign(jwk, data); + + // 7. + jwk.key_ops = key.usages; + + // 8. + jwk.ext = key[_extractable]; + + return jwk; + } default: throw new DOMException("Not implemented", "NotSupportedError"); } |