From 49c6b0b942808e3edec1ae0fc6fb9049375a3870 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:01:54 +0530 Subject: [PATCH 01/12] migrate ext/node mod.rs --- Cargo.lock | 26 ++++++++++----------- Cargo.toml | 2 +- ext/node/ops/crypto/mod.rs | 47 ++++++++++++++++++++------------------ 3 files changed, 38 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a9b0716142d416..e405bafdd27062 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3883,14 +3883,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs1" -version = "0.4.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der 0.6.1", - "pkcs8 0.9.0", - "spki 0.6.0", - "zeroize", + "der 0.7.8", + "pkcs8 0.10.2", + "spki 0.7.2", ] [[package]] @@ -4407,21 +4406,20 @@ dependencies = [ [[package]] name = "rsa" -version = "0.7.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" +checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d" dependencies = [ - "byteorder", + "const-oid", "digest 0.10.7", "num-bigint-dig", "num-integer", - "num-iter", "num-traits", "pkcs1", - "pkcs8 0.9.0", + "pkcs8 0.10.2", "rand_core 0.6.4", - "signature 1.6.4", - "smallvec", + "signature 2.1.0", + "spki 0.7.2", "subtle", "zeroize", ] @@ -6109,7 +6107,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "rand 0.8.5", "static_assertions", ] diff --git a/Cargo.toml b/Cargo.toml index 77f229e04d62f0..7b967a16f48d76 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -153,7 +153,7 @@ p256 = { version = "0.13.2", features = ["ecdh"] } p384 = { version = "0.13.0", features = ["ecdh"] } # crypto -rsa = { version = "0.7.0", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node +rsa = { version = "0.9.3", default-features = false, features = ["std", "pem", "hazmat"] } # hazmat needed for PrehashSigner in ext/node hkdf = "0.12.3" # macros diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index bf7a99ba04d901..409941423dc1dd 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -23,10 +23,13 @@ use std::rc::Rc; use p224::NistP224; use p256::NistP256; use p384::NistP384; -use rsa::padding::PaddingScheme; +use rsa::Oaep; +use rsa::Pkcs1v15Encrypt; use rsa::pkcs8::DecodePrivateKey; use rsa::pkcs8::DecodePublicKey; -use rsa::PublicKey; +use rsa::signature::hazmat::PrehashSigner; +use rsa::signature::hazmat::PrehashVerifier; +use rsa::signature::SignatureEncoding; use rsa::RsaPrivateKey; use rsa::RsaPublicKey; use secp256k1::ecdh::SharedSecret; @@ -181,12 +184,14 @@ pub fn op_node_private_encrypt( match padding { 1 => Ok( key - .encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &msg)? + .as_ref() + .encrypt(&mut rng, Pkcs1v15Encrypt, &msg)? .into(), ), 4 => Ok( key - .encrypt(&mut rng, PaddingScheme::new_oaep::(), &msg)? + .as_ref() + .encrypt(&mut rng, Oaep::new::(), &msg)? .into(), ), _ => Err(type_error("Unknown padding")), @@ -205,12 +210,12 @@ pub fn op_node_private_decrypt( match padding { 1 => Ok( key - .decrypt(PaddingScheme::new_pkcs1v15_encrypt(), &msg)? + .decrypt(Pkcs1v15Encrypt, &msg)? .into(), ), 4 => Ok( key - .decrypt(PaddingScheme::new_oaep::(), &msg)? + .decrypt(Oaep::new::(), &msg)? .into(), ), _ => Err(type_error("Unknown padding")), @@ -230,12 +235,12 @@ pub fn op_node_public_encrypt( match padding { 1 => Ok( key - .encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &msg)? + .encrypt(&mut rng, Pkcs1v15Encrypt, &msg)? .into(), ), 4 => Ok( key - .encrypt(&mut rng, PaddingScheme::new_oaep::(), &msg)? + .encrypt(&mut rng, Oaep::new::(), &msg)? .into(), ), _ => Err(type_error("Unknown padding")), @@ -372,7 +377,6 @@ pub fn op_node_sign( match key_type { "rsa" => { use rsa::pkcs1v15::SigningKey; - use signature::hazmat::PrehashSigner; let key = match key_format { "pem" => RsaPrivateKey::from_pkcs8_pem((&key).try_into()?) .map_err(|_| type_error("Invalid RSA private key"))?, @@ -387,19 +391,19 @@ pub fn op_node_sign( Ok( match digest_type { "sha224" => { - let signing_key = SigningKey::::new_with_prefix(key); + let signing_key = SigningKey::::new(key); signing_key.sign_prehash(digest)?.to_vec() } "sha256" => { - let signing_key = SigningKey::::new_with_prefix(key); + let signing_key = SigningKey::::new(key); signing_key.sign_prehash(digest)?.to_vec() } "sha384" => { - let signing_key = SigningKey::::new_with_prefix(key); + let signing_key = SigningKey::::new(key); signing_key.sign_prehash(digest)?.to_vec() } "sha512" => { - let signing_key = SigningKey::::new_with_prefix(key); + let signing_key = SigningKey::::new(key); signing_key.sign_prehash(digest)?.to_vec() } _ => { @@ -431,7 +435,6 @@ pub fn op_node_verify( match key_type { "rsa" => { use rsa::pkcs1v15::VerifyingKey; - use signature::hazmat::PrehashVerifier; let key = match key_format { "pem" => RsaPublicKey::from_public_key_pem((&key).try_into()?) .map_err(|_| type_error("Invalid RSA public key"))?, @@ -444,17 +447,17 @@ pub fn op_node_verify( } }; Ok(match digest_type { - "sha224" => VerifyingKey::::new_with_prefix(key) - .verify_prehash(digest, &signature.to_vec().try_into()?) + "sha224" => VerifyingKey::::new(key) + .verify_prehash(digest, &signature.try_into()?) .is_ok(), - "sha256" => VerifyingKey::::new_with_prefix(key) - .verify_prehash(digest, &signature.to_vec().try_into()?) + "sha256" => VerifyingKey::::new(key) + .verify_prehash(digest, &signature.try_into()?) .is_ok(), - "sha384" => VerifyingKey::::new_with_prefix(key) - .verify_prehash(digest, &signature.to_vec().try_into()?) + "sha384" => VerifyingKey::::new(key) + .verify_prehash(digest, &signature.try_into()?) .is_ok(), - "sha512" => VerifyingKey::::new_with_prefix(key) - .verify_prehash(digest, &signature.to_vec().try_into()?) + "sha512" => VerifyingKey::::new(key) + .verify_prehash(digest, &signature.try_into()?) .is_ok(), _ => { return Err(type_error(format!( From f2c9e597576bb780110b597f3f2b31315d60e8fb Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:05:56 +0530 Subject: [PATCH 02/12] rsa ext/crypto lib.rs --- ext/crypto/lib.rs | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index 87b9702ce06e9b..76dabefabfdcba 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -44,9 +44,10 @@ use sha1::Sha1; use sha2::Sha256; use sha2::Sha384; use sha2::Sha512; -use signature::RandomizedSigner; -use signature::Signer; -use signature::Verifier; +use rsa::signature::RandomizedSigner; +use rsa::signature::SignatureEncoding; +use rsa::signature::Signer; +use rsa::signature::Verifier; use std::num::NonZeroU32; use std::path::PathBuf; @@ -207,19 +208,19 @@ pub async fn op_crypto_sign_key( .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let signing_key = SigningKey::::new_with_prefix(private_key); + let signing_key = SigningKey::::new(private_key); signing_key.sign(data) } CryptoHash::Sha256 => { - let signing_key = SigningKey::::new_with_prefix(private_key); + let signing_key = SigningKey::::new(private_key); signing_key.sign(data) } CryptoHash::Sha384 => { - let signing_key = SigningKey::::new_with_prefix(private_key); + let signing_key = SigningKey::::new(private_key); signing_key.sign(data) } CryptoHash::Sha512 => { - let signing_key = SigningKey::::new_with_prefix(private_key); + let signing_key = SigningKey::::new(private_key); signing_key.sign(data) } } @@ -234,7 +235,7 @@ pub async fn op_crypto_sign_key( .ok_or_else(|| type_error("Missing argument saltLength".to_string()))? as usize; - let rng = OsRng; + let mut rng = OsRng; match args .hash .ok_or_else(|| type_error("Missing argument hash".to_string()))? @@ -242,22 +243,22 @@ pub async fn op_crypto_sign_key( CryptoHash::Sha1 => { let signing_key = SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(rng, data) + signing_key.sign_with_rng(&mut rng, data) } CryptoHash::Sha256 => { let signing_key = SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(rng, data) + signing_key.sign_with_rng(&mut rng, data) } CryptoHash::Sha384 => { let signing_key = SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(rng, data) + signing_key.sign_with_rng(&mut rng, data) } CryptoHash::Sha512 => { let signing_key = SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(rng, data) + signing_key.sign_with_rng(&mut rng, data) } } .to_vec() @@ -319,28 +320,28 @@ pub async fn op_crypto_verify_key( use rsa::pkcs1v15::Signature; use rsa::pkcs1v15::VerifyingKey; let public_key = read_rsa_public_key(args.key)?; - let signature: Signature = args.signature.to_vec().into(); + let signature: Signature = args.signature.as_ref().try_into()?; match args .hash .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let verifying_key = VerifyingKey::::new_with_prefix(public_key); + let verifying_key = VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha256 => { let verifying_key = - VerifyingKey::::new_with_prefix(public_key); + VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha384 => { let verifying_key = - VerifyingKey::::new_with_prefix(public_key); + VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha512 => { let verifying_key = - VerifyingKey::::new_with_prefix(public_key); + VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } } @@ -349,7 +350,7 @@ pub async fn op_crypto_verify_key( 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 signature: Signature = args.signature.as_ref().try_into()?; match args .hash From 86199d9686005549bdff74a44ed02398a52f14f7 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:07:39 +0530 Subject: [PATCH 03/12] rsa ext/crypto decrypt.rs --- ext/crypto/decrypt.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/ext/crypto/decrypt.rs b/ext/crypto/decrypt.rs index 551f33972ae62a..3a9f3d36b8cd40 100644 --- a/ext/crypto/decrypt.rs +++ b/ext/crypto/decrypt.rs @@ -24,7 +24,6 @@ use deno_core::unsync::spawn_blocking; use deno_core::JsBuffer; use deno_core::ToJsBuffer; use rsa::pkcs1::DecodeRsaPrivateKey; -use rsa::PaddingScheme; use serde::Deserialize; use sha1::Digest; use sha1::Sha1; @@ -117,24 +116,24 @@ fn decrypt_rsa_oaep( let label = Some(String::from_utf8_lossy(&label).to_string()); let padding = match hash { - ShaHash::Sha1 => PaddingScheme::OAEP { - digest: Box::new(Sha1::new()), - mgf_digest: Box::new(Sha1::new()), + ShaHash::Sha1 => rsa::Oaep { + digest: Box::new(Sha1::default()), + mgf_digest: Box::new(Sha1::default()), label, }, - ShaHash::Sha256 => PaddingScheme::OAEP { - digest: Box::new(Sha256::new()), - mgf_digest: Box::new(Sha256::new()), + ShaHash::Sha256 => rsa::Oaep { + digest: Box::new(Sha256::default()), + mgf_digest: Box::new(Sha256::default()), label, }, - ShaHash::Sha384 => PaddingScheme::OAEP { - digest: Box::new(Sha384::new()), - mgf_digest: Box::new(Sha384::new()), + ShaHash::Sha384 => rsa::Oaep { + digest: Box::new(Sha384::default()), + mgf_digest: Box::new(Sha384::default()), label, }, - ShaHash::Sha512 => PaddingScheme::OAEP { - digest: Box::new(Sha512::new()), - mgf_digest: Box::new(Sha512::new()), + ShaHash::Sha512 => rsa::Oaep { + digest: Box::new(Sha512::default()), + mgf_digest: Box::new(Sha512::default()), label, }, }; From 71c39117cbe1600788de838edfd873ea80392fa3 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:15:45 +0530 Subject: [PATCH 04/12] rsa ext/crypto ed25519.rs --- ext/crypto/ed25519.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ext/crypto/ed25519.rs b/ext/crypto/ed25519.rs index e2a0ce40872638..42fbaa922c73f6 100644 --- a/ext/crypto/ed25519.rs +++ b/ext/crypto/ed25519.rs @@ -3,6 +3,7 @@ use base64::prelude::BASE64_URL_SAFE_NO_PAD; use base64::Engine; use deno_core::error::AnyError; +use deno_core::error::custom_error; use deno_core::op2; use deno_core::ToJsBuffer; use elliptic_curve::pkcs8::PrivateKeyInfo; @@ -123,7 +124,9 @@ pub fn op_crypto_export_spki_ed25519( }, subject_public_key: pubkey, }; - Ok(key_info.to_vec()?.into()) + Ok(key_info.to_vec().map_err(|_| { + custom_error("DOMExceptionOperationError", "Failed to export key") + })?.into()) } #[op2] @@ -131,10 +134,12 @@ pub fn op_crypto_export_spki_ed25519( pub fn op_crypto_export_pkcs8_ed25519( #[buffer] pkey: &[u8], ) -> Result { + use rsa::pkcs1::der::Encode; + // This should probably use OneAsymmetricKey instead let pk_info = rsa::pkcs8::PrivateKeyInfo { public_key: None, - algorithm: rsa::pkcs8::AlgorithmIdentifier { + algorithm: rsa::pkcs8::AlgorithmIdentifierRef { // id-Ed25519 oid: ED25519_OID, parameters: None, @@ -142,7 +147,9 @@ pub fn op_crypto_export_pkcs8_ed25519( private_key: pkey, // OCTET STRING }; - Ok(pk_info.to_vec()?.into()) + let mut buf = Vec::new(); + pk_info.encode_to_vec(&mut buf)?; + Ok(buf.into()) } // 'x' from Section 2 of RFC 8037 From b1f690a529469d2d7c6c5ef17803a2b81f224f2e Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:17:15 +0530 Subject: [PATCH 05/12] rsa ext/crypto encrypt.rs --- ext/crypto/decrypt.rs | 1 - ext/crypto/encrypt.rs | 27 ++++++++++++--------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/ext/crypto/decrypt.rs b/ext/crypto/decrypt.rs index 3a9f3d36b8cd40..e75eac79d6e735 100644 --- a/ext/crypto/decrypt.rs +++ b/ext/crypto/decrypt.rs @@ -25,7 +25,6 @@ use deno_core::JsBuffer; use deno_core::ToJsBuffer; use rsa::pkcs1::DecodeRsaPrivateKey; use serde::Deserialize; -use sha1::Digest; use sha1::Sha1; use sha2::Sha256; use sha2::Sha384; diff --git a/ext/crypto/encrypt.rs b/ext/crypto/encrypt.rs index b263873e454060..887933f1dc6606 100644 --- a/ext/crypto/encrypt.rs +++ b/ext/crypto/encrypt.rs @@ -24,10 +24,7 @@ use deno_core::JsBuffer; use deno_core::ToJsBuffer; use rand::rngs::OsRng; use rsa::pkcs1::DecodeRsaPublicKey; -use rsa::PaddingScheme; -use rsa::PublicKey; use serde::Deserialize; -use sha1::Digest; use sha1::Sha1; use sha2::Sha256; use sha2::Sha384; @@ -119,24 +116,24 @@ fn encrypt_rsa_oaep( .map_err(|_| operation_error("failed to decode public key"))?; let mut rng = OsRng; let padding = match hash { - ShaHash::Sha1 => PaddingScheme::OAEP { - digest: Box::new(Sha1::new()), - mgf_digest: Box::new(Sha1::new()), + ShaHash::Sha1 => rsa::Oaep { + digest: Box::new(Sha1::default()), + mgf_digest: Box::new(Sha1::default()), label: Some(label), }, - ShaHash::Sha256 => PaddingScheme::OAEP { - digest: Box::new(Sha256::new()), - mgf_digest: Box::new(Sha256::new()), + ShaHash::Sha256 => rsa::Oaep { + digest: Box::new(Sha256::default()), + mgf_digest: Box::new(Sha256::default()), label: Some(label), }, - ShaHash::Sha384 => PaddingScheme::OAEP { - digest: Box::new(Sha384::new()), - mgf_digest: Box::new(Sha384::new()), + ShaHash::Sha384 => rsa::Oaep { + digest: Box::new(Sha384::default()), + mgf_digest: Box::new(Sha384::default()), label: Some(label), }, - ShaHash::Sha512 => PaddingScheme::OAEP { - digest: Box::new(Sha512::new()), - mgf_digest: Box::new(Sha512::new()), + ShaHash::Sha512 => rsa::Oaep { + digest: Box::new(Sha512::default()), + mgf_digest: Box::new(Sha512::default()), label: Some(label), }, }; From cbf704f0a1ed97bf0b97845d2344ea9edb821025 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:18:29 +0530 Subject: [PATCH 06/12] rsa ext/crypto shared.rs --- ext/crypto/ed25519.rs | 13 +++++++++---- ext/crypto/lib.rs | 17 +++++++---------- ext/crypto/shared.rs | 2 +- ext/node/ops/crypto/mod.rs | 22 +++++----------------- 4 files changed, 22 insertions(+), 32 deletions(-) diff --git a/ext/crypto/ed25519.rs b/ext/crypto/ed25519.rs index 42fbaa922c73f6..874eb74b0756d9 100644 --- a/ext/crypto/ed25519.rs +++ b/ext/crypto/ed25519.rs @@ -2,8 +2,8 @@ use base64::prelude::BASE64_URL_SAFE_NO_PAD; use base64::Engine; -use deno_core::error::AnyError; use deno_core::error::custom_error; +use deno_core::error::AnyError; use deno_core::op2; use deno_core::ToJsBuffer; use elliptic_curve::pkcs8::PrivateKeyInfo; @@ -124,9 +124,14 @@ pub fn op_crypto_export_spki_ed25519( }, subject_public_key: pubkey, }; - Ok(key_info.to_vec().map_err(|_| { - custom_error("DOMExceptionOperationError", "Failed to export key") - })?.into()) + Ok( + key_info + .to_vec() + .map_err(|_| { + custom_error("DOMExceptionOperationError", "Failed to export key") + })? + .into(), + ) } #[op2] diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index 76dabefabfdcba..68414024179cda 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -38,16 +38,16 @@ use ring::signature::EcdsaVerificationAlgorithm; use ring::signature::KeyPair; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::DecodeRsaPublicKey; +use rsa::signature::RandomizedSigner; +use rsa::signature::SignatureEncoding; +use rsa::signature::Signer; +use rsa::signature::Verifier; use rsa::RsaPrivateKey; use rsa::RsaPublicKey; use sha1::Sha1; use sha2::Sha256; use sha2::Sha384; use sha2::Sha512; -use rsa::signature::RandomizedSigner; -use rsa::signature::SignatureEncoding; -use rsa::signature::Signer; -use rsa::signature::Verifier; use std::num::NonZeroU32; use std::path::PathBuf; @@ -330,18 +330,15 @@ pub async fn op_crypto_verify_key( verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha256 => { - let verifying_key = - VerifyingKey::::new(public_key); + let verifying_key = VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha384 => { - let verifying_key = - VerifyingKey::::new(public_key); + let verifying_key = VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha512 => { - let verifying_key = - VerifyingKey::::new(public_key); + let verifying_key = VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } } diff --git a/ext/crypto/shared.rs b/ext/crypto/shared.rs index 109f51fa1c7c33..fdbdb23d9526fc 100644 --- a/ext/crypto/shared.rs +++ b/ext/crypto/shared.rs @@ -8,9 +8,9 @@ use deno_core::error::AnyError; use deno_core::JsBuffer; use deno_core::ToJsBuffer; use elliptic_curve::sec1::ToEncodedPoint; +use p256::pkcs8::DecodePrivateKey; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::EncodeRsaPublicKey; -use rsa::pkcs8::DecodePrivateKey; use rsa::RsaPrivateKey; use serde::Deserialize; use serde::Serialize; diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index 409941423dc1dd..b81eb97f1f6462 100644 --- a/ext/node/ops/crypto/mod.rs +++ b/ext/node/ops/crypto/mod.rs @@ -23,13 +23,13 @@ use std::rc::Rc; use p224::NistP224; use p256::NistP256; use p384::NistP384; -use rsa::Oaep; -use rsa::Pkcs1v15Encrypt; use rsa::pkcs8::DecodePrivateKey; use rsa::pkcs8::DecodePublicKey; use rsa::signature::hazmat::PrehashSigner; use rsa::signature::hazmat::PrehashVerifier; use rsa::signature::SignatureEncoding; +use rsa::Oaep; +use rsa::Pkcs1v15Encrypt; use rsa::RsaPrivateKey; use rsa::RsaPublicKey; use secp256k1::ecdh::SharedSecret; @@ -208,16 +208,8 @@ pub fn op_node_private_decrypt( let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?; match padding { - 1 => Ok( - key - .decrypt(Pkcs1v15Encrypt, &msg)? - .into(), - ), - 4 => Ok( - key - .decrypt(Oaep::new::(), &msg)? - .into(), - ), + 1 => Ok(key.decrypt(Pkcs1v15Encrypt, &msg)?.into()), + 4 => Ok(key.decrypt(Oaep::new::(), &msg)?.into()), _ => Err(type_error("Unknown padding")), } } @@ -233,11 +225,7 @@ pub fn op_node_public_encrypt( let mut rng = rand::thread_rng(); match padding { - 1 => Ok( - key - .encrypt(&mut rng, Pkcs1v15Encrypt, &msg)? - .into(), - ), + 1 => Ok(key.encrypt(&mut rng, Pkcs1v15Encrypt, &msg)?.into()), 4 => Ok( key .encrypt(&mut rng, Oaep::new::(), &msg)? From 37e78888a09dea71efb4f43a886b5df9743f839c Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:24:44 +0530 Subject: [PATCH 07/12] rsa ext/crypto export_key.rs --- ext/crypto/export_key.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/ext/crypto/export_key.rs b/ext/crypto/export_key.rs index a34c404020b61c..4ba30fbaa7c1a4 100644 --- a/ext/crypto/export_key.rs +++ b/ext/crypto/export_key.rs @@ -10,12 +10,12 @@ use deno_core::op2; use deno_core::ToJsBuffer; use elliptic_curve::sec1::ToEncodedPoint; use p256::pkcs8::DecodePrivateKey; -use rsa::pkcs1::UIntRef; +use rsa::pkcs1::der::Decode; +use rsa::pkcs8::der::asn1::UintRef; +use rsa::pkcs8::der::Encode; use serde::Deserialize; use serde::Serialize; use spki::der::asn1; -use spki::der::Decode; -use spki::der::Encode; use spki::AlgorithmIdentifier; use crate::shared::*; @@ -112,7 +112,7 @@ pub fn op_crypto_export_key( } } -fn uint_to_b64(bytes: UIntRef) -> String { +fn uint_to_b64(bytes: UintRef) -> String { BASE64_URL_SAFE_NO_PAD.encode(bytes.as_bytes()) } @@ -126,6 +126,7 @@ fn export_key_rsa( ) -> Result { match format { ExportKeyFormat::Spki => { + use spki::der::Encode; let subject_public_key = &key_data.as_rsa_public_key()?; // the SPKI structure @@ -158,18 +159,21 @@ fn export_key_rsa( let pk_info = rsa::pkcs8::PrivateKeyInfo { public_key: None, - algorithm: rsa::pkcs8::AlgorithmIdentifier { + algorithm: rsa::pkcs8::AlgorithmIdentifierRef { // rsaEncryption(1) oid: rsa::pkcs8::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1"), // parameters field should not be omitted (None). // It MUST have ASN.1 type NULL as per defined in RFC 3279 Section 2.3.1 - parameters: Some(asn1::AnyRef::from(asn1::Null)), + parameters: Some(rsa::pkcs8::der::asn1::AnyRef::from( + rsa::pkcs8::der::asn1::Null, + )), }, private_key, }; // Infallible because we know the private key is valid. - let pkcs8_der = pk_info.to_vec().unwrap(); + let mut pkcs8_der = Vec::new(); + pk_info.encode_to_vec(&mut pkcs8_der)?; Ok(ExportKeyResult::Pkcs8(pkcs8_der.into())) } @@ -255,6 +259,8 @@ fn export_key_ec( Ok(ExportKeyResult::Raw(subject_public_key.into())) } ExportKeyFormat::Spki => { + use spki::der::Encode; + let subject_public_key = match named_curve { EcNamedCurve::P256 => { let point = key_data.as_ec_public_key_p256()?; From 5f0893955990a32f0c58e95619de55712298977d Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:29:19 +0530 Subject: [PATCH 08/12] rsa ext/crypto import_key.rs --- ext/crypto/import_key.rs | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs index 8ef73a8c44c1e9..b0df562eec4a38 100644 --- a/ext/crypto/import_key.rs +++ b/ext/crypto/import_key.rs @@ -8,7 +8,8 @@ use deno_core::ToJsBuffer; use elliptic_curve::pkcs8::PrivateKeyInfo; use p256::pkcs8::EncodePrivateKey; use ring::signature::EcdsaKeyPair; -use rsa::pkcs1::UIntRef; +use rsa::pkcs1::UintRef; +use rsa::pkcs8::der::Encode; use serde::Deserialize; use serde::Serialize; use spki::der::Decode; @@ -121,7 +122,7 @@ macro_rules! jwt_b64_int_or_err { let bytes = BASE64_URL_SAFE_FORGIVING .decode($b64) .map_err(|_| data_error($err))?; - let $name = UIntRef::new(&bytes).map_err(|_| data_error($err))?; + let $name = UintRef::new(&bytes).map_err(|_| data_error($err))?; }; } @@ -138,9 +139,11 @@ fn import_key_rsa_jwk( public_exponent, }; - let data = public_key - .to_vec() + let mut data = Vec::new(); + public_key + .encode_to_vec(&mut data) .map_err(|_| data_error("invalid rsa public key"))?; + let public_exponent = public_key.public_exponent.as_bytes().to_vec().into(); let modulus_length = public_key.modulus.as_bytes().len() * 8; @@ -182,8 +185,9 @@ fn import_key_rsa_jwk( other_prime_infos: None, }; - let data = private_key - .to_vec() + let mut data = Vec::new(); + private_key + .encode_to_vec(&mut data) .map_err(|_| data_error("invalid rsa private key"))?; let public_exponent = @@ -203,6 +207,8 @@ fn import_key_rsa_jwk( fn import_key_rsassa( key_data: KeyData, ) -> Result { + use rsa::pkcs1::der::Decode; + match key_data { KeyData::Spki(data) => { // 2-3. @@ -227,7 +233,7 @@ fn import_key_rsassa( .map_err(|e| data_error(e.to_string()))?; if bytes_consumed - != spki::der::Length::new(pk_info.subject_public_key.len() as u16) + != rsa::pkcs1::der::Length::new(pk_info.subject_public_key.len() as u16) { return Err(data_error("public key is invalid (too long)")); } @@ -266,7 +272,7 @@ fn import_key_rsassa( .map_err(|e| data_error(e.to_string()))?; if bytes_consumed - != spki::der::Length::new(pk_info.private_key.len() as u16) + != rsa::pkcs1::der::Length::new(pk_info.private_key.len() as u16) { return Err(data_error("private key is invalid (too long)")); } @@ -292,6 +298,8 @@ fn import_key_rsassa( fn import_key_rsapss( key_data: KeyData, ) -> Result { + use rsa::pkcs1::der::Decode; + match key_data { KeyData::Spki(data) => { // 2-3. @@ -316,7 +324,7 @@ fn import_key_rsapss( .map_err(|e| data_error(e.to_string()))?; if bytes_consumed - != spki::der::Length::new(pk_info.subject_public_key.len() as u16) + != rsa::pkcs1::der::Length::new(pk_info.subject_public_key.len() as u16) { return Err(data_error("public key is invalid (too long)")); } @@ -355,7 +363,7 @@ fn import_key_rsapss( .map_err(|e| data_error(e.to_string()))?; if bytes_consumed - != spki::der::Length::new(pk_info.private_key.len() as u16) + != rsa::pkcs1::der::Length::new(pk_info.private_key.len() as u16) { return Err(data_error("private key is invalid (too long)")); } @@ -381,6 +389,8 @@ fn import_key_rsapss( fn import_key_rsaoaep( key_data: KeyData, ) -> Result { + use rsa::pkcs1::der::Decode; + match key_data { KeyData::Spki(data) => { // 2-3. @@ -405,7 +415,7 @@ fn import_key_rsaoaep( .map_err(|e| data_error(e.to_string()))?; if bytes_consumed - != spki::der::Length::new(pk_info.subject_public_key.len() as u16) + != rsa::pkcs1::der::Length::new(pk_info.subject_public_key.len() as u16) { return Err(data_error("public key is invalid (too long)")); } @@ -444,7 +454,7 @@ fn import_key_rsaoaep( .map_err(|e| data_error(e.to_string()))?; if bytes_consumed - != spki::der::Length::new(pk_info.private_key.len() as u16) + != rsa::pkcs1::der::Length::new(pk_info.private_key.len() as u16) { return Err(data_error("private key is invalid (too long)")); } @@ -534,13 +544,15 @@ fn import_key_ec_jwk( let d = decode_b64url_to_field_bytes::(&d)?; let pk = p256::SecretKey::from_be_bytes(&d)?; - pk.to_pkcs8_der()? + pk.to_pkcs8_der() + .map_err(|_| data_error("invalid JWK private key"))? } EcNamedCurve::P384 => { let d = decode_b64url_to_field_bytes::(&d)?; let pk = p384::SecretKey::from_be_bytes(&d)?; - pk.to_pkcs8_der()? + pk.to_pkcs8_der() + .map_err(|_| data_error("invalid JWK private key"))? } EcNamedCurve::P521 => { return Err(data_error("Unsupported named curve")) From ebddb679be3db7f3604126faadc5c69fdf02a0a9 Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:31:39 +0530 Subject: [PATCH 09/12] rsa ext/crypto x25519.rs --- ext/crypto/import_key.rs | 1 - ext/crypto/x25519.rs | 18 +++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs index b0df562eec4a38..5f7c214eada9e2 100644 --- a/ext/crypto/import_key.rs +++ b/ext/crypto/import_key.rs @@ -13,7 +13,6 @@ use rsa::pkcs8::der::Encode; use serde::Deserialize; use serde::Serialize; use spki::der::Decode; -use spki::der::Encode; use crate::key::CryptoNamedCurve; use crate::shared::*; diff --git a/ext/crypto/x25519.rs b/ext/crypto/x25519.rs index c2842aceb30bc8..8090f28806fbcb 100644 --- a/ext/crypto/x25519.rs +++ b/ext/crypto/x25519.rs @@ -1,6 +1,7 @@ // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. use curve25519_dalek::montgomery::MontgomeryPoint; +use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::op2; use deno_core::ToJsBuffer; @@ -120,7 +121,14 @@ pub fn op_crypto_export_spki_x25519( }, subject_public_key: pubkey, }; - Ok(key_info.to_vec()?.into()) + Ok( + key_info + .to_vec() + .map_err(|_| { + custom_error("DOMExceptionOperationError", "Failed to export key") + })? + .into(), + ) } #[op2] @@ -128,10 +136,12 @@ pub fn op_crypto_export_spki_x25519( pub fn op_crypto_export_pkcs8_x25519( #[buffer] pkey: &[u8], ) -> Result { + use rsa::pkcs1::der::Encode; + // This should probably use OneAsymmetricKey instead let pk_info = rsa::pkcs8::PrivateKeyInfo { public_key: None, - algorithm: rsa::pkcs8::AlgorithmIdentifier { + algorithm: rsa::pkcs8::AlgorithmIdentifierRef { // id-X25519 oid: X25519_OID, parameters: None, @@ -139,5 +149,7 @@ pub fn op_crypto_export_pkcs8_x25519( private_key: pkey, // OCTET STRING }; - Ok(pk_info.to_vec()?.into()) + let mut buf = Vec::new(); + pk_info.encode_to_vec(&mut buf)?; + Ok(buf.into()) } From ead2b727ae9c30769379d858f2e9604a12322f5f Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 15:45:07 +0530 Subject: [PATCH 10/12] lint --- ext/crypto/decrypt.rs | 16 ++++++++-------- ext/crypto/encrypt.rs | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/crypto/decrypt.rs b/ext/crypto/decrypt.rs index e75eac79d6e735..1532d4328c324c 100644 --- a/ext/crypto/decrypt.rs +++ b/ext/crypto/decrypt.rs @@ -116,23 +116,23 @@ fn decrypt_rsa_oaep( let padding = match hash { ShaHash::Sha1 => rsa::Oaep { - digest: Box::new(Sha1::default()), - mgf_digest: Box::new(Sha1::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label, }, ShaHash::Sha256 => rsa::Oaep { - digest: Box::new(Sha256::default()), - mgf_digest: Box::new(Sha256::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label, }, ShaHash::Sha384 => rsa::Oaep { - digest: Box::new(Sha384::default()), - mgf_digest: Box::new(Sha384::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label, }, ShaHash::Sha512 => rsa::Oaep { - digest: Box::new(Sha512::default()), - mgf_digest: Box::new(Sha512::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label, }, }; diff --git a/ext/crypto/encrypt.rs b/ext/crypto/encrypt.rs index 887933f1dc6606..b5eef46dcc6eb7 100644 --- a/ext/crypto/encrypt.rs +++ b/ext/crypto/encrypt.rs @@ -117,23 +117,23 @@ fn encrypt_rsa_oaep( let mut rng = OsRng; let padding = match hash { ShaHash::Sha1 => rsa::Oaep { - digest: Box::new(Sha1::default()), - mgf_digest: Box::new(Sha1::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label: Some(label), }, ShaHash::Sha256 => rsa::Oaep { - digest: Box::new(Sha256::default()), - mgf_digest: Box::new(Sha256::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label: Some(label), }, ShaHash::Sha384 => rsa::Oaep { - digest: Box::new(Sha384::default()), - mgf_digest: Box::new(Sha384::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label: Some(label), }, ShaHash::Sha512 => rsa::Oaep { - digest: Box::new(Sha512::default()), - mgf_digest: Box::new(Sha512::default()), + digest: Box::::default(), + mgf_digest: Box::::default(), label: Some(label), }, }; From 7d087daf7c4411620f542a2822062311600508ee Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 18:13:42 +0530 Subject: [PATCH 11/12] fix sign verify x( --- ext/crypto/00_crypto.js | 1 + ext/crypto/lib.rs | 59 ++++++++++++++++++++++++----------------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/ext/crypto/00_crypto.js b/ext/crypto/00_crypto.js index de4ad07e1b97dd..7e1fac49f5cc06 100644 --- a/ext/crypto/00_crypto.js +++ b/ext/crypto/00_crypto.js @@ -1313,6 +1313,7 @@ class SubtleCrypto { algorithm: "RSA-PSS", hash: hashAlgorithm, signature, + saltLength: normalizedAlgorithm.saltLength, }, data); } case "HMAC": { diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index 68414024179cda..4666c54acaf1d8 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -38,13 +38,15 @@ use ring::signature::EcdsaVerificationAlgorithm; use ring::signature::KeyPair; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::DecodeRsaPublicKey; -use rsa::signature::RandomizedSigner; use rsa::signature::SignatureEncoding; use rsa::signature::Signer; use rsa::signature::Verifier; +use rsa::traits::SignatureScheme; +use rsa::Pss; use rsa::RsaPrivateKey; use rsa::RsaPublicKey; use sha1::Sha1; +use sha2::Digest; use sha2::Sha256; use sha2::Sha384; use sha2::Sha512; @@ -227,7 +229,6 @@ pub async fn op_crypto_sign_key( .to_vec() } Algorithm::RsaPss => { - use rsa::pss::SigningKey; let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?; let salt_len = args @@ -241,24 +242,24 @@ pub async fn op_crypto_sign_key( .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let signing_key = - SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(&mut rng, data) + let signing_key = Pss::new_with_salt::(salt_len); + let hashed = Sha1::digest(data); + signing_key.sign(Some(&mut rng), &private_key, &hashed)? } CryptoHash::Sha256 => { - let signing_key = - SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(&mut rng, data) + let signing_key = Pss::new_with_salt::(salt_len); + let hashed = Sha256::digest(data); + signing_key.sign(Some(&mut rng), &private_key, &hashed)? } CryptoHash::Sha384 => { - let signing_key = - SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(&mut rng, data) + let signing_key = Pss::new_with_salt::(salt_len); + let hashed = Sha384::digest(data); + signing_key.sign(Some(&mut rng), &private_key, &hashed)? } CryptoHash::Sha512 => { - let signing_key = - SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(&mut rng, data) + let signing_key = Pss::new_with_salt::(salt_len); + let hashed = Sha512::digest(data); + signing_key.sign(Some(&mut rng), &private_key, &hashed)? } } .to_vec() @@ -302,6 +303,7 @@ pub async fn op_crypto_sign_key( pub struct VerifyArg { key: KeyData, algorithm: Algorithm, + salt_length: Option, hash: Option, signature: JsBuffer, named_curve: Option, @@ -344,30 +346,37 @@ pub async fn op_crypto_verify_key( } } Algorithm::RsaPss => { - use rsa::pss::Signature; - use rsa::pss::VerifyingKey; let public_key = read_rsa_public_key(args.key)?; - let signature: Signature = args.signature.as_ref().try_into()?; + let signature = args.signature.as_ref(); + + let salt_len = args + .salt_length + .ok_or_else(|| type_error("Missing argument saltLength".to_string()))? + as usize; match args .hash .ok_or_else(|| type_error("Missing argument hash".to_string()))? { CryptoHash::Sha1 => { - let verifying_key: VerifyingKey = public_key.into(); - verifying_key.verify(data, &signature).is_ok() + let pss = Pss::new_with_salt::(salt_len); + let hashed = Sha1::digest(data); + pss.verify(&public_key, &hashed, signature).is_ok() } CryptoHash::Sha256 => { - let verifying_key: VerifyingKey = public_key.into(); - verifying_key.verify(data, &signature).is_ok() + let pss = Pss::new_with_salt::(salt_len); + let hashed = Sha256::digest(data); + pss.verify(&public_key, &hashed, signature).is_ok() } CryptoHash::Sha384 => { - let verifying_key: VerifyingKey = public_key.into(); - verifying_key.verify(data, &signature).is_ok() + let pss = Pss::new_with_salt::(salt_len); + let hashed = Sha384::digest(data); + pss.verify(&public_key, &hashed, signature).is_ok() } CryptoHash::Sha512 => { - let verifying_key: VerifyingKey = public_key.into(); - verifying_key.verify(data, &signature).is_ok() + let pss = Pss::new_with_salt::(salt_len); + let hashed = Sha512::digest(data); + pss.verify(&public_key, &hashed, signature).is_ok() } } } From 93c4ae4ca050964afd3a4af272fecadc07f95e8a Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 18:45:23 +0530 Subject: [PATCH 12/12] more WPT tests! --- tools/wpt/expectation.json | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index b6443f531caab5..8c3ee870b4000d 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -2249,26 +2249,8 @@ "hmac.https.any.worker.html": true, "rsa_pkcs.https.any.html": true, "rsa_pkcs.https.any.worker.html": true, - "rsa_pss.https.any.html": [ - "RSA-PSS with SHA-1 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-256 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-384 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-512 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-1, salted verification failure with wrong saltLength", - "RSA-PSS with SHA-256, salted verification failure with wrong saltLength", - "RSA-PSS with SHA-384, salted verification failure with wrong saltLength", - "RSA-PSS with SHA-512, salted verification failure with wrong saltLength" - ], - "rsa_pss.https.any.worker.html": [ - "RSA-PSS with SHA-1 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-256 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-384 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-512 and no salt verification failure with wrong saltLength", - "RSA-PSS with SHA-1, salted verification failure with wrong saltLength", - "RSA-PSS with SHA-256, salted verification failure with wrong saltLength", - "RSA-PSS with SHA-384, salted verification failure with wrong saltLength", - "RSA-PSS with SHA-512, salted verification failure with wrong saltLength" - ], + "rsa_pss.https.any.html": true, + "rsa_pss.https.any.worker.html": true, "eddsa.https.any.html": [ "Sign and verify using generated Ed448 keys.", "importVectorKeys step: EdDSA Ed448 verification",