Skip to main content

pkcs12/
pkcs12.rs

1//! PKCS#12 example — create a PFX bundle, serialise, and parse it back.
2//!
3//! Run with: cargo run --example pkcs12 -p native-ossl
4
5use 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    // ── Generate key and self-signed certificate ───────────────────────────────
11
12    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    // ── Create the PKCS#12 bundle ─────────────────────────────────────────────
31
32    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    // ── Parse it back ─────────────────────────────────────────────────────────
38
39    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    // Public keys must match.
52    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    // ── DER round-trip ────────────────────────────────────────────────────────
57
58    let der2 = loaded.to_der()?;
59    assert_eq!(der, der2);
60    println!("DER round-trip: OK");
61
62    Ok(())
63}