ssh_attest_verify/src/ssh_attest.rs
2023-08-28 09:13:54 -05:00

71 lines
1.7 KiB
Rust

use std::str::FromStr;
use ssh_encoding::{Decode, Label, LabelError};
use x509_parser::{nom::Finish, prelude::*};
#[non_exhaustive]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Version {
V00,
V01,
}
impl AsRef<str> for Version {
fn as_ref(&self) -> &str {
match self {
Self::V00 => "ssh-sk-attest-v00",
Self::V01 => "ssh-sk-attest-v01",
}
}
}
impl FromStr for Version {
type Err = LabelError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ssh-sk-attest-v00" => Ok(Self::V00),
"ssh-sk-attest-v01" => Ok(Self::V01),
_ => Err(LabelError::new(s.into())),
}
}
}
impl Label for Version {}
#[non_exhaustive]
pub struct SshAttestationInfo {
pub version: Version,
pub attestation_cert: Vec<u8>,
pub enroll_sig: Vec<u8>,
pub auth_data: Option<Vec<u8>>,
}
impl SshAttestationInfo {
pub fn decode_cert(&self) -> Result<X509Certificate<'_>, X509Error> {
X509Certificate::from_der(&self.attestation_cert)
.finish()
.map(|(_, cert)| cert)
}
}
impl Decode for SshAttestationInfo {
type Error = ssh_encoding::Error;
fn decode(reader: &mut impl ssh_encoding::Reader) -> core::result::Result<Self, Self::Error> {
let version = Version::decode(reader)?;
let attestation_cert = Vec::decode(reader)?;
let enroll_sig = Vec::decode(reader)?;
let auth_data = match version {
Version::V00 => None,
Version::V01 => Some(Vec::decode(reader)?),
};
Ok(Self {
version,
attestation_cert,
enroll_sig,
auth_data,
})
}
}