use crate::attestation::report::AttestationReport;
use crate::attestation::verifier::{AttestationVerifier, VerifiedAttestation};
use crate::config::TeeProvider;
use crate::errors::TeeError;
#[derive(Debug, Clone)]
pub enum NativePlatform {
Tdx {
expected_mrtd: Option<String>,
},
SevSnp {
expected_measurement: Option<String>,
},
}
pub struct NativeVerifier {
pub platform: NativePlatform,
pub allow_debug: bool,
}
impl NativeVerifier {
pub fn tdx() -> Self {
Self {
platform: NativePlatform::Tdx {
expected_mrtd: None,
},
allow_debug: false,
}
}
pub fn sev_snp() -> Self {
Self {
platform: NativePlatform::SevSnp {
expected_measurement: None,
},
allow_debug: false,
}
}
pub fn with_expected_measurement(mut self, measurement: impl Into<String>) -> Self {
let m = measurement.into();
match &mut self.platform {
NativePlatform::Tdx { expected_mrtd } => *expected_mrtd = Some(m),
NativePlatform::SevSnp {
expected_measurement,
} => *expected_measurement = Some(m),
}
self
}
pub fn with_allow_debug(mut self, allow: bool) -> Self {
self.allow_debug = allow;
self
}
fn expected_provider(&self) -> TeeProvider {
match &self.platform {
NativePlatform::Tdx { .. } => TeeProvider::IntelTdx,
NativePlatform::SevSnp { .. } => TeeProvider::AmdSevSnp,
}
}
fn expected_measurement(&self) -> Option<&str> {
match &self.platform {
NativePlatform::Tdx { expected_mrtd } => expected_mrtd.as_deref(),
NativePlatform::SevSnp {
expected_measurement,
} => expected_measurement.as_deref(),
}
}
fn platform_name(&self) -> &'static str {
match &self.platform {
NativePlatform::Tdx { .. } => "Intel TDX",
NativePlatform::SevSnp { .. } => "AMD SEV-SNP",
}
}
fn debug_entity(&self) -> &'static str {
match &self.platform {
NativePlatform::Tdx { .. } => "debug mode TDs",
NativePlatform::SevSnp { .. } => "debug mode guests",
}
}
}
impl AttestationVerifier for NativeVerifier {
fn verify(&self, report: &AttestationReport) -> Result<VerifiedAttestation, TeeError> {
let expected_provider = self.expected_provider();
if report.provider != expected_provider {
return Err(TeeError::AttestationVerification(format!(
"expected {} provider, got {}",
self.platform_name(),
report.provider
)));
}
if report.claims.debug_mode && !self.allow_debug {
return Err(TeeError::AttestationVerification(format!(
"{} are not permitted",
self.debug_entity()
)));
}
if let Some(expected) = self.expected_measurement() {
if report.measurement.digest != expected {
return Err(TeeError::MeasurementMismatch {
expected: expected.to_string(),
actual: report.measurement.digest.clone(),
});
}
}
tracing::debug!(
"structural validation only — cryptographic signature verification requires platform SDK"
);
Ok(VerifiedAttestation::new(report.clone(), expected_provider))
}
fn supported_provider(&self) -> TeeProvider {
self.expected_provider()
}
}