#!/bin/bash # # ca-init.sh — initialize the fleet CA on the CA host [#697] # Usage: ca-init.sh # Creates: root CA (RSA-4096, 10y, offline dir) + intermediate (RSA-4096, 5y) # signing with the root. Keys are generated locally; nothing leaves the host. # set -euo pipefail ROOT_DIR="${1:?usage: ca-init.sh }" INT_DIR="${2:?usage: ca-init.sh }" ROOT_KEY="$ROOT_DIR/root.key" ROOT_CRT="$ROOT_DIR/root.crt" INT_KEY="$INT_DIR/intermediate.key" INT_CSR="$INT_DIR/intermediate.csr" INT_CRT="$INT_DIR/intermediate.crt" if [ -s "$ROOT_CRT" ]; then echo "root already exists at $ROOT_CRT — refusing to overwrite" >&2 exit 1 fi mkdir -p "$ROOT_DIR" "$INT_DIR/certs" "$INT_DIR/csr" chmod 700 "$ROOT_DIR" # --- Root CA (offline; signs only the intermediate) --- openssl genrsa -out "$ROOT_KEY" 4096 2>/dev/null chmod 400 "$ROOT_KEY" openssl req -x509 -new -key "$ROOT_KEY" -sha256 -days 3650 \ -out "$ROOT_CRT" \ -subj "/C=US/ST=Texas/O=Known Element Enterprises/OU=TechOps/CN=PFV Fleet Root CA" \ -addext "basicConstraints=critical,CA:TRUE,pathlen:1" \ -addext "keyUsage=critical,keyCertSign,cRLSign" \ -addext "subjectKeyIdentifier=hash" echo "root CA: $ROOT_CRT ($(openssl x509 -in "$ROOT_CRT" -noout -subject))" # --- Intermediate CA (signs leaves) --- openssl genrsa -out "$INT_KEY" 4096 2>/dev/null chmod 400 "$INT_KEY" openssl req -new -key "$INT_KEY" -out "$INT_CSR" -sha256 \ -subj "/C=US/ST=Texas/O=Known Element Enterprises/OU=TechOps/CN=PFV Fleet Intermediate CA" openssl x509 -req -in "$INT_CSR" -CA "$ROOT_CRT" -CAkey "$ROOT_KEY" \ -CAcreateserial -days 1825 -sha256 -out "$INT_CRT" \ -extfile <(printf 'basicConstraints=critical,CA:TRUE,pathlen:0\nkeyUsage=critical,keyCertSign,cRLSign\nsubjectKeyIdentifier=hash\nauthorityKeyIdentifier=keyid:always') echo "intermediate: $INT_CRT" # --- Chain file for distribution to TLS servers --- cat "$INT_CRT" "$ROOT_CRT" > "$INT_DIR/ca-chain.crt" openssl verify -CAfile "$ROOT_CRT" "$INT_CRT" echo "init complete: intermediate ready at $INT_DIR"