Skip to content

Commit

Permalink
Allow setting hash algorithm to use for signing requests of SSH agent
Browse files Browse the repository at this point in the history
Fixes: #444
Fixes: #445
Signed-off-by: Wiktor Kwapisiewicz <[email protected]>
  • Loading branch information
wiktor-k committed Jan 15, 2025
1 parent 2ca72c9 commit d4e840b
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 16 deletions.
8 changes: 6 additions & 2 deletions russh/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use std::str::FromStr;
use std::sync::Arc;

use async_trait::async_trait;
use ssh_key::{Certificate, PrivateKey};
use ssh_key::{Certificate, HashAlg, PrivateKey};
use thiserror::Error;
use tokio::io::{AsyncRead, AsyncWrite};

Expand Down Expand Up @@ -154,6 +154,7 @@ pub trait Signer: Sized {
async fn auth_publickey_sign(
&mut self,
key: &ssh_key::PublicKey,
hash_alg: Option<HashAlg>,
to_sign: CryptoVec,
) -> Result<CryptoVec, Self::Error>;
}
Expand All @@ -175,9 +176,12 @@ impl<R: AsyncRead + AsyncWrite + Unpin + Send + 'static> Signer
async fn auth_publickey_sign(
&mut self,
key: &ssh_key::PublicKey,
hash_alg: Option<HashAlg>,
to_sign: CryptoVec,
) -> Result<CryptoVec, Self::Error> {
self.sign_request(key, to_sign).await.map_err(Into::into)
self.sign_request(key, hash_alg, to_sign)
.await
.map_err(Into::into)
}
}

Expand Down
5 changes: 3 additions & 2 deletions russh/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ use kex::ClientKex;
use log::{debug, error, trace};
use russh_util::time::Instant;
use ssh_encoding::Decode;
use ssh_key::{Certificate, PrivateKey, PublicKey};
use ssh_key::{Certificate, HashAlg, PrivateKey, PublicKey};
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, ReadHalf, WriteHalf};
use tokio::pin;
use tokio::sync::mpsc::{
Expand Down Expand Up @@ -401,6 +401,7 @@ impl<H: Handler> Handle<H> {
&mut self,
user: U,
key: ssh_key::PublicKey,
hash_alg: Option<HashAlg>,
signer: &mut S,
) -> Result<AuthResult, S::Error> {
let user = user.into();
Expand All @@ -423,7 +424,7 @@ impl<H: Handler> Handle<H> {
proceed_with_methods: remaining_methods,
}) => return Ok(AuthResult::Failure { remaining_methods }),
Some(Reply::SignRequest { key, data }) => {
let data = signer.auth_publickey_sign(&key, data).await;
let data = signer.auth_publickey_sign(&key, hash_alg, data).await;
let data = match data {
Ok(data) => data,
Err(e) => return Err(e),
Expand Down
23 changes: 11 additions & 12 deletions russh/src/keys/agent/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use byteorder::{BigEndian, ByteOrder};
use bytes::Bytes;
use log::debug;
use ssh_encoding::{Decode, Encode, Reader};
use ssh_key::{Algorithm, HashAlg, PrivateKey, PublicKey, Signature};
use ssh_key::{HashAlg, PrivateKey, PublicKey, Signature};
use tokio;
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};

Expand Down Expand Up @@ -284,10 +284,11 @@ impl<S: AgentStream + Unpin> AgentClient<S> {
pub async fn sign_request(
&mut self,
public: &PublicKey,
hash_alg: Option<HashAlg>,
mut data: CryptoVec,
) -> Result<CryptoVec, Error> {
debug!("sign_request: {:?}", data);
let hash = self.prepare_sign_request(public, &data)?;
let hash = self.prepare_sign_request(public, hash_alg, &data)?;

self.read_response().await?;

Expand All @@ -307,6 +308,7 @@ impl<S: AgentStream + Unpin> AgentClient<S> {
fn prepare_sign_request(
&mut self,
public: &ssh_key::PublicKey,
hash_alg: Option<HashAlg>,
data: &[u8],
) -> Result<u32, Error> {
self.buf.clear();
Expand All @@ -315,14 +317,9 @@ impl<S: AgentStream + Unpin> AgentClient<S> {
public.key_data().encoded()?.encode(&mut self.buf)?;
data.encode(&mut self.buf)?;
debug!("public = {:?}", public);
let hash = match public.algorithm() {
Algorithm::Rsa {
hash: Some(HashAlg::Sha256),
} => 2,
Algorithm::Rsa {
hash: Some(HashAlg::Sha512),
} => 4,
Algorithm::Rsa { hash: None } => 0,
let hash = match hash_alg {
Some(HashAlg::Sha256) => 2,
Some(HashAlg::Sha512) => 4,
_ => 0,
};
hash.encode(&mut self.buf)?;
Expand Down Expand Up @@ -352,10 +349,11 @@ impl<S: AgentStream + Unpin> AgentClient<S> {
pub fn sign_request_base64(
mut self,
public: &ssh_key::PublicKey,
hash_alg: Option<HashAlg>,
data: &[u8],
) -> impl futures::Future<Output = (Self, Result<String, Error>)> {
debug!("sign_request: {:?}", data);
let r = self.prepare_sign_request(public, data);
let r = self.prepare_sign_request(public, hash_alg, data);
async move {
if let Err(e) = r {
return (self, Err(e));
Expand All @@ -380,11 +378,12 @@ impl<S: AgentStream + Unpin> AgentClient<S> {
pub async fn sign_request_signature(
&mut self,
public: &ssh_key::PublicKey,
hash_alg: Option<HashAlg>,
data: &[u8],
) -> Result<Signature, Error> {
debug!("sign_request: {:?}", data);

self.prepare_sign_request(public, data)?;
self.prepare_sign_request(public, hash_alg, data)?;
self.read_response().await?;

match self.buf.split_first() {
Expand Down

0 comments on commit d4e840b

Please sign in to comment.