diff options
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | ext/crypto/00_crypto.js | 61 | ||||
-rw-r--r-- | ext/crypto/Cargo.toml | 1 | ||||
-rw-r--r-- | ext/crypto/lib.rs | 32 |
4 files changed, 94 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock index fa521076e..826860a95 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -775,6 +775,7 @@ dependencies = [ "block-modes", "deno_core", "deno_web", + "elliptic-curve", "lazy_static", "num-traits", "p256", diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 85849153d..55e1ba9ad 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -975,6 +975,66 @@ return key; } + // TODO(@littledivy): RSA-PSS + case "ECDSA": { + switch (format) { + case "raw": { + // 1. + if ( + !ArrayPrototypeIncludes( + supportedNamedCurves, + normalizedAlgorithm.namedCurve, + ) + ) { + throw new DOMException( + "Invalid namedCurve", + "DataError", + ); + } + + // 2. + if ( + ArrayPrototypeFind( + keyUsages, + (u) => !ArrayPrototypeIncludes(["verify"], u), + ) !== undefined + ) { + throw new DOMException("Invalid key usages", "SyntaxError"); + } + + // 3. + const { data } = await core.opAsync("op_crypto_import_key", { + algorithm: "ECDSA", + namedCurve: normalizedAlgorithm.namedCurve, + }, keyData); + + const handle = {}; + WeakMapPrototypeSet(KEY_STORE, handle, { + type: "raw", + data, + }); + + // 4-5. + const algorithm = { + name: "ECDSA", + namedCurve: normalizedAlgorithm.namedCurve, + }; + + // 6-8. + const key = constructKey( + "public", + extractable, + usageIntersection(keyUsages, recognisedUsages), + algorithm, + handle, + ); + + return key; + } + default: + throw new DOMException("Not implemented", "NotSupportedError"); + } + } case "RSASSA-PKCS1-v1_5": { switch (format) { case "pkcs8": { @@ -1149,7 +1209,6 @@ throw new DOMException("Not implemented", "NotSupportedError"); } } - // TODO(@littledivy): ECDSA case "HKDF": { if (format !== "raw") { throw new DOMException("Format not supported", "NotSupportedError"); diff --git a/ext/crypto/Cargo.toml b/ext/crypto/Cargo.toml index 16839d8d1..b064f9d44 100644 --- a/ext/crypto/Cargo.toml +++ b/ext/crypto/Cargo.toml @@ -18,6 +18,7 @@ aes = "0.7.5" block-modes = "0.8.1" deno_core = { version = "0.102.0", path = "../../core" } deno_web = { version = "0.51.0", path = "../web" } +elliptic-curve = "0.10.6" lazy_static = "1.4.0" num-traits = "0.2.14" p256 = { version = "0.9.0", features = ["ecdh"] } diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index 6b67185dd..d5f95677a 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -1166,6 +1166,8 @@ pub struct ImportKeyArg { format: KeyFormat, // RSASSA-PKCS1-v1_5 hash: Option<CryptoHash>, + // ECDSA + named_curve: Option<CryptoNamedCurve>, } #[derive(Serialize)] @@ -1186,6 +1188,36 @@ pub async fn op_crypto_import_key( let algorithm = args.algorithm; match algorithm { + Algorithm::Ecdsa => { + let curve = args.named_curve.ok_or_else(|| { + type_error("Missing argument named_curve".to_string()) + })?; + + match curve { + CryptoNamedCurve::P256 => { + // 1-2. + let point = p256::EncodedPoint::from_bytes(data)?; + // 3. + if point.is_identity() { + return Err(type_error("Invalid key data".to_string())); + } + } + CryptoNamedCurve::P384 => { + // 1-2. + let point = p384::EncodedPoint::from_bytes(data)?; + // 3. + if point.is_identity() { + return Err(type_error("Invalid key data".to_string())); + } + } + }; + + Ok(ImportKeyResult { + data: zero_copy, + modulus_length: None, + public_exponent: None, + }) + } Algorithm::RsassaPkcs1v15 => { match args.format { KeyFormat::Pkcs8 => { |