use crate::attestation::claims::AttestationClaims;
use crate::config::TeeProvider;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Measurement {
pub algorithm: String,
pub digest: String,
}
impl Measurement {
pub fn new(algorithm: impl Into<String>, digest: impl Into<String>) -> Self {
Self {
algorithm: algorithm.into(),
digest: digest.into().to_ascii_lowercase(),
}
}
pub fn sha256(digest: impl Into<String>) -> Self {
Self::new("sha256", digest)
}
pub fn sha384(digest: impl Into<String>) -> Self {
Self::new("sha384", digest)
}
}
impl core::fmt::Display for Measurement {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(f, "{}:{}", self.algorithm, self.digest)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PublicKeyBinding {
pub public_key: Vec<u8>,
pub key_type: String,
pub binding_digest: String,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AttestationFormat {
NitroDocument,
TdxQuote,
SevSnpReport,
AzureMaaToken,
GcpConfidentialToken,
Mock,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AttestationReport {
pub provider: TeeProvider,
pub format: AttestationFormat,
pub issued_at_unix: u64,
pub measurement: Measurement,
pub public_key_binding: Option<PublicKeyBinding>,
pub claims: AttestationClaims,
pub evidence: Vec<u8>,
}
impl AttestationReport {
pub fn evidence_digest(&self) -> String {
use sha2::{Digest, Sha256};
let hash = Sha256::digest(&self.evidence);
hex::encode(hash)
}
pub fn is_expired(&self, max_age_secs: u64) -> bool {
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or(0);
now.saturating_sub(self.issued_at_unix) > max_age_secs
}
}