summaryrefslogtreecommitdiff
path: root/ext/crypto/00_crypto.js
diff options
context:
space:
mode:
authorLuca Casonato <hello@lcas.dev>2021-12-14 17:02:14 +0100
committerGitHub <noreply@github.com>2021-12-14 17:02:14 +0100
commitb220a58d1a678ffd46a42567909d0b0d59731d99 (patch)
tree423a9c086696e77b58a71317e005a713903fb7f5 /ext/crypto/00_crypto.js
parent5fe4d5c818d598abfdfc9ef1db0b00f56cf03c20 (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.js204
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");
}