summaryrefslogtreecommitdiff
path: root/ext/crypto/00_crypto.js
diff options
context:
space:
mode:
authorSean Michael Wykes <8363933+SeanWykes@users.noreply.github.com>2022-01-19 00:38:35 -0300
committerGitHub <noreply@github.com>2022-01-19 09:08:35 +0530
commit77e58fe7f9fc20dabf77424efbd25ce332f8f59c (patch)
treee8cdf3b06661b209ea685b5d762f670e662923b7 /ext/crypto/00_crypto.js
parentb3545dd447dcbab6629827dbe8d127ef82f8da69 (diff)
feat(ext/crypto): implement pkcs8/spki/jwk exportKey for ECDSA and ECDH (#13104)
Diffstat (limited to 'ext/crypto/00_crypto.js')
-rw-r--r--ext/crypto/00_crypto.js126
1 files changed, 126 insertions, 0 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js
index 81c475ad7..2596bb052 100644
--- a/ext/crypto/00_crypto.js
+++ b/ext/crypto/00_crypto.js
@@ -975,6 +975,10 @@
case "RSA-OAEP": {
return exportKeyRSA(format, key, innerKey);
}
+ case "ECDH":
+ case "ECDSA": {
+ return exportKeyEC(format, key, innerKey);
+ }
case "AES-CTR":
case "AES-CBC":
case "AES-GCM":
@@ -3377,6 +3381,128 @@
}
}
+ function exportKeyEC(format, key, innerKey) {
+ switch (format) {
+ case "pkcs8": {
+ // 1.
+ if (key[_type] !== "private") {
+ throw new DOMException(
+ "Key is not a private key",
+ "InvalidAccessError",
+ );
+ }
+
+ // 2.
+ const data = core.opSync("op_crypto_export_key", {
+ algorithm: key[_algorithm].name,
+ namedCurve: key[_algorithm].namedCurve,
+ format: "pkcs8",
+ }, innerKey);
+
+ return data.buffer;
+ }
+ case "spki": {
+ // 1.
+ if (key[_type] !== "public") {
+ throw new DOMException(
+ "Key is not a public key",
+ "InvalidAccessError",
+ );
+ }
+
+ // 2.
+ const data = core.opSync("op_crypto_export_key", {
+ algorithm: key[_algorithm].name,
+ namedCurve: key[_algorithm].namedCurve,
+ format: "spki",
+ }, innerKey);
+
+ return data.buffer;
+ }
+ case "jwk": {
+ if (key[_algorithm].name == "ECDSA") {
+ // 1-2.
+ const jwk = {
+ kty: "EC",
+ };
+
+ // 3.1
+ jwk.crv = key[_algorithm].namedCurve;
+
+ // Missing from spec
+ let algNamedCurve;
+
+ switch (key[_algorithm].namedCurve) {
+ case "P-256": {
+ algNamedCurve = "ES256";
+ break;
+ }
+ case "P-384": {
+ algNamedCurve = "ES384";
+ break;
+ }
+ case "P-521": {
+ algNamedCurve = "ES512";
+ break;
+ }
+ default:
+ throw new DOMException(
+ "Curve algorithm not supported",
+ "DataError",
+ );
+ }
+
+ jwk.alg = algNamedCurve;
+
+ // 3.2 - 3.4.
+ const data = core.opSync("op_crypto_export_key", {
+ format: key[_type] === "private" ? "jwkprivate" : "jwkpublic",
+ algorithm: key[_algorithm].name,
+ namedCurve: key[_algorithm].namedCurve,
+ }, innerKey);
+ ObjectAssign(jwk, data);
+
+ // 4.
+ jwk.key_ops = key.usages;
+
+ // 5.
+ jwk.ext = key[_extractable];
+
+ return jwk;
+ } else { // ECDH
+ // 1-2.
+ const jwk = {
+ kty: "EC",
+ };
+
+ // missing step from spec
+ jwk.alg = "ECDH";
+
+ // 3.1
+ jwk.crv = key[_algorithm].namedCurve;
+
+ // 3.2 - 3.4
+ const data = core.opSync("op_crypto_export_key", {
+ format: key[_type] === "private" ? "jwkprivate" : "jwkpublic",
+ algorithm: key[_algorithm].name,
+ namedCurve: key[_algorithm].namedCurve,
+ }, innerKey);
+ ObjectAssign(jwk, data);
+
+ // 4.
+ jwk.key_ops = key.usages;
+
+ // 5.
+ jwk.ext = key[_extractable];
+
+ return jwk;
+ }
+ }
+ default:
+ throw new DOMException("Not implemented", "NotSupportedError");
+ }
+ }
+
async function generateKeyAES(normalizedAlgorithm, extractable, usages) {
const algorithmName = normalizedAlgorithm.name;