From 252eacdfa1c8faf72bc5131b71d946473197bc95 Mon Sep 17 00:00:00 2001 From: Stephane N Date: Thu, 7 Sep 2023 14:57:35 +0200 Subject: [PATCH 1/6] Bump dependencies except aes for ctr feature --- Cargo.toml | 12 ++++++------ src/algorithm/public_key/rsa.rs | 9 +++++---- src/channel/backend/channel_scp.rs | 6 +++--- src/channel/local/channel_scp.rs | 6 +++--- src/client/client_auth.rs | 2 +- src/client/client_kex.rs | 8 ++++---- src/config/auth.rs | 9 +++++---- src/model/data.rs | 4 ++-- src/session/mod.rs | 2 +- 9 files changed, 30 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 5b85f07..f532ef5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,16 +22,16 @@ dangerous-dh-group1-sha1 = [] log = "0.4" rand = "0.8" num-bigint = { version = "0.4", features = ["rand"] } -strum = "0.24" -strum_macros = "0.24" +strum = "0.25" +strum_macros = "0.25" # the crate rsa has removed the internal hash implement from 0.7.0 sha1 = { version = "0.10.5", default-features = false, features = ["oid"], optional = true } sha2 = { version = "0.10.6", default-features = false, features = ["oid"]} -rsa = "^0.7" +rsa = "0.9" aes = { version = "0.7", features = ["ctr"] } -ssh-key = { version = "0.5.1", features = ["rsa", "ed25519"]} -signature = "1.6.4" -ring = "0.16.20" +ssh-key = { version = "0.6", features = ["rsa", "ed25519", "alloc"]} +signature = "2.1" +ring = "0.16" filetime = "0.2" # async diff --git a/src/algorithm/public_key/rsa.rs b/src/algorithm/public_key/rsa.rs index 9f12305..4e6a958 100644 --- a/src/algorithm/public_key/rsa.rs +++ b/src/algorithm/public_key/rsa.rs @@ -1,7 +1,8 @@ use crate::algorithm::public_key::PublicKey as PubK; use crate::model::Data; use crate::SshError; -use rsa::PublicKey; +//use rsa::PublicKey; +use rsa::pkcs1v15::Pkcs1v15Sign; pub(super) struct RsaSha256; @@ -20,7 +21,7 @@ impl PubK for RsaSha256 { let e = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let n = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let public_key = rsa::RsaPublicKey::new(n, e).unwrap(); - let scheme = rsa::PaddingScheme::new_pkcs1v15_sign::(); + let scheme = Pkcs1v15Sign::new::(); let digest = ring::digest::digest(&ring::digest::SHA256, message); let msg = digest.as_ref(); @@ -46,7 +47,7 @@ impl PubK for RsaSha512 { let e = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let n = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let public_key = rsa::RsaPublicKey::new(n, e).unwrap(); - let scheme = rsa::PaddingScheme::new_pkcs1v15_sign::(); + let scheme = Pkcs1v15Sign::new::(); let digest = ring::digest::digest(&ring::digest::SHA512, message); let msg = digest.as_ref(); @@ -73,7 +74,7 @@ impl PubK for RsaSha1 { let e = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let n = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let public_key = rsa::RsaPublicKey::new(n, e).unwrap(); - let scheme = rsa::PaddingScheme::new_pkcs1v15_sign::(); + let scheme = Pkcs1v15Sign::new::(); let digest = ring::digest::digest(&ring::digest::SHA1_FOR_LEGACY_USE_ONLY, message); let msg = digest.as_ref(); diff --git a/src/channel/backend/channel_scp.rs b/src/channel/backend/channel_scp.rs index 93f5263..58b3759 100644 --- a/src/channel/backend/channel_scp.rs +++ b/src/channel/backend/channel_scp.rs @@ -154,7 +154,7 @@ impl ScpBroker { Ok(()) } - fn send_file(&mut self, scp_file: &mut ScpFile) -> SshResult<()> { + fn send_file(&mut self, scp_file: &ScpFile) -> SshResult<()> { let mut file = match File::open(scp_file.local_path.as_path()) { Ok(f) => f, // 文件打开异常,不影响后续操作 @@ -394,7 +394,7 @@ impl ScpBroker { self.save_file(scp_file) } - fn save_file(&mut self, scp_file: &mut ScpFile) -> SshResult<()> { + fn save_file(&mut self, scp_file: &ScpFile) -> SshResult<()> { log::debug!( "name: [{}] size: [{}] type: [file] start download.", scp_file.name, @@ -466,7 +466,7 @@ impl ScpBroker { } #[cfg(any(target_os = "linux", target_os = "macos"))] - fn sync_permissions(&self, scp_file: &mut ScpFile, file: fs::File) { + fn sync_permissions(&self, scp_file: &ScpFile, file: fs::File) { let modify_time = filetime::FileTime::from_unix_time(scp_file.modify_time, 0); let access_time = filetime::FileTime::from_unix_time(scp_file.access_time, 0); if let Err(e) = diff --git a/src/channel/local/channel_scp.rs b/src/channel/local/channel_scp.rs index 2410e2e..472b554 100644 --- a/src/channel/local/channel_scp.rs +++ b/src/channel/local/channel_scp.rs @@ -156,7 +156,7 @@ where Ok(()) } - fn send_file(&mut self, scp_file: &mut ScpFile) -> SshResult<()> { + fn send_file(&mut self, scp_file: &ScpFile) -> SshResult<()> { let mut file = match File::open(scp_file.local_path.as_path()) { Ok(f) => f, // 文件打开异常,不影响后续操作 @@ -388,7 +388,7 @@ where self.save_file(scp_file) } - fn save_file(&mut self, scp_file: &mut ScpFile) -> SshResult<()> { + fn save_file(&mut self, scp_file: &ScpFile) -> SshResult<()> { log::debug!( "name: [{}] size: [{}] type: [file] start download.", scp_file.name, @@ -460,7 +460,7 @@ where } #[cfg(any(target_os = "linux", target_os = "macos"))] - fn sync_permissions(&self, scp_file: &mut ScpFile, file: fs::File) { + fn sync_permissions(&self, scp_file: &ScpFile, file: fs::File) { let modify_time = filetime::FileTime::from_unix_time(scp_file.modify_time, 0); let access_time = filetime::FileTime::from_unix_time(scp_file.access_time, 0); if let Err(e) = diff --git a/src/client/client_auth.rs b/src/client/client_auth.rs index 52cbd33..86aeb18 100644 --- a/src/client/client_auth.rs +++ b/src/client/client_auth.rs @@ -10,7 +10,7 @@ use crate::{ use super::Client; impl Client { - pub fn do_auth(&mut self, stream: &mut S, digest: &mut Digest) -> SshResult<()> + pub fn do_auth(&mut self, stream: &mut S, digest: &Digest) -> SshResult<()> where S: Read + Write, { diff --git a/src/client/client_kex.rs b/src/client/client_kex.rs index bac9de3..24a7f12 100644 --- a/src/client/client_kex.rs +++ b/src/client/client_kex.rs @@ -46,13 +46,13 @@ impl Client { self.send_qc(stream, key_exchange.get_public_key())?; // host key algorithm - let mut public_key = public_key::from(&negotiated.public_key[0]); + let public_key = public_key::from(&negotiated.public_key[0]); // generate session id let session_id = { let session_id = self.verify_signature_and_new_keys( stream, - &mut public_key, + &public_key, &mut key_exchange, &mut digest.hash_ctx, )?; @@ -100,7 +100,7 @@ impl Client { fn verify_signature_and_new_keys( &mut self, stream: &mut S, - public_key: &mut Box, + public_key: &Box, key_exchange: &mut Box, h: &mut HashCtx, ) -> SshResult> @@ -138,7 +138,7 @@ impl Client { &mut self, mut data: Data, h: &mut HashCtx, - key_exchange: &mut Box, + key_exchange: &Box, ) -> SshResult> { let ks = data.get_u8s(); h.set_k_s(&ks); diff --git a/src/config/auth.rs b/src/config/auth.rs index 2cdf88e..d578efc 100644 --- a/src/config/auth.rs +++ b/src/config/auth.rs @@ -5,7 +5,8 @@ use crate::algorithm::{ use crate::model::Data; use crate::{SshError, SshResult}; use rsa::pkcs1::DecodeRsaPrivateKey; -use rsa::PublicKeyParts; +use rsa::pkcs1v15::Pkcs1v15Sign; +use rsa::traits::PublicKeyParts; use std::fmt::Debug; use std::fs::File; use std::io::Read; @@ -93,16 +94,16 @@ impl KeyPair { KeyType::PemRsa | KeyType::SshRsa => { let (scheme, digest) = match alg { PubKey::RsaSha2_512 => ( - rsa::PaddingScheme::new_pkcs1v15_sign::(), + Pkcs1v15Sign::new::(), ring::digest::digest(&ring::digest::SHA512, sd), ), PubKey::RsaSha2_256 => ( - rsa::PaddingScheme::new_pkcs1v15_sign::(), + Pkcs1v15Sign::new::(), ring::digest::digest(&ring::digest::SHA256, sd), ), #[cfg(feature = "dangerous-rsa-sha1")] PubKey::SshRsa => ( - rsa::PaddingScheme::new_pkcs1v15_sign::(), + Pkcs1v15Sign::new::(), ring::digest::digest(&ring::digest::SHA1_FOR_LEGACY_USE_ONLY, sd), ), _ => unreachable!(), diff --git a/src/model/data.rs b/src/model/data.rs index 09e46f1..2fde405 100644 --- a/src/model/data.rs +++ b/src/model/data.rs @@ -122,14 +122,14 @@ impl Data { // 获取32位无符号整型 pub fn get_u32(&mut self) -> u32 { - let u32_buf = self.0.drain(..4).into_iter().collect::>(); + let u32_buf = self.0.drain(..4).collect::>(); u32::from_be_bytes(u32_buf.try_into().unwrap()) } // 获取字节数组 pub fn get_u8s(&mut self) -> Vec { let len = self.get_u32() as usize; - let bytes = self.0.drain(..len).into_iter().collect::>(); + let bytes = self.0.drain(..len).collect::>(); bytes } diff --git a/src/session/mod.rs b/src/session/mod.rs index b9a22fc..abf24f5 100644 --- a/src/session/mod.rs +++ b/src/session/mod.rs @@ -76,7 +76,7 @@ where digest.hash_ctx.set_i_s(server_algs.get_inner()); let server_algs = AlgList::unpack(server_algs)?; client.key_agreement(&mut stream, server_algs, &mut digest)?; - client.do_auth(&mut stream, &mut digest)?; + client.do_auth(&mut stream, &digest)?; Ok(Self { inner: SessionState::Connected(client, stream), }) From 3b4e5c412fa12019328e8ef8ab25f75deefb4148 Mon Sep 17 00:00:00 2001 From: Stephane N Date: Fri, 8 Sep 2023 08:01:54 +0200 Subject: [PATCH 2/6] Revert mutability --- src/channel/backend/channel_scp.rs | 2 +- src/client/client_kex.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/channel/backend/channel_scp.rs b/src/channel/backend/channel_scp.rs index 58b3759..7b04fed 100644 --- a/src/channel/backend/channel_scp.rs +++ b/src/channel/backend/channel_scp.rs @@ -449,7 +449,7 @@ impl ScpBroker { } #[cfg(windows)] - fn sync_permissions(&self, scp_file: &mut ScpFile) { + fn sync_permissions(&self, scp_file: &ScpFile) { let modify_time = filetime::FileTime::from_unix_time(scp_file.modify_time, 0); let access_time = filetime::FileTime::from_unix_time(scp_file.access_time, 0); if let Err(e) = diff --git a/src/client/client_kex.rs b/src/client/client_kex.rs index 24a7f12..bac9de3 100644 --- a/src/client/client_kex.rs +++ b/src/client/client_kex.rs @@ -46,13 +46,13 @@ impl Client { self.send_qc(stream, key_exchange.get_public_key())?; // host key algorithm - let public_key = public_key::from(&negotiated.public_key[0]); + let mut public_key = public_key::from(&negotiated.public_key[0]); // generate session id let session_id = { let session_id = self.verify_signature_and_new_keys( stream, - &public_key, + &mut public_key, &mut key_exchange, &mut digest.hash_ctx, )?; @@ -100,7 +100,7 @@ impl Client { fn verify_signature_and_new_keys( &mut self, stream: &mut S, - public_key: &Box, + public_key: &mut Box, key_exchange: &mut Box, h: &mut HashCtx, ) -> SshResult> @@ -138,7 +138,7 @@ impl Client { &mut self, mut data: Data, h: &mut HashCtx, - key_exchange: &Box, + key_exchange: &mut Box, ) -> SshResult> { let ks = data.get_u8s(); h.set_k_s(&ks); From 479569029481bbf56b2ed447e819e0e032decad7 Mon Sep 17 00:00:00 2001 From: Stephane N Date: Fri, 8 Sep 2023 08:02:50 +0200 Subject: [PATCH 3/6] Fix default impl --- src/config/auth.rs | 8 +++----- src/config/version.rs | 8 +++----- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/config/auth.rs b/src/config/auth.rs index d578efc..b06a73e 100644 --- a/src/config/auth.rs +++ b/src/config/auth.rs @@ -155,17 +155,15 @@ impl KeyPair { } #[derive(Clone)] +#[derive(Default)] pub(super) enum KeyType { + #[default] PemRsa, SshRsa, SshEd25519, } -impl Default for KeyType { - fn default() -> Self { - KeyType::PemRsa - } -} + #[derive(Clone, Default)] pub(crate) struct AuthInfo { diff --git a/src/config/version.rs b/src/config/version.rs index 7845142..5488734 100644 --- a/src/config/version.rs +++ b/src/config/version.rs @@ -11,17 +11,15 @@ type OurVer = String; type ServerVer = String; #[derive(Debug, Clone)] +#[derive(Default)] pub(crate) enum SshVersion { V1, V2(OurVer, ServerVer), + #[default] Unknown, } -impl Default for SshVersion { - fn default() -> Self { - SshVersion::Unknown - } -} + fn read_version(stream: &mut S, tm: Option) -> SshResult> where From 003e6bda6e154937aa05d2d885c9ff5ff062afc7 Mon Sep 17 00:00:00 2001 From: Stephane N Date: Fri, 8 Sep 2023 08:08:34 +0200 Subject: [PATCH 4/6] Onliner clone and default derives --- src/config/auth.rs | 5 +---- src/config/version.rs | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/config/auth.rs b/src/config/auth.rs index b06a73e..132e587 100644 --- a/src/config/auth.rs +++ b/src/config/auth.rs @@ -154,8 +154,7 @@ impl KeyPair { } } -#[derive(Clone)] -#[derive(Default)] +#[derive(Clone, Default)] pub(super) enum KeyType { #[default] PemRsa, @@ -163,8 +162,6 @@ pub(super) enum KeyType { SshEd25519, } - - #[derive(Clone, Default)] pub(crate) struct AuthInfo { pub username: String, diff --git a/src/config/version.rs b/src/config/version.rs index 5488734..0969f06 100644 --- a/src/config/version.rs +++ b/src/config/version.rs @@ -10,8 +10,7 @@ use crate::{ type OurVer = String; type ServerVer = String; -#[derive(Debug, Clone)] -#[derive(Default)] +#[derive(Debug, Clone, Default)] pub(crate) enum SshVersion { V1, V2(OurVer, ServerVer), @@ -19,8 +18,6 @@ pub(crate) enum SshVersion { Unknown, } - - fn read_version(stream: &mut S, tm: Option) -> SshResult> where S: Read, From 9e0890af270ff5e421b9f38b9b9c9986c98d3fc1 Mon Sep 17 00:00:00 2001 From: Jovi Hsu Date: Sun, 10 Sep 2023 12:18:25 +0000 Subject: [PATCH 5/6] fix workflows --- build_check.sh | 8 ++++++++ changelog | 3 ++- src/algorithm/public_key/rsa.rs | 2 +- src/channel/local/channel_scp.rs | 2 +- src/config/auth.rs | 2 +- 5 files changed, 13 insertions(+), 4 deletions(-) diff --git a/build_check.sh b/build_check.sh index 30eb09a..e30e664 100644 --- a/build_check.sh +++ b/build_check.sh @@ -5,6 +5,14 @@ cargo fmt --all -- --check > /dev/null echo done echo echo +echo clippy check +cargo clippy -- -D warnings > /dev/null +echo +echo +echo clippy all check +cargo clippy --all-features -- -D warnings > /dev/null +echo +echo echo linux build check cargo build --target x86_64-unknown-linux-gnu > /dev/null echo done diff --git a/changelog b/changelog index 1813849..5d3434f 100644 --- a/changelog +++ b/changelog @@ -1,9 +1,10 @@ -v0.3.3 (TBD) +v0.3.3 (2023-09-10) 1. fix hang when tcp connects to a non-existent host 2. refactor aes_ctr file 3. translate the changelogs 4. use std::time::Duration as timeout rather than u128 5. add the support for ssh message `SSH_MSG_CHANNEL_EXTENDED_DATA` + 6. bump dependencies except aes for ctr feature v0.3.2 (2023-01-10) 1. fix some error with hmac2 diff --git a/src/algorithm/public_key/rsa.rs b/src/algorithm/public_key/rsa.rs index 4e6a958..5c901a1 100644 --- a/src/algorithm/public_key/rsa.rs +++ b/src/algorithm/public_key/rsa.rs @@ -47,7 +47,7 @@ impl PubK for RsaSha512 { let e = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let n = rsa::BigUint::from_bytes_be(data.get_u8s().as_slice()); let public_key = rsa::RsaPublicKey::new(n, e).unwrap(); - let scheme = Pkcs1v15Sign::new::(); + let scheme = Pkcs1v15Sign::new::(); let digest = ring::digest::digest(&ring::digest::SHA512, message); let msg = digest.as_ref(); diff --git a/src/channel/local/channel_scp.rs b/src/channel/local/channel_scp.rs index 472b554..7da2208 100644 --- a/src/channel/local/channel_scp.rs +++ b/src/channel/local/channel_scp.rs @@ -388,7 +388,7 @@ where self.save_file(scp_file) } - fn save_file(&mut self, scp_file: &ScpFile) -> SshResult<()> { + fn save_file(&mut self, scp_file: &mut ScpFile) -> SshResult<()> { log::debug!( "name: [{}] size: [{}] type: [file] start download.", scp_file.name, diff --git a/src/config/auth.rs b/src/config/auth.rs index 132e587..8314258 100644 --- a/src/config/auth.rs +++ b/src/config/auth.rs @@ -98,7 +98,7 @@ impl KeyPair { ring::digest::digest(&ring::digest::SHA512, sd), ), PubKey::RsaSha2_256 => ( - Pkcs1v15Sign::new::(), + Pkcs1v15Sign::new::(), ring::digest::digest(&ring::digest::SHA256, sd), ), #[cfg(feature = "dangerous-rsa-sha1")] From e7415dd203edfaf64106714086d9e532831b1bc1 Mon Sep 17 00:00:00 2001 From: Jovi Hsu Date: Sun, 10 Sep 2023 13:23:45 +0000 Subject: [PATCH 6/6] bump aes to 0.8, fix workflows --- .github/workflows/build.yml | 2 +- Cargo.toml | 3 ++- changelog | 2 +- src/algorithm/encryption/aes_ctr.rs | 18 +++++++++++------- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2eacfee..912ad3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -98,6 +98,6 @@ jobs: - name: run ssh run: mkdir /run/sshd && /usr/sbin/sshd -T &&/usr/sbin/sshd -D -p 8888 & - name: Test - run: cargo test --all-features + run: cargo test --all-features -- --test-threads 1 - name: Doc test run: cargo test --doc --all-features \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index f532ef5..abd9586 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,8 @@ strum_macros = "0.25" sha1 = { version = "0.10.5", default-features = false, features = ["oid"], optional = true } sha2 = { version = "0.10.6", default-features = false, features = ["oid"]} rsa = "0.9" -aes = { version = "0.7", features = ["ctr"] } +aes = "0.8" +ctr = "0.9" ssh-key = { version = "0.6", features = ["rsa", "ed25519", "alloc"]} signature = "2.1" ring = "0.16" diff --git a/changelog b/changelog index 5d3434f..f25ec4c 100644 --- a/changelog +++ b/changelog @@ -4,7 +4,7 @@ v0.3.3 (2023-09-10) 3. translate the changelogs 4. use std::time::Duration as timeout rather than u128 5. add the support for ssh message `SSH_MSG_CHANNEL_EXTENDED_DATA` - 6. bump dependencies except aes for ctr feature + 6. bump dependencies v0.3.2 (2023-01-10) 1. fix some error with hmac2 diff --git a/src/algorithm/encryption/aes_ctr.rs b/src/algorithm/encryption/aes_ctr.rs index 9b163df..e2d9976 100644 --- a/src/algorithm/encryption/aes_ctr.rs +++ b/src/algorithm/encryption/aes_ctr.rs @@ -3,8 +3,12 @@ use crate::algorithm::hash::Hash; use crate::algorithm::mac::Mac; use crate::error::SshError; use crate::SshResult; -use aes::cipher::{NewCipher, StreamCipher, StreamCipherSeek}; -use aes::{Aes128Ctr, Aes192Ctr, Aes256Ctr}; +use aes::cipher::{KeyIvInit, StreamCipher, StreamCipherSeek}; +use ctr; + +type Aes128Ctr64BE = ctr::Ctr64BE; +type Aes192Ctr64BE = ctr::Ctr64BE; +type Aes256Ctr64BE = ctr::Ctr64BE; const CTR128_BLOCK_SIZE: usize = 16; const CTR192_BLOCK_SIZE: usize = 24; @@ -65,8 +69,8 @@ macro_rules! crate_aes { siv.clone_from_slice(&hash.iv_s_c[..$iv_size]); // TODO unwrap - let c = $alg::new_from_slices(&ckey, &civ).unwrap(); - let r = $alg::new_from_slices(&skey, &siv).unwrap(); + let c = $alg::new(&ckey.into(), &civ.into()); + let r = $alg::new(&skey.into(), &siv.into()); // hmac let (ik_c_s, ik_s_c) = hash.mix_ik(mac.bsize()); $name { @@ -133,8 +137,8 @@ macro_rules! crate_aes { } // aes-128-ctr -crate_aes!(Ctr128, Aes128Ctr, CTR128_BLOCK_SIZE, IV_SIZE); +crate_aes!(Ctr128, Aes128Ctr64BE, CTR128_BLOCK_SIZE, IV_SIZE); // aes-192-ctr -crate_aes!(Ctr192, Aes192Ctr, CTR192_BLOCK_SIZE, IV_SIZE); +crate_aes!(Ctr192, Aes192Ctr64BE, CTR192_BLOCK_SIZE, IV_SIZE); // aes-256-ctr -crate_aes!(Ctr256, Aes256Ctr, CTR256_BLOCK_SIZE, IV_SIZE); +crate_aes!(Ctr256, Aes256Ctr64BE, CTR256_BLOCK_SIZE, IV_SIZE);