Skip to content

Commit 259ed35

Browse files
committed
Add method to do OpenSSH authentication with hash algo specified
1 parent 829d385 commit 259ed35

3 files changed

Lines changed: 40 additions & 2 deletions

File tree

russh/src/auth.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,10 @@ pub enum Method {
208208
key: Arc<PrivateKey>,
209209
cert: Certificate,
210210
},
211+
OpenSshCertificateWithHashAlg {
212+
key: PrivateKeyWithHashAlg,
213+
cert: Certificate,
214+
},
211215
FuturePublicKey {
212216
key: ssh_key::PublicKey,
213217
hash_alg: Option<HashAlg>,

russh/src/client/encrypted.rs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ impl Session {
208208
&mut self.common.buffer,
209209
)?
210210
}
211-
Some(auth_method @ auth::Method::OpenSshCertificate { .. }) => {
211+
Some(auth_method @ auth::Method::OpenSshCertificate { .. }) | Some(auth_method @ auth::Method::OpenSshCertificateWithHashAlg { .. })=> {
212212
self.common.buffer.clear();
213213
enc.client_send_signature(
214214
&self.common.auth_user,
@@ -942,7 +942,7 @@ impl Encrypted {
942942
key.public_key().to_bytes()?.encode(&mut self.write)?;
943943
true
944944
}
945-
auth::Method::OpenSshCertificate { ref cert, .. } => {
945+
auth::Method::OpenSshCertificate { ref cert, .. } | auth::Method::OpenSshCertificateWithHashAlg { ref cert, .. } => {
946946
user.as_bytes().encode(&mut self.write)?;
947947
"ssh-connection".encode(&mut self.write)?;
948948
"publickey".encode(&mut self.write)?;
@@ -1059,6 +1059,20 @@ impl Encrypted {
10591059
self.write.extend_from_slice(&buffer[i0..]);
10601060
})
10611061
}
1062+
auth::Method::OpenSshCertificateWithHashAlg { key, cert} => {
1063+
let i0 = self.client_make_to_sign(
1064+
user,
1065+
&PublicKeyOrCertificate::Certificate(cert.clone()),
1066+
buffer,
1067+
)?;
1068+
1069+
sign_with_hash_alg(key, buffer)?.encode(&mut *buffer)?;
1070+
1071+
push_packet!(self.write, {
1072+
#[allow(clippy::indexing_slicing)] // length checked
1073+
self.write.extend(&buffer[i0..]);
1074+
})
1075+
}
10621076
_ => {}
10631077
}
10641078
Ok(())

russh/src/client/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,26 @@ impl<H: Handler> Handle<H> {
450450
self.wait_recv_reply().await
451451
}
452452

453+
/// Same as [`Handle::authenticate_openssh_cert`], but allows specifying a hash algorithm for RSA keys in the certificate.
454+
/// This is necessary for authentication to succeed with some old servers that does not support `rsa-sha2-512`.
455+
/// Perform public OpenSSH Certificate-based SSH authentication with a specified hash algorithm for RSA keys
456+
pub async fn authenticate_openssh_cert_with_hash_alg<U: Into<String>>(
457+
&mut self,
458+
user: U,
459+
key: PrivateKeyWithHashAlg,
460+
cert: Certificate,
461+
) -> Result<AuthResult, crate::Error> {
462+
let user = user.into();
463+
self.sender
464+
.send(Msg::Authenticate {
465+
user,
466+
method: auth::Method::OpenSshCertificateWithHashAlg { key, cert },
467+
})
468+
.await
469+
.map_err(|_| crate::Error::SendError)?;
470+
self.wait_recv_reply().await
471+
}
472+
453473
/// Authenticate using a custom method that implements the
454474
/// [`Signer`][auth::Signer] trait. Currently, this crate only provides an
455475
/// implementation for an [SSH agent][crate::keys::agent::client::AgentClient].

0 commit comments

Comments
 (0)