Skip to content

Commit b1a2c29

Browse files
committed
test_utils: Verify expected pcrs based on TestContext
Refactor the logic that was verifying expected image pcrs in test_image_pcrs_configmap_updates as a method of TestContext. It also slightly changes the logic of the poller to stop when the length of pcrs equals the one expected. Signed-off-by: Beñat Gartzia Arruabarrena <bgartzia@redhat.com>
1 parent f463c86 commit b1a2c29

2 files changed

Lines changed: 271 additions & 96 deletions

File tree

test_utils/src/lib.rs

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::path::Path;
1212
use std::sync::Once;
1313
use std::time::Duration;
1414
use tokio::process::Command;
15+
use trusted_cluster_operator_lib::reference_values::ImagePcrs;
1516

1617
pub mod timer;
1718
pub use timer::Poller;
@@ -528,6 +529,95 @@ resources:
528529

529530
Ok(())
530531
}
532+
533+
pub async fn verify_expected_pcrs(&self, expected_pcrs: &[&[Pcr]]) -> anyhow::Result<()> {
534+
let client = self.client();
535+
let namespace = self.namespace();
536+
537+
let configmap_api: Api<ConfigMap> = Api::namespaced(client.clone(), namespace);
538+
539+
let poller = Poller::new()
540+
.with_timeout(Duration::from_secs(180))
541+
.with_interval(Duration::from_secs(5))
542+
.with_error_message("image-pcrs ConfigMap not populated with data".to_string());
543+
544+
poller
545+
.poll_async(|| {
546+
let api = configmap_api.clone();
547+
async move {
548+
let cm = api.get("image-pcrs").await?;
549+
550+
if let Some(data) = &cm.data
551+
&& let Some(image_pcrs_json) = data.get("image-pcrs.json")
552+
&& let Ok(image_pcrs) = serde_json::from_str::<ImagePcrs>(image_pcrs_json)
553+
&& image_pcrs.0.len() == expected_pcrs.len()
554+
{
555+
return Ok(());
556+
}
557+
558+
Err(anyhow::anyhow!(
559+
"image-pcrs ConfigMap not yet populated with image-pcrs.json data"
560+
))
561+
}
562+
})
563+
.await?;
564+
565+
let image_pcrs_cm = configmap_api.get("image-pcrs").await?;
566+
assert_eq!(image_pcrs_cm.metadata.name.as_deref(), Some("image-pcrs"));
567+
568+
let data = image_pcrs_cm
569+
.data
570+
.as_ref()
571+
.expect("image-pcrs ConfigMap should have data field");
572+
573+
assert!(!data.is_empty(), "image-pcrs ConfigMap should have data");
574+
575+
let image_pcrs_json = data
576+
.get("image-pcrs.json")
577+
.expect("image-pcrs ConfigMap should have image-pcrs.json key");
578+
579+
assert!(
580+
!image_pcrs_json.is_empty(),
581+
"image-pcrs.json should not be empty"
582+
);
583+
584+
// Parse the image-pcrs.json using the ImagePcrs structure
585+
let image_pcrs: ImagePcrs = serde_json::from_str(image_pcrs_json)
586+
.expect("image-pcrs.json should be valid ImagePcrs JSON");
587+
588+
assert!(
589+
!image_pcrs.0.is_empty(),
590+
"image-pcrs.json should contain at least one image entry"
591+
);
592+
593+
test_info!(
594+
&self.test_name,
595+
"Checking into {} image results:",
596+
image_pcrs.0.len()
597+
);
598+
let mut found_expected_pcrs = false;
599+
600+
assert_eq!(
601+
image_pcrs.0.len(),
602+
expected_pcrs.len(),
603+
"image-pcrs.json should contain {} image entries",
604+
expected_pcrs.len()
605+
);
606+
607+
for (i, (_image_ref, image_data)) in image_pcrs.0.iter().enumerate() {
608+
if compare_pcrs(&image_data.pcrs, expected_pcrs[i]) {
609+
found_expected_pcrs = true;
610+
break;
611+
}
612+
}
613+
614+
assert!(
615+
found_expected_pcrs,
616+
"At least one image should have the expected PCR values"
617+
);
618+
619+
Ok(())
620+
}
531621
}
532622

