From 02cc37e05494e576ea8e120b9fe21b447da9546b Mon Sep 17 00:00:00 2001 From: Divy Srivastava Date: Mon, 30 Oct 2023 08:25:12 -0700 Subject: [PATCH] chore: upgrade rsa to 0.9 (#21016) --- Cargo.lock | 26 ++++++------ Cargo.toml | 2 +- ext/crypto/00_crypto.js | 1 + ext/crypto/decrypt.rs | 26 ++++++------ ext/crypto/ed25519.rs | 18 ++++++-- ext/crypto/encrypt.rs | 27 ++++++------ ext/crypto/export_key.rs | 20 ++++++--- ext/crypto/import_key.rs | 41 +++++++++++------- ext/crypto/lib.rs | 87 ++++++++++++++++++++------------------ ext/crypto/shared.rs | 2 +- ext/crypto/x25519.rs | 18 ++++++-- ext/node/ops/crypto/mod.rs | 59 +++++++++++--------------- tools/wpt/expectation.json | 22 +--------- 13 files changed, 182 insertions(+), 167 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e322d63d16..c5fb440f12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3881,14 +3881,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]] @@ -4406,21 +4405,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", ] @@ -6117,7 +6115,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 77f229e04d..7b967a16f4 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/crypto/00_crypto.js b/ext/crypto/00_crypto.js index de4ad07e1b..7e1fac49f5 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/decrypt.rs b/ext/crypto/decrypt.rs index 551f33972a..1532d4328c 100644 --- a/ext/crypto/decrypt.rs +++ b/ext/crypto/decrypt.rs @@ -24,9 +24,7 @@ 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; use sha2::Sha256; use sha2::Sha384; @@ -117,24 +115,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::::default(), + mgf_digest: Box::::default(), label, }, - ShaHash::Sha256 => PaddingScheme::OAEP { - digest: Box::new(Sha256::new()), - mgf_digest: Box::new(Sha256::new()), + ShaHash::Sha256 => rsa::Oaep { + digest: Box::::default(), + mgf_digest: Box::::default(), label, }, - ShaHash::Sha384 => PaddingScheme::OAEP { - digest: Box::new(Sha384::new()), - mgf_digest: Box::new(Sha384::new()), + ShaHash::Sha384 => rsa::Oaep { + digest: Box::::default(), + mgf_digest: Box::::default(), label, }, - ShaHash::Sha512 => PaddingScheme::OAEP { - digest: Box::new(Sha512::new()), - mgf_digest: Box::new(Sha512::new()), + ShaHash::Sha512 => rsa::Oaep { + digest: Box::::default(), + mgf_digest: Box::::default(), label, }, }; diff --git a/ext/crypto/ed25519.rs b/ext/crypto/ed25519.rs index e2a0ce4087..874eb74b07 100644 --- a/ext/crypto/ed25519.rs +++ b/ext/crypto/ed25519.rs @@ -2,6 +2,7 @@ use base64::prelude::BASE64_URL_SAFE_NO_PAD; use base64::Engine; +use deno_core::error::custom_error; use deno_core::error::AnyError; use deno_core::op2; use deno_core::ToJsBuffer; @@ -123,7 +124,14 @@ 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 +139,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 +152,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 diff --git a/ext/crypto/encrypt.rs b/ext/crypto/encrypt.rs index b263873e45..b5eef46dcc 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::::default(), + mgf_digest: Box::::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::::default(), + mgf_digest: Box::::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::::default(), + mgf_digest: Box::::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::::default(), + mgf_digest: Box::::default(), label: Some(label), }, }; diff --git a/ext/crypto/export_key.rs b/ext/crypto/export_key.rs index a34c404020..4ba30fbaa7 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()?; diff --git a/ext/crypto/import_key.rs b/ext/crypto/import_key.rs index 8ef73a8c44..5f7c214ead 100644 --- a/ext/crypto/import_key.rs +++ b/ext/crypto/import_key.rs @@ -8,11 +8,11 @@ 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; -use spki::der::Encode; use crate::key::CryptoNamedCurve; use crate::shared::*; @@ -121,7 +121,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 +138,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 +184,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 +206,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 +232,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 +271,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 +297,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 +323,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 +362,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 +388,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 +414,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 +453,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 +543,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")) diff --git a/ext/crypto/lib.rs b/ext/crypto/lib.rs index 87b9702ce0..4666c54aca 100644 --- a/ext/crypto/lib.rs +++ b/ext/crypto/lib.rs @@ -38,15 +38,18 @@ use ring::signature::EcdsaVerificationAlgorithm; use ring::signature::KeyPair; use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::DecodeRsaPublicKey; +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; -use signature::RandomizedSigner; -use signature::Signer; -use signature::Verifier; use std::num::NonZeroU32; use std::path::PathBuf; @@ -207,26 +210,25 @@ 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) } } .to_vec() } Algorithm::RsaPss => { - use rsa::pss::SigningKey; let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?; let salt_len = args @@ -234,30 +236,30 @@ 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()))? { CryptoHash::Sha1 => { - let signing_key = - SigningKey::::new_with_salt_len(private_key, salt_len); - signing_key.sign_with_rng(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(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(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(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() @@ -301,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, @@ -319,57 +322,61 @@ 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); + let verifying_key = VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha384 => { - let verifying_key = - VerifyingKey::::new_with_prefix(public_key); + let verifying_key = VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } CryptoHash::Sha512 => { - let verifying_key = - VerifyingKey::::new_with_prefix(public_key); + let verifying_key = VerifyingKey::::new(public_key); verifying_key.verify(data, &signature).is_ok() } } } Algorithm::RsaPss => { - 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 = 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() } } } diff --git a/ext/crypto/shared.rs b/ext/crypto/shared.rs index 109f51fa1c..fdbdb23d95 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/crypto/x25519.rs b/ext/crypto/x25519.rs index c2842aceb3..8090f28806 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()) } diff --git a/ext/node/ops/crypto/mod.rs b/ext/node/ops/crypto/mod.rs index bf7a99ba04..b81eb97f1f 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::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::Oaep; +use rsa::Pkcs1v15Encrypt; 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")), @@ -203,16 +208,8 @@ pub fn op_node_private_decrypt( let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?; match padding { - 1 => Ok( - key - .decrypt(PaddingScheme::new_pkcs1v15_encrypt(), &msg)? - .into(), - ), - 4 => Ok( - key - .decrypt(PaddingScheme::new_oaep::(), &msg)? - .into(), - ), + 1 => Ok(key.decrypt(Pkcs1v15Encrypt, &msg)?.into()), + 4 => Ok(key.decrypt(Oaep::new::(), &msg)?.into()), _ => Err(type_error("Unknown padding")), } } @@ -228,14 +225,10 @@ pub fn op_node_public_encrypt( let mut rng = rand::thread_rng(); match padding { - 1 => Ok( - key - .encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &msg)? - .into(), - ), + 1 => Ok(key.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 +365,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 +379,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 +423,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 +435,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!( diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index b6443f531c..8c3ee870b4 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",