From 84e9794970e998aaa510a526160258905a092d05 Mon Sep 17 00:00:00 2001 From: Kyle Willmon Date: Wed, 18 Jan 2023 09:18:41 -0600 Subject: [PATCH] chore(ext/crypto): Update rsa to 0.7.0 (#16327) Bump the rsa crate to 0.7.0 The API for the `rsa` crate has changed significantly, but I have verified that tests continue to pass throughout this update. --- Cargo.lock | 29 ++++-- Cargo.toml | 2 +- ext/crypto/00_crypto.js | 2 - ext/crypto/Cargo.toml | 5 +- ext/crypto/lib.rs | 198 ++++++++++++---------------------------- 5 files changed, 86 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 96a6b01da6..97d9caeb45 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -960,8 +960,9 @@ dependencies = [ "sec1", "serde", "serde_bytes", - "sha-1 0.10.0", + "sha1", "sha2", + "signature", "spki", "tokio", "uuid", @@ -1368,6 +1369,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle", ] @@ -3220,12 +3222,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs1" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e3a81571d9455414f4d59ce2830bc9d2654e2efc5460fd67b0e0a6a36b6753a" +checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" dependencies = [ "der", "pkcs8", + "spki", "zeroize", ] @@ -3626,9 +3629,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.7.0-pre" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6168b9a0f38e487db90dc109ad6d8f37fc5590183b7bfe8d8687e0b86116d53f" +checksum = "96144aaefe4fa4c1846c404d1ccc3dc45c9b15c2e41591597294cb7ccc2dbfd7" dependencies = [ "byteorder", "digest 0.10.5", @@ -3639,6 +3642,7 @@ dependencies = [ "pkcs1", "pkcs8", "rand_core 0.6.4", + "signature", "smallvec", "subtle", "zeroize", @@ -3975,6 +3979,17 @@ dependencies = [ "digest 0.10.5", ] +[[package]] +name = "sha1" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f04293dc80c3993519f2d7f6f511707ee7094fe0c6d3406feb330cdb3540eba3" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.5", +] + [[package]] name = "sha2" version = "0.10.6" @@ -4003,9 +4018,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.6.3" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb766570a2825fa972bceff0d195727876a9cdf2460ab2e52d455dc2de47fd9" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ "digest 0.10.5", "rand_core 0.6.4", diff --git a/Cargo.toml b/Cargo.toml index cd3768848f..bd21c9cc66 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,7 +107,7 @@ serde = { version = "=1.0.149", features = ["derive"] } serde_bytes = "0.11" serde_json = "=1.0.85" serde_repr = "=0.1.9" -sha2 = "0.10.2" +sha2 = { version = "0.10.6", features = ["oid"] } smallvec = "1.8" socket2 = "0.4.7" tar = "=0.4.38" diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index 9487652f25..7d30dcccf6 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -1307,12 +1307,10 @@ } const hashAlgorithm = key[_algorithm].hash.name; - const saltLength = normalizedAlgorithm.saltLength; return await core.opAsync("op_crypto_verify_key", { key: keyData, algorithm: "RSA-PSS", hash: hashAlgorithm, - saltLength, signature, }, data); } diff --git a/ext/crypto/Cargo.toml b/ext/crypto/Cargo.toml index 8d0838e7da..c9df238b1b 100644 --- a/ext/crypto/Cargo.toml +++ b/ext/crypto/Cargo.toml @@ -33,12 +33,13 @@ p256 = { version = "0.11.1", features = ["ecdh"] } p384 = "0.11.1" rand.workspace = true ring = { workspace = true, features = ["std"] } -rsa = { version = "=0.7.0-pre", default-features = false, features = ["std"] } +rsa = { version = "0.7.0", default-features = false, features = ["std"] } sec1 = "0.3.0" serde.workspace = true serde_bytes.workspace = true -sha-1 = "0.10.0" +sha1 = { version = "0.10.5", features = ["oid"] } sha2.workspace = true +signature = "1.6.4" spki = "0.6.0" tokio.workspace = true uuid.workspace = true diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index cbcb816d9e..0ee2faecc8 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -34,17 +34,17 @@ use ring::signature::EcdsaKeyPair; use ring::signature::EcdsaSigningAlgorithm; use ring::signature::EcdsaVerificationAlgorithm; use ring::signature::KeyPair; -use rsa::padding::PaddingScheme; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::DecodeRsaPublicKey; -use rsa::PublicKey; use rsa::RsaPrivateKey; use rsa::RsaPublicKey; use sha1::Sha1; -use sha2::Digest; use sha2::Sha256; use sha2::Sha384; use sha2::Sha512; +use signature::RandomizedSigner; +use signature::Signer; +use signature::Verifier; use std::convert::TryFrom; use std::num::NonZeroU32; use std::path::PathBuf; @@ -199,56 +199,33 @@ pub async fn op_crypto_sign_key( let signature = match algorithm { Algorithm::RsassaPkcs1v15 => { + use rsa::pkcs1v15::SigningKey; let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?; - let (padding, hashed) = match args + match args .hash .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let mut hasher = Sha1::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA1), - }, - hasher.finalize()[..].to_vec(), - ) + let signing_key = SigningKey::::new_with_prefix(private_key); + signing_key.sign(data) } CryptoHash::Sha256 => { - let mut hasher = Sha256::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_256), - }, - hasher.finalize()[..].to_vec(), - ) + let signing_key = SigningKey::::new_with_prefix(private_key); + signing_key.sign(data) } CryptoHash::Sha384 => { - let mut hasher = Sha384::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_384), - }, - hasher.finalize()[..].to_vec(), - ) + let signing_key = SigningKey::::new_with_prefix(private_key); + signing_key.sign(data) } CryptoHash::Sha512 => { - let mut hasher = Sha512::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_512), - }, - hasher.finalize()[..].to_vec(), - ) + let signing_key = SigningKey::::new_with_prefix(private_key); + signing_key.sign(data) } - }; - - private_key.sign(padding, &hashed)? + } + .to_vec() } Algorithm::RsaPss => { + use rsa::pss::SigningKey; let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?; let salt_len = args @@ -257,46 +234,32 @@ pub async fn op_crypto_sign_key( as usize; let rng = OsRng; - let (padding, digest_in) = match args + match args .hash .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let mut hasher = Sha1::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let signing_key = + SigningKey::::new_with_salt_len(private_key, salt_len); + signing_key.sign_with_rng(rng, data) } CryptoHash::Sha256 => { - let mut hasher = Sha256::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let signing_key = + SigningKey::::new_with_salt_len(private_key, salt_len); + signing_key.sign_with_rng(rng, data) } CryptoHash::Sha384 => { - let mut hasher = Sha384::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let signing_key = + SigningKey::::new_with_salt_len(private_key, salt_len); + signing_key.sign_with_rng(rng, data) } CryptoHash::Sha512 => { - let mut hasher = Sha512::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let signing_key = + SigningKey::::new_with_salt_len(private_key, salt_len); + signing_key.sign_with_rng(rng, data) } - }; - - // Sign data based on computed padding and return buffer - private_key.sign(padding, &digest_in)? + } + .to_vec() } Algorithm::Ecdsa => { let curve: &EcdsaSigningAlgorithm = @@ -337,7 +300,6 @@ pub async fn op_crypto_sign_key( pub struct VerifyArg { key: KeyData, algorithm: Algorithm, - salt_length: Option, hash: Option, signature: ZeroCopyBuf, named_curve: Option, @@ -353,102 +315,62 @@ pub async fn op_crypto_verify_key( let verification = match algorithm { Algorithm::RsassaPkcs1v15 => { + use rsa::pkcs1v15::Signature; + use rsa::pkcs1v15::VerifyingKey; let public_key = read_rsa_public_key(args.key)?; - let (padding, hashed) = match args + let signature: Signature = args.signature.to_vec().into(); + match args .hash .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let mut hasher = Sha1::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA1), - }, - hasher.finalize()[..].to_vec(), - ) + let verifying_key = VerifyingKey::::new_with_prefix(public_key); + verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha256 => { - let mut hasher = Sha256::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_256), - }, - hasher.finalize()[..].to_vec(), - ) + let verifying_key = + VerifyingKey::::new_with_prefix(public_key); + verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha384 => { - let mut hasher = Sha384::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_384), - }, - hasher.finalize()[..].to_vec(), - ) + let verifying_key = + VerifyingKey::::new_with_prefix(public_key); + verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha512 => { - let mut hasher = Sha512::new(); - hasher.update(data); - ( - PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_512), - }, - hasher.finalize()[..].to_vec(), - ) + let verifying_key = + VerifyingKey::::new_with_prefix(public_key); + verifying_key.verify(data, &signature).is_ok() } - }; - - public_key.verify(padding, &hashed, &args.signature).is_ok() + } } Algorithm::RsaPss => { - let salt_len = args - .salt_length - .ok_or_else(|| type_error("Missing argument saltLength".to_string()))? - as usize; + use rsa::pss::Signature; + use rsa::pss::VerifyingKey; let public_key = read_rsa_public_key(args.key)?; + let signature: Signature = args.signature.to_vec().into(); - let rng = OsRng; - let (padding, hashed) = match args + match args .hash .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let mut hasher = Sha1::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let verifying_key: VerifyingKey = public_key.into(); + verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha256 => { - let mut hasher = Sha256::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let verifying_key: VerifyingKey = public_key.into(); + verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha384 => { - let mut hasher = Sha384::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let verifying_key: VerifyingKey = public_key.into(); + verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha512 => { - let mut hasher = Sha512::new(); - hasher.update(data); - ( - PaddingScheme::new_pss_with_salt::(rng, salt_len), - hasher.finalize()[..].to_vec(), - ) + let verifying_key: VerifyingKey = public_key.into(); + verifying_key.verify(data, &signature).is_ok() } - }; - - public_key.verify(padding, &hashed, &args.signature).is_ok() + } } Algorithm::Hmac => { let hash: HmacAlgorithm = args.hash.ok_or_else(not_supported)?.into();