533623
#[macro_export]

tests/trusted_execution_cluster.rs

Lines changed: 181 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ use k8s_openapi::api::apps::v1::Deployment;
88
use k8s_openapi::api::core::v1::ConfigMap;
99
use kube::{Api, api::DeleteParams};
1010
use std::time::Duration;
11-
use trusted_cluster_operator_lib::reference_values::ImagePcrs;
1211
use trusted_cluster_operator_lib::{ApprovedImage, TrustedExecutionCluster};
1312
use trusted_cluster_operator_test_utils::*;
1413

@@ -45,102 +44,188 @@ named_test!(
4544
named_test! {
4645
async fn test_image_pcrs_configmap_updates() -> anyhow::Result<()> {
4746
let test_ctx = setup!().await?;
48-
let client = test_ctx.client();
49-
let namespace = test_ctx.namespace();
50-
51-
let configmap_api: Api<ConfigMap> = Api::namespaced(client.clone(), namespace);
52-
53-
let poller = Poller::new()
54-
.with_timeout(Duration::from_secs(180))
55-
.with_interval(Duration::from_secs(5))
56-
.with_error_message("image-pcrs ConfigMap not populated with data".to_string());
57-
58-
poller
59-
.poll_async(|| {
60-
let api = configmap_api.clone();
61-
async move {
62-
let cm = api.get("image-pcrs").await?;
63-
64-
if let Some(data) = &cm.data
65-
&& let Some(image_pcrs_json) = data.get("image-pcrs.json")
66-
&& let Ok(image_pcrs) = serde_json::from_str::<ImagePcrs>(image_pcrs_json)
67-
&& !image_pcrs.0.is_empty()
68-
{
69-
return Ok(());
70-
}
71-
72-
Err(anyhow::anyhow!("image-pcrs ConfigMap not yet populated with image-pcrs.json data"))
73-
}
74-
})
75-
.await?;
76-
77-
let image_pcrs_cm = configmap_api.get("image-pcrs").await?;
78-
assert_eq!(image_pcrs_cm.metadata.name.as_deref(), Some("image-pcrs"));
79-
80-
let data = image_pcrs_cm.data.as_ref()
81-
.expect("image-pcrs ConfigMap should have data field");
82-
83-
assert!(!data.is_empty(), "image-pcrs ConfigMap should have data");
84-
85-
let image_pcrs_json = data.get("image-pcrs.json")
86-
.expect("image-pcrs ConfigMap should have image-pcrs.json key");
87-
88-
assert!(!image_pcrs_json.is_empty(), "image-pcrs.json should not be empty");
89-
90-
// Parse the image-pcrs.json using the ImagePcrs structure
91-
let image_pcrs: ImagePcrs = serde_json::from_str(image_pcrs_json)
92-
.expect("image-pcrs.json should be valid ImagePcrs JSON");
93-
94-
assert!(!image_pcrs.0.is_empty(), "image-pcrs.json should contain at least one image entry");
95-
96-
let expected_pcrs = vec![
97-
Pcr {
98-
id: 4,
99-
value: hex::decode(EXPECTED_PCR4).unwrap(),
100-
events: vec![
101-
TPMEvent { pcr: 4, name: "EV_EFI_ACTION".to_string(), hash: hex::decode("3d6772b4f84ed47595d72a2c4c5ffd15f5bb72c7507fe26f2aaee2c69d5633ba").unwrap(), id: TPMEventID::Pcr4EfiCall },
102-
TPMEvent { pcr: 4, name: "EV_SEPARATOR".to_string(), hash: hex::decode("df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119").unwrap(), id: TPMEventID::Pcr4Separator },
103-
TPMEvent { pcr: 4, name: "EV_EFI_BOOT_SERVICES_APPLICATION".to_string(), hash: hex::decode("94896c17d49fc8c8df0cc2836611586edab1615ce7cb58cf13fc5798de56b367").unwrap(), id: TPMEventID::Pcr4Shim },
104-
TPMEvent { pcr: 4, name: "EV_EFI_BOOT_SERVICES_APPLICATION".to_string(), hash: hex::decode("bc6844fc7b59b4f0c7da70a307fc578465411d7a2c34b0f4dc2cc154c873b644").unwrap(), id: TPMEventID::Pcr4Grub },
105-
TPMEvent { pcr: 4, name: "EV_EFI_BOOT_SERVICES_APPLICATION".to_string(), hash: hex::decode("2b1dc59bc61dbbc3db11a6f3b0708c948efd46cceb7f6c8ea2024b8d1b8c829a").unwrap(), id: TPMEventID::Pcr4Vmlinuz },
106-
],
107-
},
108-
Pcr {
109-
id: 7,
110-
value: hex::decode("b3a56a06c03a65277d0a787fcabc1e293eaa5d6dd79398f2dda741f7b874c65d").unwrap(),
111-
events: vec![
112-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(), hash: hex::decode("ccfc4bb32888a345bc8aeadaba552b627d99348c767681ab3141f5b01e40a40e").unwrap(), id: TPMEventID::Pcr7SecureBoot },
113-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(), hash: hex::decode("adb6fc232943e39c374bf4782b6c697f43c39fca1f4b51dfceda21164e19a893").unwrap(), id: TPMEventID::Pcr7Pk },
114-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(), hash: hex::decode("b5432fe20c624811cb0296391bfdf948ebd02f0705ab8229bea09774023f0ebf").unwrap(), id: TPMEventID::Pcr7Kek },
115-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(), hash: hex::decode("4313e43de720194a0eabf4d6415d42b5a03a34fdc47bb1fc924cc4e665e6893d").unwrap(), id: TPMEventID::Pcr7Db },
116-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(), hash: hex::decode("001004ba58a184f09be6c1f4ec75a246cc2eefa9637b48ee428b6aa9bce48c55").unwrap(), id: TPMEventID::Pcr7Dbx },
117-
TPMEvent { pcr: 7, name: "EV_SEPARATOR".to_string(), hash: hex::decode("df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119").unwrap(), id: TPMEventID::Pcr7Separator },
118-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_AUTHORITY".to_string(), hash: hex::decode("4d4a8e2c74133bbdc01a16eaf2dbb5d575afeb36f5d8dfcf609ae043909e2ee9").unwrap(), id: TPMEventID::Pcr7ShimCert },
119-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_AUTHORITY".to_string(), hash: hex::decode("e8e9578f5951ef16b1c1aa18ef02944b8375ec45ed4b5d8cdb30428db4a31016").unwrap(), id: TPMEventID::Pcr7SbatLevel },
120-
TPMEvent { pcr: 7, name: "EV_EFI_VARIABLE_AUTHORITY".to_string(), hash: hex::decode("ad5901fd581e6640c742c488083b9ac2c48255bd28a16c106c6f9df52702ee3f").unwrap(), id: TPMEventID::Pcr7GrubMokListCert },
121-
],
122-
},
123-
Pcr {
124-
id: 14,
125-
value: hex::decode("17cdefd9548f4383b67a37a901673bf3c8ded6f619d36c8007562de1d93c81cc").unwrap(),
126-
events: vec![
127-
TPMEvent { pcr: 14, name: "EV_IPL".to_string(), hash: hex::decode("e8e48e3ad10bc243341b4663c0057aef0ec7894ccc9ecb0598f0830fa57f7220").unwrap(), id: TPMEventID::Pcr14MokList },
128-
TPMEvent { pcr: 14, name: "EV_IPL".to_string(), hash: hex::decode("8d8a3aae50d5d25838c95c034aadce7b548c9a952eb7925e366eda537c59c3b0").unwrap(), id: TPMEventID::Pcr14MokListX },
129-
TPMEvent { pcr: 14, name: "EV_IPL".to_string(), hash: hex::decode("4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a").unwrap(), id: TPMEventID::Pcr14MokListTrusted },
130-
],
131-
},
132-
];
133-
134-
let mut found_expected_pcrs = false;
135-
for (_image_ref, image_data) in image_pcrs.0.iter() {
136-
if compare_pcrs(&image_data.pcrs, &expected_pcrs) {
137-
found_expected_pcrs = true;
138-
break;
139-
}
140-
}
14147

