#![cfg(feature = "live-evidence")]
use crate::bitcoin_process_monitor::BitcoinProcessEvidence;
use crate::digest::TypedDigest;
use crate::live_tpm::LiveTpmDevice;
use crate::secure_boot_collector::SecureBootCollector;
use alloc::vec::Vec;
#[derive(Debug, Clone)]
pub struct LiveAttestationPayload {
pub sequence_number: u64,
pub collection_timestamp: u64,
pub secure_boot_state: Option<SecureBootCollector>,
pub process_evidence: Option<BitcoinProcessEvidence>,
pub tpm_quote: Vec<u8>,
pub pcr_banks: Vec<Vec<u8>>,
}
#[derive(Debug)]
pub struct EvidencePipeline {
tpm: LiveTpmDevice,
sequence_counter: u64,
}
impl EvidencePipeline {
pub fn new(tpm_device_path: &str) -> Result<Self, &'static str> {
let tpm = LiveTpmDevice::connect(tpm_device_path)?;
Ok(Self {
tpm,
sequence_counter: 0,
})
}
pub fn acquire_evidence(
&mut self,
nonce: &[u8],
pcr_indices: &[u32],
) -> Result<LiveAttestationPayload, &'static str> {
self.sequence_counter += 1;
let (tpm_clock, _) = self.tpm.read_clock_info().unwrap_or((0, 0));
let tpm_quote = self
.tpm
.acquire_quote(nonce, pcr_indices)
.unwrap_or_default();
let mut pcr_banks = Vec::new();
for &algo in &self.tpm.supported_banks {
if let Ok(bank) = self.tpm.read_pcr_bank(algo) {
pcr_banks.push(bank);
}
}
let secure_boot_state = SecureBootCollector::collect().ok();
let process_evidence = BitcoinProcessEvidence::collect().ok();
Ok(LiveAttestationPayload {
sequence_number: self.sequence_counter,
collection_timestamp: tpm_clock, secure_boot_state,
process_evidence,
tpm_quote,
pcr_banks,
})
}
}