From 4bce448b1c724708f8723eb571c02429a98efd79 Mon Sep 17 00:00:00 2001 From: Jin Jiu Date: Sun, 15 Sep 2024 23:57:40 +0800 Subject: [PATCH] Optimize the test case code of pki module. --- src/modules/pki/mod.rs | 274 ++++++----------------------------------- 1 file changed, 40 insertions(+), 234 deletions(-) diff --git a/src/modules/pki/mod.rs b/src/modules/pki/mod.rs index 7c93b92..1fbc679 100644 --- a/src/modules/pki/mod.rs +++ b/src/modules/pki/mod.rs @@ -186,9 +186,7 @@ mod test { assert!(test_write_api(&core, token, format!("{}roles/{}", path, role_name).as_str(), true, Some(role_data)).is_ok()); } - fn generate_root(core: &Core, token: &str, path: &str, exported: bool, is_ok: bool) { - let key_type = "rsa"; - let key_bits = 4096; + fn generate_root(core: &Core, token: &str, path: &str, exported: bool, key_type: &str, key_bits: u32, is_ok: bool) { let common_name = "test-ca"; let req_data = json!({ "common_name": common_name, @@ -266,7 +264,7 @@ mod test { assert_eq!(resp_ca_pem.unwrap_err(), RvError::ErrPkiCaNotConfig); } - fn issue_cert_by_generate_root(core: &Core, token: &str, path: &str, role_name: &str) { + fn issue_cert_by_generate_root(core: &Core, token: &str, path: &str, role_name: &str, key_type: &str, key_bits: u32) { let dns_sans = vec!["test.com", "a.test.com", "b.test.com"]; let issue_data = json!({ "ttl": "10d", @@ -293,9 +291,9 @@ mod test { for alt_name in alt_names { assert!(dns_sans.contains(&alt_name.dnsname().unwrap())); } - assert_eq!(cert_data["private_key_type"].as_str().unwrap(), "rsa"); + assert_eq!(cert_data["private_key_type"].as_str().unwrap(), key_type); let priv_key = PKey::private_key_from_pem(cert_data["private_key"].as_str().unwrap().as_bytes()).unwrap(); - assert_eq!(priv_key.bits(), 4096); + assert_eq!(priv_key.bits(), key_bits); assert!(priv_key.public_eq(&cert.public_key().unwrap())); let serial_number = cert.serial_number().to_bn().unwrap(); let serial_number_hex = serial_number.to_hex_str().unwrap(); @@ -438,8 +436,8 @@ x/+V28hUf8m8P2NxP5ALaDZagdaMfzjGZo3O3wDv33Cds0P5GMGQYnRXDxcZN/2L assert_eq!(role_data["ttl"].as_u64().unwrap(), 60 * 24 * 60 * 60); assert_eq!(role_data["max_ttl"].as_u64().unwrap(), 365 * 24 * 60 * 60); assert_eq!(role_data["not_before_duration"].as_u64().unwrap(), 30); - assert_eq!(role_data["key_type"].as_str().unwrap(), key_type); - assert_eq!(role_data["key_bits"].as_u64().unwrap(), key_bits); + assert_eq!(role_data["key_type"].as_str().unwrap(), "rsa"); + assert_eq!(role_data["key_bits"].as_u64().unwrap(), 4096); assert_eq!(role_data["country"].as_str().unwrap(), "CN"); assert_eq!(role_data["province"].as_str().unwrap(), "Beijing"); assert_eq!(role_data["locality"].as_str().unwrap(), "Beijing"); @@ -490,9 +488,9 @@ x/+V28hUf8m8P2NxP5ALaDZagdaMfzjGZo3O3wDv33Cds0P5GMGQYnRXDxcZN/2L for alt_name in alt_names { assert!(dns_sans.contains(&alt_name.dnsname().unwrap())); } - assert_eq!(cert_data["private_key_type"].as_str().unwrap(), key_type); + assert_eq!(cert_data["private_key_type"].as_str().unwrap(), "rsa"); let priv_key = PKey::private_key_from_pem(cert_data["private_key"].as_str().unwrap().as_bytes()).unwrap(); - assert_eq!(priv_key.bits(), key_bits); + assert_eq!(priv_key.bits(), 4096); assert!(priv_key.public_eq(&cert.public_key().unwrap())); let serial_number = cert.serial_number().to_bn().unwrap(); let serial_number_hex = serial_number.to_hex_str().unwrap(); @@ -516,13 +514,13 @@ x/+V28hUf8m8P2NxP5ALaDZagdaMfzjGZo3O3wDv33Cds0P5GMGQYnRXDxcZN/2L let resp_lowercase = test_read_api( &core, token, - format!("{}/cert/{}", path, serial_number_hex.to_lowercase().as_str()).as_str(), + format!("{}cert/{}", path, serial_number_hex.to_lowercase().as_str()).as_str(), true, ); let resp_uppercase = test_read_api( &core, token, - format!("{}/cert/{}", path, serial_number_hex.to_uppercase().as_str()).as_str(), + format!("{}cert/{}", path, serial_number_hex.to_uppercase().as_str()).as_str(), true, ); println!("resp_uppercase: {:?}", resp_uppercase); @@ -561,10 +559,35 @@ x/+V28hUf8m8P2NxP5ALaDZagdaMfzjGZo3O3wDv33Cds0P5GMGQYnRXDxcZN/2L // config role config_role(&core, token, path, role_name); - generate_root(&core, token, path, true, true); - generate_root(&core, token, path, false, true); + generate_root(&core, token, path, true, "rsa", 4096, true); + generate_root(&core, token, path, false, "rsa", 4096, true); + + issue_cert_by_generate_root(&core, token, path, role_name, "rsa", 4096); + + delete_root(&core, token, path, true); + } + + #[cfg(feature = "crypto_adaptor_tongsuo")] + fn test_pki_sm2_generate_root() { + let (root_token, c) = test_rusty_vault_init("test_pki_generate_root"); + let token = &root_token; + let core = c.read().unwrap(); + let path = "sm2pki/"; + let role_name = "test"; + + // mount pki backend to path: pki/ + test_mount_api(&core, token, "pki", path); + + // config ca + config_ca(&core, token, path); + + // config role + config_role(&core, token, path, role_name); + + generate_root(&core, token, path, true, "sm2", 256, true); + generate_root(&core, token, path, false, "sm2", 256, true); - issue_cert_by_generate_root(&core, token, path, role_name); + issue_cert_by_generate_root(&core, token, path, role_name, "sm2", 256); delete_root(&core, token, path, true); } @@ -823,7 +846,7 @@ x/+V28hUf8m8P2NxP5ALaDZagdaMfzjGZo3O3wDv33Cds0P5GMGQYnRXDxcZN/2L let (root_token, c) = test_rusty_vault_init("test_pki_generate_key"); let token = &root_token; let core = c.read().unwrap(); - let path = "pki/"; + let path = "pki"; // mount pki backend to path: pki/ test_mount_api(&core, token, "pki", path); @@ -922,7 +945,7 @@ x/+V28hUf8m8P2NxP5ALaDZagdaMfzjGZo3O3wDv33Cds0P5GMGQYnRXDxcZN/2L let (root_token, c) = test_rusty_vault_init("test_pki_import_key"); let token = &root_token; let core = c.read().unwrap(); - let path = "pki/"; + let path = "pki"; // mount pki backend to path: pki/ test_mount_api(&core, token, "pki", path); @@ -1613,222 +1636,5 @@ xxxxxxxxxxxxxx test_pki_encrypt_decrypt(&core, token, path, "aes-ecb-128-import", "rusty_vault test".as_bytes(), true); test_pki_encrypt_decrypt(&core, token, path, "aes-ecb-192-import", "rusty_vault test".as_bytes(), true); test_pki_encrypt_decrypt(&core, token, path, "aes-ecb-256-import", "rusty_vault test".as_bytes(), true); -<<<<<<< HEAD - } - - fn test_pki_generate_root(core: Arc>, token: &str, path: &str, key_type: &str, key_bits: u32, exported: bool, is_ok: bool) { - let core = core.read().unwrap(); - - let common_name = "test-ca"; - let req_data = json!({ - "common_name": common_name, - "ttl": "365d", - "country": "cn", - "key_type": key_type, - "key_bits": key_bits, - }) - .as_object() - .unwrap() - .clone(); - println!("generate root req_data: {:?}, is_ok: {}", req_data, is_ok); - let resp = test_write_api( - &core, - token, - format!("{}/root/generate/{}", path, if exported { "exported" } else { "internal" }).as_str(), - is_ok, - Some(req_data), - ); - if !is_ok { - return; - } - let resp_body = resp.unwrap(); - assert!(resp_body.is_some()); - let data = resp_body.unwrap().data; - assert!(data.is_some()); - let key_data = data.unwrap(); - println!("generate root result: {:?}", key_data); - - let resp_ca_pem = test_read_api(&core, token, &format!("{}/ca/pem", path), true); - let resp_ca_pem_cert_data = resp_ca_pem.unwrap().unwrap().data.unwrap(); - - let ca_cert = X509::from_pem(resp_ca_pem_cert_data["certificate"].as_str().unwrap().as_bytes()).unwrap(); - let subject = ca_cert.subject_name(); - let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap(); - assert_eq!(cn.data().as_slice(), common_name.as_bytes()); - - let not_after = Asn1Time::days_from_now(365).unwrap(); - let ttl_diff = ca_cert.not_after().diff(¬_after); - assert!(ttl_diff.is_ok()); - let ttl_diff = ttl_diff.unwrap(); - assert_eq!(ttl_diff.days, 0); - - if exported { - assert!(key_data["private_key_type"].as_str().is_some()); - assert_eq!(key_data["private_key_type"].as_str().unwrap(), key_type); - assert!(key_data["private_key"].as_str().is_some()); - let private_key_pem = key_data["private_key"].as_str().unwrap(); - match key_type { - "rsa" => { - let rsa_key = Rsa::private_key_from_pem(private_key_pem.as_bytes()); - assert!(rsa_key.is_ok()); - assert_eq!(rsa_key.unwrap().size() * 8, key_bits); - } - "sm2" | "ec" => { - let ec_key = EcKey::private_key_from_pem(private_key_pem.as_bytes()); - assert!(ec_key.is_ok()); - assert_eq!(ec_key.unwrap().group().degree(), key_bits); - } - _ => {} - } - } else { - assert!(key_data.get("private_key").is_none()); - } - } - - fn test_pki_delete_root(core: Arc>, token: &str, path: &str, is_ok: bool) { - let core = core.read().unwrap(); - - let resp = test_delete_api(&core, token, &format!("{}/root", path), is_ok); - if !is_ok { - return; - } - assert!(resp.is_ok()); - - let resp_ca_pem = test_read_api(&core, token, &format!("{}/ca/pem", path), false); - assert_eq!(resp_ca_pem.unwrap_err(), RvError::ErrPkiCaNotConfig); - } - - fn test_pki_issue_cert_by_generate_root(core: Arc>, token: &str, path: &str, key_type: &str, key_bits: u32) { - let core = core.read().unwrap(); - - let dns_sans = vec!["test.com", "a.test.com", "b.test.com"]; - let issue_data = json!({ - "ttl": "10d", - "common_name": "test.com", - "alt_names": "a.test.com,b.test.com", - }) - .as_object() - .unwrap() - .clone(); - - // issue cert - let resp = test_write_api(&core, token, &format!("{}/issue/test", path), true, Some(issue_data)); - assert!(resp.is_ok()); - let resp_body = resp.unwrap(); - assert!(resp_body.is_some()); - let data = resp_body.unwrap().data; - assert!(data.is_some()); - let cert_data = data.unwrap(); - let cert = X509::from_pem(cert_data["certificate"].as_str().unwrap().as_bytes()).unwrap(); - let alt_names = cert.subject_alt_names(); - assert!(alt_names.is_some()); - let alt_names = alt_names.unwrap(); - assert_eq!(alt_names.len(), dns_sans.len()); - for alt_name in alt_names { - assert!(dns_sans.contains(&alt_name.dnsname().unwrap())); - } - assert_eq!(cert_data["private_key_type"].as_str().unwrap(), key_type); - let priv_key = PKey::private_key_from_pem(cert_data["private_key"].as_str().unwrap().as_bytes()).unwrap(); - assert_eq!(priv_key.bits(), key_bits); - assert!(priv_key.public_eq(&cert.public_key().unwrap())); - let serial_number = cert.serial_number().to_bn().unwrap(); - let serial_number_hex = serial_number.to_hex_str().unwrap(); - assert_eq!( - cert_data["serial_number"].as_str().unwrap().replace(":", "").to_lowercase().as_str(), - serial_number_hex.to_lowercase().as_str() - ); - let expiration_time = Asn1Time::from_unix(cert_data["expiration"].as_i64().unwrap()).unwrap(); - let ttl_compare = cert.not_after().compare(&expiration_time); - assert!(ttl_compare.is_ok()); - assert_eq!(ttl_compare.unwrap(), std::cmp::Ordering::Equal); - let now_timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); - let expiration_ttl = cert_data["expiration"].as_u64().unwrap(); - let ttl = expiration_ttl - now_timestamp; - let expect_ttl = 10 * 24 * 60 * 60; - assert!(ttl <= expect_ttl); - assert!((ttl + 10) > expect_ttl); - - let authority_key_id = cert.authority_key_id(); - assert!(authority_key_id.is_some()); - - println!("authority_key_id: {:?}", authority_key_id.unwrap().as_slice()); - - let resp_ca_pem = test_read_api(&core, token, &format!("{}/ca/pem", path), true); - let resp_ca_pem_cert_data = resp_ca_pem.unwrap().unwrap().data.unwrap(); - - let ca_cert = X509::from_pem(resp_ca_pem_cert_data["certificate"].as_str().unwrap().as_bytes()).unwrap(); - let subject = ca_cert.subject_name(); - let cn = subject.entries_by_nid(Nid::COMMONNAME).next().unwrap(); - assert_eq!(cn.data().as_slice(), "test-ca".as_bytes()); - println!("ca subject_key_id: {:?}", ca_cert.subject_key_id().unwrap().as_slice()); - assert_eq!(ca_cert.subject_key_id().unwrap().as_slice(), authority_key_id.unwrap().as_slice()); - } - - #[test] - fn test_pki_module() { - let dir = env::temp_dir().join("rusty_vault_pki_module"); - assert!(fs::create_dir(&dir).is_ok()); - defer! ( - assert!(fs::remove_dir_all(&dir).is_ok()); - ); - - let mut root_token = String::new(); - println!("root_token: {:?}", root_token); - - let mut conf: HashMap = HashMap::new(); - conf.insert("path".to_string(), Value::String(dir.to_string_lossy().into_owned())); - - let backend = storage::new_backend("file", &conf).unwrap(); - - let barrier = storage::barrier_aes_gcm::AESGCMBarrier::new(Arc::clone(&backend)); - - let c = Arc::new(RwLock::new(Core { physical: backend, barrier: Arc::new(barrier), ..Default::default() })); - - { - let mut core = c.write().unwrap(); - assert!(core.config(Arc::clone(&c), None).is_ok()); - - let seal_config = SealConfig { secret_shares: 10, secret_threshold: 5 }; - - let result = core.init(&seal_config); - assert!(result.is_ok()); - let init_result = result.unwrap(); - println!("init_result: {:?}", init_result); - - let mut unsealed = false; - for i in 0..seal_config.secret_threshold { - let key = &init_result.secret_shares[i as usize]; - let unseal = core.unseal(key); - assert!(unseal.is_ok()); - unsealed = unseal.unwrap(); - } - - root_token = init_result.root_token; - - assert!(unsealed); - } - - { - println!("root_token: {:?}", root_token); - test_pki_mount(Arc::clone(&c), &root_token, "pki"); - test_pki_config_ca(Arc::clone(&c), &root_token, "pki"); - test_pki_config_role(Arc::clone(&c), &root_token, "pki", "rsa", 4096); - test_pki_issue_cert(Arc::clone(&c), &root_token, "pki", "rsa", 4096); - test_pki_generate_key(Arc::clone(&c), &root_token, "pki"); - test_pki_import_key(Arc::clone(&c), &root_token, "pki"); - test_pki_generate_root(Arc::clone(&c), &root_token, "pki", "rsa", 4096, true, true); - test_pki_generate_root(Arc::clone(&c), &root_token, "pki", "rsa", 4096, false, true); - test_pki_issue_cert_by_generate_root(Arc::clone(&c), &root_token, "pki", "rsa", 4096); - test_pki_delete_root(Arc::clone(&c), &root_token, "pki", true); - - #[cfg(feature = "crypto_adaptor_tongsuo")] - { - test_pki_mount(Arc::clone(&c), &root_token, "sm2pki"); - test_pki_generate_root(Arc::clone(&c), &root_token, "sm2pki", "sm2", 256, true, true); - test_pki_config_role(Arc::clone(&c), &root_token, "sm2pki", "sm2", 256); - test_pki_issue_cert_by_generate_root(Arc::clone(&c), &root_token, "sm2pki", "sm2", 256); - test_pki_delete_root(Arc::clone(&c), &root_token, "sm2pki", true); - } - } } }