1use ssh_encoding::Decode;
16use ssh_key::public::KeyData;
17use ssh_key::{Algorithm, EcdsaCurve, HashAlg, PublicKey};
18
19use crate::Error;
20
21pub trait PublicKeyExt {
22 fn decode(bytes: &[u8]) -> Result<PublicKey, Error>;
23}
24
25impl PublicKeyExt for PublicKey {
26 fn decode(mut bytes: &[u8]) -> Result<PublicKey, Error> {
27 let key = KeyData::decode(&mut bytes)?;
28 Ok(PublicKey::new(key, ""))
29 }
30}
31
32#[doc(hidden)]
33pub trait Verify {
34 fn verify_client_auth(&self, buffer: &[u8], sig: &[u8]) -> bool;
35 fn verify_server_auth(&self, buffer: &[u8], sig: &[u8]) -> bool;
36}
37
38pub fn parse_public_key(mut p: &[u8]) -> Result<PublicKey, Error> {
40 use ssh_encoding::Decode;
41 Ok(ssh_key::public::KeyData::decode(&mut p)?.into())
42}
43
44pub fn safe_rng() -> impl rand::CryptoRng + rand::RngCore {
46 rand::thread_rng()
47}
48
49mod private_key_with_hash_alg {
50 use std::ops::Deref;
51 use std::sync::Arc;
52
53 use ssh_key::Algorithm;
54
55 use crate::helpers::AlgorithmExt;
56
57 #[derive(Clone, Debug)]
61 pub struct PrivateKeyWithHashAlg {
62 key: Arc<crate::PrivateKey>,
63 hash_alg: Option<crate::HashAlg>,
64 }
65
66 impl PrivateKeyWithHashAlg {
67 pub fn new(
68 key: Arc<crate::PrivateKey>,
69 hash_alg: Option<crate::HashAlg>,
70 ) -> Result<Self, crate::Error> {
71 if hash_alg.is_some() && !key.algorithm().is_rsa() {
72 return Err(crate::Error::InvalidParameters);
73 }
74 Ok(Self { key, hash_alg })
75 }
76
77 pub fn algorithm(&self) -> Algorithm {
78 self.key.algorithm().with_hash_alg(self.hash_alg)
79 }
80
81 pub fn hash_alg(&self) -> Option<crate::HashAlg> {
82 self.hash_alg
83 }
84 }
85
86 impl Deref for PrivateKeyWithHashAlg {
87 type Target = crate::PrivateKey;
88
89 fn deref(&self) -> &Self::Target {
90 &self.key
91 }
92 }
93}
94
95pub use private_key_with_hash_alg::PrivateKeyWithHashAlg;
96
97pub const ALL_KEY_TYPES: &[Algorithm] = &[
98 Algorithm::Dsa,
99 Algorithm::Ecdsa {
100 curve: EcdsaCurve::NistP256,
101 },
102 Algorithm::Ecdsa {
103 curve: EcdsaCurve::NistP384,
104 },
105 Algorithm::Ecdsa {
106 curve: EcdsaCurve::NistP521,
107 },
108 Algorithm::Ed25519,
109 Algorithm::Rsa { hash: None },
110 Algorithm::Rsa {
111 hash: Some(HashAlg::Sha256),
112 },
113 Algorithm::Rsa {
114 hash: Some(HashAlg::Sha512),
115 },
116 Algorithm::SkEcdsaSha2NistP256,
117 Algorithm::SkEd25519,
118];