Skip to content

gladiola/CAGenerationAndMaintenance

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

14 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

CAGenerationAndMaintenance

Shell scripts for operating an offline, air-gapped Certificate Authority on OpenBSD using OpenSSL, with revocation status published via a separate OpenBSD OCSP Server. Updates are transferred between the offline CA machine and the OCSP server machine by USB drive.


๐ŸŒ Language / Sprache / Langue / Idioma / Lรญngua / Lingua / ่ชž่จ€ / ์–ธ์–ด / เคญเคพเคทเคพ / ะฏะทั‹ะบ / ู„ุบุฉ / Lugha / ่จ€่ชž / Lang / Wika / สปลŒlelo / Gagana / Reo / Taal / Harshe / แ‰‹แŠ•แ‰‹ / รˆdรจ / เฆญเฆพเฆทเฆพ / ่ฏญ่จ€ / Keel / Kieli / Sprรฅk / ะœะพะฒะฐ / เธ เธฒเธฉเธฒ / Bahasa / Wika / Bahasa / Basa / ฮ“ฮปฯŽฯƒฯƒฮฑ / Lingua / ืฉืคื” / Teanga

๐Ÿ‡บ๐Ÿ‡ธ English ๐Ÿ‡ฉ๐Ÿ‡ช Deutsch ๐Ÿ‡ช๐Ÿ‡ธ Espaรฑol ๐Ÿ‡ซ๐Ÿ‡ท Franรงais ๐Ÿ‡ต๐Ÿ‡น Portuguรชs
๐Ÿ‡ฎ๐Ÿ‡น Italiano ๐Ÿ‡ญ๐Ÿ‡ฐ ็น้ซ”ไธญๆ–‡ ๐Ÿ‡ฐ๐Ÿ‡ท ํ•œ๊ตญ์–ด ๐Ÿ‡ฎ๐Ÿ‡ณ เคนเคฟเคจเฅเคฆเฅ€ ๐Ÿ‡ท๐Ÿ‡บ ะ ัƒััะบะธะน
๐Ÿ‡ธ๐Ÿ‡ฆ ุงู„ุนุฑุจูŠุฉ ๐ŸŒ Kiswahili ๐Ÿ‡ฏ๐Ÿ‡ต ๆ—ฅๆœฌ่ชž ๐Ÿ‡ญ๐Ÿ‡น Kreyรฒl ayisyen ๐ŸŒบ สปลŒlelo Hawaiสปi
๐ŸŒŠ Gagana Sฤmoa ๐ŸŒฟ Te Reo Mฤori ๐Ÿ‡ฟ๐Ÿ‡ฆ Afrikaans ๐Ÿ‡ณ๐Ÿ‡ฑ Nederlands ๐ŸŒ Hausa
๐Ÿ‡ช๐Ÿ‡น แŠ แˆ›แˆญแŠ› ๐ŸŒ Yorรนbรก ๐Ÿ‡ง๐Ÿ‡ฉ เฆฌเฆพเฆ‚เฆฒเฆพ ๐Ÿ‡จ๐Ÿ‡ณ ็ฎ€ไฝ“ไธญๆ–‡ ๐Ÿ‡ช๐Ÿ‡ช Eesti
๐Ÿ‡ซ๐Ÿ‡ฎ Suomi ๐Ÿ‡ธ๐Ÿ‡ช Svenska ๐Ÿ‡ณ๐Ÿ‡ด Norsk ๐Ÿ‡บ๐Ÿ‡ฆ ะฃะบั€ะฐั—ะฝััŒะบะฐ ๐Ÿ‡น๐Ÿ‡ญ เธ เธฒเธฉเธฒเน„เธ—เธข
๐Ÿ‡ฎ๐Ÿ‡ฉ Bahasa Indonesia ๐Ÿ‡ต๐Ÿ‡ญ Filipino ๐Ÿ‡ฒ๐Ÿ‡พ Bahasa Melayu ๐ŸŒ Basa Jawa ๐Ÿ‡ฌ๐Ÿ‡ท ฮ•ฮปฮปฮทฮฝฮนฮบฮฌ
๐Ÿ“œ Latina ๐Ÿ‡ฎ๐Ÿ‡ฑ ืขื‘ืจื™ืช ๐Ÿ‡ฎ๐Ÿ‡ช Gaeilge

