Skip to content

Commit 84e21aa

Browse files
committed
Add ability to get the SSH host key and its type.
1 parent e6aa666 commit 84e21aa

File tree

2 files changed

+85
-0
lines changed

2 files changed

+85
-0
lines changed

libgit2-sys/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,10 @@ git_enum! {
489489
GIT_CERT_SSH_RAW_TYPE_UNKNOWN = 0,
490490
GIT_CERT_SSH_RAW_TYPE_RSA = 1,
491491
GIT_CERT_SSH_RAW_TYPE_DSS = 2,
492+
GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 = 3,
493+
GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 = 4,
494+
GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 = 5,
495+
GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 = 6,
492496
}
493497
}
494498

src/cert.rs

+81
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,54 @@ pub struct CertX509<'a> {
2727
_marker: marker::PhantomData<&'a raw::git_cert>,
2828
}
2929

30+
/// The SSH host key type.
31+
#[derive(Copy, Clone, Debug)]
32+
#[non_exhaustive]
33+
pub enum SshHostKeyType {
34+
/// Unknown key type
35+
Unknown = raw::GIT_CERT_SSH_RAW_TYPE_UNKNOWN as isize,
36+
/// RSA key type
37+
Rsa = raw::GIT_CERT_SSH_RAW_TYPE_RSA as isize,
38+
/// DSS key type
39+
Dss = raw::GIT_CERT_SSH_RAW_TYPE_DSS as isize,
40+
/// ECDSA 256 key type
41+
Ecdsa256 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 as isize,
42+
/// ECDSA 384 key type
43+
Ecdsa384 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 as isize,
44+
/// ECDSA 521 key type
45+
Ecdsa521 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 as isize,
46+
/// ED25519 key type
47+
Ed255219 = raw::GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 as isize,
48+
}
49+
50+
impl SshHostKeyType {
51+
/// The name of the key type as encoded in the known_hosts file.
52+
pub fn name(&self) -> &'static str {
53+
match self {
54+
SshHostKeyType::Unknown => "unknown",
55+
SshHostKeyType::Rsa => "ssh-rsa",
56+
SshHostKeyType::Dss => "ssh-dss",
57+
SshHostKeyType::Ecdsa256 => "ecdsa-sha2-nistp256",
58+
SshHostKeyType::Ecdsa384 => "ecdsa-sha2-nistp384",
59+
SshHostKeyType::Ecdsa521 => "ecdsa-sha2-nistp521",
60+
SshHostKeyType::Ed255219 => "ssh-ed25519",
61+
}
62+
}
63+
64+
/// A short name of the key type, the colloquial form used as a human-readable description.
65+
pub fn short_name(&self) -> &'static str {
66+
match self {
67+
SshHostKeyType::Unknown => "Unknown",
68+
SshHostKeyType::Rsa => "RSA",
69+
SshHostKeyType::Dss => "DSA",
70+
SshHostKeyType::Ecdsa256 => "ECDSA",
71+
SshHostKeyType::Ecdsa384 => "ECDSA",
72+
SshHostKeyType::Ecdsa521 => "ECDSA",
73+
SshHostKeyType::Ed255219 => "ED25519",
74+
}
75+
}
76+
}
77+
3078
impl<'a> Cert<'a> {
3179
/// Attempt to view this certificate as an SSH hostkey.
3280
///
@@ -87,6 +135,39 @@ impl<'a> CertHostkey<'a> {
87135
}
88136
}
89137
}
138+
139+
/// Returns the raw host key.
140+
pub fn hostkey(&self) -> Option<&[u8]> {
141+
unsafe {
142+
if (*self.raw).kind & raw::GIT_CERT_SSH_RAW == 0 {
143+
return None;
144+
}
145+
Some(slice::from_raw_parts(
146+
(*self.raw).hostkey as *const u8,
147+
(*self.raw).hostkey_len as usize,
148+
))
149+
}
150+
}
151+
152+
/// Returns the type of the host key.
153+
pub fn hostkey_type(&self) -> Option<SshHostKeyType> {
154+
unsafe {
155+
if (*self.raw).kind & raw::GIT_CERT_SSH_RAW == 0 {
156+
return None;
157+
}
158+
let t = match (*self.raw).raw_type {
159+
raw::GIT_CERT_SSH_RAW_TYPE_UNKNOWN => SshHostKeyType::Unknown,
160+
raw::GIT_CERT_SSH_RAW_TYPE_RSA => SshHostKeyType::Rsa,
161+
raw::GIT_CERT_SSH_RAW_TYPE_DSS => SshHostKeyType::Dss,
162+
raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_256 => SshHostKeyType::Ecdsa256,
163+
raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_384 => SshHostKeyType::Ecdsa384,
164+
raw::GIT_CERT_SSH_RAW_TYPE_KEY_ECDSA_521 => SshHostKeyType::Ecdsa521,
165+
raw::GIT_CERT_SSH_RAW_TYPE_KEY_ED25519 => SshHostKeyType::Ed255219,
166+
t => panic!("unexpected host key type {:?}", t),
167+
};
168+
Some(t)
169+
}
170+
}
90171
}
91172

92173
impl<'a> CertX509<'a> {

0 commit comments

Comments
 (0)