Skip to content

Commit

Permalink
Upgrade dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
honzasp committed Feb 9, 2023
1 parent a18b9c0 commit 64721ed
Show file tree
Hide file tree
Showing 12 changed files with 66 additions and 65 deletions.
27 changes: 13 additions & 14 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ path = "tests/keys/main.rs"

[dependencies]
aes = "0.8"
aes-gcm = "^0.10.0-pre"
base64 = "^0.13"
aes-gcm = "0.10"
base64 = "0.21"
bcrypt-pbkdf = "0.9"
bytes = "1.1"
cbc = "0.1"
chacha20 = "0.9"
ctr = "0.9"
derivative = "2.2"
ecdsa = {version = "0.14", features = ["sign", "verify"]}
ecdsa = {version = "0.15", features = ["signing", "verifying"]}
ed25519 = {version = "1.5", features = ["pkcs8"]}
ed25519-dalek = "1.0"
futures-core = "0.3"
Expand All @@ -42,37 +42,36 @@ hex-literal = "0.3"
hmac = "0.12"
log = "0.4"
num-bigint-dig = {version = "0.8", features = ["rand"]}
p256 = "0.11"
p384 = "0.11"
p256 = "0.12"
p384 = "0.12"
parking_lot = "0.12"
pem = "1.0"
pin-project = "1.0"
pkcs8 = {version = "0.9", features = ["encryption"]}
poly1305 = "0.7"
poly1305 = "0.8"
rand = {version = "0.8", features = ["getrandom"]}
rand_0_7 = {version = "0.7", package = "rand"} # because of x25519-dalek
rand_chacha = "0.3"
regex = {version = "1.6", features = ["std"], default-features = false}
regex-syntax = {version = "0.6", features = [], default-features = false}
rsa = {version = "0.6"}
sha-1 = {version = "0.10", default-features = false}
sha2 = "0.10"
rsa = {version = "0.8"}
sha-1 = {version = "0.10", features = ["oid"]}
sha2 = {version = "0.10", features = ["oid"]}
thiserror = "1.0"
tokio = {version = "1", features = ["sync"]}
tokio-util = {version = "0.7", features = []}
x25519-dalek = "1.1" # due to issue #89

[dev-dependencies]
anyhow = "1"
bollard = "0.12"
clap = "3.2"
bollard = "0.14"
clap = "4.1"
colored = "2.0"
enclose = "1.1"
env_logger = "0.9"
env_logger = "0.10"
futures = "0.3"
home = "0.5"
regex = "1.5"
rustix = {version = "0.35", features = ["termios"]}
rustix = {version = "0.36", features = ["termios"]}
tokio = {version = "1", features = ["full"]}