Architecture overview

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        USB drive        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Offline CA machine        โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บ   โ”‚  OCSP server machine     โ”‚
โ”‚   (OpenBSD, air-gapped)     โ”‚  export-to-usb.sh        โ”‚  (OpenBSD, networked)    โ”‚
โ”‚                             โ”‚  โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚                          โ”‚
โ”‚  /root/ca/                  โ”‚  physical carry          โ”‚  /etc/ocsp/              โ”‚
โ”‚    openssl.cnf              โ”‚                          โ”‚    index.txt             โ”‚
โ”‚    certs/ca.cert.pem        โ”‚                          โ”‚    *.crl.pem             โ”‚
โ”‚    intermediate-*/          โ”‚                          โ”‚    *-responder.crt       โ”‚
โ”‚      index.txt              โ”‚                          โ”‚  OcspServer (ASP.NET)    โ”‚
โ”‚      crl/                   โ”‚                          โ”‚  rcctl enable ocspserver โ”‚
โ”‚      certs/                 โ”‚                          โ”‚                          โ”‚
โ”‚      ocsp/                  โ”‚                          โ”‚                          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Prerequisites

Both machines run OpenBSD. Install OpenSSL if it is not already present:

pkg_add openssl

The OCSP server machine also needs the OpenBSDOCSPServer installed and registered as an rc.d service named ocspserver.

All scripts use #!/bin/sh (OpenBSD's ksh-based /bin/sh), standard OpenBSD utilities (mount_msdos, sha256, rcctl, doas), and openssl(1). Run all scripts as root via doas.


File layout

scripts/
  setup-ca.sh               Initialize root CA directories and generate root key/cert
  create-intermediate-ca.sh Create a named intermediate CA signed by the root CA
  create-server-cert.sh     Issue a TLS server certificate (mTLS)
  create-client-cert.sh     Issue a client certificate (mTLS)
  revoke-cert.sh            Revoke a certificate and regenerate the CRL
  export-to-usb.sh          Package CA data onto USB for air-gap transfer (CA side)
  import-from-usb.sh        Import from USB into the OCSP server (OCSP server side)

config/
  openssl-root.cnf.template          Root CA OpenSSL config template
  openssl-intermediate.cnf.template  Intermediate CA OpenSSL config template

Deployment planning (fill this out before running scripts)

Prepare your deployment values before running the steps below:

  • Where is the CA going to be?
    default: /root/ca
    actual:

  • What is the org and where is it?
    default: My Organization
    actual:

  • What is the project name?
    default: MY PROJECT
    actual:

  • When is the project versioned?
    default: 01012027
    actual:

  • What is the TLD?
    default: example.com
    actual:

  • What is the subdomain?
    default: app.
    actual:

  • What is the email address for the client user(s)?
    default: user@example.com
    actual:

  • Where is the USB thumb drive for transfer?
    default: /dev/sd1i
    actual:


Step-by-step usage

1 โ€” Initialize the root CA (offline CA machine, once)

doas sh scripts/setup-ca.sh /root/ca \
  "/C=US/ST=MyState/L=MyCity/O=My Organization/CN=My Organization Root CA"

This creates /root/ca/, generates an AES-256-encrypted 4096-bit root key, a self-signed certificate valid for 20 years, and an OCSP signing certificate for the root CA.

2 โ€” Create an intermediate CA (offline CA machine, once per project)

doas sh scripts/create-intermediate-ca.sh MY-PROJECT 01012027 /root/ca \
  "/C=US/ST=MyState/L=MyCity/O=My Organization/CN=My Organization Intermediate CA MY-PROJECT 01012027"

