diff --git a/Cargo.toml b/Cargo.toml index 2431faf2..b5889f69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,5 @@ [workspace] members = [ - "russh-keys", "russh", "russh-config", "cryptovec", diff --git a/russh-keys/Cargo.toml b/russh-keys/Cargo.toml deleted file mode 100644 index dc935193..00000000 --- a/russh-keys/Cargo.toml +++ /dev/null @@ -1,85 +0,0 @@ -[package] -authors = ["Pierre-Étienne Meunier "] -description = "Deal with SSH keys: load them, decrypt them, call an SSH agent." -documentation = "https://docs.rs/russh-keys" -edition = "2021" -homepage = "https://github.com/warp-tech/russh" -keywords = ["ssh"] -license = "Apache-2.0" -name = "russh-keys" -repository = "https://github.com/warp-tech/russh" -version = "0.50.0-beta.7" -rust-version = "1.65" - -[dependencies] -aes.workspace = true -async-trait.workspace = true -bytes.workspace = true -cbc = "0.1" -ctr = "0.9" -block-padding = { version = "0.3", features = ["std"] } -byteorder.workspace = true -data-encoding = "2.3" -digest.workspace = true -der = "0.7" -ecdsa = "0.16" -ed25519-dalek = { version = "2.0", features = ["rand_core", "pkcs8"] } -elliptic-curve = "0.13" -futures.workspace = true -hmac.workspace = true -inout = { version = "0.1", features = ["std"] } -log.workspace = true -md5 = "0.7" -num-integer = "0.1" -p256 = "0.13" -p384 = "0.13" -p521 = "0.13" -pbkdf2 = "0.12" -pkcs1 = "0.7" -pkcs5 = "0.7" -pkcs8 = { version = "0.10", features = ["pkcs5", "encryption"] } -rand.workspace = true -rand_core = { version = "0.6.4", features = ["std"] } -rsa.workspace = true -russh-cryptovec = { version = "0.48.0", path = "../cryptovec", features = [ - "ssh-encoding", -] } -russh-util = { version = "0.48.0", path = "../russh-util" } -sec1 = { version = "0.7", features = ["pkcs8", "der"] } -serde = { version = "1.0", features = ["derive"] } -sha1.workspace = true -sha2.workspace = true -signature.workspace = true -spki = "0.7" -ssh-encoding.workspace = true -ssh-key.workspace = true -thiserror.workspace = true -typenum = "1.17" -yasna = { version = "0.5.0", features = [ - "bit-vec", - "num-bigint", -], optional = true } -zeroize = "1.7" -getrandom = { version = "0.2.15", features = ["js"] } -tokio = { workspace = true, features = ["io-util", "time"] } - -[features] -legacy-ed25519-pkcs8-parser = ["yasna"] - -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { workspace = true, features = [ - "io-util", - "rt-multi-thread", - "time", - "net", -] } -tokio-stream.workspace = true -home.workspace = true - -[target.'cfg(windows)'.dependencies] -pageant = { version = "0.0.2", path = "../pageant" } - -[dev-dependencies] -env_logger.workspace = true -tempfile = "3.14.0" -tokio = { workspace = true, features = ["test-util", "macros", "process"] } diff --git a/russh/Cargo.toml b/russh/Cargo.toml index 6627e5fb..2909c29a 100644 --- a/russh/Cargo.toml +++ b/russh/Cargo.toml @@ -14,52 +14,87 @@ rust-version = "1.65" [features] default = ["flate2"] -legacy-ed25519-pkcs8-parser = ["russh-keys/legacy-ed25519-pkcs8-parser"] +legacy-ed25519-pkcs8-parser = ["yasna"] # Danger: 3DES cipher is insecure. des = ["dep:des"] [dependencies] -aes.workspace = true aes-gcm = "0.10" -cbc = { version = "0.1" } +aes.workspace = true async-trait.workspace = true bitflags = "2.0" +block-padding = { version = "0.3", features = ["std"] } byteorder.workspace = true bytes.workspace = true +cbc = { version = "0.1" } chacha20 = "0.9" ctr = "0.9" curve25519-dalek = "4.1.3" +data-encoding = "2.3" delegate.workspace = true digest.workspace = true +der = "0.7" +des = { version = "0.8.1", optional = true } +ecdsa = "0.16" +ed25519-dalek = { version = "2.0", features = ["rand_core", "pkcs8"] } elliptic-curve = { version = "0.13", features = ["ecdh"] } +enum_dispatch = "0.3.13" flate2 = { version = "1.0.15", optional = true } futures.workspace = true generic-array = "0.14" +getrandom = { version = "0.2.15", features = ["js"] } hex-literal = "0.4" hmac.workspace = true +inout = { version = "0.1", features = ["std"] } log.workspace = true +md5 = "0.7" num-bigint = { version = "0.4.2", features = ["rand"] } +# num-integer = "0.1" once_cell = "1.13" p256 = { version = "0.13", features = ["ecdh"] } p384 = { version = "0.13", features = ["ecdh"] } p521 = { version = "0.13", features = ["ecdh"] } +pbkdf2 = "0.12" +pkcs1 = "0.7" +pkcs5 = "0.7" +pkcs8 = { version = "0.10", features = ["pkcs5", "encryption"] } poly1305 = "0.8" +rand_core = { version = "0.6.4", features = ["getrandom", "std"] } rand.workspace = true -rand_core = { version = "0.6.4", features = ["getrandom"] } rsa.workspace = true -russh-cryptovec = { version = "0.48.0", path = "../cryptovec" } -russh-keys = { version = "0.50.0-beta.7", path = "../russh-keys" } +russh-cryptovec = { version = "0.48.0", path = "../cryptovec", features = [ + "ssh-encoding", +] } +russh-util = { version = "0.48.0", path = "../russh-util" } +sec1 = { version = "0.7", features = ["pkcs8", "der"] } sha1.workspace = true sha2.workspace = true signature.workspace = true +spki = "0.7" ssh-encoding.workspace = true ssh-key.workspace = true subtle = "2.4" thiserror.workspace = true -russh-util = { version = "0.48.0", path = "../russh-util" } -des = { version = "0.8.1", optional = true } tokio = { workspace = true, features = ["io-util", "sync", "time"] } -enum_dispatch = "0.3.13" +typenum = "1.17" +yasna = { version = "0.5.0", features = [ + "bit-vec", + "num-bigint", +], optional = true } +zeroize = "1.7" + +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tokio = { workspace = true, features = [ + "io-util", + "rt-multi-thread", + "time", + "net", +] } +tokio-stream.workspace = true +home.workspace = true + +[target.'cfg(windows)'.dependencies] +pageant = { version = "0.0.2", path = "../pageant" } [dev-dependencies] anyhow = "1.0.4" @@ -79,6 +114,7 @@ shell-escape = "0.1" tokio-fd = "0.3" termion = "2" ratatui = "0.29.0" +tempfile = "3.14.0" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] russh-sftp = "2.0.5" diff --git a/russh/examples/echoserver.rs b/russh/examples/echoserver.rs index cbb6a962..183d30cf 100644 --- a/russh/examples/echoserver.rs +++ b/russh/examples/echoserver.rs @@ -3,10 +3,9 @@ use std::sync::Arc; use async_trait::async_trait; use rand_core::OsRng; -use russh::keys::*; +use russh::keys::{Certificate, *}; use russh::server::{Msg, Server as _, Session}; use russh::*; -use russh_keys::Certificate; use tokio::sync::Mutex; #[tokio::main] @@ -20,7 +19,7 @@ async fn main() { auth_rejection_time: std::time::Duration::from_secs(3), auth_rejection_time_initial: Some(std::time::Duration::from_secs(0)), keys: vec![ - russh_keys::PrivateKey::random(&mut OsRng, russh_keys::Algorithm::Ed25519).unwrap(), + russh::keys::PrivateKey::random(&mut OsRng, russh::keys::Algorithm::Ed25519).unwrap(), ], preferred: Preferred { // kex: std::borrow::Cow::Owned(vec![russh::kex::DH_GEX_SHA256]), diff --git a/russh/examples/ratatui_app.rs b/russh/examples/ratatui_app.rs index fc6a0088..5f6ab152 100644 --- a/russh/examples/ratatui_app.rs +++ b/russh/examples/ratatui_app.rs @@ -121,7 +121,7 @@ impl AppServer { auth_rejection_time: std::time::Duration::from_secs(3), auth_rejection_time_initial: Some(std::time::Duration::from_secs(0)), keys: vec![ - russh_keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(), + russh::keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(), ], nodelay: true, ..Default::default() diff --git a/russh/examples/ratatui_shared_app.rs b/russh/examples/ratatui_shared_app.rs index 850c07be..dffa6fbd 100644 --- a/russh/examples/ratatui_shared_app.rs +++ b/russh/examples/ratatui_shared_app.rs @@ -123,7 +123,7 @@ impl AppServer { auth_rejection_time: std::time::Duration::from_secs(3), auth_rejection_time_initial: Some(std::time::Duration::from_secs(0)), keys: vec![ - russh_keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(), + russh::keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(), ], nodelay: true, ..Default::default() diff --git a/russh/examples/sftp_client.rs b/russh/examples/sftp_client.rs index b775c7d7..5e29fb79 100644 --- a/russh/examples/sftp_client.rs +++ b/russh/examples/sftp_client.rs @@ -2,8 +2,8 @@ use std::sync::Arc; use async_trait::async_trait; use log::{error, info, LevelFilter}; +use russh::keys::*; use russh::*; -use russh_keys::*; use russh_sftp::client::SftpSession; use russh_sftp::protocol::OpenFlags; use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; diff --git a/russh/examples/sftp_server.rs b/russh/examples/sftp_server.rs index 8b4ec473..f0076949 100644 --- a/russh/examples/sftp_server.rs +++ b/russh/examples/sftp_server.rs @@ -53,7 +53,7 @@ impl russh::server::Handler for SshSession { async fn auth_publickey( &mut self, user: &str, - public_key: &russh_keys::ssh_key::PublicKey, + public_key: &russh::keys::ssh_key::PublicKey, ) -> Result { info!("credentials: {}, {:?}", user, public_key); Ok(Auth::Accept) @@ -182,7 +182,7 @@ async fn main() { auth_rejection_time: Duration::from_secs(3), auth_rejection_time_initial: Some(Duration::from_secs(0)), keys: vec![ - russh_keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(), + russh::keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap(), ], ..Default::default() }; diff --git a/russh/examples/test.rs b/russh/examples/test.rs index 08a037c1..9694c9a1 100644 --- a/russh/examples/test.rs +++ b/russh/examples/test.rs @@ -15,7 +15,7 @@ async fn main() -> anyhow::Result<()> { config.auth_rejection_time = std::time::Duration::from_secs(3); config .keys - .push(russh_keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap()); + .push(russh::keys::PrivateKey::random(&mut OsRng, ssh_key::Algorithm::Ed25519).unwrap()); let config = Arc::new(config); let mut sh = Server { clients: Arc::new(Mutex::new(HashMap::new())), diff --git a/russh/src/auth.rs b/russh/src/auth.rs index 77c68102..1cdf2579 100644 --- a/russh/src/auth.rs +++ b/russh/src/auth.rs @@ -18,12 +18,12 @@ use std::str::FromStr; use std::sync::Arc; use async_trait::async_trait; -use russh_keys::helpers::NameList; -use russh_keys::key::PrivateKeyWithHashAlg; use ssh_key::{Certificate, PrivateKey}; use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; +use crate::helpers::NameList; +use crate::keys::key::PrivateKeyWithHashAlg; use crate::CryptoVec; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -163,12 +163,12 @@ pub enum AgentAuthError { #[error(transparent)] Send(#[from] crate::SendError), #[error(transparent)] - Key(#[from] russh_keys::Error), + Key(#[from] crate::keys::Error), } #[async_trait] impl Signer - for russh_keys::agent::client::AgentClient + for crate::keys::agent::client::AgentClient { type Error = AgentAuthError; diff --git a/russh/src/cert.rs b/russh/src/cert.rs index 1e6ffbd5..26cac9ba 100644 --- a/russh/src/cert.rs +++ b/russh/src/cert.rs @@ -1,11 +1,12 @@ -use russh_keys::key::PrivateKeyWithHashAlg; use ssh_key::{Certificate, HashAlg, PublicKey}; #[cfg(not(target_arch = "wasm32"))] use { - russh_keys::helpers::AlgorithmExt, ssh_encoding::Decode, ssh_key::public::KeyData, + crate::helpers::AlgorithmExt, ssh_encoding::Decode, ssh_key::public::KeyData, ssh_key::Algorithm, }; +use crate::keys::key::PrivateKeyWithHashAlg; + #[derive(Debug)] pub(crate) enum PublicKeyOrCertificate { PublicKey { diff --git a/russh/src/client/encrypted.rs b/russh/src/client/encrypted.rs index 3a3ca8cb..052d0d66 100644 --- a/russh/src/client/encrypted.rs +++ b/russh/src/client/encrypted.rs @@ -18,12 +18,12 @@ use std::ops::Deref; use bytes::Bytes; use log::{debug, error, info, trace, warn}; -use russh_keys::helpers::{map_err, sign_with_hash_alg, AlgorithmExt, EncodedExt, NameList}; use ssh_encoding::{Decode, Encode}; use super::IncomingSshPacket; use crate::cert::PublicKeyOrCertificate; use crate::client::{Handler, Msg, Prompt, Reply, Session}; +use crate::helpers::{map_err, sign_with_hash_alg, AlgorithmExt, EncodedExt, NameList}; use crate::keys::key::parse_public_key; use crate::parsing::{ChannelOpenConfirmation, ChannelType, OpenChannelMessage}; use crate::session::{Encrypted, EncryptedState, GlobalRequestResponse}; diff --git a/russh/src/client/kex.rs b/russh/src/client/kex.rs index 24627491..408612b0 100644 --- a/russh/src/client/kex.rs +++ b/russh/src/client/kex.rs @@ -5,8 +5,6 @@ use std::sync::Arc; use bytes::Bytes; use log::{debug, error, warn}; -use russh_cryptovec::CryptoVec; -use russh_keys::key::parse_public_key; use signature::Verifier; use ssh_encoding::{Decode, Encode}; use ssh_key::{Mpint, PublicKey, Signature}; @@ -15,10 +13,11 @@ use super::IncomingSshPacket; use crate::client::{Config, NewKeys}; use crate::kex::dh::groups::DhGroup; use crate::kex::{KexAlgorithm, KexAlgorithmImplementor, KexCause, KexProgress, KEXES}; +use crate::keys::key::parse_public_key; use crate::negotiation::{Names, Select}; use crate::session::Exchange; use crate::sshbuffer::PacketWriter; -use crate::{msg, negotiation, strict_kex_violation, Error, SshId}; +use crate::{msg, negotiation, strict_kex_violation, CryptoVec, Error, SshId}; thread_local! { static HASH_BUFFER: RefCell = RefCell::new(CryptoVec::new()); diff --git a/russh/src/client/mod.rs b/russh/src/client/mod.rs index 432cff46..f50830d8 100644 --- a/russh/src/client/mod.rs +++ b/russh/src/client/mod.rs @@ -45,8 +45,6 @@ use futures::task::{Context, Poll}; use futures::Future; use kex::ClientKex; use log::{debug, error, trace}; -use russh_keys::key::PrivateKeyWithHashAlg; -use russh_keys::map_err; use russh_util::time::Instant; use ssh_encoding::Decode; use ssh_key::{Certificate, PrivateKey, PublicKey}; @@ -61,13 +59,14 @@ pub use crate::auth::AuthResult; use crate::channels::{Channel, ChannelMsg, ChannelRef, WindowSizeRef}; use crate::cipher::{self, clear, OpeningKey}; use crate::kex::{KexCause, KexProgress, SessionKexState}; +use crate::keys::key::PrivateKeyWithHashAlg; use crate::msg::{is_kex_msg, validate_server_msg_strict_kex}; use crate::session::{CommonSession, EncryptedState, GlobalRequestResponse, NewKeys}; use crate::ssh_read::SshRead; use crate::sshbuffer::{IncomingSshPacket, PacketWriter, SSHBuffer, SshId}; use crate::{ - auth, msg, negotiation, ChannelId, ChannelOpenFailure, CryptoVec, Disconnect, Error, Limits, - MethodSet, Sig, + auth, map_err, msg, negotiation, ChannelId, ChannelOpenFailure, CryptoVec, Disconnect, Error, + Limits, MethodSet, Sig, }; mod encrypted; @@ -397,7 +396,7 @@ impl Handle { /// Authenticate using a custom method that implements the /// [`Signer`][auth::Signer] trait. Currently, this crate only provides an - /// implementation for an [SSH agent][russh_keys::agent::client::AgentClient]. + /// implementation for an [SSH agent][crate::keys::agent::client::AgentClient]. pub async fn authenticate_publickey_with, S: auth::Signer>( &mut self, user: U, diff --git a/russh/src/client/session.rs b/russh/src/client/session.rs index c5f38943..cfd8ec7d 100644 --- a/russh/src/client/session.rs +++ b/russh/src/client/session.rs @@ -1,11 +1,10 @@ use log::error; -use russh_keys::map_err; use ssh_encoding::Encode; use tokio::sync::oneshot; use crate::client::Session; use crate::session::EncryptedState; -use crate::{msg, ChannelId, CryptoVec, Disconnect, Pty, Sig}; +use crate::{map_err, msg, ChannelId, CryptoVec, Disconnect, Pty, Sig}; impl Session { fn channel_open_generic( diff --git a/russh-keys/src/helpers.rs b/russh/src/helpers.rs similarity index 98% rename from russh-keys/src/helpers.rs rename to russh/src/helpers.rs index 55c0ffa9..b54c5baa 100644 --- a/russh-keys/src/helpers.rs +++ b/russh/src/helpers.rs @@ -121,4 +121,4 @@ mod algorithm { #[doc(hidden)] pub use algorithm::AlgorithmExt; -use crate::key::PrivateKeyWithHashAlg; +use crate::keys::key::PrivateKeyWithHashAlg; diff --git a/russh-keys/src/agent/client.rs b/russh/src/keys/agent/client.rs similarity index 99% rename from russh-keys/src/agent/client.rs rename to russh/src/keys/agent/client.rs index e638b753..7969df8a 100644 --- a/russh-keys/src/agent/client.rs +++ b/russh/src/keys/agent/client.rs @@ -3,7 +3,6 @@ use core::str; use byteorder::{BigEndian, ByteOrder}; use bytes::Bytes; use log::debug; -use russh_cryptovec::CryptoVec; use ssh_encoding::{Decode, Encode, Reader}; use ssh_key::{Algorithm, HashAlg, PrivateKey, PublicKey, Signature}; use tokio; @@ -11,7 +10,8 @@ use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use super::{msg, Constraint}; use crate::helpers::EncodedExt; -use crate::{key, Error}; +use crate::keys::{key, Error}; +use crate::CryptoVec; pub trait AgentStream: AsyncRead + AsyncWrite {} diff --git a/russh-keys/src/agent/mod.rs b/russh/src/keys/agent/mod.rs similarity index 100% rename from russh-keys/src/agent/mod.rs rename to russh/src/keys/agent/mod.rs diff --git a/russh-keys/src/agent/msg.rs b/russh/src/keys/agent/msg.rs similarity index 100% rename from russh-keys/src/agent/msg.rs rename to russh/src/keys/agent/msg.rs diff --git a/russh-keys/src/agent/server.rs b/russh/src/keys/agent/server.rs similarity index 99% rename from russh-keys/src/agent/server.rs rename to russh/src/keys/agent/server.rs index af5543c2..50ab8f0b 100644 --- a/russh-keys/src/agent/server.rs +++ b/russh/src/keys/agent/server.rs @@ -8,7 +8,6 @@ use byteorder::{BigEndian, ByteOrder}; use bytes::Bytes; use futures::future::Future; use futures::stream::{Stream, StreamExt}; -use russh_cryptovec::CryptoVec; use ssh_encoding::{Decode, Encode, Reader}; use ssh_key::PrivateKey; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; @@ -17,8 +16,9 @@ use {std, tokio}; use super::{msg, Constraint}; use crate::helpers::{sign_with_hash_alg, EncodedExt}; -use crate::key::PrivateKeyWithHashAlg; -use crate::Error; +use crate::keys::key::PrivateKeyWithHashAlg; +use crate::keys::Error; +use crate::CryptoVec; #[derive(Clone)] #[allow(clippy::type_complexity)] diff --git a/russh-keys/src/format/mod.rs b/russh/src/keys/format/mod.rs similarity index 99% rename from russh-keys/src/format/mod.rs rename to russh/src/keys/format/mod.rs index 3fe82b18..d2e6d4e0 100644 --- a/russh-keys/src/format/mod.rs +++ b/russh/src/keys/format/mod.rs @@ -7,7 +7,7 @@ use ssh_key::private::RsaKeypair; use ssh_key::PrivateKey; use super::is_base64_char; -use crate::Error; +use crate::keys::Error; pub mod openssh; diff --git a/russh-keys/src/format/openssh.rs b/russh/src/keys/format/openssh.rs similarity index 95% rename from russh-keys/src/format/openssh.rs rename to russh/src/keys/format/openssh.rs index 152ac347..cdcbb98a 100644 --- a/russh-keys/src/format/openssh.rs +++ b/russh/src/keys/format/openssh.rs @@ -1,6 +1,6 @@ use ssh_key::PrivateKey; -use crate::Error; +use crate::keys::Error; /// Decode a secret key given in the OpenSSH format, deciphering it if /// needed using the supplied password. diff --git a/russh-keys/src/format/pkcs5.rs b/russh/src/keys/format/pkcs5.rs similarity index 97% rename from russh-keys/src/format/pkcs5.rs rename to russh/src/keys/format/pkcs5.rs index f4851226..47d4fc18 100644 --- a/russh-keys/src/format/pkcs5.rs +++ b/russh/src/keys/format/pkcs5.rs @@ -2,7 +2,7 @@ use aes::*; use ssh_key::PrivateKey; use super::Encryption; -use crate::Error; +use crate::keys::Error; /// Decode a secret key in the PKCS#5 format, possibly deciphering it /// using the supplied password. diff --git a/russh-keys/src/format/pkcs8.rs b/russh/src/keys/format/pkcs8.rs similarity index 99% rename from russh-keys/src/format/pkcs8.rs rename to russh/src/keys/format/pkcs8.rs index 77965252..559956aa 100644 --- a/russh-keys/src/format/pkcs8.rs +++ b/russh/src/keys/format/pkcs8.rs @@ -8,7 +8,7 @@ use spki::ObjectIdentifier; use ssh_key::private::{EcdsaKeypair, Ed25519Keypair, Ed25519PrivateKey, KeypairData}; use ssh_key::PrivateKey; -use crate::Error; +use crate::keys::Error; /// Decode a PKCS#8-encoded private key (ASN.1 or X9.62) pub fn decode_pkcs8( @@ -79,7 +79,7 @@ where p256::SecretKey: TryFrom, p384::SecretKey: TryFrom, p521::SecretKey: TryFrom, - crate::Error: From, + crate::keys::Error: From, { Ok(match curve_oid { NistP256::OID => { diff --git a/russh-keys/src/format/pkcs8_legacy.rs b/russh/src/keys/format/pkcs8_legacy.rs similarity index 99% rename from russh-keys/src/format/pkcs8_legacy.rs rename to russh/src/keys/format/pkcs8_legacy.rs index 064c2dc2..3c8e40b2 100644 --- a/russh-keys/src/format/pkcs8_legacy.rs +++ b/russh/src/keys/format/pkcs8_legacy.rs @@ -9,7 +9,7 @@ use ssh_key::PrivateKey; use yasna::BERReaderSeq; use super::Encryption; -use crate::Error; +use crate::keys::Error; const PBES2: &[u64] = &[1, 2, 840, 113549, 1, 5, 13]; const ED25519: &[u64] = &[1, 3, 101, 112]; diff --git a/russh-keys/src/format/tests.rs b/russh/src/keys/format/tests.rs similarity index 100% rename from russh-keys/src/format/tests.rs rename to russh/src/keys/format/tests.rs diff --git a/russh-keys/src/key.rs b/russh/src/keys/key.rs similarity index 87% rename from russh-keys/src/key.rs rename to russh/src/keys/key.rs index 1b1f8ec1..f75ff266 100644 --- a/russh-keys/src/key.rs +++ b/russh/src/keys/key.rs @@ -16,7 +16,7 @@ use ssh_encoding::Decode; use ssh_key::public::KeyData; use ssh_key::{Algorithm, EcdsaCurve, HashAlg, PublicKey}; -use crate::Error; +use crate::keys::Error; pub trait PublicKeyExt { fn decode(bytes: &[u8]) -> Result; @@ -58,8 +58,8 @@ mod private_key_with_hash_alg { /// have a hash algorithm associated with them. #[derive(Clone, Debug)] pub struct PrivateKeyWithHashAlg { - key: Arc, - hash_alg: Option, + key: Arc, + hash_alg: Option, } impl PrivateKeyWithHashAlg { @@ -68,11 +68,11 @@ mod private_key_with_hash_alg { /// Will fail if you specify a `hash_alg` for a key type other than RSA. /// For RSA, passing `None` is mapped to the legacy `sha-rsa` (SHA-1). pub fn new( - key: Arc, - hash_alg: Option, - ) -> Result { + key: Arc, + hash_alg: Option, + ) -> Result { if hash_alg.is_some() && !key.algorithm().is_rsa() { - return Err(crate::Error::InvalidParameters); + return Err(crate::keys::Error::InvalidParameters); } Ok(Self { key, hash_alg }) } @@ -81,13 +81,13 @@ mod private_key_with_hash_alg { self.key.algorithm().with_hash_alg(self.hash_alg) } - pub fn hash_alg(&self) -> Option { + pub fn hash_alg(&self) -> Option { self.hash_alg } } impl Deref for PrivateKeyWithHashAlg { - type Target = crate::PrivateKey; + type Target = crate::keys::PrivateKey; fn deref(&self) -> &Self::Target { &self.key diff --git a/russh-keys/src/known_hosts.rs b/russh/src/keys/known_hosts.rs similarity index 98% rename from russh-keys/src/known_hosts.rs rename to russh/src/keys/known_hosts.rs index 0cc94478..879cbfce 100644 --- a/russh-keys/src/known_hosts.rs +++ b/russh/src/keys/known_hosts.rs @@ -8,7 +8,7 @@ use hmac::{Hmac, Mac}; use log::debug; use sha1::Sha1; -use crate::Error; +use crate::keys::Error; /// Check whether the host is known, from its standard location. pub fn check_known_hosts( @@ -76,7 +76,7 @@ pub fn known_host_keys_path>( port: u16, path: P, ) -> Result, Error> { - use crate::parse_public_key_base64; + use crate::keys::parse_public_key_base64; let mut f = if let Ok(f) = File::open(path) { BufReader::new(f) @@ -189,7 +189,7 @@ mod test { use std::fs::File; use super::*; - use crate::parse_public_key_base64; + use crate::keys::parse_public_key_base64; #[test] fn test_check_known_hosts() { diff --git a/russh-keys/src/lib.rs b/russh/src/keys/mod.rs similarity index 98% rename from russh-keys/src/lib.rs rename to russh/src/keys/mod.rs index f5809805..b92f9599 100644 --- a/russh-keys/src/lib.rs +++ b/russh/src/keys/mod.rs @@ -1,10 +1,3 @@ -#![deny(trivial_casts, unstable_features, unused_import_braces)] -#![deny( - clippy::unwrap_used, - clippy::expect_used, - clippy::indexing_slicing, - clippy::panic -)] //! This crate contains methods to deal with SSH keys, as defined in //! crate Russh. This includes in particular various functions for //! opening key files, deciphering encrypted keys, and dealing with @@ -17,7 +10,7 @@ //! (`b"Please sign this"`, below). //! //!``` -//! use russh_keys::*; +//! use russh::keys::*; //! use futures::Future; //! //! #[derive(Clone)] @@ -42,7 +35,7 @@ //! core.spawn(async move { //! let mut listener = tokio::net::UnixListener::bind(&agent_path_) //! .unwrap(); -//! russh_keys::agent::server::serve(tokio_stream::wrappers::UnixListenerStream::new(listener), X {}).await +//! russh::keys::agent::server::serve(tokio_stream::wrappers::UnixListenerStream::new(listener), X {}).await //! }); //! let key = decode_secret_key(PKCS8_ENCRYPTED, Some("blabla")).unwrap(); //! let public = key.public_key().clone(); @@ -71,14 +64,14 @@ use std::string::FromUtf8Error; use aes::cipher::block_padding::UnpadError; use aes::cipher::inout::PadError; use data_encoding::BASE64_MIME; -use helpers::EncodedExt; use thiserror::Error; +use crate::helpers::EncodedExt; + pub mod key; +pub use key::PrivateKeyWithHashAlg; mod format; -#[doc(hidden)] -pub mod helpers; pub use format::*; // Reexports pub use signature; @@ -201,7 +194,7 @@ impl From for Error { /// Load a public key from a file. Ed25519, EC-DSA and RSA keys are supported. /// /// ``` -/// russh_keys::load_public_key("../files/id_ed25519.pub").unwrap(); +/// russh::keys::load_public_key("../files/id_ed25519.pub").unwrap(); /// ``` pub fn load_public_key>(path: P) -> Result { let mut pubkey = String::new(); @@ -221,7 +214,7 @@ pub fn load_public_key>(path: P) -> Result Result { let base = BASE64_MIME.decode(key.as_bytes())?; @@ -287,7 +280,7 @@ mod test { use futures::Future; use super::*; - use crate::key::PublicKeyExt; + use crate::keys::key::PublicKeyExt; const ED25519_KEY: &str = "-----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAAABDLGyfA39 @@ -646,7 +639,7 @@ Ow== #[test] #[cfg(feature = "legacy-ed25519-pkcs8-parser")] - fn test_decode_pkcs8_ed25519_generated_by_russh_0_43() -> Result<(), crate::Error> { + fn test_decode_pkcs8_ed25519_generated_by_russh_0_43() -> Result<(), crate::keys::Error> { // Generated by russh 0.43 let key = "-----BEGIN PRIVATE KEY----- MHMCAQEwBQYDK2VwBEIEQBHw4cXPpGgA+KdvPF5gxrzML+oa3yQk0JzIbWvmqM5H30RyBF8GrOWz diff --git a/russh/src/lib.rs b/russh/src/lib.rs index cbb7df08..778c6b48 100644 --- a/russh/src/lib.rs +++ b/russh/src/lib.rs @@ -60,10 +60,7 @@ //! # Design principles //! //! The main goal of this library is conciseness, and reduced size and -//! readability of the library's code. Moreover, this library is split -//! between Russh, which implements the main logic of SSH clients -//! and servers, and Russh-keys, which implements calls to -//! cryptographic primitives. +//! readability of the library's code. //! //! One non-goal is to implement all possible cryptographic algorithms //! published since the initial release of SSH. Technical debt is @@ -113,8 +110,7 @@ pub mod kex; /// MAC algorithm names pub mod mac; -/// Re-export of the `russh-keys` crate. -pub use russh_keys as keys; +pub mod keys; mod msg; mod negotiation; @@ -128,6 +124,8 @@ mod pty; pub use pty::Pty; pub use sshbuffer::SshId; +mod helpers; + macro_rules! push_packet { ( $buffer:expr, $x:expr ) => {{ use byteorder::{BigEndian, ByteOrder}; @@ -277,7 +275,7 @@ pub enum Error { RequestDenied, #[error(transparent)] - Keys(#[from] russh_keys::Error), + Keys(#[from] crate::keys::Error), #[error(transparent)] IO(#[from] std::io::Error), diff --git a/russh/src/negotiation.rs b/russh/src/negotiation.rs index e1e3790a..69a3d86d 100644 --- a/russh/src/negotiation.rs +++ b/russh/src/negotiation.rs @@ -16,11 +16,11 @@ use std::borrow::Cow; use log::debug; use rand::RngCore; -use russh_keys::helpers::NameList; use ssh_encoding::{Decode, Encode}; use ssh_key::{Algorithm, EcdsaCurve, HashAlg, PrivateKey}; use crate::cipher::CIPHERS; +use crate::helpers::NameList; use crate::kex::{EXTENSION_OPENSSH_STRICT_KEX_AS_CLIENT, EXTENSION_OPENSSH_STRICT_KEX_AS_SERVER}; #[cfg(not(target_arch = "wasm32"))] use crate::server::Config; diff --git a/russh/src/parsing.rs b/russh/src/parsing.rs index 6323f242..10e45d53 100644 --- a/russh/src/parsing.rs +++ b/russh/src/parsing.rs @@ -1,6 +1,6 @@ -use russh_keys::helpers::map_err; use ssh_encoding::{Decode, Encode, Reader}; +use crate::helpers::map_err; use crate::{msg, CryptoVec}; #[derive(Debug)] diff --git a/russh/src/server/encrypted.rs b/russh/src/server/encrypted.rs index d90d5e03..11278628 100644 --- a/russh/src/server/encrypted.rs +++ b/russh/src/server/encrypted.rs @@ -22,8 +22,6 @@ use bytes::Bytes; use cert::PublicKeyOrCertificate; use log::{debug, error, info, trace, warn}; use msg; -use russh_keys::helpers::NameList; -use russh_keys::map_err; use signature::Verifier; use ssh_encoding::{Decode, Encode, Reader}; use ssh_key::{PublicKey, Signature}; @@ -31,6 +29,8 @@ use tokio::time::Instant; use super::super::*; use super::*; +use crate::helpers::NameList; +use crate::map_err; use crate::msg::SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; use crate::parsing::{ChannelOpenConfirmation, ChannelType, OpenChannelMessage}; diff --git a/russh/src/server/kex.rs b/russh/src/server/kex.rs index defe961c..881a62bc 100644 --- a/russh/src/server/kex.rs +++ b/russh/src/server/kex.rs @@ -4,14 +4,14 @@ use std::cell::RefCell; use client::GexParams; use log::debug; use num_bigint::BigUint; -use russh_keys::helpers::sign_with_hash_alg; -use russh_keys::key::PrivateKeyWithHashAlg; use ssh_encoding::Encode; use ssh_key::Algorithm; use super::*; +use crate::helpers::sign_with_hash_alg; use crate::kex::dh::biguint_to_mpint; use crate::kex::{KexAlgorithm, KexAlgorithmImplementor, KexCause, KEXES}; +use crate::keys::key::PrivateKeyWithHashAlg; use crate::negotiation::{is_key_compatible_with_algo, Names, Select}; use crate::{msg, negotiation}; diff --git a/russh/src/server/mod.rs b/russh/src/server/mod.rs index 0f7415ee..32866135 100644 --- a/russh/src/server/mod.rs +++ b/russh/src/server/mod.rs @@ -41,7 +41,6 @@ use client::GexParams; use futures::future::Future; use log::{debug, error, info, warn}; use msg::{is_kex_msg, validate_client_msg_strict_kex}; -use russh_keys::map_err; use russh_util::runtime::JoinHandle; use russh_util::time::Instant; use ssh_key::{Certificate, PrivateKey}; @@ -55,7 +54,7 @@ use crate::kex::{KexProgress, SessionKexState}; use crate::session::*; use crate::ssh_read::*; use crate::sshbuffer::*; -use crate::*; +use crate::{map_err, *}; mod kex; mod session; diff --git a/russh/src/server/session.rs b/russh/src/server/session.rs index 7c833a27..1d70342d 100644 --- a/russh/src/server/session.rs +++ b/russh/src/server/session.rs @@ -5,16 +5,15 @@ use channels::WindowSizeRef; use kex::ServerKex; use log::debug; use negotiation::parse_kex_algo_list; -use russh_keys::helpers::NameList; -use russh_keys::map_err; use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt}; use tokio::sync::mpsc::{channel, Receiver, Sender}; use tokio::sync::oneshot; use super::*; use crate::channels::{Channel, ChannelMsg, ChannelRef}; +use crate::helpers::NameList; use crate::kex::{KexCause, SessionKexState, EXTENSION_SUPPORT_AS_CLIENT}; -use crate::msg; +use crate::{map_err, msg}; /// A connected server session. This type is unique to a client. #[derive(Debug)] diff --git a/russh/src/tests.rs b/russh/src/tests.rs index 7075287e..a65a92d7 100644 --- a/russh/src/tests.rs +++ b/russh/src/tests.rs @@ -11,11 +11,11 @@ mod compress { use async_trait::async_trait; use log::debug; use rand_core::OsRng; - use russh_keys::key::PrivateKeyWithHashAlg; use ssh_key::PrivateKey; use super::server::{Server as _, Session}; use super::*; + use crate::keys::key::PrivateKeyWithHashAlg; use crate::server::Msg; #[tokio::test] @@ -105,7 +105,7 @@ mod compress { async fn auth_publickey( &mut self, _: &str, - _: &russh_keys::ssh_key::PublicKey, + _: &crate::keys::ssh_key::PublicKey, ) -> Result { debug!("auth_publickey"); Ok(server::Auth::Accept) @@ -130,7 +130,7 @@ mod compress { async fn check_server_key( &mut self, - _server_public_key: &russh_keys::ssh_key::PublicKey, + _server_public_key: &crate::keys::ssh_key::PublicKey, ) -> Result { // println!("check_server_key: {:?}", server_public_key); Ok(true) @@ -141,12 +141,12 @@ mod compress { mod channels { use async_trait::async_trait; use rand_core::OsRng; - use russh_keys::key::PrivateKeyWithHashAlg; use server::Session; use ssh_key::PrivateKey; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use super::*; + use crate::keys::key::PrivateKeyWithHashAlg; use crate::CryptoVec; async fn test_session( @@ -227,7 +227,7 @@ mod channels { async fn check_server_key( &mut self, - _server_public_key: &russh_keys::ssh_key::PublicKey, + _server_public_key: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(true) } @@ -263,7 +263,7 @@ mod channels { async fn auth_publickey( &mut self, _: &str, - _: &russh_keys::ssh_key::PublicKey, + _: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(server::Auth::Accept) } @@ -309,7 +309,7 @@ mod channels { async fn check_server_key( &mut self, - _server_public_key: &russh_keys::ssh_key::PublicKey, + _server_public_key: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(true) } @@ -336,7 +336,7 @@ mod channels { async fn auth_publickey( &mut self, _: &str, - _: &russh_keys::ssh_key::PublicKey, + _: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(server::Auth::Accept) } @@ -405,7 +405,7 @@ mod channels { async fn check_server_key( &mut self, - _server_public_key: &russh_keys::ssh_key::PublicKey, + _server_public_key: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(true) } @@ -422,7 +422,7 @@ mod channels { async fn auth_publickey( &mut self, _: &str, - _: &russh_keys::ssh_key::PublicKey, + _: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(server::Auth::Accept) } @@ -482,7 +482,7 @@ mod channels { async fn check_server_key( &mut self, - _server_public_key: &russh_keys::ssh_key::PublicKey, + _server_public_key: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(true) } @@ -509,7 +509,7 @@ mod channels { async fn auth_publickey( &mut self, _: &str, - _: &russh_keys::ssh_key::PublicKey, + _: &crate::keys::ssh_key::PublicKey, ) -> Result { Ok(server::Auth::Accept) } diff --git a/russh/tests/test_backpressure.rs b/russh/tests/test_backpressure.rs index f2adea9f..2b0e6aba 100644 --- a/russh/tests/test_backpressure.rs +++ b/russh/tests/test_backpressure.rs @@ -4,9 +4,9 @@ use std::sync::Arc; use futures::FutureExt; use rand::RngCore; use rand_core::OsRng; +use russh::keys::key::PrivateKeyWithHashAlg; use russh::server::{self, Auth, Msg, Server as _, Session}; use russh::{client, Channel, ChannelMsg}; -use russh_keys::key::PrivateKeyWithHashAlg; use ssh_key::PrivateKey; use tokio::io::AsyncWriteExt; use tokio::sync::watch; diff --git a/russh/tests/test_data_stream.rs b/russh/tests/test_data_stream.rs index e7b493d5..35ebc96a 100644 --- a/russh/tests/test_data_stream.rs +++ b/russh/tests/test_data_stream.rs @@ -3,9 +3,9 @@ use std::sync::Arc; use rand::RngCore; use rand_core::OsRng; +use russh::keys::key::PrivateKeyWithHashAlg; use russh::server::{self, Auth, Msg, Server as _, Session}; use russh::{client, Channel}; -use russh_keys::key::PrivateKeyWithHashAlg; use ssh_key::PrivateKey; use tokio::io::{AsyncReadExt, AsyncWriteExt};