Skip to content

Commit 6c5ab24

Browse files
sarroutbiansasaki
authored andcommitted
Increase coverage of struct_filler.rs
Signed-off-by: Sergio Arroutbi <[email protected]>
1 parent 3c46585 commit 6c5ab24

File tree

1 file changed

+246
-0
lines changed

1 file changed

+246
-0
lines changed

keylime-push-model-agent/src/struct_filler.rs

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,78 @@ mod tests {
361361
assert!(context_info.flush_context().is_ok());
362362
} // test_attestation_request
363363

364+
#[tokio::test]
365+
async fn test_filler_from_hardware_get_attestation_request() {
366+
let _mutex = testing::lock_tests().await;
367+
let context_info_result = context_info::ContextInfo::new_from_str(
368+
context_info::AlgorithmConfigurationString {
369+
tpm_encryption_alg: "rsa".to_string(),
370+
tpm_hash_alg: "sha256".to_string(),
371+
tpm_signing_alg: "rsassa".to_string(),
372+
agent_data_path: "".to_string(),
373+
disabled_signing_algorithms: vec![],
374+
},
375+
);
376+
377+
let mut context_info = match context_info_result {
378+
Ok(ctx) => ctx,
379+
Err(e) => {
380+
println!("Skipping test_filler_from_hardware_get_attestation_request: TPM not available or failed to init: {e:?}");
381+
return;
382+
}
383+
};
384+
385+
let mut filler = FillerFromHardware::new(&mut context_info);
386+
387+
let request = filler.get_attestation_request();
388+
389+
assert_eq!(request.data.type_, "attestation");
390+
let attributes = request.data.attributes;
391+
assert_eq!(
392+
attributes.evidence_supported.len(),
393+
3,
394+
"Should contain tpm_quote, uefi_log, and ima_log evidence"
395+
);
396+
397+
let tpm_quote_evidence = attributes.evidence_supported.iter().find(|e| {
398+
matches!(e, structures::EvidenceSupported::Certification { evidence_type, .. } if evidence_type == "tpm_quote")
399+
}).expect("tpm_quote evidence not found");
400+
401+
if let structures::EvidenceSupported::Certification {
402+
capabilities,
403+
..
404+
} = tpm_quote_evidence
405+
{
406+
assert!(
407+
!capabilities.hash_algorithms.is_empty(),
408+
"Hash algorithms should be populated from TPM"
409+
);
410+
assert!(
411+
!capabilities.signature_schemes.is_empty(),
412+
"Signature schemes should be populated from TPM"
413+
);
414+
assert!(
415+
capabilities.available_subjects.sha256.is_some(),
416+
"SHA256 PCR banks should be populated"
417+
);
418+
assert!(
419+
!capabilities.certification_keys.is_empty(),
420+
"AK certification key should be present"
421+
);
422+
} else {
423+
panic!("Expected Certification evidence for tpm_quote");
424+
}
425+
426+
let _ = attributes.evidence_supported.iter().find(|e| {
427+
matches!(e, structures::EvidenceSupported::EvidenceLog { evidence_type, .. } if evidence_type == "ima_log")
428+
}).expect("ima_log evidence not found");
429+
430+
let _ = attributes.evidence_supported.iter().find(|e| {
431+
matches!(e, structures::EvidenceSupported::EvidenceLog { evidence_type, .. } if evidence_type == "uefi_log")
432+
}).expect("uefi_log evidence not found");
433+
assert!(context_info.flush_context().is_ok());
434+
}
435+
364436
#[tokio::test]
365437
async fn test_session_request() {
366438
use keylime::context_info;
@@ -482,4 +554,178 @@ mod tests {
482554
.await;
483555
assert!(context_info.flush_context().is_ok());
484556
}
557+
558+
#[tokio::test]
559+
async fn test_get_filler_request_with_tpm() {
560+
let _mutex = testing::lock_tests().await;
561+
let context_info_result = context_info::ContextInfo::new_from_str(
562+
context_info::AlgorithmConfigurationString {
563+
tpm_encryption_alg: "rsa".to_string(),
564+
tpm_hash_alg: "sha256".to_string(),
565+
tpm_signing_alg: "rsassa".to_string(),
566+
agent_data_path: "".to_string(),
567+
disabled_signing_algorithms: vec![],
568+
},
569+
);
570+
571+
if let Ok(mut ctx) = context_info_result {
572+
{
573+
let mut filler = get_filler_request(Some(&mut ctx));
574+
// To check the type, we can't directly compare types of Box<dyn Trait>.
575+
// A simple way is to check the output of a method.
576+
let req = filler.get_session_request();
577+
// FillerFromHardware returns a specific agent_id
578+
assert_eq!(req.data.attributes.agent_id, "example-agent");
579+
}
580+
assert!(ctx.clone().flush_context().is_ok());
581+
}
582+
}
583+
584+
#[tokio::test]
585+
async fn test_get_filler_request_without_tpm() {
586+
let mut filler = get_filler_request(None);
587+
// TestingFiller returns an empty auth_supported vector
588+
let req = filler.get_session_request();
589+
assert!(req.data.attributes.auth_supported.is_empty());
590+
}
591+
592+
#[tokio::test]
593+
async fn test_testing_filler_methods() {
594+
let mut filler = TestingFiller::new();
595+
596+
// Test get_attestation_request
597+
let attestation_req = filler.get_attestation_request();
598+
assert_eq!(attestation_req.data.type_, "attestation");
599+
assert!(attestation_req
600+
.data
601+
.attributes
602+
.evidence_supported
603+
.is_empty());
604+
605+
// Test get_session_request
606+
let session_req = filler.get_session_request();
607+
assert_eq!(session_req.data.data_type, "session");
608+
assert!(session_req.data.attributes.auth_supported.is_empty());
609+
610+
// Test get_evidence_handling_request
611+
let dummy_response = crate::attestation::ResponseInformation {
612+
status_code: reqwest::StatusCode::OK,
613+
headers: reqwest::header::HeaderMap::new(),
614+
body: "{}".to_string(),
615+
};
616+
let dummy_config = crate::attestation::NegotiationConfig {
617+
avoid_tpm: true,
618+
url: "",
619+
timeout: 0,
620+
ca_certificate: "",
621+
client_certificate: "",
622+
key: "",
623+
insecure: None,
624+
ima_log_path: None,
625+
uefi_log_path: None,
626+
max_retries: 0,
627+
initial_delay_ms: 0,
628+
max_delay_ms: None,
629+
verifier_url: "",
630+
};
631+
let evidence_req = filler
632+
.get_evidence_handling_request(&dummy_response, &dummy_config)
633+
.await;
634+
assert_eq!(evidence_req.data.data_type, "error");
635+
assert!(evidence_req.data.attributes.evidence_collected.is_empty());
636+
}
637+
638+
#[tokio::test]
639+
async fn test_filler_from_hardware_new_with_uefi_error() {
640+
let _mutex = testing::lock_tests().await;
641+
let context_info_result = context_info::ContextInfo::new_from_str(
642+
context_info::AlgorithmConfigurationString {
643+
tpm_encryption_alg: "rsa".to_string(),
644+
tpm_hash_alg: "sha256".to_string(),
645+
tpm_signing_alg: "rsassa".to_string(),
646+
agent_data_path: "".to_string(),
647+
disabled_signing_algorithms: vec![],
648+
},
649+
);
650+
651+
if let Ok(mut ctx) = context_info_result {
652+
// Temporarily override config to point to a non-existent path
653+
let original_path =
654+
std::env::var("KEYLIME_CONFIG_PATH").unwrap_or_default();
655+
std::env::set_var(
656+
"KEYLIME_CONFIG_PATH",
657+
"test-data/non-existent-config.conf",
658+
);
659+
660+
// Create a temporary config file with an invalid path for measuredboot_ml_path
661+
let temp_dir = tempfile::tempdir().unwrap();
662+
let config_path = temp_dir.path().join("keylime.conf");
663+
let mut file = std::fs::File::create(&config_path).unwrap();
664+
use std::io::Write;
665+
writeln!(file, "[agent]").unwrap();
666+
writeln!(
667+
file,
668+
"measuredboot_ml_path = /path/to/non/existent/log"
669+
)
670+
.unwrap();
671+
std::env::set_var("KEYLIME_CONFIG_PATH", config_path);
672+
673+
let filler = FillerFromHardware::new(&mut ctx);
674+
assert!(filler.uefi_log_handler.is_none());
675+
676+
// Restore original config path
677+
std::env::set_var("KEYLIME_CONFIG_PATH", original_path);
678+
assert!(ctx.flush_context().is_ok());
679+
}
680+
}
681+
682+
#[tokio::test]
683+
async fn test_get_evidence_handling_request_final_with_parsing_error() {
684+
let _mutex = testing::lock_tests().await;
685+
let context_info_result = context_info::ContextInfo::new_from_str(
686+
context_info::AlgorithmConfigurationString {
687+
tpm_encryption_alg: "rsa".to_string(),
688+
tpm_hash_alg: "sha256".to_string(),
689+
tpm_signing_alg: "rsassa".to_string(),
690+
agent_data_path: "".to_string(),
691+
disabled_signing_algorithms: vec![],
692+
},
693+
);
694+
695+
if let Ok(mut ctx) = context_info_result {
696+
let mut filler = FillerFromHardware::new(&mut ctx);
697+
let malformed_response =
698+
crate::attestation::ResponseInformation {
699+
status_code: reqwest::StatusCode::CREATED,
700+
headers: reqwest::header::HeaderMap::new(),
701+
body: "this is not valid json".to_string(),
702+
};
703+
let dummy_config = crate::attestation::NegotiationConfig {
704+
avoid_tpm: true,
705+
url: "",
706+
timeout: 0,
707+
ca_certificate: "",
708+
client_certificate: "",
709+
key: "",
710+
insecure: None,
711+
ima_log_path: None,
712+
uefi_log_path: None,
713+
max_retries: 0,
714+
initial_delay_ms: 0,
715+
max_delay_ms: None,
716+
verifier_url: "",
717+
};
718+
719+
let result = filler
720+
.get_evidence_handling_request_final(
721+
&malformed_response,
722+
&dummy_config,
723+
)
724+
.await;
725+
726+
assert_eq!(result.data.data_type, "error");
727+
assert!(result.data.attributes.evidence_collected.is_empty());
728+
assert!(ctx.flush_context().is_ok());
729+
}
730+
}
485731
}

0 commit comments

Comments
 (0)