use ssh_key::PublicKey;
#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)]
#[non_exhaustive]
pub enum SshKeyError {
#[error("Malformed or invalid OpenSSH public key: {0}")]
InvalidFormat(String),
#[error("Unsupported key type: expected ssh-ed25519")]
UnsupportedKeyType,
}
impl crate::AuthsErrorInfo for SshKeyError {
fn error_code(&self) -> &'static str {
match self {
Self::InvalidFormat(_) => "AUTHS-E1301",
Self::UnsupportedKeyType => "AUTHS-E1302",
}
}
fn suggestion(&self) -> Option<&'static str> {
match self {
Self::InvalidFormat(_) => Some("Check that the public key is a valid OpenSSH format"),
Self::UnsupportedKeyType => Some("Only ssh-ed25519 keys are supported"),
}
}
}
pub fn openssh_pub_to_raw_ed25519(openssh_pub: &str) -> Result<[u8; 32], SshKeyError> {
let public_key = PublicKey::from_openssh(openssh_pub)
.map_err(|e| SshKeyError::InvalidFormat(e.to_string()))?;
let ed25519_key = public_key
.key_data()
.ed25519()
.ok_or(SshKeyError::UnsupportedKeyType)?;
Ok(ed25519_key.0)
}