crabgraph 0.3.3

A safe, ergonomic, high-performance cryptographic library for Rust built on audited primitives
Documentation
//! Demonstrates PKCS#8 private key and SPKI public key import/export functionality.
//!
//! This example shows how to:
//! - Export Ed25519 and X25519 keys to PKCS#8 DER and PEM formats
//! - Import keys from PKCS#8 DER and PEM formats
//! - Export public keys to SPKI (SubjectPublicKeyInfo) format
//! - Use the keys after import/export roundtrip
//!
//! Run with:
//! ```bash
//! cargo run --example pkcs8_example --all-features
//! ```

use crabgraph::asym::{Ed25519KeyPair, X25519KeyPair};
use crabgraph::CrabResult;

fn main() -> CrabResult<()> {
    println!("=== CrabGraph PKCS#8 Import/Export Example ===\n");

    // =========================
    // Ed25519 Signing Key
    // =========================
    println!("--- Ed25519 Signing Key ---");

    // Generate a new Ed25519 keypair
    let ed25519_key = Ed25519KeyPair::generate()?;
    println!("✓ Generated Ed25519 keypair");

    // Export to PKCS#8 DER (binary format)
    let ed25519_der = ed25519_key.to_pkcs8_der()?;
    println!("✓ Exported to PKCS#8 DER: {} bytes", ed25519_der.len());

    // Export to PKCS#8 PEM (text format)
    let ed25519_pem = ed25519_key.to_pkcs8_pem()?;
    println!("✓ Exported to PKCS#8 PEM:\n{}\n", &ed25519_pem[..80]);
    println!("  ... (truncated)\n");

    // Import from DER
    let ed25519_from_der = Ed25519KeyPair::from_pkcs8_der(&ed25519_der)?;
    println!("✓ Imported from PKCS#8 DER");

    // Import from PEM
    let ed25519_from_pem = Ed25519KeyPair::from_pkcs8_pem(&ed25519_pem)?;
    println!("✓ Imported from PKCS#8 PEM");

    // Verify the imported key works
    let message = b"Hello, PKCS#8!";
    let signature = ed25519_from_pem.sign(message);
    ed25519_from_der.public_key().verify(message, &signature)?;
    println!("✓ Imported key works correctly for signing/verification\n");

    // Export public key to SPKI
    let ed25519_pubkey = ed25519_key.public_key();
    let pubkey_der = ed25519_pubkey.to_public_key_der()?;
    let pubkey_pem = ed25519_pubkey.to_public_key_pem()?;
    println!("✓ Exported public key to SPKI DER: {} bytes", pubkey_der.len());
    println!("✓ Exported public key to SPKI PEM:\n{}\n", &pubkey_pem[..80]);
    println!("  ... (truncated)\n");

    // =========================
    // X25519 Key Exchange
    // =========================
    println!("--- X25519 Key Exchange Key ---");

    // Generate a new X25519 keypair
    let x25519_key = X25519KeyPair::generate()?;
    println!("✓ Generated X25519 keypair");

    // Export to PKCS#8 DER (binary format)
    let x25519_der = x25519_key.to_pkcs8_der()?;
    println!("✓ Exported to PKCS#8 DER: {} bytes", x25519_der.len());

    // Export to PKCS#8 PEM (text format)
    let x25519_pem = x25519_key.to_pkcs8_pem()?;
    println!("✓ Exported to PKCS#8 PEM:\n{}\n", &x25519_pem[..80]);
    println!("  ... (truncated)\n");

    // Import from DER
    let x25519_from_der = X25519KeyPair::from_pkcs8_der(&x25519_der)?;
    println!("✓ Imported from PKCS#8 DER");

    // Import from PEM
    let x25519_from_pem = X25519KeyPair::from_pkcs8_pem(&x25519_pem)?;
    println!("✓ Imported from PKCS#8 PEM");

    // Verify the imported key works
    let peer_key = X25519KeyPair::generate()?;
    let shared1 = x25519_from_pem.diffie_hellman(&peer_key.public_key())?;
    let shared2 = peer_key.diffie_hellman(&x25519_from_der.public_key())?;
    assert_eq!(shared1.as_bytes(), shared2.as_bytes());
    println!("✓ Imported key works correctly for key exchange\n");

    // Export public key to SPKI
    let x25519_pubkey = x25519_key.public_key();
    let pubkey_der = x25519_pubkey.to_public_key_der()?;
    let pubkey_pem = x25519_pubkey.to_public_key_pem()?;
    println!("✓ Exported public key to SPKI DER: {} bytes", pubkey_der.len());
    println!("✓ Exported public key to SPKI PEM:\n{}\n", &pubkey_pem[..80]);
    println!("  ... (truncated)\n");

    // =========================
    // Algorithm OIDs
    // =========================
    println!("--- Algorithm Object Identifiers (OIDs) ---");
    println!("Ed25519: 1.3.101.112 (RFC 8410)");
    println!("X25519:  1.3.101.110 (RFC 8410)");
    println!("\nPKCS#8 format is defined in RFC 5208 and RFC 5958");
    println!("SPKI format is defined in RFC 5280\n");

    // =========================
    // OpenSSL Compatibility
    // =========================
    println!("--- OpenSSL Compatibility ---");
    println!("Keys exported by CrabGraph can be imported by OpenSSL:");
    println!("  openssl pkey -in key.pem -text -noout");
    println!("\nKeys generated by OpenSSL can be imported by CrabGraph:");
    println!("  Ed25519: openssl genpkey -algorithm ED25519 -out ed25519_key.pem");
    println!("  X25519:  openssl genpkey -algorithm X25519 -out x25519_key.pem\n");

    println!("=== All operations completed successfully! ===");

    Ok(())
}