use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::sync::RwLock;
use tracing::debug;
use crate::config::AppConfig;
use crate::error::AppError;
use crate::tee::TeeState;
use crate::tee::types::{AttestationResponse, TeeStatus};
pub fn get_tee_status(tee_state: &TeeState) -> TeeStatus {
tee_state.status.clone()
}
pub async fn generate_attestation_report(
tee_state: &TeeState,
config: &Arc<RwLock<AppConfig>>,
nonce: &str,
) -> Result<AttestationResponse, AppError> {
let nonce_bytes = hex::decode(nonce)
.map_err(|e| AppError::Validation(format!("nonce must be hex-encoded: {e}")))?;
if nonce_bytes.is_empty() || nonce_bytes.len() > 64 {
return Err(AppError::Validation(
"nonce must be 1-64 bytes (2-128 hex chars)".into(),
));
}
let vta_did = config.read().await.vta_did.clone();
let user_data = vta_did.as_deref().unwrap_or("").as_bytes();
debug!(nonce_len = nonce_bytes.len(), "generating attestation report");
let mut report = tee_state.provider.attest(user_data, &nonce_bytes)?;
report.vta_did = vta_did;
let self_verified = tee_state.provider.verify(&report)?;
Ok(AttestationResponse {
report,
self_verified,
})
}
pub async fn get_cached_report(
tee_state: &TeeState,
config: &Arc<RwLock<AppConfig>>,
) -> Result<AttestationResponse, AppError> {
let cache_ttl = {
#[cfg(feature = "tee")]
{
config.read().await.tee.attestation_cache_ttl
}
#[cfg(not(feature = "tee"))]
{
let _ = config;
300u64
}
};
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_secs();
let time_bucket = now / cache_ttl;
let nonce = hex::encode(time_bucket.to_be_bytes());
generate_attestation_report(tee_state, config, &nonce).await
}