1use native_ossl::pkcs12::Pkcs12;
6use native_ossl::pkey::KeygenCtx;
7use native_ossl::x509::{X509Builder, X509NameOwned};
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10 let mut kgen = KeygenCtx::new(c"ED25519")?;
13 let priv_key = kgen.generate()?;
14 let pub_key = native_ossl::pkey::Pkey::<native_ossl::pkey::Public>::from(priv_key.clone());
15
16 let mut name = X509NameOwned::new()?;
17 name.add_entry_by_txt(c"CN", b"example.com")?;
18
19 let cert = X509Builder::new()?
20 .set_version(2)?
21 .set_serial_number(1)?
22 .set_not_before_offset(0)?
23 .set_not_after_offset(365 * 86400)?
24 .set_subject_name(&name)?
25 .set_issuer_name(&name)?
26 .set_public_key(&pub_key)?
27 .sign(&priv_key, None)?
28 .build();
29
30 let password = "correct horse battery staple";
33 let p12 = Pkcs12::create(password, "example.com", &priv_key, &cert, &[])?;
34 let der = p12.to_der()?;
35 println!("PKCS#12 bundle: {} bytes", der.len());
36
37 let loaded = Pkcs12::from_der(&der)?;
40 let (recovered_key, recovered_cert, ca_chain) = loaded.parse(password)?;
41
42 println!(
43 "Recovered key algorithm: Ed25519 = {}",
44 recovered_key.is_a(c"ED25519")
45 );
46 if let Some(subject) = recovered_cert.subject_name().to_string() {
47 println!("Recovered cert subject: {subject}");
48 }
49 println!("CA chain length: {}", ca_chain.len());
50
51 assert!(priv_key.public_eq(&recovered_key));
53 assert_eq!(cert.to_der()?, recovered_cert.to_der()?);
54 println!("Key and certificate match original: OK");
55
56 let der2 = loaded.to_der()?;
59 assert_eq!(der, der2);
60 println!("DER round-trip: OK");
61
62 Ok(())
63}