diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/crypto/00_crypto.js | 20 | ||||
-rw-r--r-- | ext/crypto/key.rs | 10 | ||||
-rw-r--r-- | ext/crypto/lib.deno_crypto.d.ts | 2 | ||||
-rw-r--r-- | ext/crypto/lib.rs | 16 |
4 files changed, 47 insertions, 1 deletions
diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index a95c0be1b..0e5a511e5 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -92,6 +92,7 @@ "verify": { "RSASSA-PKCS1-v1_5": null, "RSA-PSS": "RsaPssParams", + "ECDSA": "EcdsaParams", "HMAC": null, }, "importKey": { @@ -1185,6 +1186,25 @@ signature, }, data); } + case "ECDSA": { + // 1. + if (key[_type] !== "public") { + throw new DOMException( + "Key type not supported", + "InvalidAccessError", + ); + } + // 2. + const hash = normalizedAlgorithm.hash.name; + // 3-8. + return await core.opAsync("op_crypto_verify_key", { + key: keyData, + algorithm: "ECDSA", + hash, + signature, + namedCurve: key[_algorithm].namedCurve, + }, data); + } } throw new TypeError("unreachable"); diff --git a/ext/crypto/key.rs b/ext/crypto/key.rs index d2420bfe9..663217887 100644 --- a/ext/crypto/key.rs +++ b/ext/crypto/key.rs @@ -4,6 +4,7 @@ use ring::agreement::Algorithm as RingAlgorithm; use ring::digest; use ring::hmac::Algorithm as HmacAlgorithm; use ring::signature::EcdsaSigningAlgorithm; +use ring::signature::EcdsaVerificationAlgorithm; use serde::Deserialize; use serde::Serialize; @@ -57,6 +58,15 @@ impl From<CryptoNamedCurve> for &EcdsaSigningAlgorithm { } } +impl From<CryptoNamedCurve> for &EcdsaVerificationAlgorithm { + fn from(curve: CryptoNamedCurve) -> &'static EcdsaVerificationAlgorithm { + match curve { + CryptoNamedCurve::P256 => &ring::signature::ECDSA_P256_SHA256_FIXED, + CryptoNamedCurve::P384 => &ring::signature::ECDSA_P384_SHA384_FIXED, + } + } +} + impl From<CryptoHash> for HmacAlgorithm { fn from(hash: CryptoHash) -> HmacAlgorithm { match hash { diff --git a/ext/crypto/lib.deno_crypto.d.ts b/ext/crypto/lib.deno_crypto.d.ts index 5169e5c3b..a62e69632 100644 --- a/ext/crypto/lib.deno_crypto.d.ts +++ b/ext/crypto/lib.deno_crypto.d.ts @@ -175,7 +175,7 @@ interface SubtleCrypto { data: BufferSource, ): Promise<ArrayBuffer>; verify( - algorithm: AlgorithmIdentifier | RsaPssParams, + algorithm: AlgorithmIdentifier | RsaPssParams | EcdsaParams, key: CryptoKey, signature: BufferSource, data: BufferSource, diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index 7c4010f53..f2df7ba10 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -33,6 +33,8 @@ use ring::rand as RingRand; use ring::rand::SecureRandom; use ring::signature::EcdsaKeyPair; use ring::signature::EcdsaSigningAlgorithm; +use ring::signature::EcdsaVerificationAlgorithm; +use ring::signature::KeyPair; use rsa::padding::PaddingScheme; use rsa::pkcs8::FromPrivateKey; use rsa::pkcs8::ToPrivateKey; @@ -407,6 +409,7 @@ pub struct VerifyArg { salt_length: Option<u32>, hash: Option<CryptoHash>, signature: ZeroCopyBuf, + named_curve: Option<CryptoNamedCurve>, } pub async fn op_crypto_verify_key( @@ -528,6 +531,19 @@ pub async fn op_crypto_verify_key( let key = HmacKey::new(hash, &*args.key.data); ring::hmac::verify(&key, data, &*args.signature).is_ok() } + Algorithm::Ecdsa => { + let signing_alg: &EcdsaSigningAlgorithm = + args.named_curve.ok_or_else(not_supported)?.try_into()?; + let verify_alg: &EcdsaVerificationAlgorithm = + args.named_curve.ok_or_else(not_supported)?.try_into()?; + + let private_key = EcdsaKeyPair::from_pkcs8(signing_alg, &*args.key.data)?; + let public_key_bytes = private_key.public_key().as_ref(); + let public_key = + ring::signature::UnparsedPublicKey::new(verify_alg, public_key_bytes); + + public_key.verify(data, &*args.signature).is_ok() + } _ => return Err(type_error("Unsupported algorithm".to_string())), }; |