Module picky::x509[][src]

Expand description

X.509 certificates implementation based on RFC5280

Example

use picky::key::PrivateKey;
use picky::pem::{parse_pem, Pem};
use picky::{signature::SignatureAlgorithm, hash::HashAlgorithm};
use picky::x509::key_id_gen_method::{KeyIdGenError, KeyIdGenMethod};
use picky::x509::{certificate::CertType, csr::Csr};
use picky::x509::{name::DirectoryName, date::UTCDate};
use picky::x509::certificate::CertificateBuilder;

// Generate a self-signed root certificate

// Load private key
let root_key = PrivateKey::from_pem_str(root_key_pem_str)?;

let root = CertificateBuilder::new()
    .validity(UTCDate::ymd(2020, 9, 28).unwrap(), UTCDate::ymd(2023, 9, 28).unwrap())
    .self_signed(DirectoryName::new_common_name("My Root CA"), &root_key)
    .ca(true)
    .signature_hash_type(SignatureAlgorithm::RsaPkcs1v15(HashAlgorithm::SHA2_512))
    .key_id_gen_method(KeyIdGenMethod::SPKFullDER(HashAlgorithm::SHA2_384))
    .build()?;

assert_eq!(root.ty(), CertType::Root);

// Generate intermediate certificate signed by root CA

let intermediate_key = PrivateKey::from_pem_str(intermediate_key_pem_str)?;

let intermediate = CertificateBuilder::new()
    .validity(UTCDate::ymd(2020, 10, 15).unwrap(), UTCDate::ymd(2021, 10, 15).unwrap())
    .subject(DirectoryName::new_common_name("My Authority"), intermediate_key.to_public_key())
    .issuer_cert(&root, &root_key)
    .signature_hash_type(SignatureAlgorithm::RsaPkcs1v15(HashAlgorithm::SHA2_224))
    .key_id_gen_method(KeyIdGenMethod::SPKValueHashedLeftmost160(HashAlgorithm::SHA1))
    .ca(true)
    .pathlen(0)
    .build()?;

assert_eq!(intermediate.ty(), CertType::Intermediate);

// Generate leaf certificate signed by intermediate authority

let leaf_key = PrivateKey::from_pem_str(leaf_key_pem_str)?;

// A CSR can be used
let csr = Csr::generate(
    DirectoryName::new_common_name("My Leaf"),
    &leaf_key,
    SignatureAlgorithm::RsaPkcs1v15(HashAlgorithm::SHA1),
)?;

let signed_leaf = CertificateBuilder::new()
    .validity(UTCDate::ymd(2020, 11, 1).unwrap(), UTCDate::ymd(2021, 1, 1).unwrap())
    .subject_from_csr(csr)
    .issuer_cert(&intermediate, &intermediate_key)
    .signature_hash_type(SignatureAlgorithm::RsaPkcs1v15(HashAlgorithm::SHA2_384))
    .key_id_gen_method(KeyIdGenMethod::SPKFullDER(HashAlgorithm::SHA2_512))
    .build()?;

assert_eq!(signed_leaf.ty(), CertType::Leaf);

// Check leaf using CA chain

let chain = [intermediate, root];

signed_leaf
    .verifier()
    .chain(chain.iter())
    .exact_date(&UTCDate::ymd(2020, 12, 20).unwrap())
    .verify()?;

// If `not_after` date is behind…

let err = signed_leaf
    .verifier()
    .chain(chain.iter())
    .exact_date(&UTCDate::ymd(2021, 1, 2).unwrap())
    .verify()
    .err()
    .unwrap();

assert_eq!(
    err.to_string(),
    "invalid certificate \'CN=My Leaf\': \
     certificate expired (not after: 2021-01-01 00:00:00, now: 2021-01-02 00:00:00)"
);

Re-exports

pub use certificate::Cert;
pub use csr::Csr;
pub use key_id_gen_method::KeyIdGenMethod;

Modules

certificate
csr
date
extension
key_id_gen_method
name

Structs

Extension

RFC 5280 #4.1.2.9

Extensions

RFC 5280 #4.1.2.9

Enums

DirectoryString

RFC 5280 #4.1.2.4