← Week 1: Certificate Issuance Pipeline

Day 1: Project Setup and Architecture

Phase 2 · June 17, 2026

← Week 1: Certificate Issuance Pipeline

Agenda (2–3 hours)

  • Design (45 min): Module architecture, data model, decisions
  • Setup (30 min): cargo new, dependencies, module stubs
  • Read (30 min): rcgen README + CertificateParams docs; skim rcgen examples/
  • Challenge (45 min): Stub out all modules with types and trait signatures
← Week 1: Certificate Issuance Pipeline

What We're Building

A CLI tool that can:

pki init                          # create root + intermediate CA
pki issue --type server example.com  # issue a TLS server cert
pki issue --type client alice        # issue a client cert
pki revoke <serial>               # revoke a cert, update CRL
pki inspect <cert.pem>            # parse and display a cert
pki serve-ocsp                    # run an OCSP HTTP responder

By end of Phase 2: issue, revoke, inspect, mTLS-test — all in Rust, no openssl binary.

← Week 1: Certificate Issuance Pipeline

Core Data Model

// ca.rs
pub struct Ca {
    pub cert: rcgen::Certificate,    // certificate (contains public key)
    pub key:  rcgen::KeyPair,        // private key
    pub kind: CaKind,
}

pub enum CaKind { Root, Intermediate }

// store.rs
pub struct CertRecord {
    pub serial:      String,     // hex serial
    pub subject:     String,
    pub not_after:   String,     // RFC 3339
    pub pem:         String,
    pub revoked_at:  Option<String>,
    pub revocation_reason: Option<String>,
}
← Week 1: Certificate Issuance Pipeline

Dependency Choices

[dependencies]
rcgen   = { version = "0.13", features = ["pem", "x509-parser"] }
x509-parser = "0.16"
rustls  = "0.23"
tokio-rustls = "0.26"
tokio   = { version = "1", features = ["full"] }
axum    = "0.7"
der     = "0.7"
clap    = { version = "4", features = ["derive"] }
serde   = { version = "1", features = ["derive"] }
serde_json = "1"
time    = { version = "0.3", features = ["formatting", "parsing"] }
anyhow  = "1"

anyhow for error handling throughout — this is a tool, not a library.

← Week 1: Certificate Issuance Pipeline

Module Responsibilities

Module Responsibility
ca.rs Ca struct, new_root(), new_intermediate()
issue.rs issue_server_cert(), issue_client_cert()
revoke.rs generate_crl(), build_ocsp_response()
validate.rs validate_chain(), check_revocation()
store.rs Load/save PEM files, CertRecord JSON index
tls.rs server_config(), client_config() wrappers
main.rs clap CLI dispatch
← Week 1: Certificate Issuance Pipeline

Challenge Assignment

  1. cargo new toy-pki — add all dependencies to Cargo.toml
  2. Create each module file with:
    • Public types (structs/enums) — no implementations yet
    • Function signatures with todo!() bodies
    • use imports that will be needed
  3. Verify cargo check passes (no implementation required, just types compile)
  4. Write a README.md for the project describing what it does and how to use it

This front-loads design decisions so you're not making them under pressure mid-implementation.

← Week 1: Certificate Issuance Pipeline

Resources

  • rcgen examples: github.com/rustls/rcgen/tree/main/rcgen/examples
  • rcgen docs: docs.rs/rcgen — read CertificateParams, KeyPair, Certificate
  • rcgen CRL support: docs.rs/rcgen — CertificateRevocationListParams
  • anyhow docs: docs.rs/anyhow — Result<T> alias, bail!, context()