Skip to content

Commit a301dde

Browse files
sarroutbiGeminiclaude
committed
Improve TLS testing infrastructure and reliability
This change consolidates duplicate certificate generation code and improves test infrastructure reliability based on code review feedback. Key improvements: 1. Consolidate Certificate Generation Utilities: - Removed three separate and nearly identical certificate generation helper functions from https_client.rs, registration.rs, and registrar_client.rs (261 lines of duplicate code eliminated) - Introduced a single, comprehensive utility function crypto::testing::generate_tls_certs_for_test that creates CA, server, and client certificate sets for testing purposes - All relevant tests refactored to use this new shared utility, reducing code duplication and improving maintainability 2. Strengthen Mockoon TLS Test Assertion: - Fixed weak assertion assert!(result.is_err() || result.is_ok()) in test_mockoon_registrar_https_registration test - Changed to assert!(result.is_err()) to specifically verify that connection fails as expected when mock server lacks TLS configuration 3. Replace Brittle Sleep with Polling Mechanism: - Replaced sleep 3 command in tests/mockoon_registrar_tests.sh with robust polling loop using curl to check server responsiveness - Added 15-second timeout with proper error handling - Makes tests less prone to failures on slower or busier CI runners Co-Authored-By: Gemini <[email protected]> Co-Authored-By: Claude <[email protected]> Signed-off-by: Sergio Arroutbi <[email protected]>
1 parent cc154d3 commit a301dde

File tree

5 files changed

+266
-299
lines changed

5 files changed

+266
-299
lines changed

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

Lines changed: 29 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -540,83 +540,20 @@ mod tests {
540540
assert_eq!(timeout, None);
541541
}
542542

