mod util;
use certkit::cert::extensions::ExtendedKeyUsageOption;
use certkit::cert::params::{CertificationRequestInfo, DistinguishedName, Validity};
use certkit::issuer::Issuer;
use certkit::key::{KeyPair, PublicKey};
use regex::Regex;
use std::fs;
use std::process::Command;
use time::OffsetDateTime;
#[test]
fn test_openssl_validate_cert() {
let ca_cert_with_key = util::generate_ca_cert();
let server_key = KeyPair::generate_ecdsa_p256();
let server_dn = DistinguishedName::builder()
.common_name("server.myca.local".to_string())
.build();
let server_public_key = PublicKey::from_key_pair(&server_key);
let server_cert_info = CertificationRequestInfo::builder()
.subject(server_dn)
.subject_public_key(server_public_key)
.usages(vec![ExtendedKeyUsageOption::ServerAuth])
.build();
let validity = Validity {
not_before: OffsetDateTime::now_utc(),
not_after: OffsetDateTime::now_utc() + time::Duration::days(365),
};
let server_cert = ca_cert_with_key.issue(&server_cert_info, validity);
let server_cert_pem = server_cert.to_pem().unwrap();
let cert_path = "/tmp/test_server_cert.pem";
fs::write(cert_path, server_cert_pem).expect("Failed to write server certificate");
let output = Command::new("openssl")
.arg("x509")
.arg("-in")
.arg(cert_path)
.arg("-noout")
.arg("-text")
.env("LANG", "C")
.output()
.expect("Failed to execute OpenSSL command");
assert!(
output.status.success(),
"OpenSSL command failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let output_text = String::from_utf8_lossy(&output.stdout);
println!("output_text {output_text}");
assert!(
output_text.contains("Issuer: C=, ST=, L=, O=, OU=, CN=myca.local")
|| output_text.contains("Issuer: C = , ST = , L = , O = , OU = , CN = myca.local"),
"Issuer field is incorrect"
);
assert!(
output_text.contains("Subject: C=, ST=, L=, O=, OU=, CN=server.myca.local")
|| output_text
.contains("Subject: C = , ST = , L = , O = , OU = , CN = server.myca.local"),
"Subject field is incorrect"
);
assert!(
output_text.contains("Version: 3 (0x2)"),
"Version field is incorrect"
);
assert!(
output_text.contains("Serial Number: 1 (0x1)"),
"Serial Number field is incorrect"
);
let not_before_regex = Regex::new(r"Not Before: .+").unwrap();
let not_after_regex = Regex::new(r"Not After : .+").unwrap();
assert!(
not_before_regex.is_match(&output_text),
"Missing or incorrect Not Before field"
);
assert!(
not_after_regex.is_match(&output_text),
"Missing or incorrect Not After field"
);
assert!(
output_text.contains("Signature Algorithm: ecdsa-with-SHA256"),
"Signature Algorithm field is incorrect"
);
fs::remove_file(cert_path).expect("Failed to remove test certificate");
}
#[test]
fn test_openssl_crate_validate_cert() {
let ca_cert_with_key = util::generate_ca_cert();
let server_key = KeyPair::generate_ecdsa_p256();
let server_dn = DistinguishedName::builder()
.common_name("server.myca.local".to_string())
.build();
let server_public_key = PublicKey::from_key_pair(&server_key);
let server_cert_info = CertificationRequestInfo::builder()
.subject(server_dn)
.subject_public_key(server_public_key)
.usages(vec![ExtendedKeyUsageOption::ServerAuth])
.build();
let validity = Validity {
not_before: OffsetDateTime::now_utc(),
not_after: OffsetDateTime::now_utc() + time::Duration::days(365),
};
let server_cert = ca_cert_with_key.issue(&server_cert_info, validity);
let server_cert_pem = server_cert.to_pem().unwrap();
use openssl::x509::X509;
let x509 = X509::from_pem(server_cert_pem.as_bytes()).expect("Failed to parse PEM");
let subject = x509
.subject_name()
.entries_by_nid(openssl::nid::Nid::COMMONNAME)
.next()
.unwrap()
.data()
.as_utf8()
.unwrap();
assert_eq!(
subject.to_string(),
"server.myca.local",
"Subject CN mismatch"
);
let issuer = x509
.issuer_name()
.entries_by_nid(openssl::nid::Nid::COMMONNAME)
.next()
.unwrap()
.data()
.as_utf8()
.unwrap();
assert_eq!(issuer.to_string(), "myca.local", "Issuer CN mismatch");
assert_eq!(
x509.version(),
2,
"X509 version should be 3 (0-based index)"
);
let serial = x509.serial_number().to_bn().unwrap().to_dec_str().unwrap();
assert_eq!(serial.to_string(), "1", "Serial number should be 1");
let sig_alg = x509.signature_algorithm().object().nid();
assert_eq!(
sig_alg,
openssl::nid::Nid::ECDSA_WITH_SHA256,
"Signature algorithm should be ecdsa-with-SHA256"
);
}