From 2a4f451c8dcb7196534a3033b8c9177f817e6100 Mon Sep 17 00:00:00 2001 From: Eric Rodrigues Pires Date: Sun, 1 Dec 2024 19:30:16 -0300 Subject: [PATCH] Fix improper RSA key conversion from `ssh_key` crate (#400) Co-authored-by: Eugene --- Cargo.toml | 2 +- cryptovec/src/platform/mod.rs | 6 ++---- russh-keys/src/agent/server.rs | 4 ++-- russh-keys/src/helpers.rs | 33 +++++++++++++++++++++++++++++++++ russh-keys/src/lib.rs | 4 ++-- russh/src/client/encrypted.rs | 6 +++--- russh/src/server/kex.rs | 4 ++-- 7 files changed, 45 insertions(+), 14 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 93944667..6c98ede3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ futures = "0.3" hmac = "0.12" log = "0.4" rand = "0.8" -rsa = "0.9" +rsa = "=0.9.6" sha1 = { version = "0.10", features = ["oid"] } sha2 = { version = "0.10", features = ["oid"] } signature = "2.2" diff --git a/cryptovec/src/platform/mod.rs b/cryptovec/src/platform/mod.rs index 03ca1099..0ffa16bc 100644 --- a/cryptovec/src/platform/mod.rs +++ b/cryptovec/src/platform/mod.rs @@ -19,18 +19,16 @@ pub use windows::{memset, mlock, munlock}; #[cfg(test)] mod tests { - use wasm_bindgen_test::wasm_bindgen_test; - use super::*; - #[wasm_bindgen_test] + #[test] fn test_memset() { let mut buf = vec![0u8; 10]; memset(buf.as_mut_ptr(), 0xff, buf.len()); assert_eq!(buf, vec![0xff; 10]); } - #[wasm_bindgen_test] + #[test] fn test_memset_partial() { let mut buf = vec![0u8; 10]; memset(buf.as_mut_ptr(), 0xff, 5); diff --git a/russh-keys/src/agent/server.rs b/russh-keys/src/agent/server.rs index 984310a1..66f5ff65 100644 --- a/russh-keys/src/agent/server.rs +++ b/russh-keys/src/agent/server.rs @@ -16,7 +16,7 @@ use tokio::time::sleep; use {std, tokio}; use super::{msg, Constraint}; -use crate::helpers::EncodedExt; +use crate::helpers::{sign_workaround, EncodedExt}; use crate::Error; #[derive(Clone)] @@ -342,7 +342,7 @@ impl Result { + Ok(match key.key_data() { + ssh_key::private::KeypairData::Rsa(rsa_keypair) => { + let pk = rsa::RsaPrivateKey::from_components( + >::try_from(&rsa_keypair.public.n)?, + >::try_from(&rsa_keypair.public.e)?, + >::try_from(&rsa_keypair.private.d)?, + vec![ + >::try_from(&rsa_keypair.private.p)?, + >::try_from(&rsa_keypair.private.q)?, + ], + )?; + let signature = signature::Signer::try_sign( + &rsa::pkcs1v15::SigningKey::::new(pk), + data, + )?; + ssh_key::Signature::new( + ssh_key::Algorithm::Rsa { + hash: Some(ssh_key::HashAlg::Sha512), + }, + ::to_vec(&signature), + )? + } + keypair => signature::Signer::try_sign(keypair, data)?, + }) +} diff --git a/russh-keys/src/lib.rs b/russh-keys/src/lib.rs index 00a8e5ce..df038a2d 100644 --- a/russh-keys/src/lib.rs +++ b/russh-keys/src/lib.rs @@ -857,7 +857,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux client.request_identities().await?; let buf = russh_cryptovec::CryptoVec::from_slice(b"blabla"); let len = buf.len(); - let buf = client.sign_request(&public, buf).await.unwrap(); + let buf = client.sign_request(public, buf).await.unwrap(); let (a, b) = buf.split_at(len); match key.public_key().key_data() { @@ -943,7 +943,7 @@ Cog3JMeTrb3LiPHgN6gU2P30MRp6L1j1J/MtlOAr5rux client.request_identities().await.unwrap(); let buf = russh_cryptovec::CryptoVec::from_slice(b"blabla"); let len = buf.len(); - let buf = client.sign_request(&public, buf).await.unwrap(); + let buf = client.sign_request(public, buf).await.unwrap(); let (a, b) = buf.split_at(len); if let ssh_key::public::KeyData::Ed25519 { .. } = public.key_data() { let sig = &b[b.len() - 64..]; diff --git a/russh/src/client/encrypted.rs b/russh/src/client/encrypted.rs index 489fc524..8fe978e2 100644 --- a/russh/src/client/encrypted.rs +++ b/russh/src/client/encrypted.rs @@ -18,7 +18,7 @@ use std::num::Wrapping; use bytes::Bytes; use log::{debug, error, info, trace, warn}; -use russh_keys::helpers::{map_err, EncodedExt}; +use russh_keys::helpers::{map_err, sign_workaround, EncodedExt}; use ssh_encoding::{Decode, Encode}; use crate::cert::PublicKeyOrCertificate; @@ -1049,7 +1049,7 @@ impl Encrypted { )?; // Extend with self-signature. - let signature = signature::Signer::try_sign(&**key, buffer)?; + let signature = sign_workaround(key, buffer)?; signature.encoded()?.encode(&mut *buffer)?; push_packet!(self.write, { @@ -1065,7 +1065,7 @@ impl Encrypted { )?; // Extend with self-signature. - let signature = signature::Signer::try_sign(&**key, buffer)?; + let signature = sign_workaround(key, buffer)?; signature.encoded()?.encode(&mut *buffer)?; push_packet!(self.write, { diff --git a/russh/src/server/kex.rs b/russh/src/server/kex.rs index 85a4a5d0..0f34a34b 100644 --- a/russh/src/server/kex.rs +++ b/russh/src/server/kex.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use std::ops::DerefMut; use log::debug; -use russh_keys::helpers::EncodedExt; +use russh_keys::helpers::{sign_workaround, EncodedExt}; use ssh_encoding::Encode; use super::*; @@ -145,7 +145,7 @@ impl KexDh { debug!("hash: {:?}", hash); debug!("key: {:?}", config.keys[kexdhdone.key]); - let signature = signature::Signer::try_sign(&config.keys[kexdhdone.key], &hash)?; + let signature = sign_workaround(&config.keys[kexdhdone.key], &hash)?; signature.encoded()?.encode(&mut *buffer)?; cipher.write(&buffer, write_buffer);