#!/bin/bash export SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P ) DEFAULT_DOMAIN='reverse.com' DEFAULT_IP='123.123.123.123' # create certificates # $ make tls-server example.com ssl # $ make tls-server sub.example.com ssl # creates example.com.ssl.tls-server.crt: # - request created with example.com.tls-server.cnf # - signed by example.com.ca-tls.crt using config example.com.ca-tls.cnf check_result() { if [ $1 -ne 0 ]; then echo -e "\e[91m Error\e[39m $2" exit $1 fi echo -e "\e[92m +\e[39m" } warn_result() { if [ $1 -ne 0 ]; then echo -e "\e[93m Warning\e[39m $2" fi } check_prompt() { if [ $1 -ne 0 ]; then warn_result "$@" read -p 'Would you like to continue [y/n]: ' answer if [ "$answer" != 'y' ] && [ "$answer" != 'Y' ]; then echo 'Goodbye' exit 1 fi fi } domainPath() { local domain=$1 local lookup="$SCRIPT_PATH/$DEFAULT_DOMAIN/lookup" local path=$lookup/$domain if [ -e $path ]; then echo $(head -n 1 $path) fi } # type: for avail crt-types see crt-*/etc/*.cnf {email|tls-client|tls-server|code-signing} # domain: a valid domain, stored in /lookup # fileName: a unique filename. If the file exists, the last version will be revoked as affiliationChanged # # files will be stored in ./crt-*/$domain.$filename.$type.ext # --- # make tls-server example.com ssl # --- make() { local type=$1 local domain=$2 local fileName=$3 local path=$(domainPath $domain) if [ -z $path ]; then check_result 1 "domain $domain not found in $SCRIPT_PATH/$DEFAULT_DOMAIN" fi local baseType case "$type" in email) baseType='email' echo "create $baseType/$type" ;; tls-server|tls-client) baseType='tls' echo "create $baseType/$type" ;; code-signing) baseType='software' echo "create $baseType/$type" ;; *) check_result 1 "invalid request type $type; {email|tls-client|tls-server|code-signing}" exit 1 esac local lvl=$(grep -o '/intermediate/' <<< "$path" | wc -l) case "$lvl" in 0) export CA_0_SCRIPT_PATH="$path" ;; 1) export CA_1_SCRIPT_PATH="$path" ;; 2) export CA_2_SCRIPT_PATH="$path" ;; esac local caCrl="$path/ca-$baseType/db/$domain.ca-$baseType.crl" local caCnf="$path/ca-$baseType/etc/$domain.ca-$baseType.cnf" local caPwd="$path/ca-$baseType/private/$domain.ca-$baseType.pwd" local csrCnf="$path/crt-$baseType/etc/$domain.$type.cnf" local key="$path/crt-$baseType/private/$domain.$fileName.$type.key" local csr="$path/crt-$baseType/$domain.$fileName.$type.csr" local crt="$path/crt-$baseType/$domain.$fileName.$type.crt" local p12="$path/crt-$baseType/$domain.$fileName.$type.p12" local chain="$path/$domain.ca-$baseType.chain.pem" if [ -e $crt ]; then local lastSrl=$(openssl x509 -in $crt -serial -noout) local lastFnr=$(openssl x509 -in $crt -fingerprint -noout) check_prompt 1 "certificate $domain.$fileName.$type.crt exists as \n\t$lastSrl\n\t$lastFnr\nRevoke this version and create a new verion." echo 'Please set the revokation reason, type any other key to continue without setting the CRL reason.' echo '[1] unspecified' echo '[2] keyCompromise' echo '[3] CACompromise' echo '[4] affiliationChanged' echo '[5] superseded' echo '[6] cessationOfOperation' echo '[7] certificateHold' echo '[8] removeFromCRL' read -p 'Please set the revokation reason [1-8]: ' answer local revokationReason=no case "$answer" in 1) revokationReason=unspecified ;; 2) revokationReason=keyCompromise ;; 3) revokationReason=CACompromise ;; 4) revokationReason=affiliationChanged ;; 5) revokationReason=superseded ;; 6) revokationReason=cessationOfOperation ;; 7) revokationReason=certificateHold ;; 8) revokationReason=removeFromCRL ;; *) warn_result 1 'Nothing matched. Continue without setting a reason.' esac if [ $revokationReason == 'no' ]; then openssl ca \ -config $caCnf \ -revoke $crt \ -passin file:$caPwd else openssl ca \ -config $caCnf \ -revoke $crt \ -passin file:$caPwd \ -crl_reason $revokationReason fi openssl ca -gencrl \ -config $caCnf \ -out $caCrl \ -passin file:$caPwd fi # note -subj # if you want to use multiple values you should remove the -subj and use the prompt. # /O/ST must match, see CA-configs. # I prefer to bypass the prompt for ~300 domains with ~2k subdomains. case "$type" in tls-server) export SAN="DNS:$domain,DNS:*.$domain" openssl req -new \ -config $csrCnf \ -out $csr \ -keyout $key \ -subj "/C=BE/ST=Antwerp/O=### Network $domain/CN=$domain" openssl ca \ -batch \ -config $caCnf \ -in $csr \ -out $crt \ -passin file:$caPwd \ -extensions server_ext openssl pkcs12 -export \ -name "$domain (TLS Network Component)" \ -inkey $key \ -passout pass:\ -in $crt \ -certfile $chain \ -out $p12 ;; *) check_result 1 "invalid request type $type; {email|tls-client|tls-server|code-signing}" exit 1 esac }