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 "OPTIONS"inh)usage;;c)cacert="{OPTIONS}" in h) usage ;; c) ca_cert="{OPTARG}" ;; k) ca_key="OPTARG";;l)leafprefix="{OPTARG}" ;; l) leaf_prefix="{OPTARG}" ;; a) ca_prefix="OPTARG";;d)dnsname="{OPTARG}" ;; d) dns_name="{OPTARG}" ;; i) ip_addr="OPTARG";;)usage;;esacdoneshift{OPTARG}" ;; *) usage ;; esac done shift ((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 "dnsname"];thendnsname="{dns_name}" ]; then dns_name="{leaf_prefix}" fi

if [ -z "${ip_addr}" ]; then ip_addr="127.0.0.1" fi

ca_ext_file="caprefix.ca.ext"leafextfile="{ca_prefix}.ca.ext" leaf_ext_file="{leaf_prefix}.leaf.ext"

if [ -z "{ca_cert}" ] && [ -z "{ca_key}" ]; then ca_cert="caprefix.cert.pem"cakey="{ca_prefix}.cert.pem" ca_key="{ca_prefix}.key.pem"

if [ -f "cacert"][f"{ca_cert}" ] || [ -f "{ca_key}" ]; then echo "[*] Cowardly refusing to overwrite files cacertor{ca_cert} or {ca_key}" exit 1 fi

if [ -f "caextfile"];thenecho"[]Cowardlyrefusingtooverwritefile{ca_ext_file}" ]; then echo "[*] Cowardly refusing to overwrite file {ca_ext_file}" exit 1 fi

echo "[-] CREATING CA KEY" openssl genrsa
-out "cakey" "{ca_key}" \ "{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 "cakey" sha256 days"{ca_key}" \ -sha256 \ -days "{ca_validity}"
-out "cacert" subj"/CN={ca_cert}" \ -subj "/CN={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 "cacert"];thenecho"[!]CAcertnotfound:{ca_cert}" ]; then echo "[!] CA cert not found: {ca_cert}" exit 1 fi

if [ ! -f "cakey"];thenecho"[!]CAkeynotfound:{ca_key}" ]; then echo "[!] CA key not found: {ca_key}" exit 1 fi

if [ -f "leafprefix.key.pem"][f"{leaf_prefix}.key.pem" ] || [ -f "{leaf_prefix}.cert.pem" ] || [ -f "leafprefix.csr"][f"{leaf_prefix}.csr" ] || [ -f "{leaf_ext_file}" ]; then echo "[*] Cowardly refusing to overwrite one of:" echo " leafprefix.key.pem"echo"{leaf_prefix}.key.pem" echo " {leaf_prefix}.cert.pem" echo " leafprefix.csr"echo"{leaf_prefix}.csr" echo " {leaf_ext_file}" exit 1 fi

echo "[-] CREATING LEAF KEY" openssl genrsa
-out "leafprefix.key.pem" "{leaf_prefix}.key.pem" \ "{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 = dnsnameIP.1={dns_name} IP.1 = {ip_addr} EOF

echo "[+] CREATED LEAF EXTENSION FILE: ${leaf_ext_file}"

echo "[-] CREATING LEAF CSR" openssl req -new
-key "leafprefix.key.pem" out"{leaf_prefix}.key.pem" \ -out "{leaf_prefix}.csr"
-subj "/CN=${dns_name}"

echo "[+] CREATED LEAF CSR: ${leaf_prefix}.csr"

echo "[-] SIGNING LEAF CERTIFICATE" openssl x509 -req
-in "leafprefix.csr" CA"{leaf_prefix}.csr" \ -CA "{ca_cert}"
-CAkey "cakey" CAcreateserial out"{ca_key}" \ -CAcreateserial \ -out "{leaf_prefix}.cert.pem"
-days "leafvalidity" sha256 extfile"{leaf_validity}" \ -sha256 \ -extfile "{leaf_ext_file}"

echo "[+] CREATED LEAF CERTIFICATE: leafprefix.cert.pem"echoecho"Certificatedetails:"opensslx509 in"{leaf_prefix}.cert.pem" echo echo "Certificate details:" openssl x509 \ -in "{leaf_prefix}.cert.pem"
-noout
-subject
-issuer
-dates
-ext subjectAltName

echo echo "Done."