diff --git a/Cargo.lock b/Cargo.lock index d2ea8c7a..9ee9f574 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -100,9 +100,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" +checksum = "722e23542a15cea1f65d4a1419c4cfd7a26706c70871a13a04238ca3f40f1661" [[package]] name = "cpufeatures" @@ -115,9 +115,9 @@ dependencies = [ [[package]] name = "crypto-bigint" -version = "0.3.2" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c6a1d5fa1de37e071642dfa44ec552ca5b299adb128fab16138e24b548fd21" +checksum = "9f2b443d17d49dad5ef0ede301c3179cc923b8822f3393b4d2c28c269dd4a122" dependencies = [ "generic-array", "rand_core 0.6.4", @@ -135,16 +135,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "ctr" version = "0.9.1" @@ -169,13 +159,13 @@ dependencies = [ [[package]] name = "der" -version = "0.5.1" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6919815d73839e7ad218de758883aae3a257ba6759ce7a9992501efbb53d705c" +checksum = "13dd2ae565c0a381dde7fade45fce95984c568bdcb4700a4fdbe3175e0380b2f" dependencies = [ "const-oid", - "crypto-bigint", - "pem-rfc7468 0.3.1", + "pem-rfc7468", + "zeroize", ] [[package]] @@ -194,15 +184,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adfbc57365a37acbd2ebf2b64d7e69bb766e2fea813521ed536f5d0520dcf86c" dependencies = [ "block-buffer 0.10.3", + "const-oid", "crypto-common", "subtle", ] [[package]] name = "ecdsa" -version = "0.13.4" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0d69ae62e0ce582d56380743515fefaf1a8c70cec685d9677636d7e30ae9dc9" +checksum = "85789ce7dfbd0f0624c07ef653a08bb2ebf43d3e16531361f46d36dd54334fed" dependencies = [ "der", "elliptic-curve", @@ -233,13 +224,14 @@ dependencies = [ [[package]] name = "elliptic-curve" -version = "0.11.12" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b477563c2bfed38a3b7a60964c49e058b2510ad3f12ba3483fd8f62c2306d6" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ "base16ct", "crypto-bigint", "der", + "digest 0.10.5", "ff", "generic-array", "group", @@ -260,9 +252,9 @@ dependencies = [ [[package]] name = "ff" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +checksum = "df689201f395c6b90dfe87127685f8dbfc083a5e779e613575d8bd7314300c3e" dependencies = [ "rand_core 0.6.4", "subtle", @@ -291,9 +283,9 @@ dependencies = [ [[package]] name = "group" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +checksum = "7391856def869c1c81063a03457c676fbcd419709c3dfb33d8d319de484b154d" dependencies = [ "ff", "rand_core 0.6.4", @@ -308,12 +300,11 @@ checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] name = "hmac" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "crypto-mac", - "digest 0.9.0", + "digest 0.10.5", ] [[package]] @@ -411,14 +402,13 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "p256" -version = "0.10.1" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19736d80675fbe9fe33426268150b951a3fb8f5cfca2a23a17c85ef3adb24e3b" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" dependencies = [ "ecdsa", "elliptic-curve", - "sec1", - "sha2 0.9.9", + "sha2 0.10.6", ] [[package]] @@ -430,15 +420,6 @@ dependencies = [ "digest 0.10.5", ] -[[package]] -name = "pem-rfc7468" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01de5d978f34aa4b2296576379fcc416034702fd94117c56ffd8a1a767cefb30" -dependencies = [ - "base64ct", -] - [[package]] name = "pem-rfc7468" version = "0.6.0" @@ -450,9 +431,9 @@ dependencies = [ [[package]] name = "pkcs1" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78f66c04ccc83dd4486fd46c33896f4e17b24a7a3a6400dedc48ed0ddd72320" +checksum = "2e3a81571d9455414f4d59ce2830bc9d2654e2efc5460fd67b0e0a6a36b6753a" dependencies = [ "der", "pkcs8", @@ -461,13 +442,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cabda3fb821068a9a4fab19a683eac3af12edf0f34b94a8be53c4972b8149d0" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ "der", "spki", - "zeroize", ] [[package]] @@ -549,9 +529,9 @@ dependencies = [ [[package]] name = "rfc6979" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96ef608575f6392792f9ecf7890c00086591d29a83910939d430753f7c050525" +checksum = "88c86280f057430a52f4861551b092a01b419b8eacefc7c995eacb9dc132fe32" dependencies = [ "crypto-bigint", "hmac", @@ -560,9 +540,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.6.1" +version = "0.7.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf22754c49613d2b3b119f0e5d46e34a2c628a937e3024b8762de4e7d8c710b" +checksum = "237a0c597c9fdb501f592f52e8ab754dc43787dd8a8bf20c191f562817d50b08" dependencies = [ "byteorder", "digest 0.10.5", @@ -573,6 +553,7 @@ dependencies = [ "pkcs1", "pkcs8", "rand_core 0.6.4", + "signature", "smallvec", "subtle", "zeroize", @@ -580,10 +561,11 @@ dependencies = [ [[package]] name = "sec1" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08da66b8b0965a5555b6bd6639e68ccba85e1e2506f5fbb089e93f8a04e1a2d1" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ + "base16ct", "der", "generic-array", "subtle", @@ -622,11 +604,11 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "deb766570a2825fa972bceff0d195727876a9cdf2460ab2e52d455dc2de47fd9" dependencies = [ - "digest 0.9.0", + "digest 0.10.5", "rand_core 0.6.4", ] @@ -644,9 +626,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" [[package]] name = "spki" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d01ac02a6ccf3e07db148d2be087da624fea0221a16152ed01f0496a6b0a27" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", "der", @@ -654,7 +636,7 @@ dependencies = [ [[package]] name = "ssh-key" -version = "0.4.3" +version = "0.5.0-pre" dependencies = [ "aes", "base64ct", @@ -663,7 +645,7 @@ dependencies = [ "ed25519-dalek", "hex-literal", "p256", - "pem-rfc7468 0.6.0", + "pem-rfc7468", "rand_chacha", "rand_core 0.6.4", "rsa", diff --git a/ssh-key/Cargo.toml b/ssh-key/Cargo.toml index 03101200..dba3c9b8 100644 --- a/ssh-key/Cargo.toml +++ b/ssh-key/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssh-key" -version = "0.4.3" +version = "0.5.0-pre" description = """ Pure Rust implementation of SSH key file format decoders/encoders as described in RFC4251 and RFC4253 as well as the OpenSSH key formats, certificates @@ -27,12 +27,12 @@ aes = { version = "0.8", optional = true, default-features = false } ctr = { version = "0.9", optional = true, default-features = false } bcrypt-pbkdf = { version = "0.9", optional = true, default-features = false } ed25519-dalek = { version = "1.0.1", optional = true, default-features = false, features = ["u64_backend"] } -p256 = { version = "0.10", optional = true, default-features = false, features = ["ecdsa"] } +p256 = { version = "0.11", optional = true, default-features = false, features = ["ecdsa"] } rand_core = { version = "0.6", optional = true, default-features = false } -rsa = { version = "0.6.1", optional = true } -sec1 = { version = "0.2", optional = true, default-features = false } +rsa = { version = "=0.7.0-rc.0", optional = true } +sec1 = { version = "0.3", optional = true, default-features = false, features = ["point"] } serde = { version = "1", optional = true } -sha2 = { version = "0.10", optional = true, default-features = false } +sha2 = { version = "0.10.6", optional = true, default-features = false, features = ["oid"] } signature = { version = "1.3.1", optional = true, default-features = false } subtle = { version = "2", optional = true, default-features = false } diff --git a/ssh-key/src/private.rs b/ssh-key/src/private.rs index 2dd6bb09..7917cdd5 100644 --- a/ssh-key/src/private.rs +++ b/ssh-key/src/private.rs @@ -168,7 +168,7 @@ use subtle::{Choice, ConstantTimeEq}; const CONVERSION_ERROR_MSG: &str = "SSH private key conversion error"; /// Default key size to use for RSA keys in bits. -#[cfg(feature = "rsa")] +#[cfg(all(feature = "rand_core", feature = "rsa"))] const DEFAULT_RSA_KEY_SIZE: usize = 4096; /// Maximum supported block size. diff --git a/ssh-key/src/private/rsa.rs b/ssh-key/src/private/rsa.rs index 3bbdb6e1..36536e8d 100644 --- a/ssh-key/src/private/rsa.rs +++ b/ssh-key/src/private/rsa.rs @@ -11,7 +11,8 @@ use zeroize::Zeroize; use { crate::Error, rand_core::{CryptoRng, RngCore}, - rsa::PublicKeyParts, + rsa::{pkcs1v15, PublicKeyParts}, + sha2::{digest::const_oid::AssociatedOid, Digest}, }; #[cfg(feature = "subtle")] @@ -194,7 +195,7 @@ impl TryFrom<&RsaKeypair> for rsa::RsaPrivateKey { rsa::BigUint::try_from(&key.private.p)?, rsa::BigUint::try_from(&key.private.p)?, ], - ); + )?; if ret.size().saturating_mul(8) >= RsaKeypair::MIN_KEY_SIZE { Ok(ret) @@ -242,6 +243,19 @@ impl TryFrom<&rsa::RsaPrivateKey> for RsaKeypair { } } +#[cfg(feature = "rsa")] +#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))] +impl TryFrom<&RsaKeypair> for pkcs1v15::SigningKey +where + D: Digest + AssociatedOid, +{ + type Error = Error; + + fn try_from(keypair: &RsaKeypair) -> Result> { + Ok(pkcs1v15::SigningKey::new_with_prefix(keypair.try_into()?)) + } +} + #[cfg(feature = "subtle")] #[cfg_attr(docsrs, doc(cfg(feature = "subtle")))] impl ConstantTimeEq for RsaKeypair { diff --git a/ssh-key/src/public/rsa.rs b/ssh-key/src/public/rsa.rs index 245e7d6e..26c95b9d 100644 --- a/ssh-key/src/public/rsa.rs +++ b/ssh-key/src/public/rsa.rs @@ -8,7 +8,8 @@ use crate::{ #[cfg(feature = "rsa")] use { crate::{private::RsaKeypair, Error}, - rsa::PublicKeyParts, + rsa::{pkcs1v15, PublicKeyParts}, + sha2::{digest::const_oid::AssociatedOid, Digest}, }; /// RSA public key. @@ -101,3 +102,16 @@ impl TryFrom<&rsa::RsaPublicKey> for RsaPublicKey { }) } } + +#[cfg(feature = "rsa")] +#[cfg_attr(docsrs, doc(cfg(feature = "rsa")))] +impl TryFrom<&RsaPublicKey> for pkcs1v15::VerifyingKey +where + D: Digest + AssociatedOid, +{ + type Error = Error; + + fn try_from(key: &RsaPublicKey) -> Result> { + Ok(pkcs1v15::VerifyingKey::new_with_prefix(key.try_into()?)) + } +} diff --git a/ssh-key/src/signature.rs b/ssh-key/src/signature.rs index 1afdd0bb..a8e24068 100644 --- a/ssh-key/src/signature.rs +++ b/ssh-key/src/signature.rs @@ -21,8 +21,7 @@ use crate::{ #[cfg(feature = "rsa")] use { crate::{private::RsaKeypair, public::RsaPublicKey, HashAlg}, - rsa::PublicKey as _, - sha2::{Digest, Sha256, Sha512}, + sha2::{Sha256, Sha512}, }; const DSA_SIGNATURE_SIZE: usize = 40; @@ -399,19 +398,15 @@ impl Verifier for EcdsaPublicKey { #[cfg_attr(docsrs, doc(cfg(feature = "rsa")))] impl Signer for RsaKeypair { fn try_sign(&self, message: &[u8]) -> signature::Result { - let padding = rsa::padding::PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_512), - }; - let digest = sha2::Sha512::digest(message); - let data = rsa::RsaPrivateKey::try_from(self)? - .sign(padding, digest.as_ref()) + let data = rsa::pkcs1v15::SigningKey::::try_from(self)? + .try_sign(message) .map_err(|_| signature::Error::new())?; Ok(Signature { algorithm: Algorithm::Rsa { hash: Some(HashAlg::Sha512), }, - data, + data: data.to_vec(), }) } } @@ -420,28 +415,18 @@ impl Signer for RsaKeypair { #[cfg_attr(docsrs, doc(cfg(feature = "rsa")))] impl Verifier for RsaPublicKey { fn verify(&self, message: &[u8], signature: &Signature) -> signature::Result<()> { - let key = rsa::RsaPublicKey::try_from(self)?; - match signature.algorithm { - Algorithm::Rsa { - hash: Some(HashAlg::Sha256), - } => { - let digest = Sha256::digest(message); - let padding = rsa::padding::PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_256), - }; - key.verify(padding, digest.as_ref(), signature.as_bytes()) - .map_err(|_| signature::Error::new()) - } - Algorithm::Rsa { - hash: Some(HashAlg::Sha512), - } => { - let padding = rsa::padding::PaddingScheme::PKCS1v15Sign { - hash: Some(rsa::hash::Hash::SHA2_512), - }; - let digest = Sha512::digest(message); - key.verify(padding, digest.as_ref(), signature.as_bytes()) - .map_err(|_| signature::Error::new()) + Algorithm::Rsa { hash: Some(hash) } => { + let signature = rsa::pkcs1v15::Signature::from(signature.data.clone()); + + match hash { + HashAlg::Sha256 => rsa::pkcs1v15::VerifyingKey::::try_from(self)? + .verify(message, &signature) + .map_err(|_| signature::Error::new()), + HashAlg::Sha512 => rsa::pkcs1v15::VerifyingKey::::try_from(self)? + .verify(message, &signature) + .map_err(|_| signature::Error::new()), + } } _ => Err(signature::Error::new()), }