chore: upgrade rsa to 0.9 (#21016)

This commit is contained in:
Divy Srivastava 2023-10-30 08:25:12 -07:00 committed by GitHub
parent f3b580d001
commit 02cc37e054
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 182 additions and 167 deletions

26
Cargo.lock generated
View file

@ -3881,14 +3881,13 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]] [[package]]
name = "pkcs1" name = "pkcs1"
version = "0.4.1" version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eff33bdbdfc54cc98a2eca766ebdec3e1b8fb7387523d5c9c9a2891da856f719" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
dependencies = [ dependencies = [
"der 0.6.1", "der 0.7.8",
"pkcs8 0.9.0", "pkcs8 0.10.2",
"spki 0.6.0", "spki 0.7.2",
"zeroize",
] ]
[[package]] [[package]]
@ -4406,21 +4405,20 @@ dependencies = [
[[package]] [[package]]
name = "rsa" name = "rsa"
version = "0.7.2" version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "094052d5470cbcef561cb848a7209968c9f12dfa6d668f4bca048ac5de51099c" checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d"
dependencies = [ dependencies = [
"byteorder", "const-oid",
"digest 0.10.7", "digest 0.10.7",
"num-bigint-dig", "num-bigint-dig",
"num-integer", "num-integer",
"num-iter",
"num-traits", "num-traits",
"pkcs1", "pkcs1",
"pkcs8 0.9.0", "pkcs8 0.10.2",
"rand_core 0.6.4", "rand_core 0.6.4",
"signature 1.6.4", "signature 2.1.0",
"smallvec", "spki 0.7.2",
"subtle", "subtle",
"zeroize", "zeroize",
] ]
@ -6117,7 +6115,7 @@ version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [ dependencies = [
"cfg-if 0.1.10", "cfg-if 1.0.0",
"rand 0.8.5", "rand 0.8.5",
"static_assertions", "static_assertions",
] ]

View file

@ -153,7 +153,7 @@ p256 = { version = "0.13.2", features = ["ecdh"] }
p384 = { version = "0.13.0", features = ["ecdh"] } p384 = { version = "0.13.0", features = ["ecdh"] }
# crypto # 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" hkdf = "0.12.3"
# macros # macros

View file

@ -1313,6 +1313,7 @@ class SubtleCrypto {
algorithm: "RSA-PSS", algorithm: "RSA-PSS",
hash: hashAlgorithm, hash: hashAlgorithm,
signature, signature,
saltLength: normalizedAlgorithm.saltLength,
}, data); }, data);
} }
case "HMAC": { case "HMAC": {

View file

@ -24,9 +24,7 @@ use deno_core::unsync::spawn_blocking;
use deno_core::JsBuffer; use deno_core::JsBuffer;
use deno_core::ToJsBuffer; use deno_core::ToJsBuffer;
use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::DecodeRsaPrivateKey;
use rsa::PaddingScheme;
use serde::Deserialize; use serde::Deserialize;
use sha1::Digest;
use sha1::Sha1; use sha1::Sha1;
use sha2::Sha256; use sha2::Sha256;
use sha2::Sha384; use sha2::Sha384;
@ -117,24 +115,24 @@ fn decrypt_rsa_oaep(
let label = Some(String::from_utf8_lossy(&label).to_string()); let label = Some(String::from_utf8_lossy(&label).to_string());
let padding = match hash { let padding = match hash {
ShaHash::Sha1 => PaddingScheme::OAEP { ShaHash::Sha1 => rsa::Oaep {
digest: Box::new(Sha1::new()), digest: Box::<Sha1>::default(),
mgf_digest: Box::new(Sha1::new()), mgf_digest: Box::<Sha1>::default(),
label, label,
}, },
ShaHash::Sha256 => PaddingScheme::OAEP { ShaHash::Sha256 => rsa::Oaep {
digest: Box::new(Sha256::new()), digest: Box::<Sha256>::default(),
mgf_digest: Box::new(Sha256::new()), mgf_digest: Box::<Sha256>::default(),
label, label,
}, },
ShaHash::Sha384 => PaddingScheme::OAEP { ShaHash::Sha384 => rsa::Oaep {
digest: Box::new(Sha384::new()), digest: Box::<Sha384>::default(),
mgf_digest: Box::new(Sha384::new()), mgf_digest: Box::<Sha384>::default(),
label, label,
}, },
ShaHash::Sha512 => PaddingScheme::OAEP { ShaHash::Sha512 => rsa::Oaep {
digest: Box::new(Sha512::new()), digest: Box::<Sha512>::default(),
mgf_digest: Box::new(Sha512::new()), mgf_digest: Box::<Sha512>::default(),
label, label,
}, },
}; };

View file

@ -2,6 +2,7 @@
use base64::prelude::BASE64_URL_SAFE_NO_PAD; use base64::prelude::BASE64_URL_SAFE_NO_PAD;
use base64::Engine; use base64::Engine;
use deno_core::error::custom_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;
use deno_core::ToJsBuffer; use deno_core::ToJsBuffer;
@ -123,7 +124,14 @@ pub fn op_crypto_export_spki_ed25519(
}, },
subject_public_key: pubkey, 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] #[op2]
@ -131,10 +139,12 @@ pub fn op_crypto_export_spki_ed25519(
pub fn op_crypto_export_pkcs8_ed25519( pub fn op_crypto_export_pkcs8_ed25519(
#[buffer] pkey: &[u8], #[buffer] pkey: &[u8],
) -> Result<ToJsBuffer, AnyError> { ) -> Result<ToJsBuffer, AnyError> {
use rsa::pkcs1::der::Encode;
// This should probably use OneAsymmetricKey instead // This should probably use OneAsymmetricKey instead
let pk_info = rsa::pkcs8::PrivateKeyInfo { let pk_info = rsa::pkcs8::PrivateKeyInfo {
public_key: None, public_key: None,
algorithm: rsa::pkcs8::AlgorithmIdentifier { algorithm: rsa::pkcs8::AlgorithmIdentifierRef {
// id-Ed25519 // id-Ed25519
oid: ED25519_OID, oid: ED25519_OID,
parameters: None, parameters: None,
@ -142,7 +152,9 @@ pub fn op_crypto_export_pkcs8_ed25519(
private_key: pkey, // OCTET STRING 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 // 'x' from Section 2 of RFC 8037

View file

@ -24,10 +24,7 @@ use deno_core::JsBuffer;
use deno_core::ToJsBuffer; use deno_core::ToJsBuffer;
use rand::rngs::OsRng; use rand::rngs::OsRng;
use rsa::pkcs1::DecodeRsaPublicKey; use rsa::pkcs1::DecodeRsaPublicKey;
use rsa::PaddingScheme;
use rsa::PublicKey;
use serde::Deserialize; use serde::Deserialize;
use sha1::Digest;
use sha1::Sha1; use sha1::Sha1;
use sha2::Sha256; use sha2::Sha256;
use sha2::Sha384; use sha2::Sha384;
@ -119,24 +116,24 @@ fn encrypt_rsa_oaep(
.map_err(|_| operation_error("failed to decode public key"))?; .map_err(|_| operation_error("failed to decode public key"))?;
let mut rng = OsRng; let mut rng = OsRng;
let padding = match hash { let padding = match hash {
ShaHash::Sha1 => PaddingScheme::OAEP { ShaHash::Sha1 => rsa::Oaep {
digest: Box::new(Sha1::new()), digest: Box::<Sha1>::default(),
mgf_digest: Box::new(Sha1::new()), mgf_digest: Box::<Sha1>::default(),
label: Some(label), label: Some(label),
}, },
ShaHash::Sha256 => PaddingScheme::OAEP { ShaHash::Sha256 => rsa::Oaep {
digest: Box::new(Sha256::new()), digest: Box::<Sha256>::default(),
mgf_digest: Box::new(Sha256::new()), mgf_digest: Box::<Sha256>::default(),
label: Some(label), label: Some(label),
}, },
ShaHash::Sha384 => PaddingScheme::OAEP { ShaHash::Sha384 => rsa::Oaep {
digest: Box::new(Sha384::new()), digest: Box::<Sha384>::default(),
mgf_digest: Box::new(Sha384::new()), mgf_digest: Box::<Sha384>::default(),
label: Some(label), label: Some(label),
}, },
ShaHash::Sha512 => PaddingScheme::OAEP { ShaHash::Sha512 => rsa::Oaep {
digest: Box::new(Sha512::new()), digest: Box::<Sha512>::default(),
mgf_digest: Box::new(Sha512::new()), mgf_digest: Box::<Sha512>::default(),
label: Some(label), label: Some(label),
}, },
}; };

View file

@ -10,12 +10,12 @@ use deno_core::op2;
use deno_core::ToJsBuffer; use deno_core::ToJsBuffer;
use elliptic_curve::sec1::ToEncodedPoint; use elliptic_curve::sec1::ToEncodedPoint;
use p256::pkcs8::DecodePrivateKey; 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::Deserialize;
use serde::Serialize; use serde::Serialize;
use spki::der::asn1; use spki::der::asn1;
use spki::der::Decode;
use spki::der::Encode;
use spki::AlgorithmIdentifier; use spki::AlgorithmIdentifier;
use crate::shared::*; 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()) BASE64_URL_SAFE_NO_PAD.encode(bytes.as_bytes())
} }
@ -126,6 +126,7 @@ fn export_key_rsa(
) -> Result<ExportKeyResult, deno_core::anyhow::Error> { ) -> Result<ExportKeyResult, deno_core::anyhow::Error> {
match format { match format {
ExportKeyFormat::Spki => { ExportKeyFormat::Spki => {
use spki::der::Encode;
let subject_public_key = &key_data.as_rsa_public_key()?; let subject_public_key = &key_data.as_rsa_public_key()?;
// the SPKI structure // the SPKI structure
@ -158,18 +159,21 @@ fn export_key_rsa(
let pk_info = rsa::pkcs8::PrivateKeyInfo { let pk_info = rsa::pkcs8::PrivateKeyInfo {
public_key: None, public_key: None,
algorithm: rsa::pkcs8::AlgorithmIdentifier { algorithm: rsa::pkcs8::AlgorithmIdentifierRef {
// rsaEncryption(1) // rsaEncryption(1)
oid: rsa::pkcs8::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1"), oid: rsa::pkcs8::ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.1"),
// parameters field should not be omitted (None). // parameters field should not be omitted (None).
// It MUST have ASN.1 type NULL as per defined in RFC 3279 Section 2.3.1 // 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, private_key,
}; };
// Infallible because we know the private key is valid. // 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())) Ok(ExportKeyResult::Pkcs8(pkcs8_der.into()))
} }
@ -255,6 +259,8 @@ fn export_key_ec(
Ok(ExportKeyResult::Raw(subject_public_key.into())) Ok(ExportKeyResult::Raw(subject_public_key.into()))
} }
ExportKeyFormat::Spki => { ExportKeyFormat::Spki => {
use spki::der::Encode;
let subject_public_key = match named_curve { let subject_public_key = match named_curve {
EcNamedCurve::P256 => { EcNamedCurve::P256 => {
let point = key_data.as_ec_public_key_p256()?; let point = key_data.as_ec_public_key_p256()?;

View file

@ -8,11 +8,11 @@ use deno_core::ToJsBuffer;
use elliptic_curve::pkcs8::PrivateKeyInfo; use elliptic_curve::pkcs8::PrivateKeyInfo;
use p256::pkcs8::EncodePrivateKey; use p256::pkcs8::EncodePrivateKey;
use ring::signature::EcdsaKeyPair; use ring::signature::EcdsaKeyPair;
use rsa::pkcs1::UIntRef; use rsa::pkcs1::UintRef;
use rsa::pkcs8::der::Encode;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;
use spki::der::Decode; use spki::der::Decode;
use spki::der::Encode;
use crate::key::CryptoNamedCurve; use crate::key::CryptoNamedCurve;
use crate::shared::*; use crate::shared::*;
@ -121,7 +121,7 @@ macro_rules! jwt_b64_int_or_err {
let bytes = BASE64_URL_SAFE_FORGIVING let bytes = BASE64_URL_SAFE_FORGIVING
.decode($b64) .decode($b64)
.map_err(|_| data_error($err))?; .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, public_exponent,
}; };
let data = public_key let mut data = Vec::new();
.to_vec() public_key
.encode_to_vec(&mut data)
.map_err(|_| data_error("invalid rsa public key"))?; .map_err(|_| data_error("invalid rsa public key"))?;
let public_exponent = let public_exponent =
public_key.public_exponent.as_bytes().to_vec().into(); public_key.public_exponent.as_bytes().to_vec().into();
let modulus_length = public_key.modulus.as_bytes().len() * 8; let modulus_length = public_key.modulus.as_bytes().len() * 8;
@ -182,8 +184,9 @@ fn import_key_rsa_jwk(
other_prime_infos: None, other_prime_infos: None,
}; };
let data = private_key let mut data = Vec::new();
.to_vec() private_key
.encode_to_vec(&mut data)
.map_err(|_| data_error("invalid rsa private key"))?; .map_err(|_| data_error("invalid rsa private key"))?;
let public_exponent = let public_exponent =
@ -203,6 +206,8 @@ fn import_key_rsa_jwk(
fn import_key_rsassa( fn import_key_rsassa(
key_data: KeyData, key_data: KeyData,
) -> Result<ImportKeyResult, deno_core::anyhow::Error> { ) -> Result<ImportKeyResult, deno_core::anyhow::Error> {
use rsa::pkcs1::der::Decode;
match key_data { match key_data {
KeyData::Spki(data) => { KeyData::Spki(data) => {
// 2-3. // 2-3.
@ -227,7 +232,7 @@ fn import_key_rsassa(
.map_err(|e| data_error(e.to_string()))?; .map_err(|e| data_error(e.to_string()))?;
if bytes_consumed 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)")); 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()))?; .map_err(|e| data_error(e.to_string()))?;
if bytes_consumed 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)")); return Err(data_error("private key is invalid (too long)"));
} }
@ -292,6 +297,8 @@ fn import_key_rsassa(
fn import_key_rsapss( fn import_key_rsapss(
key_data: KeyData, key_data: KeyData,
) -> Result<ImportKeyResult, deno_core::anyhow::Error> { ) -> Result<ImportKeyResult, deno_core::anyhow::Error> {
use rsa::pkcs1::der::Decode;
match key_data { match key_data {
KeyData::Spki(data) => { KeyData::Spki(data) => {
// 2-3. // 2-3.
@ -316,7 +323,7 @@ fn import_key_rsapss(
.map_err(|e| data_error(e.to_string()))?; .map_err(|e| data_error(e.to_string()))?;
if bytes_consumed 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)")); 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()))?; .map_err(|e| data_error(e.to_string()))?;
if bytes_consumed 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)")); return Err(data_error("private key is invalid (too long)"));
} }
@ -381,6 +388,8 @@ fn import_key_rsapss(
fn import_key_rsaoaep( fn import_key_rsaoaep(
key_data: KeyData, key_data: KeyData,
) -> Result<ImportKeyResult, deno_core::anyhow::Error> { ) -> Result<ImportKeyResult, deno_core::anyhow::Error> {
use rsa::pkcs1::der::Decode;
match key_data { match key_data {
KeyData::Spki(data) => { KeyData::Spki(data) => {
// 2-3. // 2-3.
@ -405,7 +414,7 @@ fn import_key_rsaoaep(
.map_err(|e| data_error(e.to_string()))?; .map_err(|e| data_error(e.to_string()))?;
if bytes_consumed 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)")); 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()))?; .map_err(|e| data_error(e.to_string()))?;
if bytes_consumed 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)")); 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::<p256::NistP256>(&d)?; let d = decode_b64url_to_field_bytes::<p256::NistP256>(&d)?;
let pk = p256::SecretKey::from_be_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 => { EcNamedCurve::P384 => {
let d = decode_b64url_to_field_bytes::<p384::NistP384>(&d)?; let d = decode_b64url_to_field_bytes::<p384::NistP384>(&d)?;
let pk = p384::SecretKey::from_be_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 => { EcNamedCurve::P521 => {
return Err(data_error("Unsupported named curve")) return Err(data_error("Unsupported named curve"))

View file

@ -38,15 +38,18 @@ use ring::signature::EcdsaVerificationAlgorithm;
use ring::signature::KeyPair; use ring::signature::KeyPair;
use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::DecodeRsaPrivateKey;
use rsa::pkcs1::DecodeRsaPublicKey; 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::RsaPrivateKey;
use rsa::RsaPublicKey; use rsa::RsaPublicKey;
use sha1::Sha1; use sha1::Sha1;
use sha2::Digest;
use sha2::Sha256; use sha2::Sha256;
use sha2::Sha384; use sha2::Sha384;
use sha2::Sha512; use sha2::Sha512;
use signature::RandomizedSigner;
use signature::Signer;
use signature::Verifier;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::path::PathBuf; 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()))? .ok_or_else(|| type_error("Missing argument hash".to_string()))?
{ {
CryptoHash::Sha1 => { CryptoHash::Sha1 => {
let signing_key = SigningKey::<Sha1>::new_with_prefix(private_key); let signing_key = SigningKey::<Sha1>::new(private_key);
signing_key.sign(data) signing_key.sign(data)
} }
CryptoHash::Sha256 => { CryptoHash::Sha256 => {
let signing_key = SigningKey::<Sha256>::new_with_prefix(private_key); let signing_key = SigningKey::<Sha256>::new(private_key);
signing_key.sign(data) signing_key.sign(data)
} }
CryptoHash::Sha384 => { CryptoHash::Sha384 => {
let signing_key = SigningKey::<Sha384>::new_with_prefix(private_key); let signing_key = SigningKey::<Sha384>::new(private_key);
signing_key.sign(data) signing_key.sign(data)
} }
CryptoHash::Sha512 => { CryptoHash::Sha512 => {
let signing_key = SigningKey::<Sha512>::new_with_prefix(private_key); let signing_key = SigningKey::<Sha512>::new(private_key);
signing_key.sign(data) signing_key.sign(data)
} }
} }
.to_vec() .to_vec()
} }
Algorithm::RsaPss => { Algorithm::RsaPss => {
use rsa::pss::SigningKey;
let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?; let private_key = RsaPrivateKey::from_pkcs1_der(&args.key.data)?;
let salt_len = args 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()))? .ok_or_else(|| type_error("Missing argument saltLength".to_string()))?
as usize; as usize;
let rng = OsRng; let mut rng = OsRng;
match args match args
.hash .hash
.ok_or_else(|| type_error("Missing argument hash".to_string()))? .ok_or_else(|| type_error("Missing argument hash".to_string()))?
{ {
CryptoHash::Sha1 => { CryptoHash::Sha1 => {
let signing_key = let signing_key = Pss::new_with_salt::<Sha1>(salt_len);
SigningKey::<Sha1>::new_with_salt_len(private_key, salt_len); let hashed = Sha1::digest(data);
signing_key.sign_with_rng(rng, data) signing_key.sign(Some(&mut rng), &private_key, &hashed)?
} }
CryptoHash::Sha256 => { CryptoHash::Sha256 => {
let signing_key = let signing_key = Pss::new_with_salt::<Sha256>(salt_len);
SigningKey::<Sha256>::new_with_salt_len(private_key, salt_len); let hashed = Sha256::digest(data);
signing_key.sign_with_rng(rng, data) signing_key.sign(Some(&mut rng), &private_key, &hashed)?
} }
CryptoHash::Sha384 => { CryptoHash::Sha384 => {
let signing_key = let signing_key = Pss::new_with_salt::<Sha384>(salt_len);
SigningKey::<Sha384>::new_with_salt_len(private_key, salt_len); let hashed = Sha384::digest(data);
signing_key.sign_with_rng(rng, data) signing_key.sign(Some(&mut rng), &private_key, &hashed)?
} }
CryptoHash::Sha512 => { CryptoHash::Sha512 => {
let signing_key = let signing_key = Pss::new_with_salt::<Sha512>(salt_len);
SigningKey::<Sha512>::new_with_salt_len(private_key, salt_len); let hashed = Sha512::digest(data);
signing_key.sign_with_rng(rng, data) signing_key.sign(Some(&mut rng), &private_key, &hashed)?
} }
} }
.to_vec() .to_vec()
@ -301,6 +303,7 @@ pub async fn op_crypto_sign_key(
pub struct VerifyArg { pub struct VerifyArg {
key: KeyData, key: KeyData,
algorithm: Algorithm, algorithm: Algorithm,
salt_length: Option<u32>,
hash: Option<CryptoHash>, hash: Option<CryptoHash>,
signature: JsBuffer, signature: JsBuffer,
named_curve: Option<CryptoNamedCurve>, named_curve: Option<CryptoNamedCurve>,
@ -319,57 +322,61 @@ pub async fn op_crypto_verify_key(
use rsa::pkcs1v15::Signature; use rsa::pkcs1v15::Signature;
use rsa::pkcs1v15::VerifyingKey; use rsa::pkcs1v15::VerifyingKey;
let public_key = read_rsa_public_key(args.key)?; 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 match args
.hash .hash
.ok_or_else(|| type_error("Missing argument hash".to_string()))? .ok_or_else(|| type_error("Missing argument hash".to_string()))?
{ {
CryptoHash::Sha1 => { CryptoHash::Sha1 => {
let verifying_key = VerifyingKey::<Sha1>::new_with_prefix(public_key); let verifying_key = VerifyingKey::<Sha1>::new(public_key);
verifying_key.verify(data, &signature).is_ok() verifying_key.verify(data, &signature).is_ok()
} }
CryptoHash::Sha256 => { CryptoHash::Sha256 => {
let verifying_key = let verifying_key = VerifyingKey::<Sha256>::new(public_key);
VerifyingKey::<Sha256>::new_with_prefix(public_key);
verifying_key.verify(data, &signature).is_ok() verifying_key.verify(data, &signature).is_ok()
} }
CryptoHash::Sha384 => { CryptoHash::Sha384 => {
let verifying_key = let verifying_key = VerifyingKey::<Sha384>::new(public_key);
VerifyingKey::<Sha384>::new_with_prefix(public_key);
verifying_key.verify(data, &signature).is_ok() verifying_key.verify(data, &signature).is_ok()
} }
CryptoHash::Sha512 => { CryptoHash::Sha512 => {
let verifying_key = let verifying_key = VerifyingKey::<Sha512>::new(public_key);
VerifyingKey::<Sha512>::new_with_prefix(public_key);
verifying_key.verify(data, &signature).is_ok() verifying_key.verify(data, &signature).is_ok()
} }
} }
} }
Algorithm::RsaPss => { Algorithm::RsaPss => {
use rsa::pss::Signature;
use rsa::pss::VerifyingKey;
let public_key = read_rsa_public_key(args.key)?; 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 match args
.hash .hash
.ok_or_else(|| type_error("Missing argument hash".to_string()))? .ok_or_else(|| type_error("Missing argument hash".to_string()))?
{ {
CryptoHash::Sha1 => { CryptoHash::Sha1 => {
let verifying_key: VerifyingKey<Sha1> = public_key.into(); let pss = Pss::new_with_salt::<Sha1>(salt_len);
verifying_key.verify(data, &signature).is_ok() let hashed = Sha1::digest(data);
pss.verify(&public_key, &hashed, signature).is_ok()
} }
CryptoHash::Sha256 => { CryptoHash::Sha256 => {
let verifying_key: VerifyingKey<Sha256> = public_key.into(); let pss = Pss::new_with_salt::<Sha256>(salt_len);
verifying_key.verify(data, &signature).is_ok() let hashed = Sha256::digest(data);
pss.verify(&public_key, &hashed, signature).is_ok()
} }
CryptoHash::Sha384 => { CryptoHash::Sha384 => {
let verifying_key: VerifyingKey<Sha384> = public_key.into(); let pss = Pss::new_with_salt::<Sha384>(salt_len);
verifying_key.verify(data, &signature).is_ok() let hashed = Sha384::digest(data);
pss.verify(&public_key, &hashed, signature).is_ok()
} }
CryptoHash::Sha512 => { CryptoHash::Sha512 => {
let verifying_key: VerifyingKey<Sha512> = public_key.into(); let pss = Pss::new_with_salt::<Sha512>(salt_len);
verifying_key.verify(data, &signature).is_ok() let hashed = Sha512::digest(data);
pss.verify(&public_key, &hashed, signature).is_ok()
} }
} }
} }

View file

@ -8,9 +8,9 @@ use deno_core::error::AnyError;
use deno_core::JsBuffer; use deno_core::JsBuffer;
use deno_core::ToJsBuffer; use deno_core::ToJsBuffer;
use elliptic_curve::sec1::ToEncodedPoint; use elliptic_curve::sec1::ToEncodedPoint;
use p256::pkcs8::DecodePrivateKey;
use rsa::pkcs1::DecodeRsaPrivateKey; use rsa::pkcs1::DecodeRsaPrivateKey;
use rsa::pkcs1::EncodeRsaPublicKey; use rsa::pkcs1::EncodeRsaPublicKey;
use rsa::pkcs8::DecodePrivateKey;
use rsa::RsaPrivateKey; use rsa::RsaPrivateKey;
use serde::Deserialize; use serde::Deserialize;
use serde::Serialize; use serde::Serialize;

View file

@ -1,6 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use curve25519_dalek::montgomery::MontgomeryPoint; use curve25519_dalek::montgomery::MontgomeryPoint;
use deno_core::error::custom_error;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::op2; use deno_core::op2;
use deno_core::ToJsBuffer; use deno_core::ToJsBuffer;
@ -120,7 +121,14 @@ pub fn op_crypto_export_spki_x25519(
}, },
subject_public_key: pubkey, 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] #[op2]
@ -128,10 +136,12 @@ pub fn op_crypto_export_spki_x25519(
pub fn op_crypto_export_pkcs8_x25519( pub fn op_crypto_export_pkcs8_x25519(
#[buffer] pkey: &[u8], #[buffer] pkey: &[u8],
) -> Result<ToJsBuffer, AnyError> { ) -> Result<ToJsBuffer, AnyError> {
use rsa::pkcs1::der::Encode;
// This should probably use OneAsymmetricKey instead // This should probably use OneAsymmetricKey instead
let pk_info = rsa::pkcs8::PrivateKeyInfo { let pk_info = rsa::pkcs8::PrivateKeyInfo {
public_key: None, public_key: None,
algorithm: rsa::pkcs8::AlgorithmIdentifier { algorithm: rsa::pkcs8::AlgorithmIdentifierRef {
// id-X25519 // id-X25519
oid: X25519_OID, oid: X25519_OID,
parameters: None, parameters: None,
@ -139,5 +149,7 @@ pub fn op_crypto_export_pkcs8_x25519(
private_key: pkey, // OCTET STRING 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())
} }

View file

@ -23,10 +23,13 @@ use std::rc::Rc;
use p224::NistP224; use p224::NistP224;
use p256::NistP256; use p256::NistP256;
use p384::NistP384; use p384::NistP384;
use rsa::padding::PaddingScheme;
use rsa::pkcs8::DecodePrivateKey; use rsa::pkcs8::DecodePrivateKey;
use rsa::pkcs8::DecodePublicKey; 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::RsaPrivateKey;
use rsa::RsaPublicKey; use rsa::RsaPublicKey;
use secp256k1::ecdh::SharedSecret; use secp256k1::ecdh::SharedSecret;
@ -181,12 +184,14 @@ pub fn op_node_private_encrypt(
match padding { match padding {
1 => Ok( 1 => Ok(
key key
.encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &msg)? .as_ref()
.encrypt(&mut rng, Pkcs1v15Encrypt, &msg)?
.into(), .into(),
), ),
4 => Ok( 4 => Ok(
key key
.encrypt(&mut rng, PaddingScheme::new_oaep::<sha1::Sha1>(), &msg)? .as_ref()
.encrypt(&mut rng, Oaep::new::<sha1::Sha1>(), &msg)?
.into(), .into(),
), ),
_ => Err(type_error("Unknown padding")), _ => Err(type_error("Unknown padding")),
@ -203,16 +208,8 @@ pub fn op_node_private_decrypt(
let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?; let key = RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)?;
match padding { match padding {
1 => Ok( 1 => Ok(key.decrypt(Pkcs1v15Encrypt, &msg)?.into()),
key 4 => Ok(key.decrypt(Oaep::new::<sha1::Sha1>(), &msg)?.into()),
.decrypt(PaddingScheme::new_pkcs1v15_encrypt(), &msg)?
.into(),
),
4 => Ok(
key
.decrypt(PaddingScheme::new_oaep::<sha1::Sha1>(), &msg)?
.into(),
),
_ => Err(type_error("Unknown padding")), _ => Err(type_error("Unknown padding")),
} }
} }
@ -228,14 +225,10 @@ pub fn op_node_public_encrypt(
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
match padding { match padding {
1 => Ok( 1 => Ok(key.encrypt(&mut rng, Pkcs1v15Encrypt, &msg)?.into()),
key
.encrypt(&mut rng, PaddingScheme::new_pkcs1v15_encrypt(), &msg)?
.into(),
),
4 => Ok( 4 => Ok(
key key
.encrypt(&mut rng, PaddingScheme::new_oaep::<sha1::Sha1>(), &msg)? .encrypt(&mut rng, Oaep::new::<sha1::Sha1>(), &msg)?
.into(), .into(),
), ),
_ => Err(type_error("Unknown padding")), _ => Err(type_error("Unknown padding")),
@ -372,7 +365,6 @@ pub fn op_node_sign(
match key_type { match key_type {
"rsa" => { "rsa" => {
use rsa::pkcs1v15::SigningKey; use rsa::pkcs1v15::SigningKey;
use signature::hazmat::PrehashSigner;
let key = match key_format { let key = match key_format {
"pem" => RsaPrivateKey::from_pkcs8_pem((&key).try_into()?) "pem" => RsaPrivateKey::from_pkcs8_pem((&key).try_into()?)
.map_err(|_| type_error("Invalid RSA private key"))?, .map_err(|_| type_error("Invalid RSA private key"))?,
@ -387,19 +379,19 @@ pub fn op_node_sign(
Ok( Ok(
match digest_type { match digest_type {
"sha224" => { "sha224" => {
let signing_key = SigningKey::<sha2::Sha224>::new_with_prefix(key); let signing_key = SigningKey::<sha2::Sha224>::new(key);
signing_key.sign_prehash(digest)?.to_vec() signing_key.sign_prehash(digest)?.to_vec()
} }
"sha256" => { "sha256" => {
let signing_key = SigningKey::<sha2::Sha256>::new_with_prefix(key); let signing_key = SigningKey::<sha2::Sha256>::new(key);
signing_key.sign_prehash(digest)?.to_vec() signing_key.sign_prehash(digest)?.to_vec()
} }
"sha384" => { "sha384" => {
let signing_key = SigningKey::<sha2::Sha384>::new_with_prefix(key); let signing_key = SigningKey::<sha2::Sha384>::new(key);
signing_key.sign_prehash(digest)?.to_vec() signing_key.sign_prehash(digest)?.to_vec()
} }
"sha512" => { "sha512" => {
let signing_key = SigningKey::<sha2::Sha512>::new_with_prefix(key); let signing_key = SigningKey::<sha2::Sha512>::new(key);
signing_key.sign_prehash(digest)?.to_vec() signing_key.sign_prehash(digest)?.to_vec()
} }
_ => { _ => {
@ -431,7 +423,6 @@ pub fn op_node_verify(
match key_type { match key_type {
"rsa" => { "rsa" => {
use rsa::pkcs1v15::VerifyingKey; use rsa::pkcs1v15::VerifyingKey;
use signature::hazmat::PrehashVerifier;
let key = match key_format { let key = match key_format {
"pem" => RsaPublicKey::from_public_key_pem((&key).try_into()?) "pem" => RsaPublicKey::from_public_key_pem((&key).try_into()?)
.map_err(|_| type_error("Invalid RSA public key"))?, .map_err(|_| type_error("Invalid RSA public key"))?,
@ -444,17 +435,17 @@ pub fn op_node_verify(
} }
}; };
Ok(match digest_type { Ok(match digest_type {
"sha224" => VerifyingKey::<sha2::Sha224>::new_with_prefix(key) "sha224" => VerifyingKey::<sha2::Sha224>::new(key)
.verify_prehash(digest, &signature.to_vec().try_into()?) .verify_prehash(digest, &signature.try_into()?)
.is_ok(), .is_ok(),
"sha256" => VerifyingKey::<sha2::Sha256>::new_with_prefix(key) "sha256" => VerifyingKey::<sha2::Sha256>::new(key)
.verify_prehash(digest, &signature.to_vec().try_into()?) .verify_prehash(digest, &signature.try_into()?)
.is_ok(), .is_ok(),
"sha384" => VerifyingKey::<sha2::Sha384>::new_with_prefix(key) "sha384" => VerifyingKey::<sha2::Sha384>::new(key)
.verify_prehash(digest, &signature.to_vec().try_into()?) .verify_prehash(digest, &signature.try_into()?)
.is_ok(), .is_ok(),
"sha512" => VerifyingKey::<sha2::Sha512>::new_with_prefix(key) "sha512" => VerifyingKey::<sha2::Sha512>::new(key)
.verify_prehash(digest, &signature.to_vec().try_into()?) .verify_prehash(digest, &signature.try_into()?)
.is_ok(), .is_ok(),
_ => { _ => {
return Err(type_error(format!( return Err(type_error(format!(

View file

@ -2249,26 +2249,8 @@
"hmac.https.any.worker.html": true, "hmac.https.any.worker.html": true,
"rsa_pkcs.https.any.html": true, "rsa_pkcs.https.any.html": true,
"rsa_pkcs.https.any.worker.html": true, "rsa_pkcs.https.any.worker.html": true,
"rsa_pss.https.any.html": [ "rsa_pss.https.any.html": true,
"RSA-PSS with SHA-1 and no salt verification failure with wrong saltLength", "rsa_pss.https.any.worker.html": true,
"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"
],
"eddsa.https.any.html": [ "eddsa.https.any.html": [
"Sign and verify using generated Ed448 keys.", "Sign and verify using generated Ed448 keys.",
"importVectorKeys step: EdDSA Ed448 verification", "importVectorKeys step: EdDSA Ed448 verification",