543-
// Helper function to generate test certificates
544-
#[cfg(test)]
545-
fn generate_test_tls_certificates(
546-
temp_dir: &std::path::Path,
547-
) -> (String, String, String) {
548-
use keylime::crypto;
549-
use std::fs::File;
550-
use std::io::Write;
551-
552-
let ca_path = temp_dir.join("ca.pem");
553-
let cert_path = temp_dir.join("cert.pem");
554-
let key_path = temp_dir.join("key.pem");
555-
556-
// Generate CA certificate
557-
let ca_key = crypto::testing::rsa_generate(2048)
558-
.expect("Failed to generate CA key");
559-
let ca_cert = crypto::x509::CertificateBuilder::new()
560-
.private_key(&ca_key)
561-
.common_name("Test Registrar CA")
562-
.build()
563-
.expect("Failed to build CA cert");
564-
565-
// Generate client certificate
566-
let client_key = crypto::testing::rsa_generate(2048)
567-
.expect("Failed to generate client key");
568-
let client_cert = crypto::x509::CertificateBuilder::new()
569-
.private_key(&client_key)
570-
.common_name("test-agent")
571-
.build()
572-
.expect("Failed to build client cert");
573-
574-
// Write certificates to files
575-
let mut ca_file =
576-
File::create(&ca_path).expect("Failed to create CA file");
577-
ca_file
578-
.write_all(
579-
&ca_cert.to_pem().expect("Failed to convert CA to PEM"),
580-
)
581-
.expect("Failed to write CA cert");
582-
583-
let mut cert_file =
584-
File::create(&cert_path).expect("Failed to create cert file");
585-
cert_file
586-
.write_all(
587-
&client_cert.to_pem().expect("Failed to convert cert to PEM"),
588-
)
589-
.expect("Failed to write cert");
590-
591-
let mut key_file =
592-
File::create(&key_path).expect("Failed to create key file");
593-
key_file
594-
.write_all(
595-
&client_key
596-
.private_key_to_pem_pkcs8()
597-
.expect("Failed to convert key to PEM"),
598-
)
599-
.expect("Failed to write key");
600-
601-
(
602-
ca_path.to_string_lossy().to_string(),
603-
cert_path.to_string_lossy().to_string(),
604-
key_path.to_string_lossy().to_string(),
605-
)
606-
}
607-
608543
#[tokio::test]
609544
async fn test_register_agent_with_real_tls_certs() {
610545
let _mutex = testing::lock_tests().await;
611546

612547
let tmpdir = tempfile::tempdir().expect("failed to create tmpdir");
613-
let (ca_path, cert_path, key_path) =
614-
generate_test_tls_certificates(tmpdir.path());
548+
let (ca_path, _server_cert, _server_key, cert_path, key_path) =
549+
keylime::crypto::testing::generate_tls_certs_for_test(
550+
tmpdir.path(),
551+
);
615552

616553
// Verify files were created
617-
assert!(std::path::Path::new(&ca_path).exists());
618-
assert!(std::path::Path::new(&cert_path).exists());
619-
assert!(std::path::Path::new(&key_path).exists());
554+
assert!(ca_path.exists());
555+
assert!(cert_path.exists());
556+
assert!(key_path.exists());
620557

621558
let mut config = get_testing_config(tmpdir.path(), None);
622559
let alg_config = AlgorithmConfigurationString {
@@ -638,9 +575,9 @@ mod tests {
638575
.expect("Failed to create context info from string");
639576

640577
let tls_config = RegistrarTlsConfig {
641-
ca_cert: Some(ca_path),
642-
client_cert: Some(cert_path),
643-
client_key: Some(key_path),
578+
ca_cert: Some(ca_path.to_string_lossy().to_string()),
579+
client_cert: Some(cert_path.to_string_lossy().to_string()),
580+
client_key: Some(key_path.to_string_lossy().to_string()),
644581
insecure: Some(false),
645582
timeout: Some(5000),
646583
};
@@ -695,21 +632,32 @@ mod tests {
695632
#[actix_rt::test]
696633
async fn test_tls_config_all_fields_set() {
697634
let tmpdir = tempfile::tempdir().expect("failed to create tmpdir");
698-
let (ca_path, cert_path, key_path) =
699-
generate_test_tls_certificates(tmpdir.path());
635+
let (ca_path, _server_cert, _server_key, cert_path, key_path) =
636+
keylime::crypto::testing::generate_tls_certs_for_test(
637+
tmpdir.path(),
638+
);
700639

701640
let tls_config = RegistrarTlsConfig {
702-
ca_cert: Some(ca_path.clone()),
703-
client_cert: Some(cert_path.clone()),
704-
client_key: Some(key_path.clone()),
641+
ca_cert: Some(ca_path.to_string_lossy().to_string()),
642+
client_cert: Some(cert_path.to_string_lossy().to_string()),
643+
client_key: Some(key_path.to_string_lossy().to_string()),
705644
insecure: Some(false),
706645
timeout: Some(10000),
707646
};
708647

709648
// Verify all fields are set correctly
710-
assert_eq!(tls_config.ca_cert, Some(ca_path));
711-
assert_eq!(tls_config.client_cert, Some(cert_path));
712-
assert_eq!(tls_config.client_key, Some(key_path));
649+
assert_eq!(
650+
tls_config.ca_cert,
651+
Some(ca_path.to_string_lossy().to_string())
652+
);
653+
assert_eq!(
654+
tls_config.client_cert,
655+
Some(cert_path.to_string_lossy().to_string())
656+
);
657+
assert_eq!(
658+
tls_config.client_key,
659+
Some(key_path.to_string_lossy().to_string())
660+
);
713661
assert_eq!(tls_config.insecure, Some(false));
714662
assert_eq!(tls_config.timeout, Some(10000));
715663
}

keylime/src/crypto.rs

Lines changed: 107 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1130,7 +1130,7 @@ pub fn decrypt_aead(key: &[u8], data: &[u8]) -> Result<Vec<u8>, CryptoError> {
11301130
pub mod testing {
11311131
use super::*;
11321132
use openssl::encrypt::Encrypter;
1133-
use std::path::Path;
1133+
use std::path::{Path, PathBuf};
11341134

11351135
#[derive(Error, Debug)]
11361136
pub enum CryptoTestError {
@@ -1249,6 +1249,112 @@ pub mod testing {
12491249
.map_err(CryptoError::IOWriteError)?;
12501250
Ok(())
12511251
}
1252+
1253+
/// Generates a full set of TLS certificates (CA, server, client) for testing purposes.
1254+
///
1255+
/// # Arguments
1256+
/// * `temp_dir` - The temporary directory to write the certificate files into.
1257+
///
1258+
/// # Returns
1259+
/// A tuple containing the paths to the generated files:
1260+
/// (ca_cert, server_cert, server_key, client_cert, client_key)
1261+
pub fn generate_tls_certs_for_test(
1262+
temp_dir: &Path,
1263+
) -> (PathBuf, PathBuf, PathBuf, PathBuf, PathBuf) {
1264+
use std::fs::File;
1265+
use std::io::Write;
1266+
1267+
// Define paths
1268+
let ca_path = temp_dir.join("ca.pem");
1269+
let server_cert_path = temp_dir.join("server_cert.pem");
1270+
let server_key_path = temp_dir.join("server_key.pem");
1271+
let client_cert_path = temp_dir.join("client_cert.pem");
1272+
let client_key_path = temp_dir.join("client_key.pem");
1273+
1274+
// Generate CA
1275+
let ca_key = rsa_generate(2048).expect("Failed to generate CA key");
1276+
let ca_cert = x509::CertificateBuilder::new()
1277+
.private_key(&ca_key)
1278+
.common_name("Test CA")
1279+
.build()
1280+
.expect("Failed to build CA cert");
1281+
1282+
// Generate server certificate
1283+
let server_key =
1284+
rsa_generate(2048).expect("Failed to generate server key");
1285+
let server_cert = x509::CertificateBuilder::new()
1286+
.private_key(&server_key)
1287+
.common_name("localhost")
1288+
.add_ips(vec!["127.0.0.1"])
1289+
.build()
1290+
.expect("Failed to build server cert");
1291+
1292+
// Generate client certificate
1293+
let client_key =
1294+
rsa_generate(2048).expect("Failed to generate client key");
1295+
let client_cert = x509::CertificateBuilder::new()
1296+
.private_key(&client_key)
1297+
.common_name("test-client")
1298+
.build()
1299+
.expect("Failed to build client cert");
1300+
1301+
// Write files
1302+
let mut ca_file =
1303+
File::create(&ca_path).expect("Failed to create CA file");
1304+
ca_file
1305+
.write_all(
1306+
&ca_cert.to_pem().expect("Failed to convert CA to PEM"),
1307+
)
1308+
.expect("Failed to write CA cert");
1309+
1310+
let mut server_cert_file = File::create(&server_cert_path)
1311+
.expect("Failed to create server cert file");
1312+
server_cert_file
1313+
.write_all(
1314+
&server_cert
1315+
.to_pem()
1316+
.expect("Failed to convert server cert to PEM"),
1317+
)
1318+
.expect("Failed to write server cert");
1319+
1320+
let mut server_key_file = File::create(&server_key_path)
1321+
.expect("Failed to create server key file");
1322+
server_key_file
1323+
.write_all(
1324+
&server_key
1325+
.private_key_to_pem_pkcs8()
1326+
.expect("Failed to convert key to PEM"),
1327+
)
1328+
.expect("Failed to write server key");
1329+
1330+
let mut client_cert_file = File::create(&client_cert_path)
1331+
.expect("Failed to create client cert file");
1332+
client_cert_file
1333+
.write_all(
1334+
&client_cert
1335+
.to_pem()
1336+
.expect("Failed to convert client cert to PEM"),
1337+
)
1338+
.expect("Failed to write client cert");
1339+
1340+
let mut client_key_file = File::create(&client_key_path)
1341+
.expect("Failed to create client key file");
1342+
client_key_file
1343+
.write_all(
1344+
&client_key
1345+
.private_key_to_pem_pkcs8()
1346+
.expect("Failed to convert key to PEM"),
1347+
)
1348+
.expect("Failed to write client key");
1349+
1350+
(
1351+
ca_path,
1352+
server_cert_path,
1353+
server_key_path,
1354+
client_cert_path,
1355+
client_key_path,
1356+
)
1357+
}
12521358
}
12531359

12541360
// Unit Testing

0 commit comments

Comments
 (0)