pub mod verification;
mod versions;

pub use sev::firmware::guest::AttestationReport;
pub use versions::*;

pub enum ReportSignature {
    Ecdsa384 { r: [u8; 72], s: [u8; 72] },
}

impl TryFrom<&ReportSignature> for p384::ecdsa::Signature {
    type Error = p384::ecdsa::Error;

    fn try_from(value: &ReportSignature) -> Result<Self, Self::Error> {
        match value {
            ReportSignature::Ecdsa384 { r, s } => {
                // `Signature::from_scalars` expects big endian values, but the valuev from the
                // attestation report are little endian. Additionally, values are larger than
                // required and zero filled
                if r[48..] != [0; 24] || s[48..] != [0; 24] {
                    return Err(Self::Error::new());
                }
                let mut r: [u8; 48] = r[..48].try_into().expect("Should have correct size");
                r.reverse();
                let mut s: [u8; 48] = s[..48].try_into().expect("Should have correct size");
                s.reverse();

                p384::ecdsa::Signature::from_scalars(r, s)
            }
        }
    }
}

#[derive(Debug)]
pub enum SignatureError {
    UnknownAlgorithm,
}

impl TryFrom<&AttestationReport> for ReportSignature {
    type Error = SignatureError;

    fn try_from(report: &AttestationReport) -> Result<Self, Self::Error> {
        match report.sig_algo {
            1 => Ok(ReportSignature::Ecdsa384 {
                r: *report.signature.r(),
                s: *report.signature.s(),
            }),
            _ => Err(SignatureError::UnknownAlgorithm),
        }
    }
}