[features]
Expand Down
8 changes: 0 additions & 8 deletions examples/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +32,29 @@ fn main() -> ExitCode {
fn run_main() -> Result<ExitCode> {
let matches = clap::Command::new("client")
.arg(clap::Arg::new("private-key").short('i')
.takes_value(true)
.action(clap::ArgAction::Append)
.value_parser(clap::value_parser!(PathBuf))
.value_hint(clap::ValueHint::FilePath)
.value_name("key-file"))
.arg(clap::Arg::new("port").short('p')
.takes_value(true)
.value_parser(clap::value_parser!(u16))
.value_name("port"))
.arg(clap::Arg::new("username").short('l')
.takes_value(true)
.value_name("login"))
.arg(clap::Arg::new("destination")
.required(true)
.takes_value(true)
.value_name("destination"))
.arg(clap::Arg::new("command")
.takes_value(true)
.value_name("command"))
.arg(clap::Arg::new("want-tty").short('t')
.action(clap::ArgAction::SetTrue))
.arg(clap::Arg::new("local-tunnel").short('L')
.takes_value(true)
.action(clap::ArgAction::Append)
.value_name("[local-host:]local-port:remote-host:remote-port"))
.arg(clap::Arg::new("remote-tunnel").short('R')
.takes_value(true)
.action(clap::ArgAction::Append)
.value_name("[remote-host:]remote-port:local-host:local-port"))
.arg(clap::Arg::new("known-hosts").short('k')
.takes_value(true)
.value_hint(clap::ValueHint::FilePath)
.value_name("host-file"))
.get_matches();
Expand Down
7 changes: 3 additions & 4 deletions src/cipher/chacha_poly.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use chacha20::cipher::{KeyIvInit as _, StreamCipherCore as _};
use chacha20::cipher::generic_array::GenericArray;
use chacha20::cipher::inout::InOutBuf;
use poly1305::universal_hash::{NewUniversalHash as _};
use poly1305::universal_hash::KeyInit as _;
use crate::{Result, Error};
use crate::mac::MacVerified;
use super::{CipherAlgo, CipherAlgoVariant, AeadCipherAlgo, AeadEncrypt, AeadDecrypt};
Expand Down Expand Up @@ -49,7 +48,7 @@ impl AeadEncrypt for ChachaPolyCipher {
let poly_key = poly1305::Key::from_slice(&poly_key_block[..32]);
let poly = poly1305::Poly1305::new(poly_key);
let poly_tag = poly.compute_unpadded(packet);
tag.copy_from_slice(&poly_tag.into_bytes());
tag.copy_from_slice(&poly_tag)
}
}

Expand All @@ -72,7 +71,7 @@ impl AeadDecrypt for ChachaPolyCipher {
let poly_tag = poly.compute_unpadded(packet);
let verified =
// note that this is a constant-time comparison
if poly_tag == poly1305::Tag::new(*GenericArray::from_slice(tag)) {
if poly_tag == *poly1305::Tag::from_slice(tag) {
MacVerified::assertion()
} else {
return Err(Error::Mac)
Expand Down
21 changes: 15 additions & 6 deletions src/host_file.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
//! Support for OpenSSH-compatible `known_hosts` file.

use guard::guard;
use base64::Engine as _;
use bytes::{Bytes, BytesMut};
use hmac::Mac as _;
use rand::RngCore as _;
use std::str;
use crate::pubkey::Pubkey;
use crate::util::base64_encode;

/// Representation of an OpenSSH-compatible `known_hosts` file.
///
Expand Down Expand Up @@ -437,7 +439,7 @@ fn decode_line(mut bytes: &[u8], line_i: usize) -> Result<LineContent, &'static

// ...followed by base64-encoded public key
let key_base64 = read_field(&mut bytes).ok_or("expected key data in base64 after key type")?;
let key_blob = base64::decode(key_base64).map_err(|_| "key data is invalid base64")?;
let key_blob = base64_decode(key_base64).map_err(|_| "key data is invalid base64")?;
let key = Pubkey::decode(Bytes::copy_from_slice(&key_blob))
.ok().ok_or("could not decode the public key")?;
if key.type_str() != key_type {
Expand Down Expand Up @@ -466,7 +468,7 @@ fn encode_entry(entry: &Entry) -> String {
output.push(' ');
output.push_str(&entry.key.type_str());
output.push(' ');
output.push_str(&base64::encode(&entry.key.encode()));
output.push_str(&base64_encode(&entry.key.encode()));

if let Some(comment) = &entry.key_comment {
output.push(' ');
Expand Down Expand Up @@ -511,16 +513,16 @@ fn decode_hashed_pattern(bytes: &[u8]) -> Result<HashedPattern, &'static str> {
let salt_base64 = parts.next().ok_or("invalid format of hashed pattern")?;
let hash_base64 = parts.next().ok_or("expected a pipe '|' in the hashed pattern")?;

let salt = base64::decode(salt_base64).ok().ok_or("invalid base64 in the salt")?;
let hash = base64::decode(hash_base64).ok().ok_or("invalid base64 in the hash")?;
let salt = base64_decode(salt_base64).ok().ok_or("invalid base64 in the salt")?;
let hash = base64_decode(hash_base64).ok().ok_or("invalid base64 in the hash")?;
Ok(HashedPattern { salt, hash })
}

fn encode_hashed_pattern(pattern: &HashedPattern, output: &mut String) {
output.push_str("|1|");
output.push_str(&base64::encode(&pattern.salt));
output.push_str(&base64_encode(&pattern.salt));
output.push('|');
output.push_str(&base64::encode(&pattern.hash));
output.push_str(&base64_encode(&pattern.hash));
}

fn build_hashed_pattern(hostname: &str) -> HashedPattern {
Expand Down Expand Up @@ -621,6 +623,13 @@ fn consume_whitespace(bytes: &mut &[u8]) {
*bytes = &bytes[white_len..];
}

fn base64_decode(mut data_base64: &[u8]) -> Result<Vec<u8>, base64::DecodeError> {
while data_base64.last() == Some(&b'=') {
data_base64 = &data_base64[..data_base64.len() - 1];
}
base64::engine::general_purpose::STANDARD_NO_PAD.decode(data_base64)
}

#[cfg(test)]
mod tests {
use hex_literal::hex;
Expand Down
4 changes: 2 additions & 2 deletions src/pubkey/ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ pub struct EcdsaPrivkey<C>
impl EcdsaPrivkey<p256::NistP256> {
/// Get the public key associated with this private key.
pub fn pubkey(&self) -> EcdsaPubkey<p256::NistP256> {
EcdsaPubkey { verifying: self.signing.verifying_key() }
EcdsaPubkey { verifying: *self.signing.verifying_key() }
}
}

impl EcdsaPrivkey<p384::NistP384> {
/// Get the public key associated with this private key.
pub fn pubkey(&self) -> EcdsaPubkey<p384::NistP384> {
EcdsaPubkey { verifying: self.signing.verifying_key() }
EcdsaPubkey { verifying: *self.signing.verifying_key() }
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/pubkey/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use derivative::Derivative;
use std::fmt;
use crate::codec::{PacketDecode, PacketEncode};
use crate::error::{Result, Error};
use crate::util::base64_encode;
pub use self::ecdsa::{ECDSA_SHA2_NISTP256, ECDSA_SHA2_NISTP384, EcdsaPubkey, EcdsaPrivkey};
pub use self::ed25519::{SSH_ED25519, Ed25519Pubkey, Ed25519Privkey};
pub use self::rsa::{SSH_RSA_SHA1, RSA_SHA2_256, RSA_SHA2_512, RsaPubkey, RsaPrivkey};
Expand Down Expand Up @@ -142,7 +143,7 @@ impl Pubkey {
pub fn fingerprint(&self) -> String {
use sha2::Digest;
let digest = sha2::Sha256::digest(self.encode());
format!("SHA256:{}", base64::encode_config(digest, base64::STANDARD_NO_PAD))
format!("SHA256:{}", base64_encode(&digest))
}
}

Expand Down
19 changes: 8 additions & 11 deletions src/pubkey/rsa.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use bytes::Bytes;
use guard::guard;
use rsa::{PublicKey as _, PublicKeyParts as _};
use rsa::{PublicKey as _, PublicKeyParts as _, pkcs8};
use sha1::digest;
use std::fmt;
use crate::codec::{PacketDecode, PacketEncode};
Expand Down Expand Up @@ -75,8 +75,8 @@ fn verify<H: RsaHash>(pubkey: &Pubkey, message: &[u8], signature_blob: Bytes) ->
hasher.update(message);
let hashed = hasher.finalize();

let padding = rsa::PaddingScheme::PKCS1v15Sign { hash: Some(H::HASH) };
match pubkey.pubkey.verify(padding, hashed.as_slice(), &signature) {
let scheme = rsa::pkcs1v15::Pkcs1v15Sign::new::<H>();
match pubkey.pubkey.verify(scheme, hashed.as_slice(), &signature) {
Ok(_) => Ok(SignatureVerified::assertion()),
Err(_) => Err(Error::Signature),
}
Expand All @@ -89,8 +89,8 @@ fn sign<H: RsaHash>(privkey: &Privkey, message: &[u8]) -> Result<Bytes> {
hasher.update(message);
let hashed = hasher.finalize();

let padding = rsa::PaddingScheme::PKCS1v15Sign { hash: Some(H::HASH) };
let signature = privkey.privkey.sign(padding, hashed.as_slice())
let scheme = rsa::pkcs1v15::Pkcs1v15Sign::new::<H>();
let signature = privkey.privkey.sign(scheme, hashed.as_slice())
.map_err(|_| Error::Crypto("could not sign with RSA"))?;

let mut signature_blob = PacketEncode::new();
Expand Down Expand Up @@ -121,29 +121,26 @@ pub(super) fn decode_privkey(blob: &mut PacketDecode) -> Result<RsaPrivkey> {
let _iqmp = blob.get_biguint()?;
let p = blob.get_biguint()?;
let q = blob.get_biguint()?;
let privkey = rsa::RsaPrivateKey::from_components(n, e, d, vec![p, q]);
let privkey = rsa::RsaPrivateKey::from_components(n, e, d, vec![p, q])
.map_err(|_| Error::Decode("decoded ssh-rsa privkey is invalid"))?;
Ok(RsaPrivkey { privkey })
}



trait RsaHash: digest::Digest {
const HASH: rsa::Hash;
trait RsaHash: digest::Digest + pkcs8::AssociatedOid {
const ALGO_NAME: &'static str;
}

impl RsaHash for sha1::Sha1 {
const HASH: rsa::Hash = rsa::Hash::SHA1;
const ALGO_NAME: &'static str = "ssh-rsa";
}

impl RsaHash for sha2::Sha256 {
const HASH: rsa::Hash = rsa::Hash::SHA2_256;
const ALGO_NAME: &'static str = "rsa-sha2-256";
}

impl RsaHash for sha2::Sha512 {
const HASH: rsa::Hash = rsa::Hash::SHA2_512;
const ALGO_NAME: &'static str = "rsa-sha2-512";
}

Expand Down
7 changes: 7 additions & 0 deletions src/util.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use base64::Engine as _;
use bytes::BytesMut;
use futures_core::ready;
use rand::{CryptoRng, RngCore};
Expand Down Expand Up @@ -47,3 +48,9 @@ pub trait CryptoRngCore: CryptoRng + RngCore {
impl<T: CryptoRng + RngCore> CryptoRngCore for T {
fn as_rngcore(&mut self) -> &mut dyn RngCore { self }
}

// the `base64` in the latest version seems to have taken an unfortunate inspiration from Boost :(

pub fn base64_encode(data: &[u8]) -> String {
base64::engine::general_purpose::STANDARD_NO_PAD.encode(data)
}
10 changes: 2 additions & 8 deletions tests/compat/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,10 @@ async fn main() -> ExitCode {

let args = clap::Command::new("test-compat")
.arg(clap::Arg::new("server").short('s')
.takes_value(true)
.action(clap::ArgAction::Append)
.multiple_values(true)
.use_value_delimiter(true)
.require_value_delimiter(true))
.action(clap::ArgAction::Append))
.arg(clap::Arg::new("case").short('c')
.takes_value(true)
.action(clap::ArgAction::Append))
.arg(clap::Arg::new("force-addr").short('f')
.takes_value(true))
.arg(clap::Arg::new("force-addr").short('f'))
.get_matches();

let servers = args.get_many::<String>("server").map(|xs| xs.cloned().collect());
Expand Down
5 changes: 4 additions & 1 deletion tests/compat/ssh_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ impl SshServer {
}

// create and start a new container
let create_opts = CreateContainerOptions { name: container_name.as_str() };
let create_opts = CreateContainerOptions {
name: container_name.as_str(),
.. CreateContainerOptions::default()
};
let create_config = Config {
exposed_ports: Some(vec![("22/tcp", HashMap::new())].into_iter().collect()),
image: Some(image_name.as_str()),
Expand Down
Loading

0 comments on commit 64721ed

Please sign in to comment.