1use ssh_key::PublicKey;
4
5#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)]
7#[non_exhaustive]
8pub enum SshKeyError {
9 #[error("Malformed or invalid OpenSSH public key: {0}")]
10 InvalidFormat(String),
11
12 #[error("Unsupported key type: expected ssh-ed25519")]
13 UnsupportedKeyType,
14}
15
16impl crate::AuthsErrorInfo for SshKeyError {
17 fn error_code(&self) -> &'static str {
18 match self {
19 Self::InvalidFormat(_) => "AUTHS-E1301",
20 Self::UnsupportedKeyType => "AUTHS-E1302",
21 }
22 }
23
24 fn suggestion(&self) -> Option<&'static str> {
25 match self {
26 Self::InvalidFormat(_) => Some("Check that the public key is a valid OpenSSH format"),
27 Self::UnsupportedKeyType => Some("Only ssh-ed25519 keys are supported"),
28 }
29 }
30}
31
32pub fn openssh_pub_to_raw_ed25519(openssh_pub: &str) -> Result<[u8; 32], SshKeyError> {
43 let public_key = PublicKey::from_openssh(openssh_pub)
44 .map_err(|e| SshKeyError::InvalidFormat(e.to_string()))?;
45
46 let ed25519_key = public_key
47 .key_data()
48 .ed25519()
49 .ok_or(SshKeyError::UnsupportedKeyType)?;
50
51 Ok(ed25519_key.0)
52}