| 76 | } |
| 77 | |
| 78 | async fn run_oneshot(file_path: &str, config: &Config) -> anyhow::Result<()> { |
| 79 | use std::fs; |
| 80 | |
| 81 | info!("Running in oneshot mode for file: {}", file_path); |
| 82 | |
| 83 | // Read the JSON file |
| 84 | let content = fs::read_to_string(file_path) |
| 85 | .map_err(|e| anyhow::anyhow!("Failed to read file {}: {}", file_path, e))?; |
| 86 | |
| 87 | // Parse as VerificationRequest |
| 88 | let request: VerificationRequest = serde_json::from_str(&content) |
| 89 | .map_err(|e| anyhow::anyhow!("Failed to parse JSON: {}", e))?; |
| 90 | |
| 91 | // Create verifier |
| 92 | let verifier = CvmVerifier::new( |
| 93 | config.image_cache_dir.clone(), |
| 94 | config.image_download_url.clone(), |
| 95 | std::time::Duration::from_secs(config.image_download_timeout_secs), |
| 96 | config.pccs_url.clone(), |
| 97 | ); |
| 98 | |
| 99 | // Run verification |
| 100 | info!("Starting verification..."); |
| 101 | let response = verifier.verify(request).await?; |
| 102 | |
| 103 | // Persist response next to the input file for convenience |
| 104 | let output_path = format!("{file_path}.verification.json"); |
| 105 | let serialized = serde_json::to_string_pretty(&response) |
| 106 | .map_err(|e| anyhow::anyhow!("Failed to encode verification result: {}", e))?; |
| 107 | fs::write(&output_path, serialized).map_err(|e| { |
| 108 | anyhow::anyhow!( |
| 109 | "Failed to write verification result to {}: {}", |
| 110 | output_path, |
| 111 | e |
| 112 | ) |
| 113 | })?; |
| 114 | info!("Stored verification result at {}", output_path); |
| 115 | |
| 116 | // Output results |
| 117 | println!("\n=== Verification Results ==="); |
| 118 | println!("Valid: {}", response.is_valid); |
| 119 | println!("Quote verified: {}", response.details.quote_verified); |
| 120 | println!( |
| 121 | "Event log verified: {}", |
| 122 | response.details.event_log_verified |
| 123 | ); |
| 124 | println!( |
| 125 | "OS image hash verified: {}", |
| 126 | response.details.os_image_hash_verified |
| 127 | ); |
| 128 | |
| 129 | if let Some(tcb_status) = &response.details.tcb_status { |
| 130 | println!("TCB status: {}", tcb_status); |
| 131 | } |
| 132 | |
| 133 | if !response.details.advisory_ids.is_empty() { |
| 134 | println!("Advisory IDs: {:?}", response.details.advisory_ids); |
| 135 | } |