142-
assert!(found_expected_pcrs,
143-
"At least one image should have the expected PCR values");
48+
test_ctx.verify_expected_pcrs(
49+
&[&[
50+
Pcr {
51+
id: 4,
52+
value: hex::decode(EXPECTED_PCR4).unwrap(),
53+
events: vec![
54+
TPMEvent {
55+
pcr: 4,
56+
name: "EV_EFI_ACTION".to_string(),
57+
hash: hex::decode(
58+
"3d6772b4f84ed47595d72a2c4c5ffd15f5bb72c7507fe26f2aaee2c69d5633ba",
59+
)
60+
.unwrap(),
61+
id: TPMEventID::Pcr4EfiCall,
62+
},
63+
TPMEvent {
64+
pcr: 4,
65+
name: "EV_SEPARATOR".to_string(),
66+
hash: hex::decode(
67+
"df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119",
68+
)
69+
.unwrap(),
70+
id: TPMEventID::Pcr4Separator,
71+
},
72+
TPMEvent {
73+
pcr: 4,
74+
name: "EV_EFI_BOOT_SERVICES_APPLICATION".to_string(),
75+
hash: hex::decode(
76+
"94896c17d49fc8c8df0cc2836611586edab1615ce7cb58cf13fc5798de56b367",
77+
)
78+
.unwrap(),
79+
id: TPMEventID::Pcr4Shim,
80+
},
81+
TPMEvent {
82+
pcr: 4,
83+
name: "EV_EFI_BOOT_SERVICES_APPLICATION".to_string(),
84+
hash: hex::decode(
85+
"bc6844fc7b59b4f0c7da70a307fc578465411d7a2c34b0f4dc2cc154c873b644",
86+
)
87+
.unwrap(),
88+
id: TPMEventID::Pcr4Grub,
89+
},
90+
TPMEvent {
91+
pcr: 4,
92+
name: "EV_EFI_BOOT_SERVICES_APPLICATION".to_string(),
93+
hash: hex::decode(
94+
"2b1dc59bc61dbbc3db11a6f3b0708c948efd46cceb7f6c8ea2024b8d1b8c829a",
95+
)
96+
.unwrap(),
97+
id: TPMEventID::Pcr4Vmlinuz,
98+
},
99+
],
100+
},
101+
Pcr {
102+
id: 7,
103+
value: hex::decode(
104+
"b3a56a06c03a65277d0a787fcabc1e293eaa5d6dd79398f2dda741f7b874c65d",
105+
)
106+
.unwrap(),
107+
events: vec![
108+
TPMEvent {
109+
pcr: 7,
110+
name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(),
111+
hash: hex::decode(
112+
"ccfc4bb32888a345bc8aeadaba552b627d99348c767681ab3141f5b01e40a40e",
113+
)
114+
.unwrap(),
115+
id: TPMEventID::Pcr7SecureBoot,
116+
},
117+
TPMEvent {
118+
pcr: 7,
119+
name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(),
120+
hash: hex::decode(
121+
"adb6fc232943e39c374bf4782b6c697f43c39fca1f4b51dfceda21164e19a893",
122+
)
123+
.unwrap(),
124+
id: TPMEventID::Pcr7Pk,
125+
},
126+
TPMEvent {
127+
pcr: 7,
128+
name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(),
129+
hash: hex::decode(
130+
"b5432fe20c624811cb0296391bfdf948ebd02f0705ab8229bea09774023f0ebf",
131+
)
132+
.unwrap(),
133+
id: TPMEventID::Pcr7Kek,
134+
},
135+
TPMEvent {
136+
pcr: 7,
137+
name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(),
138+
hash: hex::decode(
139+
"4313e43de720194a0eabf4d6415d42b5a03a34fdc47bb1fc924cc4e665e6893d",
140+
)
141+
.unwrap(),
142+
id: TPMEventID::Pcr7Db,
143+
},
144+
TPMEvent {
145+
pcr: 7,
146+
name: "EV_EFI_VARIABLE_DRIVER_CONFIG".to_string(),
147+
hash: hex::decode(
148+
"001004ba58a184f09be6c1f4ec75a246cc2eefa9637b48ee428b6aa9bce48c55",
149+
)
150+
.unwrap(),
151+
id: TPMEventID::Pcr7Dbx,
152+
},
153+
TPMEvent {
154+
pcr: 7,
155+
name: "EV_SEPARATOR".to_string(),
156+
hash: hex::decode(
157+
"df3f619804a92fdb4057192dc43dd748ea778adc52bc498ce80524c014b81119",
158+
)
159+
.unwrap(),
160+
id: TPMEventID::Pcr7Separator,
161+
},
162+
TPMEvent {
163+
pcr: 7,
164+
name: "EV_EFI_VARIABLE_AUTHORITY".to_string(),
165+
hash: hex::decode(
166+
"4d4a8e2c74133bbdc01a16eaf2dbb5d575afeb36f5d8dfcf609ae043909e2ee9",
167+
)
168+
.unwrap(),
169+
id: TPMEventID::Pcr7ShimCert,
170+
},
171+
TPMEvent {
172+
pcr: 7,
173+
name: "EV_EFI_VARIABLE_AUTHORITY".to_string(),
174+
hash: hex::decode(
175+
"e8e9578f5951ef16b1c1aa18ef02944b8375ec45ed4b5d8cdb30428db4a31016",
176+
)
177+
.unwrap(),
178+
id: TPMEventID::Pcr7SbatLevel,
179+
},
180+
TPMEvent {
181+
pcr: 7,
182+
name: "EV_EFI_VARIABLE_AUTHORITY".to_string(),
183+
hash: hex::decode(
184+
"ad5901fd581e6640c742c488083b9ac2c48255bd28a16c106c6f9df52702ee3f",
185+
)
186+
.unwrap(),
187+
id: TPMEventID::Pcr7GrubMokListCert,
188+
},
189+
],
190+
},
191+
Pcr {
192+
id: 14,
193+
value: hex::decode(
194+
"17cdefd9548f4383b67a37a901673bf3c8ded6f619d36c8007562de1d93c81cc",
195+
)
196+
.unwrap(),
197+
events: vec![
198+
TPMEvent {
199+
pcr: 14,
200+
name: "EV_IPL".to_string(),
201+
hash: hex::decode(
202+
"e8e48e3ad10bc243341b4663c0057aef0ec7894ccc9ecb0598f0830fa57f7220",
203+
)
204+
.unwrap(),
205+
id: TPMEventID::Pcr14MokList,
206+
},
207+
TPMEvent {
208+
pcr: 14,
209+
name: "EV_IPL".to_string(),
210+
hash: hex::decode(
211+
"8d8a3aae50d5d25838c95c034aadce7b548c9a952eb7925e366eda537c59c3b0",
212+
)
213+
.unwrap(),
214+
id: TPMEventID::Pcr14MokListX,
215+
},
216+
TPMEvent {
217+
pcr: 14,
218+
name: "EV_IPL".to_string(),
219+
hash: hex::decode(
220+
"4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a",
221+
)
222+
.unwrap(),
223+
id: TPMEventID::Pcr14MokListTrusted,
224+
},
225+
],
226+
},
227+
]]
228+
).await?;
144229

145230
test_ctx.cleanup().await?;
146231

0 commit comments

Comments
 (0)