Files are created under /root/ca/intermediate-MY-PROJECT-01012027/.

3 โ€” Issue a server certificate (offline CA machine)

doas sh scripts/create-server-cert.sh MY-PROJECT 01012027 \
  app.example.com \
  "DNS:app.example.com,DNS:www.example.com" \
  /root/ca

Outputs under the intermediate CA directory:

  • private/app.example.com.01012027.key.pem โ€” encrypted private key
  • certs/app.example.com.01012027.cert.pem โ€” signed certificate
  • certs/app.example.com.01012027.server.full.pfx โ€” PKCS#12 bundle

4 โ€” Issue client certificates (offline CA machine)

doas sh scripts/create-client-cert.sh MY-PROJECT 01012027 \
  user@example.com /root/ca

Repeat for each user. Transfer each .full.pfx bundle to the respective user over a secure channel.

5 โ€” Revoke a certificate (offline CA machine)

doas sh scripts/revoke-cert.sh MY-PROJECT 01012027 \
  certs/client-user@example.com.01012027.cert.pem \
  keyCompromise /root/ca

To renew the CRL without revoking anything (e.g. on a scheduled basis):

doas sh scripts/revoke-cert.sh MY-PROJECT 01012027 --crl-only /root/ca

6 โ€” Transfer to OCSP server via USB (air-gap workflow)

On the offline CA machine

Insert a FAT32-formatted USB drive. Confirm the device:

dmesg | tail -20          # look for "sd1 at ..." lines
disklabel sd1             # identify the FAT32 partition (usually 'i')

Then export:

doas sh scripts/export-to-usb.sh MY-PROJECT 01012027 /root/ca /dev/sd1i

The script writes a SHA256 checksum manifest and unmounts the drive safely. Physically carry the USB drive to the OCSP server machine.

On the OCSP server machine

dmesg | tail -20          # confirm USB device name
disklabel sd1
doas sh scripts/import-from-usb.sh /dev/sd1i /etc/ocsp ocspserver

The script verifies checksums, copies updated files to /etc/ocsp/, and reloads the ocspserver daemon via rcctl. If EnableIndexTxtWatch is true in appsettings.json, the OCSP server will also pick up index.txt changes automatically without a reload.

7 โ€” Verify OCSP responses

openssl ocsp \
  -issuer /etc/ocsp/intermediate-MY-PROJECT-01012027/ca-chain.cert.pem \
  -cert /path/to/cert.pem \
  -url http://localhost:2560 \
  -resp_text

Naming conventions

File Pattern
Intermediate CA key intermediate-PROJECT-DATE.key.pem
Intermediate CA cert intermediate-PROJECT-DATE.cert.pem
Certificate chain ca-chain-PROJECT-DATE.cert.pem
Server cert SERVER_DOMAIN.DATE.cert.pem
Server PKCS#12 SERVER_DOMAIN.DATE.server.full.pfx
Client cert client-USER_EMAIL.DATE.cert.pem
Client PKCS#12 client-USER_EMAIL.DATE.full.pfx
CRL intermediate.crl.pem / intermediate.crl.der
OCSP signing cert INTER_NAME-ocsp.cert.pem

Security notes

  • The offline CA machine must never be connected to a network.
  • Root and intermediate private keys are AES-256 encrypted. Store passphrases in a hardware token or physical vault, separate from the keys themselves.
  • Always verify USB drive checksums before importing โ€” import-from-usb.sh does this automatically using OpenBSD's sha256 -C.
  • CRLs expire after 30 days by default. Schedule regular CRL renewal:
    doas sh scripts/revoke-cert.sh MY-PROJECT DATE --crl-only
    # then export-to-usb + import-from-usb
  • OCSP signing certificates expire after 375 days. Renew them by rerunning create-intermediate-ca.sh with the same arguments; it skips steps that are already complete and only generates a new OCSP cert when needed.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages