Projects
Eulaceura:Factory
secGear
_service:obs_scm:0082-optimize-ima-verify.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:0082-optimize-ima-verify.patch of Package secGear
From 7d54eae7dbfdbad1de6bac40468c8de9a7260a8b Mon Sep 17 00:00:00 2001 From: houmingyong <houmingyong@huawei.com> Date: Mon, 26 Aug 2024 20:13:49 +0800 Subject: [PATCH 1/2] optimize ima verify Signed-off-by: houmingyong <houmingyong@huawei.com> --- .../attestation-service/service/src/lib.rs | 17 +++- .../attestation-service/verifier/src/lib.rs | 20 ---- .../verifier/src/virtcca/ima.rs | 93 +++++++++---------- .../verifier/src/virtcca/mod.rs | 13 ++- 4 files changed, 69 insertions(+), 74 deletions(-) diff --git a/service/attestation/attestation-service/service/src/lib.rs b/service/attestation/attestation-service/service/src/lib.rs index cc3f4328..3ec73d3d 100644 --- a/service/attestation/attestation-service/service/src/lib.rs +++ b/service/attestation/attestation-service/service/src/lib.rs @@ -100,11 +100,20 @@ impl AttestationService { let verifier = Verifier::default(); let claims_evidence = verifier.verify_evidence(user_data, evidence).await?; - let mut passed = false; - let ima_result = verifier.verify_ima(evidence, &claims_evidence).await; - if ima_result.is_ok() { - passed = true; + let mut passed = true; + log::debug!("claims evidece ima: {:?}", claims_evidence["ima"].clone()); + match claims_evidence["ima"].clone() { + serde_json::Value::Object(obj) => { + for (_k, v) in obj { + if v == Value::Bool(false) { + passed = false; + break; + } + } + } + _ => log::debug!("no ima result"), } + // get reference by keys in claims_evidence let mut ops_refs = ReferenceOps::default(); let refs_of_claims = ops_refs.query(&claims_evidence["payload"].to_string()); diff --git a/service/attestation/attestation-service/verifier/src/lib.rs b/service/attestation/attestation-service/verifier/src/lib.rs index 58df3bd4..0b776c29 100644 --- a/service/attestation/attestation-service/verifier/src/lib.rs +++ b/service/attestation/attestation-service/verifier/src/lib.rs @@ -34,10 +34,6 @@ pub struct Verifier {} #[async_trait] pub trait VerifierAPIs { async fn verify_evidence(&self, user_data: &[u8], evidence: &[u8]) -> Result<TeeClaim>; - async fn verify_ima(&self, - evidence: &[u8], - claim: &serde_json::Value, - ) -> Result<()>; } const MAX_CHALLENGE_LEN: usize = 64; @@ -61,20 +57,4 @@ impl VerifierAPIs for Verifier { _ => bail!("unsupported tee type:{:?}", tee_type), } } - async fn verify_ima(&self, - evidence: &[u8], - claim: &serde_json::Value, - ) -> Result<()> { - let aa_evidence: Evidence = serde_json::from_slice(evidence)?; - let tee_type = aa_evidence.tee; - let digest_list_file = "/etc/attestation/attestation-service/verifier/digest_list_file".to_string(); - match tee_type { - #[cfg(feature = "virtcca-verifier")] - TeeType::Virtcca => virtcca::ima::ImaVerify::default().ima_verify(evidence, claim, digest_list_file), - _ => { - log::info!("unsupported ima type:{:?}", tee_type); - Ok(()) - }, - } - } } diff --git a/service/attestation/attestation-service/verifier/src/virtcca/ima.rs b/service/attestation/attestation-service/verifier/src/virtcca/ima.rs index 44292e83..30a151fa 100644 --- a/service/attestation/attestation-service/verifier/src/virtcca/ima.rs +++ b/service/attestation/attestation-service/verifier/src/virtcca/ima.rs @@ -12,46 +12,20 @@ use anyhow::{Result, bail}; use ima_measurements::{Event, EventData, Parser}; use fallible_iterator::FallibleIterator; -use std::fs; -use std::process::Command; -use serde_json::Value; -use rand::Rng; +use serde_json::{Value, Map, json}; -use attestation_types::{Evidence, VirtccaEvidence}; +const IMA_REFERENCE_FILE: &str = "/etc/attestation/attestation-service/verifier/virtcca/ima/digest_list_file"; -#[derive(Debug)] -pub struct ImaVerify { - log_path: String, -} - -impl Default for ImaVerify { - fn default() -> Self { - let mut rng = rand::thread_rng(); - let n: u64 = rng.gen(); - ImaVerify { - // log_path: format!("/tmp/attestation-service/ima-log-{}", n), // todo fs::write depends attestation-service dir exist - log_path: format!("/tmp/ima-log-{}", n), - } - } -} +#[derive(Debug, Default)] +pub struct ImaVerify {} impl ImaVerify { - // todo return detail verify result list with policy - pub fn ima_verify(&self, evidence: &[u8], claim: &Value, digest_list_file: String) -> Result<()> { - let aa_evidence: Evidence = serde_json::from_slice(evidence)?; - let evidence = aa_evidence.evidence.as_bytes(); - let virtcca_ev: VirtccaEvidence = serde_json::from_slice(evidence)?; - let ima_log = match virtcca_ev.ima_log { - Some(ima_log) => ima_log, - _ => {log::info!("no ima log"); return Ok(())}, - }; - - fs::write(&self.log_path, &ima_log).expect("write img log failed"); - let f = fs::File::open(&self.log_path).expect("ima log file not found"); - - let claim_ima_log_hash = claim["payload"]["cvm"]["rem"][0].clone(); - let mut parser = Parser::new(f); + pub fn ima_verify(&self, ima_log: &[u8], ima_log_hash: Vec<u8>) -> Result<Value> { + if ima_log.to_vec().is_empty() { + return Ok(json!({})); + } + let mut parser = Parser::new(ima_log); let mut events: Vec<Event> = Vec::new(); while let Some(event) = parser.next()? { events.push(event); @@ -60,32 +34,55 @@ impl ImaVerify { let pcr_values = parser.pcr_values(); let pcr_10 = pcr_values.get(&10).expect("PCR 10 not measured"); let string_pcr_sha256 = hex::encode(pcr_10.sha256); + let string_ima_log_hash = hex::encode(ima_log_hash); - if Value::String(string_pcr_sha256.clone()) != claim_ima_log_hash { - log::error!("ima log verify failed string_pcr_sha256 {}, string_claim_ima_log_hash {}", string_pcr_sha256, claim_ima_log_hash); + if string_pcr_sha256.clone() != string_ima_log_hash { + log::error!("ima log verify failed string_pcr_sha256 {}, string_ima_log_hash {}", + string_pcr_sha256, string_ima_log_hash); bail!("ima log hash verify failed"); } + let ima_refs: Vec<_> = file_reader(IMA_REFERENCE_FILE)? + .into_iter() + .map(String::from) + .collect(); + + let mut ima_detail = Map::new(); // parser each file digest in ima log, and compare with reference base value for event in events { - let file_digest = match event.data { - EventData::ImaNg{digest, name} => {drop(name); digest.digest}, + let (name ,file_digest) = match event.data { + EventData::ImaNg{digest, name} => (name, digest.digest), _ => bail!("Inalid event {:?}", event), }; let hex_str_digest = hex::encode(file_digest); - //log::info!("hex_str_digest {}", hex_str_digest); - let output = Command::new("grep") - .arg("-E") - .arg("-i") - .arg(&hex_str_digest) - .arg(&digest_list_file) - .output()?; - if output.stdout.is_empty() { + if ima_refs.contains(&hex_str_digest) { + ima_detail.insert(name, Value::Bool(true)); + } else { log::error!("there is no refernce base value of file digest {:?}", hex_str_digest); + ima_detail.insert(name, Value::Bool(false)); } } + let js_ima_detail: Value = ima_detail.into(); + log::debug!("ima verify detail result: {:?}", js_ima_detail); - Ok(()) + Ok(js_ima_detail) } } +use std::io::BufRead; +use std::io::BufReader; +fn file_reader(file_path: &str) -> ::std::io::Result<Vec<String>> { + let file = std::fs::File::open(file_path)?; + let mut strings = Vec::<String>::new(); + let mut reader = BufReader::new(file); + let mut buf = String::new(); + let mut n: usize; + loop { + n = reader.read_line(&mut buf)?; + if n == 0 { break; } + buf.pop(); + strings.push(buf.clone()); + buf.clear(); + } + Ok(strings) +} diff --git a/service/attestation/attestation-service/verifier/src/virtcca/mod.rs b/service/attestation/attestation-service/verifier/src/virtcca/mod.rs index 3ececb78..a99f9358 100644 --- a/service/attestation/attestation-service/verifier/src/virtcca/mod.rs +++ b/service/attestation/attestation-service/verifier/src/virtcca/mod.rs @@ -103,10 +103,18 @@ impl Evidence { // verify cvm token evidence.verify_cvm_token(user_data)?; + // verify ima + let ima_log = match virtcca_ev.ima_log { + Some(ima_log) => ima_log, + _ => {log::info!("no ima log"); vec![]}, + }; + let ima: serde_json::Value = ima::ImaVerify::default() + .ima_verify(&ima_log, evidence.cvm_token.rem[0].clone())?; + // todo parsed TeeClaim - evidence.parse_claim_from_evidence() + evidence.parse_claim_from_evidence(ima) } - fn parse_claim_from_evidence(&self) -> Result<TeeClaim> { + fn parse_claim_from_evidence(&self, ima: serde_json::Value) -> Result<TeeClaim> { let payload = json!({ "vcca.cvm.challenge": hex::encode(self.cvm_token.challenge.clone()), "vcca.cvm.rpv": hex::encode(self.cvm_token.rpv.clone()), @@ -120,6 +128,7 @@ impl Evidence { let claim = json!({ "tee": "vcca", "payload" : payload, + "ima": ima, }); Ok(claim as TeeClaim) } -- 2.46.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2