CA.sh/CA.sh

107 lines
2.7 KiB
Bash
Executable File

#!/bin/sh
# Generate CA + wildcard cert for any hostname
CA_name='local CA'
helptext='Usage:
./CA.sh <host> Generate a CA and sign a wildacrd cert for <host> with it.'
set -o errexit # (-e) exit immediately if any command has a non-zero exit status
set -o nounset # (-u) don't accept undefined variables
#set -o xtrace # for debugging
# Check input.
if [ "$#" -lt 1 ] || [ "$#" -gt 1 ]; then
>&2 echo "$helptext"
exit 1
fi
host="$1"
# Check if host is an IP address.
ip=0
# If `ipcalc-ng` is available, use it.
if command -v ipcalc-ng >/dev/null; then
if ipcalc-ng -sc "$host"; then
ip=1
fi
# Else if `ip` is available, use it.
# Note: a simple number also passes this check,
# but it's good enough for our purposes.
elif command -v ip >/dev/null; then
if ip route get "$host" >/dev/null 2>&1; then
ip=1
fi
fi
# If host is an IDN, convert it to punycode.
# Use the `idn` command, if available.
if command -v idn >/dev/null; then
host=$(echo "$host" | idn)
fi
# Create CA directory, if it does not exist.
mkdir -p CA
cd CA
# Generate CA.
if [ ! -f "ca.key" ] && [ ! -f "ca.crt" ]; then
openssl genrsa -out ca.key 2048
openssl req -new -x509 -key ca.key -out ca.crt -subj "/CN=$CA_name" -days 30
openssl x509 -in ca.crt -noout -text
# Copy the CA cert under a new name, allowing it to be accepted in the
# Android trust store (/system/etc/security/cacerts/).
mkdir -p android
filename=$(openssl x509 -inform PEM -subject_hash_old -in ca.crt | head -1)
cp ca.crt "android/$filename.0"
fi
# Generate wildcard cert.
if [ ! -f "$host.key" ] && [ ! -f "$host.crt" ]; then
# Set the Subject Alternative Name based on whether
# the host is an IP address or not.
if [ $ip -eq 1 ]; then
SAN1="IP:$host"
SAN2="IP = $host"
else
SAN1="DNS:*.$host, DNS:$host"
SAN2="DNS.1 = *.$host
DNS.2 = $host"
fi
openssl genrsa -out "$host.key" 2048
openssl req -new -key "$host.key" -out "$host.csr" -subj "/CN=$host" \
-addext "subjectAltName = $SAN1"
#openssl req -in "$host.csr" -noout -text
# Prepare X.509 extensions file.
echo "basicConstraints=CA:FALSE
subjectAltName=@my_subject_alt_names
subjectKeyIdentifier = hash
[ my_subject_alt_names ]
$SAN2" > ext.conf
# Sign the cert.
openssl x509 -req -in "$host.csr" -out "$host.crt" -days 30 \
-CA ca.crt -CAkey ca.key -extfile ext.conf -CAcreateserial
openssl x509 -in "$host.crt" -noout -text
rm "$host.csr"
# Remove X.509 extensions file.
rm ext.conf
fi
# Create bundle (probably not be required).
#cat "$host.crt" ca.crt > "$host.bundle.crt"
# Show generated files.
if command -v tree >/dev/null; then
cd ..
echo '=== Generated files ==='
tree CA
fi