Simple CA cert generator & leaf cert signer
July 10, 2026 · View on GitHub
#!/bin/bash
Simple CA cert generator & leaf cert signer
By dominic@sensepost.com
All rights reserved 2019
set -euo pipefail
ca_prefix="ca" leaf_prefix="host" ca_validity="1825" # days leaf_validity="730" # days size=2048
ca_cert="" ca_key="" dns_name="" ip_addr=""
usage() { echo "Simple CA & leaf cert generator & signer" echo echo "Usage:" echo " $0 [-h] [-c <ca.cert.pem> -k <ca.key.pem>] [-l <leaf_prefix>] [-a <ca_prefix>] [-d <dns_name>] [-i <ip_addr>]" echo echo "Options:" echo " -h This help" echo " -c <ca.cert.pem> Specify a CA cert to use instead of generating one. Requires -k" echo " -k <ca.key.pem> Specify the key for the CA cert. Requires -c" echo " -l <leaf_prefix> Specify the name prefix of the leaf certificate and key" echo " -a <ca_prefix> Specify the name prefix of the CA certificate and key" echo " -d <dns_name> DNS SAN for the leaf cert, e.g. design.orbitonline.com" echo " -i <ip_addr> IP SAN for the leaf cert, e.g. 127.0.0.1" echo echo "Examples:" echo " $0 -l sub.example.com -d sub.example.com -i 127.0.0.1" echo " $0 -c ca.cert.pem -k ca.key.pem -l localhost -d localhost -i 127.0.0.1" exit 1 }
while getopts "hc:k:l:a:d:i:" OPTIONS; do case "{OPTARG}" ;; k) ca_key="{OPTARG}" ;; a) ca_prefix="{OPTARG}" ;; i) ip_addr="((OPTIND - 1))
if [ "${OPTIND}" -eq 1 ]; then echo "Using defaults -a ca -l host" fi
if { [ -z "{ca_cert}" ] && [ -n "{ca_key}" ]; } || { [ -n "{ca_cert}" ] && [ -z "{ca_key}" ]; }; then echo "[!] -c and -k are required together; you cannot provide just one." usage fi
if [ -z "{leaf_prefix}" fi
if [ -z "${ip_addr}" ]; then ip_addr="127.0.0.1" fi
ca_ext_file="{leaf_prefix}.leaf.ext"
if [ -z "{ca_cert}" ] && [ -z "{ca_key}" ]; then ca_cert="{ca_prefix}.key.pem"
if [ -f "{ca_key}" ]; then echo "[*] Cowardly refusing to overwrite files {ca_key}" exit 1 fi
if [ -f "{ca_ext_file}" exit 1 fi
echo "[-] CREATING CA KEY"
openssl genrsa
-out "{size}"
echo "[+] CREATED CA KEY"
echo "[-] CREATING CA EXTENSION FILE" cat > "${ca_ext_file}" <<EOF basicConstraints = critical, CA:TRUE keyUsage = critical, keyCertSign, cRLSign subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer EOF
echo "[-] CREATING CA CERT"
openssl req -x509 -new -nodes
-key "{ca_validity}"
-out "{ca_prefix} Local Test CA"
-extensions v3_ca
-config <(cat /etc/ssl/openssl.cnf 2>/dev/null || printf "[req]\ndistinguished_name=dn\n[dn]\n"; printf "\n[v3_ca]\n"; cat "${ca_ext_file}")
echo "[+] CREATED CA CERT: ${ca_cert}" fi
if [ ! -f "{ca_cert}" exit 1 fi
if [ ! -f "{ca_key}" exit 1 fi
if [ -f "{leaf_prefix}.cert.pem" ] || [ -f "{leaf_ext_file}" ]; then echo "[*] Cowardly refusing to overwrite one of:" echo " {leaf_prefix}.cert.pem" echo " {leaf_ext_file}" exit 1 fi
echo "[-] CREATING LEAF KEY"
openssl genrsa
-out "{size}"
echo "[+] CREATED LEAF KEY: ${leaf_prefix}.key.pem"
echo "[-] CREATING LEAF EXTENSION FILE" cat > "${leaf_ext_file}" <<EOF basicConstraints = CA:FALSE keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer subjectAltName = @alt_names
[alt_names] DNS.1 = {ip_addr} EOF
echo "[+] CREATED LEAF EXTENSION FILE: ${leaf_ext_file}"
echo "[-] CREATING LEAF CSR"
openssl req -new
-key "{leaf_prefix}.csr"
-subj "/CN=${dns_name}"
echo "[+] CREATED LEAF CSR: ${leaf_prefix}.csr"
echo "[-] SIGNING LEAF CERTIFICATE"
openssl x509 -req
-in "{ca_cert}"
-CAkey "{leaf_prefix}.cert.pem"
-days "{leaf_ext_file}"
echo "[+] CREATED LEAF CERTIFICATE: {leaf_prefix}.cert.pem"
-noout
-subject
-issuer
-dates
-ext subjectAltName
echo echo "Done."