#!/bin/bash export SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P ) # create an empty directory and execute this script. # the initializer is demo(); @see end of this file DEFAULT_DOMAIN='reverse.com' DEFAULT_IP='192.168.0.42' #local DEFAULT_CA_RSA_KEYSIZE_PASSWORD=8192 #local DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY=8192 #local DEFAULT_CA_RSA_KEYSIZE_REQUEST=4096 DEFAULT_CA_RSA_KEYSIZE_PASSWORD=4096 DEFAULT_CA_PWD_GEN_PUBEXP=7 DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY=8192 DEFAULT_CA_RSA_KEYSIZE_REQUEST=8192 DEFAULT_CA_MD_REQUEST=sha512 DEFAULT_CA_MD=sha512 DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY=4096 DEFAULT_CRT_PWD_GEN_PUBEXP=7 DEFAULT_CRT_RSA_KEYSIZE_REQUEST=2048 DEFAULT_CRT_MD_REQUEST=sha512 #rm -rf $SCRIPT_PATH/$DEFAULT_DOMAIN/* > /dev/null 2>&1 #exit 1 #find $SCRIPT_PATH/$DEFAULT_DOMAIN/ -name "*.*" -type f|xargs rm -f ############################################################## # # constants # ############################################################## declare -A DIR_NAME DIR_NAME[cnf]='etc' DIR_NAME[db]='db' DIR_NAME[private]='private' DIR_NAME[public]='public' DIR_NAME[intermediateDir]='intermediate' DIR_NAME[lookup]='lookup' DIR_NAME[caRoot]='ca' DIR_NAME[caEmail]='ca-email' DIR_NAME[caSoftware]='ca-software' DIR_NAME[caTls]='ca-tls' DIR_NAME[crtEmail]='crt-email' DIR_NAME[crtSoftware]='crt-software' DIR_NAME[crtTls]='crt-tls' DIR_NAME[email]='email' DIR_NAME[software]='software' DIR_NAME[tls]='tls' declare -r DIR_NAME declare -A FILE_NAME FILE_NAME[cnf]='%s.%s.cnf' FILE_NAME[csr]='%s.%s.csr' FILE_NAME[p12]='%s.%s.p12' FILE_NAME[crt]='%s.%s.crt' FILE_NAME[crtPem]='%s.%s.crt.pem' FILE_NAME[cer]='%s.%s.cer' FILE_NAME[chainPem]='%s.%s.chain.pem' FILE_NAME[chainP7c]='%s.%s.chain.p7c' FILE_NAME[crtDb]='%s.%s.crt.db' FILE_NAME[crtSrl]='%s.%s.crt.srl' FILE_NAME[crl]='%s.%s.crl' FILE_NAME[crlPem]='%s.%s.crl.pem' FILE_NAME[crlSrl]='%s.%s.crl.srl' FILE_NAME[key]='%s.%s.key' FILE_NAME[keyPem]='%s.%s.key.pem' FILE_NAME[password]='%s.%s.pwd' declare -r FILE_NAME declare -A DIRECTORIES_CA_ROOT DIRECTORIES_CA_ROOT[caPath]=${DIR_NAME[caRoot]} DIRECTORIES_CA_ROOT[dbPath]=${DIR_NAME[caRoot]}/${DIR_NAME[db]} DIRECTORIES_CA_ROOT[cnfPath]=${DIR_NAME[caRoot]}/${DIR_NAME[cnf]} DIRECTORIES_CA_ROOT[privatePath]=${DIR_NAME[caRoot]}/${DIR_NAME[private]} declare -r DIRECTORIES_CA_ROOT declare -A DIRECTORIES_CA_EMAIL DIRECTORIES_CA_EMAIL[caPath]=${DIR_NAME[caEmail]} DIRECTORIES_CA_EMAIL[dbPath]=${DIR_NAME[caEmail]}/${DIR_NAME[db]} DIRECTORIES_CA_EMAIL[cnfPath]=${DIR_NAME[caEmail]}/${DIR_NAME[cnf]} DIRECTORIES_CA_EMAIL[privatePath]=${DIR_NAME[caEmail]}/${DIR_NAME[private]} declare -r DIRECTORIES_CA_EMAIL declare -A DIRECTORIES_CRT_EMAIL DIRECTORIES_CRT_EMAIL[crtPath]=${DIR_NAME[crtEmail]} DIRECTORIES_CRT_EMAIL[cnfPath]=${DIR_NAME[crtEmail]}/${DIR_NAME[cnf]} DIRECTORIES_CRT_EMAIL[privatePath]=${DIR_NAME[crtEmail]}/${DIR_NAME[private]} declare -r DIRECTORIES_CRT_EMAIL declare -A DIRECTORIES_CA_SOFTWARE DIRECTORIES_CA_SOFTWARE[caPath]=${DIR_NAME[caSoftware]} DIRECTORIES_CA_SOFTWARE[dbPath]=${DIR_NAME[caSoftware]}/${DIR_NAME[db]} DIRECTORIES_CA_SOFTWARE[cnfPath]=${DIR_NAME[caSoftware]}/${DIR_NAME[cnf]} DIRECTORIES_CA_SOFTWARE[privatePath]=${DIR_NAME[caSoftware]}/${DIR_NAME[private]} declare -r DIRECTORIES_CA_SOFTWARE declare -A DIRECTORIES_CRT_SOFTWARE DIRECTORIES_CRT_SOFTWARE[crtPath]=${DIR_NAME[crtSoftware]} DIRECTORIES_CRT_SOFTWARE[cnfPath]=${DIR_NAME[crtSoftware]}/${DIR_NAME[cnf]} DIRECTORIES_CRT_SOFTWARE[privatePath]=${DIR_NAME[crtSoftware]}/${DIR_NAME[private]} declare -r DIRECTORIES_CRT_SOFTWARE declare -A DIRECTORIES_CA_TLS DIRECTORIES_CA_TLS[caPath]=${DIR_NAME[caTls]} DIRECTORIES_CA_TLS[dbPath]=${DIR_NAME[caTls]}/${DIR_NAME[db]} DIRECTORIES_CA_TLS[cnfPath]=${DIR_NAME[caTls]}/${DIR_NAME[cnf]} DIRECTORIES_CA_TLS[privatePath]=${DIR_NAME[caTls]}/${DIR_NAME[private]} declare -r DIRECTORIES_CA_TLS declare -A DIRECTORIES_CRT_TLS DIRECTORIES_CRT_TLS[crtPath]=${DIR_NAME[crtTls]} DIRECTORIES_CRT_TLS[cnfPath]=${DIR_NAME[crtTls]}/${DIR_NAME[cnf]} DIRECTORIES_CRT_TLS[privatePath]=${DIR_NAME[crtTls]}/${DIR_NAME[private]} declare -r DIRECTORIES_CRT_TLS declare -A DIRECTORIES_PUB DIRECTORIES_PUB[email]=${DIR_NAME[public]}/${DIR_NAME[email]} DIRECTORIES_PUB[software]=${DIR_NAME[public]}/${DIR_NAME[software]} DIRECTORIES_PUB[tls]=${DIR_NAME[public]}/${DIR_NAME[tls]} declare -r DIRECTORIES_PUB ############################################################## # # consolol # ############################################################## writeNewCert() { local domain=$1 local x=$(printf '%-64s' "create certificates for") local y=$(printf '%-64s' "$domain") local z=$(printf '%-64s' '') echo -e "\e[90m$z\e[39m" echo -e "\e[92m$x\e[39m" echo -e "\e[96m$y\e[39m" echo -e "\e[90m$z\e[39m" } writeDelCert() { local domain=$1 local x=$(printf '%-64s' "delete certificates for") local y=$(printf '%-64s' "$domain") local z=$(printf '%-64s' '') echo -e "\e[90m$z\e[39m" echo -e "\e[91m$x\e[39m" echo -e "\e[96m$y\e[39m" echo -e "\e[90m$z\e[39m" } writeRevCert() { local domain=$1 local x=$(printf '%-64s' "revoke certificates for") local y=$(printf '%-64s' "$domain") local z=$(printf '%-64s' '') echo -e "\e[90m$z\e[39m" echo -e "\e[93m$x\e[39m" echo -e "\e[96m$y\e[39m" echo -e "\e[90m$z\e[39m" } writeNewType() { local type=$1 echo -e "\e[97m• \e[92mcreate\e[97m $type\e[39m" } writeDelType() { local type=$1 echo -e "\e[97m• \e[91mdelete\e[97m $type\e[39m" } writeRevType() { local type=$1 echo -e "\e[97m• \e[93mrevoke\e[97m $type\e[39m" } writeNewItem() { local item=$1 echo -e "\e[90m \e[92m+\e[90m $item\e[39m" } writeNewItem2() { local item=$1 echo -e "\e[90m \e[92m+\e[90m $item\e[39m" } writeDelItem() { local item=$1 echo -e "\e[90m \e[91m-\e[90m $item\e[39m" } writeDelItem2() { local item=$1 echo -e "\e[90m \e[91m-\e[90m $item\e[39m" } do_unlock() { rm -rf "/var/lock/$DEFAULT_DOMAIN" } do_exit() { if [ $1 -ne 30 ]; then do_unlock fi exit $1 } check_result() { if [ $1 -ne 0 ]; then echo -e "\e[91m Error\e[39m $2" do_exit "$1" else echo -e "\e[92m OK\e[39m" fi } idle_result() { if [ $1 -ne 0 ]; then echo -e "\e[93m Nothing to do.\e[39m $2" return $1 fi echo -e "\e[92m Ok\e[39m" } warn_result() { if [ $1 -ne 0 ]; then echo -e "\e[93mWarning\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' do_exit "$1" fi fi } certificate() { # entry point local reverseDomain=$1 # registered domain; MUST avail in lookup folder local domain=$2 # what you want to do; {create|delete|revoke} local action=$3 # the certificate type; {email|tls-client|tls-client-external|tls-server|tls-server-external|code-signing} local configType=$4 # infix/prefix... for new files. # the given name should be related to the cert; e.g. foo.com for tls-server-external local fileNameInfix=$5 # optional named arg san # used for $ENV:SAN=$envVar in tls-server-external; if not present: $ENV:SAN="DNS:$fileNameInfix,DNS:*.$fileNameInfix" local san # optional named arg password # used for personal certificates and is required for email, tls-client, and tls-client-external local password # subj defaults # we have to redefine the common name in tls-server as $domain declare -A SUBJ_DEFAULT SUBJ_DEFAULT[C]='BE' SUBJ_DEFAULT[ST]='Antwerp' SUBJ_DEFAULT[L]='Antwerp' SUBJ_DEFAULT[O]="### Network $domain" SUBJ_DEFAULT[OU]='' SUBJ_DEFAULT[CN]="### Network $domain" # subjects cust declare -A SUBJ while [[ ${6} ]]; do case "${6}" in -san) # used for $ENV:SAN=$envVar in tls-server-external; if not present: $ENV:SAN="DNS:$fileNameInfix,DNS:*.$fileNameInfix" local san=${7} shift ;; -password) # used for personal certificates and is required for email, tls-client, and tls-client-external local password=${7} shift ;; # certificate subjects -C) SUBJ[C]=${7} shift ;; -ST) SUBJ[ST]=${7} shift ;; -L) SUBJ[L]=${7} shift ;; -O) SUBJ[O]=${7} shift ;; -OU) SUBJ[OU]=${7} shift ;; -CN) SUBJ[CN]=${7} shift ;; -emailAddress) SUBJ[emailAddress]=${7} shift ;; *) echo "Unknown parameter: ${6}" >&2 return 1 esac if ! shift; then echo 'Missing parameter argument.' >&2 return 1 fi done local lookupPath="$SCRIPT_PATH/$reverseDomain/lookup" if [ ! -d $lookupPath ]; then check_result 1 "Lookup directory for $reverseDomain is not here." fi if [ ! -f "$lookupPath/$domain" ]; then check_result 1 "$domain is not here :(" fi ############################################################## # # bootstrap # ############################################################## local fileName="$fileNameInfix;;$domain" getDomainPath() { local lookupPath=$1 local domain=$2 echo $(head -n 1 $lookupPath/$domain) } getBaseType() { local type=$1 case "$type" in email) echo 'email' ;; tls-server|tls-server-external|tls-client|tls-client-external) echo 'tls' ;; code-signing) echo 'software' ;; *) check_result 1 "invalid request type $type; {email|tls-client|tls-client-external|tls-server|tls-server-external|code-signing}" esac } declare -A FILES declare -A DIRS getFiles() { local domain=$1 local domainPath=$2 local baseType=$3 local configType=$4 local fileName=$5 local caType local crtType DIRS[ca]=$domainPath DIRS[pub]=$domainPath/${DIR_NAME[public]} case "$baseType" in email) local caType=${DIR_NAME[caEmail]} local crtType=${DIR_NAME[crtEmail]} DIRS[caDb]=$domainPath/${DIRECTORIES_CA_EMAIL[dbPath]} DIRS[caCnf]=$domainPath/${DIRECTORIES_CA_EMAIL[cnfPath]} DIRS[caPrivate]=$domainPath/${DIRECTORIES_CA_EMAIL[privatePath]} DIRS[crt]=$domainPath/${DIRECTORIES_CRT_EMAIL[crtPath]} DIRS[crtCnf]=$domainPath/${DIRECTORIES_CRT_EMAIL[cnfPath]} DIRS[crtPrivate]=$domainPath/${DIRECTORIES_CRT_EMAIL[privatePath]} DIRS[pubCrt]=$domainPath/${DIRECTORIES_PUB[email]} ;; tls) local caType=${DIR_NAME[caTls]} local crtType=${DIR_NAME[crtTls]} DIRS[caDb]=$domainPath/${DIRECTORIES_CA_TLS[dbPath]} DIRS[caCnf]=$domainPath/${DIRECTORIES_CA_TLS[cnfPath]} DIRS[caPrivate]=$domainPath/${DIRECTORIES_CA_TLS[privatePath]} DIRS[crt]=$domainPath/${DIRECTORIES_CRT_TLS[crtPath]} DIRS[crtCnf]=$domainPath/${DIRECTORIES_CRT_TLS[cnfPath]} DIRS[crtPrivate]=$domainPath/${DIRECTORIES_CRT_TLS[privatePath]} DIRS[pubCrt]=$domainPath/${DIRECTORIES_PUB[tls]} ;; software) local caType=${DIR_NAME[caSoftware]} local crtType=${DIR_NAME[crtSoftware]} DIRS[caDb]=$domainPath/${DIRECTORIES_CA_SOFTWARE[dbPath]} DIRS[caCnf]=$domainPath/${DIRECTORIES_CA_SOFTWARE[cnfPath]} DIRS[caPrivate]=$domainPath/${DIRECTORIES_CA_SOFTWARE[privatePath]} DIRS[crt]=$domainPath/${DIRECTORIES_CRT_SOFTWARE[crtPath]} DIRS[crtCnf]=$domainPath/${DIRECTORIES_CRT_SOFTWARE[cnfPath]} DIRS[crtPrivate]=$domainPath/${DIRECTORIES_CRT_SOFTWARE[privatePath]} DIRS[pubCrt]=$domainPath/${DIRECTORIES_PUB[software]} ;; *) check_result 1 "invalid request baseType '$baseType' {email|tls|software}" esac # the directories are always present for index in "${!DIRS[@]}" do if [ ! -d "${DIRS[$index]}" ]; then check_result 1 'directory not found' fi done FILES[caChainPem]=${DIRS[ca]}/$(printf ${FILE_NAME[chainPem]} $domain $caType) FILES[caCrl]=${DIRS[caDb]}/$(printf ${FILE_NAME[crl]} $domain $caType) FILES[caCnf]=${DIRS[caCnf]}/$(printf ${FILE_NAME[cnf]} $domain $caType) FILES[caPwd]=${DIRS[caPrivate]}/$(printf ${FILE_NAME[password]} $domain $caType) # the CA files are always present for index in "${!FILES[@]}" do if [ ! -f "${FILES[$index]}" ]; then check_result 1 "Required CA file ${FILES[$index]} not found" fi done FILES[crt]=${DIRS[crt]}/$(printf ${FILE_NAME[crt]} $fileName $configType) FILES[crtCsr]=${DIRS[crt]}/$(printf ${FILE_NAME[csr]} $fileName $configType) FILES[crtP12]=${DIRS[crt]}/$(printf ${FILE_NAME[p12]} $fileName $configType) FILES[crtChainPem]=${DIRS[crt]}/$(printf ${FILE_NAME[chainPem]} $fileName $configType) FILES[crtCnf]=${DIRS[crtCnf]}/$(printf ${FILE_NAME[cnf]} $domain $configType) FILES[crtKey]=${DIRS[crtPrivate]}/$(printf ${FILE_NAME[key]} $fileName $configType) FILES[pubCaCrl]=${DIRS[pub]}/$(printf ${FILE_NAME[crl]} $domain $caType) FILES[pubCer]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[cer]} $fileName $configType) FILES[pubChainP7c]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[chainP7c]} $fileName $configType) FILES[pubKeyPem]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[keyPem]} $fileName $configType) FILES[pubCrtPem]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[crtPem]} $fileName $configType) } local domainPath=$(getDomainPath $lookupPath $domain) local baseType=$(getBaseType $configType) getFiles $domain $domainPath $baseType $configType $fileName local lvl=$(grep -o '/intermediate/' <<< "$domainPath" | wc -l) case "$lvl" in 0) export CA_0_SCRIPT_PATH="$domainPath" ;; 1) export CA_1_SCRIPT_PATH="$domainPath" ;; 2) export CA_2_SCRIPT_PATH="$domainPath" ;; esac testPassword() { local password=$1 if [ -z "$password" ]; then check_result 1 "A password is required but was not set or ist empty.\n You can add it with parameter -password" fi } testSubject() { local type=$1 local name=$2 local insert=$3 local default=$4 case "$type" in match) if [ ! -z "$insert" ]; then if [ "$default" != "$insert" ]; then check_result 1 "Invalid data for subject /$name=$insert\nThis field must match with the CA policy /$name=$default\nRemove the argument -$name and I will set it for you." fi fi ;; supplied) if [ -z "$insert" ]; then check_result 1 "Invalid data for subject /$name=\nThis field must be present and can not be empty.\nYou have to add the parameter -$name" fi ;; esac } concatSubj() { declare -A MERGED local result="" for index in "${!SUBJ_DEFAULT[@]}" do MERGED[$index]=${SUBJ_DEFAULT[$index]} done for index in "${!SUBJ[@]}" do MERGED[$index]=${SUBJ[$index]} done for index in "${!MERGED[@]}" do result="${result}/${index}=${MERGED[$index]}" done echo $result } ############################################################## # # actions # ############################################################## case "$action" in create) local subject=$(concatSubj) writeNewCert "$configType: $fileNameInfix" revokeAfterValidation() { if [ -e ${FILES[crt]} ]; then writeRevType "This certificate exists. We have to revoke it." certificate "$reverseDomain" "$domain" revoke "$configType" "$fileNameInfix" writeNewType "$subject" fi } writeNewType "new $subject" case "$configType" in code-signing) # see CA policy testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}" testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}" testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}" testPassword $password revokeAfterValidation writeNewItem 'key' openssl genpkey \ -algorithm RSA \ -out ${FILES[crtKey]} \ -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \ -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP check_result $? 'unable to create key' writeNewItem 'csr' openssl req -new \ -config ${FILES[crtCnf]} \ -out ${FILES[crtCsr]} \ -key ${FILES[crtKey]} \ -subj "$subject" \ -passout pass:$password check_result $? 'unable to create csr' writeNewItem 'create crt' openssl ca \ -batch \ -config ${FILES[caCnf]} \ -in ${FILES[crtCsr]} \ -out ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ -extensions codesign_ext \ > /dev/null 2>&1 check_result $? 'unable to create crt' writeNewItem 'verify sslclient' openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]} writeNewItem 'publish as p12' openssl pkcs12 -export \ -name "$domain: $fileNameInfix (Software Certificate)" \ -inkey ${FILES[crtKey]} \ -in ${FILES[crt]} \ -certfile ${FILES[caChainPem]} \ -out ${FILES[crtP12]} \ -passout pass:$password \ -passin pass:$password \ > /dev/null 2>&1 check_result $? 'unable to create p12' ;; email) # see CA policy testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}" testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}" testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}" testSubject 'supplied' 'emailAddress' "${SUBJ[emailAddress]}" testPassword $password revokeAfterValidation writeNewItem 'key' openssl genpkey \ -algorithm RSA \ -out ${FILES[crtKey]} \ -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \ -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP check_result $? 'unable to create key' writeNewItem 'csr' openssl req -new \ -config ${FILES[crtCnf]} \ -out ${FILES[crtCsr]} \ -key ${FILES[crtKey]} \ -subj "$subject" \ -passout pass:$password check_result $? 'unable to create csr' writeNewItem 'create crt' openssl ca \ -batch \ -config ${FILES[caCnf]} \ -notext \ -in ${FILES[crtCsr]} \ -out ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ -extensions email_ext check_result $? 'unable to create crt' writeNewItem 'verify sslclient' openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]} writeNewItem 'publish as p12' openssl pkcs12 -export \ -name "${SUBJ[emailAddress]} (Email Address)" \ -inkey ${FILES[crtKey]} \ -in ${FILES[crt]} \ -certfile ${FILES[caChainPem]} \ -out ${FILES[crtP12]} \ -passout pass:$password \ -passin pass:$password \ > /dev/null 2>&1 check_result $? 'unable to create p12' ;; tls-client|tls-client-external) case "$configType" in tls-client) # see CA policy testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}" testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}" testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}" testPassword $password revokeAfterValidation writeNewItem 'key' openssl genpkey \ -algorithm RSA \ -out ${FILES[crtKey]} \ -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \ -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP check_result $? 'unable to create key' writeNewItem 'csr' openssl req -new \ -config ${FILES[crtCnf]} \ -out ${FILES[crtCsr]} \ -key ${FILES[crtKey]} \ -subj "$subject" \ -passout pass:$password check_result $? 'unable to create csr' writeNewItem 'create crt' openssl ca \ -batch \ -config ${FILES[caCnf]} \ -in ${FILES[crtCsr]} \ -out ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ -extensions client_ext \ > /dev/null 2>&1 check_result $? 'unable to create crt' ;; tls-client-external) # see CA policy testSubject 'supplied' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}" testSubject 'supplied' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}" testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}" testPassword $password revokeAfterValidation writeNewItem 'key' openssl genpkey \ -algorithm RSA \ -out ${FILES[crtKey]} \ -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \ -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP check_result $? 'unable to create key' writeNewItem 'csr' openssl req -new \ -config ${FILES[crtCnf]} \ -out ${FILES[crtCsr]} \ -key ${FILES[crtKey]} \ -subj "$subject" \ -passout pass:$password check_result $? 'unable to create csr' writeNewItem 'create crt' openssl ca \ -batch \ -config ${FILES[caCnf]} \ -in ${FILES[crtCsr]} \ -out ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ -extensions client_ext \ -policy extern_pol \ > /dev/null 2>&1 check_result $? 'unable to create crt' ;; esac writeNewItem 'verify sslclient' openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]} writeNewItem 'publish as p12' openssl pkcs12 -export \ -name "$fileNameInfix (TLS Network Access)" \ -inkey ${FILES[crtKey]} \ -in ${FILES[crt]} \ -certfile ${FILES[caChainPem]} \ -out ${FILES[crtP12]} \ -passout pass:$password \ -passin pass:$password \ > /dev/null 2>&1 check_result $? 'unable to create p12' #??? #writeNewItem 'pem key from p12' #openssl pkcs12 -nocerts \ # -in ${FILES[crtP12]} \ # -out ${FILES[pubKeyPem]} \ # > /dev/null 2>&1 #check_result $? 'unable to create pem key' # #writeNewItem 'pem crt from p12' #openssl pkcs12 -clcerts -nokeys \ # -in ${FILES[crtP12]} \ # -out ${FILES[pubCrtPem]} \ # > /dev/null 2>&1 #check_result $? 'unable to create p12' ;; tls-server|tls-server-external) case "$configType" in tls-server) SUBJ_DEFAULT[CN]=$domain # see CA policy testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}" testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}" testSubject 'match' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}" revokeAfterValidation export SAN="DNS:$domain,DNS:*.$domain" writeNewItem 'key' openssl genpkey \ -algorithm RSA \ -out ${FILES[crtKey]} \ -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \ -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP check_result $? 'unable to create key' writeNewItem 'csr' openssl req -new \ -config ${FILES[crtCnf]} \ -out ${FILES[crtCsr]} \ -key ${FILES[crtKey]} \ -subj "$subject" check_result $? 'unable to create csr' writeNewItem 'create crt' openssl ca \ -batch \ -config ${FILES[caCnf]} \ -in ${FILES[crtCsr]} \ -out ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ -extensions server_ext check_result $? 'unable to create crt' ;; tls-server-external) # see CA policy testSubject 'supplied' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}" testSubject 'supplied' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}" testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}" revokeAfterValidation if [ -z $san ]; then local san="DNS:$fileNameInfix,DNS:*.$fileNameInfix" fi export SAN="$san" writeNewItem 'key' openssl genpkey \ -algorithm RSA \ -out ${FILES[crtKey]} \ -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \ -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP check_result $? 'unable to create key' writeNewItem 'csr' openssl req -new \ -config ${FILES[crtCnf]} \ -out ${FILES[crtCsr]} \ -key ${FILES[crtKey]} \ -subj "$subject" check_result $? 'unable to create csr' writeNewItem 'create crt' openssl ca \ -batch \ -config ${FILES[caCnf]} \ -in ${FILES[crtCsr]} \ -out ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ -extensions server_ext \ -policy extern_pol \ > /dev/null 2>&1 check_result $? 'unable to create crt' ;; esac writeNewItem 'verify sslclient' openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]} writeNewItem 'publish as p12' openssl pkcs12 -export \ -name "$fileNameInfix (TLS Network Component)" \ -inkey ${FILES[crtKey]} \ -passout pass:\ -in ${FILES[crt]} \ -certfile ${FILES[caChainPem]} \ -out ${FILES[crtP12]} \ > /dev/null 2>&1 check_result $? 'unable to create p12' writeNewItem 'pem key from p12' openssl pkcs12 -nocerts -nodes \ -in ${FILES[crtP12]} \ -passin pass:\ -out ${FILES[pubKeyPem]} \ > /dev/null 2>&1 check_result $? 'unable to create pem key' writeNewItem 'passfree pem key' openssl rsa \ -in ${FILES[pubKeyPem]} \ -out ${FILES[pubKeyPem]} \ > /dev/null 2>&1 check_result $? 'unable to create passfree pem key' writeNewItem 'pem crt from p12' openssl pkcs12 -clcerts -nokeys \ -in ${FILES[crtP12]} \ -passin pass:\ -out ${FILES[pubCrtPem]} \ > /dev/null 2>&1 check_result $? 'unable to create p12' cat ${FILES[crt]} ${FILES[caChainPem]} > ${FILES[crtChainPem]} writeNewItem 'publish crt as application/pkix-cert' openssl x509 \ -in ${FILES[crt]} \ -out ${FILES[pubCer]} \ -outform der writeNewItem 'publish pem chain as application/pkcs7-mime' openssl crl2pkcs7 -nocrl \ -certfile ${FILES[crtChainPem]} \ -out ${FILES[pubChainP7c]} \ -outform der ;; esac ;; delete) writeDelCert "$configType: $fileNameInfix" declare -A REMOVE for type in crt crtCsr crtP12 crtKey pubCrtPem pubKeyPem pubCer pubChainP7c do if [ -e ${FILES[$type]} ]; then writeDelItem ${FILES[$type]} REMOVE[$type]=${FILES[$type]} fi done check_prompt 1 'Files will be permanently removed from disk!' if [ -e ${FILES[crt]} ]; then writeRevType "existing $configType: $fileNameInfix" certificate "$reverseDomain" "$domain" revoke "$configType" "$fileNameInfix" fi writeDelType 'files' for index in "${!REMOVE[@]}" do writeDelItem ${REMOVE[$index]} rm ${REMOVE[$index]} > /dev/null 2>&1 check_result $? 'unable to delete file' done ;; revoke) writeRevCert "$configType: $fileNameInfix" if [ -e ${FILES[crt]} ]; then local lastSrl=$(openssl x509 -in ${FILES[crt]} -serial -noout) local lastFnr=$(openssl x509 -in ${FILES[crt]} -fingerprint -noout) local revokationReason case "$configType" in email) local revokationReason=affiliationChanged ;; tls-server|tls-server-external|tls-client|tls-client-external) local revokationReason=affiliationChanged ;; code-signing) local revokationReason=affiliationChanged ;; esac check_prompt 1 "certificate $fileName.$configType.crt exists as \n\t$lastSrl\n\t$lastFnr\n" echo "" echo -e "Please set the revokation reason. Default CRL reason for type $configType is $revokationReason." echo -e " [1] unspecified" echo -e " [2] keyCompromise" echo -e " [3] CACompromise" echo -e " [4] affiliationChanged" echo -e " [5] superseded" echo -e " [6] cessationOfOperation" echo -e " [7] certificateHold" echo -e " [8] removeFromCRL" echo -e " [n] set no reason" echo "" read -p "Please set the revokation reason or nothing for default: " answer echo "" case "$answer" in 1) local revokationReason=unspecified ;; 2) local revokationReason=keyCompromise ;; 3) local revokationReason=CACompromise ;; 4) local revokationReason=affiliationChanged ;; 5) local revokationReason=superseded ;; 6) local revokationReason=cessationOfOperation ;; 7) local revokationReason=certificateHold ;; 8) local revokationReason=removeFromCRL ;; 'n'|'N') local revokationReason=no ;; esac writeNewType 'revokation' if [ $revokationReason == 'no' ]; then writeNewItem "revoke without reason" openssl ca \ -config ${FILES[caCnf]} \ -revoke ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ > /dev/null 2>&1 idle_result $? 'unable to revoke' else writeNewItem "revoke with $revokationReason" openssl ca \ -config ${FILES[caCnf]} \ -revoke ${FILES[crt]} \ -passin file:${FILES[caPwd]} \ -crl_reason $revokationReason \ > /dev/null 2>&1 idle_result $? 'unable to revoke' fi writeNewItem 'update crl' openssl ca -gencrl \ -config ${FILES[caCnf]} \ -out ${FILES[caCrl]} \ -passin file:${FILES[caPwd]} \ > /dev/null 2>&1 check_result $? 'unable to update crl' writeNewItem 'publish crl as application/pkix-crl' openssl crl \ -in ${FILES[caCrl]} \ -out ${FILES[pubCaCrl]} \ -outform der \ > /dev/null 2>&1 check_result $? 'unable to publish crl' fi ;; *) check_result 1 "invalid action '$action' {create|delete|revoke}" esac } ############################################################## # # asynch? # ############################################################## if [ -d "/var/lock/$DEFAULT_DOMAIN" ]; then check_result 30 "Already locked" fi mkdir "/var/lock/$DEFAULT_DOMAIN" check_result $? "Lock failed" ## # Create a simple CA-chain. # # create some CAs # root_ca 'reverse.com' 'domain1.com;domain2.com' 'sub1;sub2' # root_ca 'reverse.com' 'domain1.com' 'sub3' # root_ca 'reverse.com' 'domain2.com' 'sub4' # root_ca 'reverse.com' 'domain3.com' # # result # - ./reverse.com # - reverse.com.ca.crt (root CA) # - reverse.com.ca-tls.crt # - ./intermediate # - ./domain1.com # - domain1.com.ca.crt (sub root CA) # - domain1.com.ca-tls.crt # - domain1.com.ca-email.crt # - domain1.com.ca-software.crt # - ./intermediate # - ./sub1.domain1.com # - sub1.domain1.com.ca.crt (sub sub root CA) # - sub1.domain1.com.ca-tls.crt # - sub1.domain1.com.ca-email.crt # - sub1.domain1.com.ca-software.crt # - ./sub2.domain1.com # - sub2.domain1.com.ca.crt (sub sub root CA) # - sub2.domain1.com.ca-tls.crt # - sub2.domain1.com.ca-email.crt # - sub2.domain1.com.ca-software.crt # - ./sub3.domain1.com # - sub3.domain1.com.ca.crt (sub sub root CA) # - sub3.domain1.com.ca-tls.crt # - sub3.domain1.com.ca-email.crt # - sub3.domain1.com.ca-software.crt # - ./domain2.com # - domain2.com.ca.crt (sub root CA) # - domain2.com.ca-tls.crt # - domain2.com.ca-email.crt # - domain2.com.ca-software.crt # - ./intermediate # - ./sub1.domain1.com # - sub1.domain2.com.ca.crt (sub sub root CA) # - sub1.domain2.com.ca-tls.crt # - sub1.domain2.com.ca-email.crt # - sub1.domain2.com.ca-software.crt # - ./sub2.domain1.com # - sub2.domain2.com.ca.crt (sub sub root CA) # - sub2.domain2.com.ca-tls.crt # - sub2.domain2.com.ca-email.crt # - sub2.domain2.com.ca-software.crt # - ./sub4.domain1.com # - sub4.domain2.com.ca.crt (sub sub root CA) # - sub4.domain2.com.ca-tls.crt # - sub4.domain2.com.ca-email.crt # - sub4.domain2.com.ca-software.crt # - ./domain3.com # - domain3.com.ca.crt (sub root CA) # - domain3.com.ca-tls.crt # - domain3.com.ca-email.crt # - domain3.com.ca-software.crt # # # # root_ca reverse-domain [public-domain [subdomain-prefix]] root_ca() { # the base; the IP or reverse host address. # this allows us to use this function for multiple servers on same host. # this is the network root CA. # this function creates also the reverse host based CA for TLS - signed by the root CA. local reverseHost=$1 # list of domains separated by ; # root_ca reverse.tld foo.tld;bar.tld;alice.tld - for foo.tld, bar.tld, and alice.tld # # this function creates an intermediate CA for each domain. # the intermediate CAs will be signed by the Root CA of reverse host. # this function creates also domain based CAs for TLS, email and code signing - signed by the domain based intermediate CA. local domainList=$2 # list of subdomain names separated by ; # mail;smtp # # note that all names in this list will be applied to each given domain. # to avoid this you must call this function multiple times. # root_ca will not destroy, delete or override previous created CAs # root_ca reverse.tld foo.tld;bar.tld mail;smtp - for mail.foo.tld, smtp.foo.tld, mail.bar.tld, and smtp.bar.tld # root_ca reverse.tld foo.tld;alice.tld imap - for imap.foo.tld, and imap.alice.tld # # this function creates an intermediate CA for each subdomain. # the intermediate CAs will be signed by the intermediate CA of their owner domain # this function creates also sub domain based CAs for TLS, email and code signing - signed by the subdomain based intermediate CA. local subDomainNameList=$3 ############################################################## # # CRT config partial factories # ############################################################## makeModulCsrConfigBlock_title() { local outputFile=$1 local domain=$2 local title=$3 { echo "# $title certificate request for $domain" echo '' } >> $outputFile } ############################################################## # # CRT config factories # ############################################################## modulCsrEmailConfig() { local outputFile=$1 local domain=$2 { makeModulCsrConfigBlock_title $outputFile $domain 'Email' echo '[ req ]' echo "default_bits = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST # RSA key size" echo 'encrypt_key = yes # Protect private key' echo "default_md = $DEFAULT_CRT_MD_REQUEST # MD to use" echo 'utf8 = yes # Input is UTF-8' echo 'string_mask = utf8only # Emit UTF-8 strings' echo 'prompt = yes # Prompt for DN' echo 'distinguished_name = email_dn # DN template' echo 'req_extensions = email_reqext # Desired extensions' echo '' echo "[ email_dn ]" echo 'countryName = "1. Country Name (2 letters) (eg, US) "' echo 'countryName_max = 2' echo 'countryName_default = "BE"' echo 'stateOrProvinceName = "2. State or Province Name (eg, region) "' echo 'localityName = "3. Locality Name (eg, city) "' echo 'organizationName = "4. Organization Name (eg, company) "' echo "organizationName_default = \""### Network $domain\""" echo 'organizationalUnitName = "5. Organizational Unit Name (eg, section) "' echo 'commonName = "6. Common Name (eg, full name)"' echo 'commonName_max = 64' echo 'emailAddress = "7. Email Address (eg, name@fqdn)"' echo 'emailAddress_max = 40' echo '' echo '[ email_reqext ]' echo 'keyUsage = critical,digitalSignature,keyEncipherment' echo 'extendedKeyUsage = critical,emailProtection,clientAuth' echo 'subjectKeyIdentifier = hash' echo 'subjectAltName = email:move' } >> $outputFile } modulCsrTlsClientConfig() { local outputFile=$1 local domain=$2 { makeModulCsrConfigBlock_title $outputFile $domain 'TLS Client' echo '[ req ]' echo "default_bits = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST # RSA key size" echo 'encrypt_key = yes # Protect private key' echo "default_md = $DEFAULT_CRT_MD_REQUEST # MD to use" echo 'utf8 = yes # Input is UTF-8' echo 'string_mask = utf8only # Emit UTF-8 strings' echo 'prompt = yes # Prompt for DN' echo 'distinguished_name = client_dn # DN template' echo 'req_extensions = client_reqext # Desired extensions' echo '' echo "[ client_dn ]" echo 'countryName = "1. Country Name (2 letters) (eg, US) "' echo 'countryName_max = 2' echo 'countryName_default = "BE"' echo 'stateOrProvinceName = "2. State or Province Name (eg, region) "' echo 'localityName = "3. Locality Name (eg, city) "' echo 'organizationName = "4. Organization Name (eg, company) "' echo "organizationName_default = \""### Network $domain\""" echo 'organizationalUnitName = "5. Organizational Unit Name (eg, section) "' echo 'commonName = "6. Common Name (eg, full name)"' echo 'commonName_max = 64' echo 'emailAddress = "7. Email Address (eg, name@fqdn)"' echo 'emailAddress_max = 40' echo '' echo '[ client_reqext ]' echo 'keyUsage = critical,digitalSignature' echo 'extendedKeyUsage = critical,clientAuth' echo 'subjectKeyIdentifier = hash' echo 'subjectAltName = email:move' } >> $outputFile } modulCsrTlsClientExternalConfig() { local outputFile=$1 local domain=$2 { makeModulCsrConfigBlock_title $outputFile $domain 'TLS External Client' echo '[ req ]' echo "default_bits = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST # RSA key size" echo 'encrypt_key = yes # Protect private key' echo "default_md = $DEFAULT_CRT_MD_REQUEST # MD to use" echo 'utf8 = yes # Input is UTF-8' echo 'string_mask = utf8only # Emit UTF-8 strings' echo 'prompt = yes # Prompt for DN' echo 'distinguished_name = client_dn # DN template' echo 'req_extensions = client_reqext # Desired extensions' echo '' echo "[ client_dn ]" echo 'countryName = "1. Country Name (2 letters) (eg, US) "' echo 'countryName_max = 2' echo 'stateOrProvinceName = "2. State or Province Name (eg, region) "' echo 'localityName = "3. Locality Name (eg, city) "' echo 'organizationName = "4. Organization Name (eg, company) "' echo 'organizationalUnitName = "5. Organizational Unit Name (eg, section) "' echo 'commonName = "6. Common Name (eg, full name)"' echo 'commonName_max = 64' echo 'emailAddress = "7. Email Address (eg, name@fqdn)"' echo 'emailAddress_max = 40' echo '' echo '[ client_reqext ]' echo 'keyUsage = critical,digitalSignature' echo 'extendedKeyUsage = critical,clientAuth' echo 'subjectKeyIdentifier = hash' echo 'subjectAltName = email:move' } >> $outputFile } modulCsrTlsServerConfig() { local outputFile=$1 local domain=$2 { makeModulCsrConfigBlock_title $outputFile $domain 'TLS Server' echo '[ req ]' echo "default_bits = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST # RSA key size" echo 'encrypt_key = no # Protect private key' echo "default_md = $DEFAULT_CRT_MD_REQUEST # MD to use" echo 'utf8 = yes # Input is UTF-8' echo 'string_mask = utf8only # Emit UTF-8 strings' echo 'prompt = yes # Prompt for DN' echo 'distinguished_name = server_dn # DN template' echo 'req_extensions = server_reqext # Desired extensions' echo '' echo "[ server_dn ]" echo 'countryName = "1. Country Name (2 letters) (eg, US) "' echo 'countryName_max = 2' echo 'countryName_default = "BE"' echo 'stateOrProvinceName = "2. State or Province Name (eg, region) "' echo 'localityName = "3. Locality Name (eg, city) "' echo 'organizationName = "4. Organization Name (eg, company) "' echo "organizationName_default = \""### Network $domain\""" echo 'organizationalUnitName = "5. Organizational Unit Name (eg, section) "' echo 'commonName = "6. Common Name (eg, full name)"' echo 'commonName_max = 64' echo "commonName_default = \""$domain\""" echo 'emailAddress = "7. Email Address (eg, name@fqdn)"' echo 'emailAddress_max = 40' echo '' echo '[ server_reqext ]' echo 'keyUsage = critical,digitalSignature,keyEncipherment' echo 'extendedKeyUsage = serverAuth,clientAuth' echo 'subjectKeyIdentifier = hash' echo 'subjectAltName = $ENV::SAN' } >> $outputFile } modulCsrTlsServerExternalConfig() { local outputFile=$1 local domain=$2 { makeModulCsrConfigBlock_title $outputFile $domain 'TLS External Server' echo '[ req ]' echo "default_bits = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST # RSA key size" echo 'encrypt_key = no # Protect private key' echo "default_md = $DEFAULT_CRT_MD_REQUEST # MD to use" echo 'utf8 = yes # Input is UTF-8' echo 'string_mask = utf8only # Emit UTF-8 strings' echo 'prompt = yes # Prompt for DN' echo 'distinguished_name = server_dn # DN template' echo 'req_extensions = server_reqext # Desired extensions' echo '' echo "[ server_dn ]" echo 'countryName = "1. Country Name (2 letters) (eg, US) "' echo 'countryName_max = 2' echo 'stateOrProvinceName = "2. State or Province Name (eg, region) "' echo 'localityName = "3. Locality Name (eg, city) "' echo 'organizationName = "4. Organization Name (eg, company) "' echo 'organizationalUnitName = "5. Organizational Unit Name (eg, section) "' echo 'commonName = "6. Common Name (eg, full name)"' echo 'commonName_max = 64' echo 'emailAddress = "7. Email Address (eg, name@fqdn)"' echo 'emailAddress_max = 40' echo '' echo '[ server_reqext ]' echo 'keyUsage = critical,digitalSignature,keyEncipherment' echo 'extendedKeyUsage = serverAuth,clientAuth' echo 'subjectKeyIdentifier = hash' echo 'subjectAltName = $ENV::SAN' } >> $outputFile } modulCsrSoftwareConfig() { local outputFile=$1 local domain=$2 { makeModulCsrConfigBlock_title $outputFile $domain 'Software' echo '[ req ]' echo "default_bits = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST # RSA key size" echo 'encrypt_key = yes # Protect private key' echo "default_md = $DEFAULT_CRT_MD_REQUEST # MD to use" echo 'utf8 = yes # Input is UTF-8' echo 'string_mask = utf8only # Emit UTF-8 strings' echo 'prompt = yes # Prompt for DN' echo 'distinguished_name = codesign_dn # DN template' echo 'req_extensions = codesign_reqext # Desired extensions' echo '' echo '[ codesign_dn ]' echo 'countryName = "1. Country Name (2 letters) (eg, US) "' echo 'countryName_max = 2' echo 'stateOrProvinceName = "2. State or Province Name (eg, region) "' echo 'localityName = "3. Locality Name (eg, city) "' echo 'organizationName = "4. Organization Name (eg, company) "' echo 'organizationalUnitName = "5. Organizational Unit Name (eg, section) "' echo 'commonName = "6. Common Name (eg, full name)"' echo 'commonName_max = 64' echo '' echo '[ codesign_reqext ]' echo 'keyUsage = critical,digitalSignature' echo 'extendedKeyUsage = critical,codeSigning' echo 'subjectKeyIdentifier = hash' } >> $outputFile } ############################################################## # # CA config partial factories # ############################################################## makeModulCaConfigBlock_title() { local outputFile=$1 local title=$2 { echo "# $title" echo '' } >> $outputFile } makeModulCaConfigBlock_section() { local outputFile=$1 local title=$2 { echo '' echo '' echo "# $title" echo '' } >> $outputFile } makeModulCaConfigBlock_default() { local outputFile=$1 local domain=$2 local level=$3 local type=$4 { echo '[ default ]' echo "ca = $domain" echo "ca_type = $type" echo 'ca_dir = $ca_type' echo "db_dir = \$ca_dir/${DIR_NAME[db]}" echo "private_dir = \$ca_dir/${DIR_NAME[private]}" echo "dir = \$ENV::CA_${level}_SCRIPT_PATH # Top dir" echo "base_url = http://$domain # CA base URL" echo "ip_url = http://$DEFAULT_IP # CA base URL on IP" echo 'aia_url = $base_url/$ca.$ca_type.cer # CA certificate URL' echo 'ip_aia_url = $ip_url/$ca.$ca_type.cer # CA certificate URL' echo 'crl_url = $base_url/$ca.$ca_type.crl # CRL distribution point' echo 'ip_crl_url = $ip_url/$ca.$ca_type.cer # CRL distribution point' echo 'name_opt = multiline,-esc_msb,utf8 # Display UTF-8 characters' echo '' } >> $outputFile } makeModulCaConfigBlock_req() { local outputFile=$1 { echo '[ req ]' echo "default_bits = $DEFAULT_CA_RSA_KEYSIZE_REQUEST # RSA key size" echo 'encrypt_key = yes # Protect private key' echo "default_md = $DEFAULT_CA_MD_REQUEST # MD to use" echo 'utf8 = yes # Input is UTF-8' echo 'string_mask = utf8only # Emit UTF-8 strings' echo 'prompt = no # Dont prompt for DN' echo 'distinguished_name = ca_dn # DN section' echo 'req_extensions = ca_reqext # Desired extensions' echo '' } >> $outputFile } makeModulCaConfigBlock_ca_dn() { local outputFile=$1 local oN=$2 local cN=$3 { echo '[ ca_dn ]' echo 'countryName = "BE"' echo "organizationName = \""### Network $oN\""" echo 'organizationalUnitName = "interop"' echo "commonName = \""### Network $cN\""" echo '' } >> $outputFile } makeModulCaConfigBlock_ca_reqext() { local outputFile=$1 local case=$2 if [ "$case" == 'signing' ]; then { echo '[ ca_reqext ]' echo 'keyUsage = critical,keyCertSign,cRLSign' echo 'basicConstraints = critical,CA:true,pathlen:0' echo 'subjectKeyIdentifier = hash' echo '' } >> $outputFile else { echo '[ ca_reqext ]' echo 'keyUsage = critical,keyCertSign,cRLSign' echo 'basicConstraints = critical,CA:true' echo 'subjectKeyIdentifier = hash' echo '' } >> $outputFile fi } makeModulCaConfigBlock_ca() { local outputFile=$1 local defaultCa=$2 local x509_extensions=$3 local copy_extensions=$4 local policy=$5 local days=$6 local crlDays=$7 local keyFileFormat=$(printf ${FILE_NAME[key]} '$ca' '$ca_type') local crtSrlFileFormat=$(printf ${FILE_NAME[crtSrl]} '$ca' '$ca_type') local crlSrlFileFormat=$(printf ${FILE_NAME[crlSrl]} '$ca' '$ca_type') local crtDbFileFormat=$(printf ${FILE_NAME[crtDb]} '$ca' '$ca_type') local crtFileFormat=$(printf ${FILE_NAME[crt]} '$ca' '$ca_type') local pDir='$dir/$private_dir' local dDir='$dir/$db_dir' { echo '[ ca ]' echo "default_ca = $defaultCa # The default CA section" echo '' echo "[ $defaultCa ]" echo "certificate = \$dir/$crtFileFormat # The CA cert" echo 'new_certs_dir = $dir/$ca_dir # Certificate archive' echo "private_key = $pDir/$keyFileFormat # CA private key" echo "serial = $dDir/$crtSrlFileFormat # Serial number file" echo "crlnumber = $dDir/$crlSrlFileFormat # CRL number file" echo "database = $dDir/$crtDbFileFormat # Index file" echo 'unique_subject = yes # Require unique subject' echo "default_days = $days # How long to certify for" echo "default_md = $DEFAULT_CA_MD # MD to use" echo "policy = $policy # Default naming policy" echo 'email_in_dn = no # Add email to cert DN' echo 'preserve = yes # Keep passed DN ordering' echo 'name_opt = $name_opt # Subject DN display options' echo 'cert_opt = ca_default # Certificate display options' echo "copy_extensions = $copy_extensions # Copy extensions from CSR" echo "x509_extensions = $x509_extensions # Default cert extensions" echo "default_crl_days = $crlDays # How long before next CRL" echo 'crl_extensions = crl_ext # CRL extensions' echo '' } >> $outputFile } ############################################################## # # CA config factories # ############################################################## # args: out file, domain, nesting level (required for $ENV) modulCaConfig() { local outputFile=$1 local domain=$2 local level=$3 if [ -z "$3" ]; then level=0 fi local suffix='Certificate Authority' if [ $level == '0' ]; then suffix="Root $suffix" fi makeModulCaConfigBlock_title $outputFile "Network $domain $suffix" makeModulCaConfigBlock_default $outputFile $domain $level 'ca' makeModulCaConfigBlock_section $outputFile 'CA certificate request' makeModulCaConfigBlock_req $outputFile makeModulCaConfigBlock_ca_dn $outputFile $domain "$domain $suffix" makeModulCaConfigBlock_ca_reqext $outputFile makeModulCaConfigBlock_section $outputFile 'CA operational settings' makeModulCaConfigBlock_ca $outputFile 'root_ca' 'server_ext' 'none' 'root_ca_pol' '730' '365' { echo '[ root_ca_pol ]' echo 'countryName = match # Must match' echo 'stateOrProvinceName = optional # Included if present' echo 'localityName = optional # Included if present' echo 'organizationName = match # Must match' echo 'organizationalUnitName = optional # Included if present' echo 'commonName = match # Must match' echo '' echo '[ extension_ca_pol ]' echo 'countryName = match # Must match' echo 'stateOrProvinceName = optional # Included if present' echo 'localityName = optional # Included if present' echo 'organizationName = match # Must match' echo 'organizationalUnitName = optional # Included if present' echo 'commonName = supplied # Must be present' echo '' echo '[ intermediate_ca_pol ]' echo 'countryName = supplied # Must be present' echo 'stateOrProvinceName = optional # Included if present' echo 'localityName = optional # Included if present' echo 'organizationName = supplied # Must be present' echo 'organizationalUnitName = optional # Included if present' echo 'commonName = supplied # Must be present' echo '' echo '' echo '# Extensions' echo '' echo '[ root_ca_ext ]' echo 'keyUsage = critical,keyCertSign,cRLSign' echo 'basicConstraints = critical,CA:true' echo 'subjectKeyIdentifier = hash' echo 'authorityKeyIdentifier = keyid:always' echo '' echo '[ signing_ca_ext ]' echo 'keyUsage = critical,keyCertSign,cRLSign' echo 'basicConstraints = critical,CA:true,pathlen:0' echo 'subjectKeyIdentifier = hash' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo 'crlDistributionPoints = @crl_info' echo '' echo '[ crl_ext ]' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo '' echo '[ issuer_info ]' echo 'caIssuers;URI.0 = $aia_url' echo 'caIssuers;URI.1 = $ip_aia_url' echo '' echo '[ crl_info ]' echo 'URI.0 = $crl_url' echo 'URI.1 = $ip_crl_url' } >> $outputFile } # args: out file, domain, nesting level (required for $ENV) modulCaTlsConfig() { local outputFile=$1 local domain=$2 local level=$3 makeModulCaConfigBlock_title $outputFile "Network $domain TLS Registration Authority" makeModulCaConfigBlock_default $outputFile $domain $level 'ca-tls' makeModulCaConfigBlock_section $outputFile 'CA certificate request' makeModulCaConfigBlock_req $outputFile makeModulCaConfigBlock_ca_dn $outputFile $domain "$domain TLS Registration Authority" makeModulCaConfigBlock_ca_reqext $outputFile 'signing' makeModulCaConfigBlock_section $outputFile 'CA operational settings' makeModulCaConfigBlock_ca $outputFile 'tls_ca' 'server_ext' 'copy' 'match_pol' '730' '1' { echo '[ match_pol ]' echo 'countryName = match # Must match NO' echo 'stateOrProvinceName = optional # Included if present' echo 'localityName = optional # Included if present' echo 'organizationName = match # Must match Green AS' echo 'organizationalUnitName = optional # Included if present' echo 'commonName = supplied # Must be present' echo '' echo '[ extern_pol ]' echo 'countryName = supplied # Must be present' echo 'stateOrProvinceName = optional # Included if present' echo 'localityName = optional # Included if present' echo 'organizationName = supplied # Must be present' echo 'organizationalUnitName = optional # Included if present' echo 'commonName = supplied # Must be present' echo '' echo '[ any_pol ]' echo 'domainComponent = optional' echo 'countryName = optional' echo 'stateOrProvinceName = optional' echo 'localityName = optional' echo 'organizationName = optional' echo 'organizationalUnitName = optional' echo 'commonName = optional' echo 'emailAddress = optional' echo '' echo '' echo '# Extensions' echo '' echo '[ server_ext ]' echo 'keyUsage = critical,digitalSignature,keyEncipherment' echo 'basicConstraints = critical,CA:false' echo 'extendedKeyUsage = serverAuth,clientAuth' echo 'subjectKeyIdentifier = hash' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo 'crlDistributionPoints = @crl_info' echo '' echo '[ client_ext ]' echo 'keyUsage = critical,digitalSignature' echo 'basicConstraints = critical,CA:false' echo 'extendedKeyUsage = clientAuth' echo 'subjectKeyIdentifier = hash' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo 'crlDistributionPoints = @crl_info' echo '' echo '[ crl_ext ]' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo '' echo '[ issuer_info ]' echo 'caIssuers;URI.0 = $aia_url' echo '' echo '[ crl_info ]' echo 'URI.0 = $crl_url' } >> $outputFile } # args: out file, domain, nesting level (required for $ENV) modulCaEmailConfig() { local outputFile=$1 local domain=$2 local level=$3 makeModulCaConfigBlock_title $outputFile "Network $domain Email Registration Authority" makeModulCaConfigBlock_default $outputFile $domain $level 'ca-email' makeModulCaConfigBlock_section $outputFile 'CA certificate request' makeModulCaConfigBlock_req $outputFile makeModulCaConfigBlock_ca_dn $outputFile $domain "$domain Email Registration Authority" makeModulCaConfigBlock_ca_reqext $outputFile 'signing' makeModulCaConfigBlock_section $outputFile 'CA operational settings' makeModulCaConfigBlock_ca $outputFile 'email_ca' 'email_ext' 'copy' 'match_pol' '730' '1' { echo '[ match_pol ]' echo 'countryName = match # Must match NO' echo 'stateOrProvinceName = optional # Included if present' echo 'localityName = optional # Included if present' echo 'organizationName = match # Must match Green AS' echo 'organizationalUnitName = optional # Included if present' echo 'commonName = supplied # Must be present' echo '' echo '[ any_pol ]' echo 'domainComponent = optional' echo 'countryName = optional' echo 'stateOrProvinceName = optional' echo 'localityName = optional' echo 'organizationName = optional' echo 'organizationalUnitName = optional' echo 'commonName = optional' echo 'emailAddress = optional' echo '' echo '' echo '# Extensions' echo '' echo '[ email_ext ]' echo 'keyUsage = critical,digitalSignature,keyEncipherment' echo 'basicConstraints = CA:false' echo 'extendedKeyUsage = emailProtection,clientAuth,anyExtendedKeyUsage' echo 'subjectKeyIdentifier = hash' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo 'crlDistributionPoints = @crl_info' echo '' echo '[ crl_ext ]' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo '' echo '[ issuer_info ]' echo 'caIssuers;URI.0 = $aia_url' echo '' echo '[ crl_info ]' echo 'URI.0 = $crl_url' } >> $outputFile } # args: out file, domain, nesting level (required for $ENV) modulCaSoftwareConfig() { local outputFile=$1 local domain=$2 local level=$3 makeModulCaConfigBlock_title $outputFile "Network $domain Software Registration Authority" makeModulCaConfigBlock_default $outputFile $domain $level 'ca-software' makeModulCaConfigBlock_section $outputFile 'CA certificate request' makeModulCaConfigBlock_req $outputFile makeModulCaConfigBlock_ca_dn $outputFile $domain "$domain Software Registration Authority" makeModulCaConfigBlock_ca_reqext $outputFile 'signing' makeModulCaConfigBlock_section $outputFile 'CA operational settings' makeModulCaConfigBlock_ca $outputFile 'software_ca' 'codesign_ext' 'copy' 'match_pol' '1826' '30' { echo '[ match_pol ]' echo 'countryName = match # Must match NO' echo 'stateOrProvinceName = optional # Included if present' echo 'localityName = optional # Included if present' echo 'organizationName = match # Must match Green AS' echo 'organizationalUnitName = optional # Included if present' echo 'commonName = supplied # Must be present' echo '' echo '[ any_pol ]' echo 'domainComponent = optional' echo 'countryName = optional' echo 'stateOrProvinceName = optional' echo 'localityName = optional' echo 'organizationName = optional' echo 'organizationalUnitName = optional' echo 'commonName = optional' echo 'emailAddress = optional' echo '' echo '' echo '# Extensions' echo '' echo '[ codesign_ext ]' echo 'keyUsage = critical,digitalSignature' echo 'basicConstraints = CA:false' echo 'extendedKeyUsage = critical,codeSigning' echo 'subjectKeyIdentifier = hash' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo 'crlDistributionPoints = @crl_info' echo '' echo '[ crl_ext ]' echo 'authorityKeyIdentifier = keyid:always' echo 'authorityInfoAccess = @issuer_info' echo '' echo '[ issuer_info ]' echo 'caIssuers;URI.0 = $aia_url' echo '' echo '[ crl_info ]' echo 'URI.0 = $crl_url' } >> $outputFile } ############################################################## # # more factories!!! # ############################################################## makeConfigFile() { local domain=$1 local modul=$2 local outputFile=$3 local level=$4 if [ ! -e "$outputFile" ]; then writeNewItem "CA config $modul" eval $modul $outputFile $domain $level check_result $? 'unable to create config' fi } makeCsrConfigFile() { local domain=$1 local modul=$2 local outputFile=$3 if [ ! -e "$outputFile" ]; then writeNewItem "certificate request config $modul" eval $modul $outputFile $domain check_result $? 'unable to create config' fi } makeUserTlsCsrFiles() { local domain=$1 local cnfPath=$2 makeCsrConfigFile \ $domain \ 'modulCsrTlsClientConfig' \ $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-client') makeCsrConfigFile \ $domain \ 'modulCsrTlsClientExternalConfig' \ $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-client-external') makeCsrConfigFile \ $domain \ 'modulCsrTlsServerConfig' \ $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-server') makeCsrConfigFile \ $domain \ 'modulCsrTlsServerExternalConfig' \ $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-server-external') } makeUserSoftwareCsrFiles() { local domain=$1 local cnfPath=$2 makeCsrConfigFile \ $domain \ 'modulCsrSoftwareConfig' \ $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'code-signing') } makeUserEmailCsrFiles() { local domain=$1 local cnfPath=$2 makeCsrConfigFile \ $domain \ 'modulCsrEmailConfig' \ $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'email') } makePasswordFile() { local domain=$1 local pwdFile=$2 if [ ! -e $pwdFile ]; then writeNewItem 'pass' openssl genpkey \ -algorithm RSA \ -out $pwdFile \ -pkeyopt rsa_keygen_bits:$DEFAULT_CA_RSA_KEYSIZE_PASSWORD \ -pkeyopt rsa_keygen_pubexp:$DEFAULT_CA_PWD_GEN_PUBEXP check_result $? 'unable to create password' fi } makeKeyFile() { local domain=$1 local keyFile=$2 local pwdFile=$3 if [ ! -e $keyFile ]; then writeNewItem 'key' openssl genrsa -aes256 \ -passout file:$pwdFile \ -out $keyFile $DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY check_result $? 'unable to create private key' fi } makeDbFiles() { local domain=$1 local database=$2 local crtSerial=$3 local crlSerial=$4 local time=$(date +%Y%m%d%H%M%S)001 local hex=$(echo "obase=16; $time" | bc) if [ ! -e $database ]; then writeNewItem 'database files' touch $database check_result $? 'unable to create database index' writeNewItem 'crt serial' echo $hex > $crtSerial check_result $? 'unable to create crt serial' writeNewItem 'crl serial' echo $hex > $crlSerial check_result $? 'unable to create crl serial' fi } makeCsrFile() { local domain=$1 local cnfFile=$2 local csrFile=$3 local keyFile=$4 local pwdFile=$5 if [ ! -e $csrFile ]; then writeNewItem 'csr' openssl req -new \ -config $cnfFile \ -out $csrFile \ -key $keyFile -passin file:$pwdFile \ > /dev/null 2>&1 check_result $? 'unable to create csr' fi } makeCrtFile() { local domain=$1 local cnfFile=$2 local csrFile=$3 local crtFile=$4 local pwdFile=$5 local case=$6 if [ ! -e $crtFile ]; then writeNewItem 'crt' if [ "$case" == 'root_ca' ]; then openssl ca -selfsign -batch \ -config $cnfFile \ -in $csrFile \ -passin file:$pwdFile \ -out $crtFile \ -extensions root_ca_ext \ -enddate 20820508235959Z \ > /dev/null 2>&1 check_result $? 'unable to create crt' fi if [ "$case" == 'intermediate_ca' ]; then openssl ca -batch \ -config $cnfFile \ -in $csrFile \ -passin file:$pwdFile \ -out $crtFile \ -extensions root_ca_ext \ -policy intermediate_ca_pol \ -enddate 20820508235959Z \ > /dev/null 2>&1 check_result $? 'unable to create crt' fi if [ "$case" == 'signing_ca' ]; then openssl ca -batch \ -config $cnfFile \ -in $csrFile \ -passin file:$pwdFile \ -out $crtFile \ -extensions signing_ca_ext \ -policy extension_ca_pol \ -enddate 20820508235959Z \ > /dev/null 2>&1 check_result $? 'unable to create crt' fi fi } makeCrlFile() { local domain=$1 local cnfFile=$2 local crlFile=$3 local pwdFile=$4 if [ ! -e $crlFile ]; then writeNewItem 'crl' openssl ca -gencrl \ -config $cnfFile \ -passin file:$pwdFile \ -out $crlFile \ > /dev/null 2>&1 check_result $? 'unable to create crl' fi } makeChain() { local domain=$1 local child=$2 local parents=$3 local chainPemFile=$4 local chainP7cFile=$5 if [ ! -e $chainPemFile ]; then writeNewItem 'pem chain' cat $child $parents > $chainPemFile check_result $? 'unable to create pem chain' fi } # All published certificates must be in DER format. # MIME type: application/pkix-cert. [RFC 2585#section-4.1] publishCrt() { local fromCrt=$1 local toDer=$2 rm $toDer > /dev/null 2>&1 writeNewItem 'publish crt as application/pkix-cert' openssl x509 \ -in $fromCrt \ -out $toDer \ -outform der check_result $? 'unable to create cer file' } # All published CRLs must be in DER format. # MIME type: application/pkix-crl. [RFC 2585#section-4.2] publishCACrl() { local fromCrl=$1 local toDer=$2 rm $toDer > /dev/null 2>&1 writeNewItem 'publish crl as application/pkix-crl' openssl crl \ -in $fromCrl \ -out $toDer \ -outform der check_result $? 'unable to create der crl file' } # PKCS#7 is used to bundle two or more certificates. # MIME type: application/pkcs7-mime. [RFC 5273#page-3] publishCAChain() { local fromChainPem=$1 local toChainP7c=$2 rm $toChainP7c > /dev/null 2>&1 writeNewItem 'publish pem chain as application/pkcs7-mime' openssl crl2pkcs7 -nocrl \ -certfile $fromChainPem \ -out $toChainP7c \ -outform der check_result $? 'unable to create p7c chain file' } ############################################################## # # CA factories # ############################################################## # # the root! rooooooooooot! # # note: we need the env var for openssl config # # ./reverse root CA # makeRootCa() { local domain=$1 local baseDir=$2 local cnfFile=$3 local csrFile=$4 local keyFile=$5 local pwdFile=$6 local crtFile=$7 local crlFile=$8 export CA_0_SCRIPT_PATH="$baseDir" makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile makeCrtFile $domain $cnfFile $csrFile $crtFile $pwdFile 'root_ca' makeCrlFile $domain $cnfFile $crlFile $pwdFile } # # intermediate CA level 1 # # note: we need the env vars for openssl config # # ./reverse/domain root CA # makeIntermediateCa() { local domain=$1 local baseDir=$2 local cnfFile=$3 local csrFile=$4 local keyFile=$5 local pwdFile=$6 local crtFile=$7 local crlFile=$8 local chainPemFile=$9 local rootBaseDir=${10} local rootCnfFile=${11} local rootPwdFile=${12} local rootCrtFile=${13} export CA_1_SCRIPT_PATH="$baseDir" export CA_0_SCRIPT_PATH="$rootBaseDir" makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile makeCrtFile $domain $rootCnfFile $csrFile $crtFile $rootPwdFile 'intermediate_ca' makeCrlFile $domain $cnfFile $crlFile $pwdFile makeChain $domain $crtFile $rootCrtFile $chainPemFile } # # intermediate CA level 2 # # note: we need the env vars for openssl config # # ./reverse/domain/subdomain root CA # makeIntermediateIntermediateCa() { local domain=$1 local baseDir=$2 local cnfFile=$3 local csrFile=$4 local keyFile=$5 local pwdFile=$6 local crtFile=$7 local crlFile=$8 local chainPemFile=$9 local rootBaseDir=${10} local rootCnfFile=${11} local rootPwdFile=${12} local rootCrtFile=${13} export CA_2_SCRIPT_PATH="$baseDir" export CA_1_SCRIPT_PATH="$rootBaseDir" makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile makeCrtFile $domain $rootCnfFile $csrFile $crtFile $rootPwdFile 'intermediate_ca' makeCrlFile $domain $cnfFile $crlFile $pwdFile makeChain $domain $crtFile $rootCrtFile $chainPemFile } # # signing CA # # note: we need the env var for openssl config # # ./reverse-tls # ./reverse/domain-[tls|email|software] # ./reverse/domain/subdomain-[tls|email|software] # makeSigningCa() { local domain=$1 local baseDir=$2 local cnfFile=$3 local csrFile=$4 local keyFile=$5 local pwdFile=$6 local crtFile=$7 local crlFile=$8 local chainPemFile=$9 local rootCnfFile=${10} local rootPwdFile=${11} local rootCrtFile=${12} export CA_0_SCRIPT_PATH="$baseDir" makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile makeCrtFile $domain $rootCnfFile $csrFile $crtFile $rootPwdFile 'signing_ca' makeCrlFile $domain $cnfFile $crlFile $pwdFile makeChain $domain $crtFile $rootCrtFile $chainPemFile } ############################################################## # # output # ############################################################## # # LEVEL 0 (reverse) # declare -A LEVEL0 LEVEL0[domain]=$reverseHost LEVEL0[path]="$SCRIPT_PATH/$reverseHost" declare -A LEVEL0_PATH # lookup table LEVEL0_PATH[lookup]=${LEVEL0[path]}/${DIR_NAME[lookup]} # root ca LEVEL0_PATH[caPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[caPath]} LEVEL0_PATH[caDbPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[dbPath]} LEVEL0_PATH[caCnfPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[cnfPath]} LEVEL0_PATH[caPrvPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[privatePath]} # tls ca LEVEL0_PATH[caTlsPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[caPath]} LEVEL0_PATH[caTlsDbPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[dbPath]} LEVEL0_PATH[caTlsCnfPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[cnfPath]} LEVEL0_PATH[caTlsPrvPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[privatePath]} # domains LEVEL0_PATH[intermediatePath]=${LEVEL0[path]}/${DIR_NAME[intermediateDir]} # tls crt LEVEL0_PATH[crtTlsPath]=${LEVEL0[path]}/${DIRECTORIES_CRT_TLS[crtPath]} LEVEL0_PATH[crtTlsCnfPath]=${LEVEL0[path]}/${DIRECTORIES_CRT_TLS[cnfPath]} LEVEL0_PATH[crtTlsPrvPath]=${LEVEL0[path]}/${DIRECTORIES_CRT_TLS[privatePath]} # pub LEVEL0_PATH[pub]=${LEVEL0[path]}/${DIR_NAME[public]} LEVEL0_PATH[pubTls]=${LEVEL0[path]}/${DIRECTORIES_PUB[tls]} writeNewCert ${LEVEL0[domain]} writeNewType 'directories' for index in "${!LEVEL0_PATH[@]}" do writeNewItem ${LEVEL0_PATH[$index]} mkdir -p "${LEVEL0_PATH[$index]}" > /dev/null 2>&1 check_result $? 'unable to create directory' done ############################################################## # # lookup # # ca=$(head -n 1 $lookup/$domain) # ############################################################## lookupAdd() { local domain=$1 local path=$2 local lookup=${LEVEL0_PATH[lookup]} writeNewItem "add $domain" rm $lookup/$domain > /dev/null 2>&1 echo $path >> $lookup/$domain check_result $? 'unable to add $domain' } writeNewType 'lookup' lookupAdd ${LEVEL0[domain]} ${LEVEL0[path]} writeNewType 'user request configs' makeUserTlsCsrFiles \ ${LEVEL0[domain]} \ ${LEVEL0_PATH[crtTlsCnfPath]} # # The following part is the worst thing you've ever seen. \o/ # Thanks to openssl's path party. # # # root CA # writeNewType 'Root CA' # ./ local __0__caCsr=${LEVEL0[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) local __0__caCrt=${LEVEL0[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) # ./ca/db local __0__caCrtDb=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) local __0__caCrtSrl=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) local __0__caCrlSrl=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) local __0__caCrl=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) # ./ca/etc local __0__caConfig=${LEVEL0_PATH[caCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) # ./ca/private local __0__caPwd=${LEVEL0_PATH[caPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) local __0__caKey=${LEVEL0_PATH[caPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) # ./public local __0__caCrtDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) local __0__caCrlDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]}) makeConfigFile \ ${LEVEL0[domain]} \ 'modulCaConfig' \ $__0__caConfig \ '0' makePasswordFile \ ${LEVEL0[domain]} \ $__0__caPwd makeKeyFile \ ${LEVEL0[domain]} \ $__0__caKey \ $__0__caPwd makeDbFiles \ ${LEVEL0[domain]} \ $__0__caCrtDb \ $__0__caCrtSrl \ $__0__caCrlSrl makeRootCa \ ${LEVEL0[domain]} \ ${LEVEL0[path]} \ $__0__caConfig \ $__0__caCsr \ $__0__caKey \ $__0__caPwd \ $__0__caCrt \ $__0__caCrl publishCrt $__0__caCrt $__0__caCrtDer publishCACrl $__0__caCrl $__0__caCrlDer # # tls CA # writeNewType 'TLS CA' # ./ local __0__tlsCsr=${LEVEL0[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsCrt=${LEVEL0[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsChainPem=${LEVEL0[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/db local __0__tlsCrtDb=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsCrtSrl=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsCrlSrl=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsCrl=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/etc local __0__tlsConfig=${LEVEL0_PATH[caTlsCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/private local __0__tlsPwd=${LEVEL0_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsKey=${LEVEL0_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) # ./public local __0__tlsChainP7c=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsCrtDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) local __0__tlsCrlDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]}) makeConfigFile \ ${LEVEL0[domain]} \ 'modulCaTlsConfig' \ $__0__tlsConfig \ '0' makePasswordFile \ ${LEVEL0[domain]} \ $__0__tlsPwd makeKeyFile \ ${LEVEL0[domain]} \ $__0__tlsKey \ $__0__tlsPwd makeDbFiles \ ${LEVEL0[domain]} \ $__0__tlsCrtDb \ $__0__tlsCrtSrl \ $__0__tlsCrlSrl makeSigningCa \ ${LEVEL0[domain]} \ ${LEVEL0[path]} \ $__0__tlsConfig \ $__0__tlsCsr \ $__0__tlsKey \ $__0__tlsPwd \ $__0__tlsCrt \ $__0__tlsCrl \ $__0__tlsChainPem \ $__0__caConfig \ $__0__caPwd \ $__0__caCrt publishCrt $__0__tlsCrt $__0__tlsCrtDer publishCACrl $__0__tlsCrl $__0__tlsCrlDer publishCAChain $__0__tlsChainPem $__0__tlsChainP7c certificate ${LEVEL0[domain]} ${LEVEL0[domain]} create tls-server ssl # # LEVEL 1 (domain) # # intermediate CA for domain level # ./intermediate if [ ! -z "$domainList" ]; then level1domains=$(echo $domainList | tr ";" "\n") for level1domain in $level1domains do # # LEVEL 1 (domain) # declare -A LEVEL1 LEVEL1[domain]=$level1domain LEVEL1[path]="${LEVEL0_PATH[intermediatePath]}/$level1domain" declare -A LEVEL1_PATH # sub root ca LEVEL1_PATH[caPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[caPath]} LEVEL1_PATH[caDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[dbPath]} LEVEL1_PATH[caCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[cnfPath]} LEVEL1_PATH[caPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[privatePath]} # email ca LEVEL1_PATH[caEmailPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[caPath]} LEVEL1_PATH[caEmailDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[dbPath]} LEVEL1_PATH[caEmailCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[cnfPath]} LEVEL1_PATH[caEmailPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[privatePath]} # software ca LEVEL1_PATH[caSoftwarePath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[caPath]} LEVEL1_PATH[caSoftwareDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[dbPath]} LEVEL1_PATH[caSoftwareCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[cnfPath]} LEVEL1_PATH[caSoftwarePrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[privatePath]} # tls ca LEVEL1_PATH[caTlsPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[caPath]} LEVEL1_PATH[caTlsDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[dbPath]} LEVEL1_PATH[caTlsCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[cnfPath]} LEVEL1_PATH[caTlsPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[privatePath]} # email crt LEVEL1_PATH[crtEmailPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_EMAIL[crtPath]} LEVEL1_PATH[crtEmailCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_EMAIL[cnfPath]} LEVEL1_PATH[crtEmailPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_EMAIL[privatePath]} # software crt LEVEL1_PATH[crtSoftwarePath]=${LEVEL1[path]}/${DIRECTORIES_CRT_SOFTWARE[crtPath]} LEVEL1_PATH[crtSoftwareCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_SOFTWARE[cnfPath]} LEVEL1_PATH[crtSoftwarePrvPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_SOFTWARE[privatePath]} # tls crt LEVEL1_PATH[crtTlsPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_TLS[crtPath]} LEVEL1_PATH[crtTlsCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_TLS[cnfPath]} LEVEL1_PATH[crtTlsPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_TLS[privatePath]} # subdomains LEVEL1_PATH[intermediatePath]=${LEVEL1[path]}/${DIR_NAME[intermediateDir]} # pub LEVEL1_PATH[pub]=${LEVEL1[path]}/${DIR_NAME[public]} LEVEL1_PATH[pubTls]=${LEVEL1[path]}/${DIRECTORIES_PUB[tls]} LEVEL1_PATH[pubSoftware]=${LEVEL1[path]}/${DIRECTORIES_PUB[software]} LEVEL1_PATH[pubEmail]=${LEVEL1[path]}/${DIRECTORIES_PUB[email]} writeNewCert ${LEVEL1[domain]} writeNewType 'directories' for index in "${!LEVEL1_PATH[@]}" do writeNewItem ${LEVEL1_PATH[$index]} mkdir -p "${LEVEL1_PATH[$index]}" > /dev/null 2>&1 check_result $? 'unable to create directory' done writeNewType 'lookup' lookupAdd ${LEVEL1[domain]} ${LEVEL1[path]} writeNewType 'user request configs' makeUserSoftwareCsrFiles \ ${LEVEL1[domain]} \ ${LEVEL1_PATH[crtSoftwareCnfPath]} makeUserEmailCsrFiles \ ${LEVEL1[domain]} \ ${LEVEL1_PATH[crtEmailCnfPath]} makeUserTlsCsrFiles \ ${LEVEL1[domain]} \ ${LEVEL1_PATH[crtTlsCnfPath]} # # sub root CA # writeNewType 'Intermediate CA' # ./ local __1__caCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) # ./ca/db local __1__caCrtDb=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caCrtSrl=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caCrlSrl=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caCrl=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) # ./ca/etc local __1__caConfig=${LEVEL1_PATH[caCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) # ./ca/private local __1__caPwd=${LEVEL1_PATH[caPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caKey=${LEVEL1_PATH[caPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) # ./public local __1__caChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) local __1__caCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]}) makeConfigFile \ ${LEVEL1[domain]} \ 'modulCaConfig' \ $__1__caConfig \ '1' makePasswordFile \ ${LEVEL1[domain]} \ $__1__caPwd makeKeyFile \ ${LEVEL1[domain]} \ $__1__caKey \ $__1__caPwd makeDbFiles \ ${LEVEL1[domain]} \ $__1__caCrtDb \ $__1__caCrtSrl \ $__1__caCrlSrl makeIntermediateCa \ ${LEVEL1[domain]} \ ${LEVEL1[path]} \ $__1__caConfig \ $__1__caCsr \ $__1__caKey \ $__1__caPwd \ $__1__caCrt \ $__1__caCrl \ $__1__caChainPem \ ${LEVEL0[path]} \ $__0__caConfig \ $__0__caPwd \ $__0__caCrt publishCrt $__1__caCrt $__1__caCrtDer publishCACrl $__1__caCrl $__1__caCrlDer publishCAChain $__1__caChainPem $__1__caChainP7c # # tls CA # writeNewType 'TLS CA' # ./ local __1__tlsCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/db local __1__tlsCrtDb=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsCrtSrl=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsCrlSrl=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsCrl=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/etc local __1__tlsConfig=${LEVEL1_PATH[caTlsCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/private local __1__tlsPwd=${LEVEL1_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsKey=${LEVEL1_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) # ./public local __1__tlsChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) local __1__tlsCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]}) makeConfigFile \ ${LEVEL1[domain]} \ 'modulCaTlsConfig' \ $__1__tlsConfig \ '1' makePasswordFile \ ${LEVEL1[domain]} \ $__1__tlsPwd makeKeyFile \ ${LEVEL1[domain]} \ $__1__tlsKey \ $__1__tlsPwd makeDbFiles \ ${LEVEL1[domain]} \ $__1__tlsCrtDb \ $__1__tlsCrtSrl \ $__1__tlsCrlSrl makeSigningCa \ ${LEVEL1[domain]} \ ${LEVEL1[path]} \ $__1__tlsConfig \ $__1__tlsCsr \ $__1__tlsKey \ $__1__tlsPwd \ $__1__tlsCrt \ $__1__tlsCrl \ $__1__tlsChainPem \ $__1__caConfig \ $__1__caPwd \ $__1__caChainPem publishCrt $__1__tlsCrt $__1__tlsCrtDer publishCACrl $__1__tlsCrl $__1__tlsCrlDer publishCAChain $__1__tlsChainPem $__1__tlsChainP7c certificate ${LEVEL0[domain]} ${LEVEL1[domain]} create tls-server ssl # # email CA # writeNewType 'Email CA' # ./ local __1__emailCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) # ./ca-email/db local __1__emailCrtDb=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailCrtSrl=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailCrlSrl=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailCrl=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) # ./ca-email/etc local __1__emailConfig=${LEVEL1_PATH[caEmailCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) # ./ca-email/private local __1__emailPwd=${LEVEL1_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailKey=${LEVEL1_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) # ./public local __1__emailChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) local __1__emailCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]}) makeConfigFile \ ${LEVEL1[domain]} \ 'modulCaEmailConfig' \ $__1__emailConfig \ '1' makePasswordFile \ ${LEVEL1[domain]} \ $__1__emailPwd makeKeyFile \ ${LEVEL1[domain]} \ $__1__emailKey \ $__1__emailPwd makeDbFiles \ ${LEVEL1[domain]} \ $__1__emailCrtDb \ $__1__emailCrtSrl \ $__1__emailCrlSrl makeSigningCa \ ${LEVEL1[domain]} \ ${LEVEL1[path]} \ $__1__emailConfig \ $__1__emailCsr \ $__1__emailKey \ $__1__emailPwd \ $__1__emailCrt \ $__1__emailCrl \ $__1__emailChainPem \ $__1__caConfig \ $__1__caPwd \ $__1__caChainPem publishCrt $__1__emailCrt $__1__emailCrtDer publishCACrl $__1__emailCrl $__1__emailCrlDer publishCAChain $__1__emailChainPem $__1__emailChainP7c # # software CA # writeNewType 'Software CA' # ./ local __1__softwareCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) # ./ca-software/db local __1__softwareCrtDb=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareCrtSrl=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareCrlSrl=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareCrl=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) # ./ca-software/etc local __1__softwareConfig=${LEVEL1_PATH[caSoftwareCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) # ./ca-software/private local __1__softwarePwd=${LEVEL1_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareKey=${LEVEL1_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) # ./public local __1__softwareChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) local __1__softwareCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]}) makeConfigFile \ ${LEVEL1[domain]} \ 'modulCaSoftwareConfig' \ $__1__softwareConfig \ '1' makePasswordFile \ ${LEVEL1[domain]} \ $__1__softwarePwd makeKeyFile \ ${LEVEL1[domain]} \ $__1__softwareKey \ $__1__softwarePwd makeDbFiles \ ${LEVEL1[domain]} \ $__1__softwareCrtDb \ $__1__softwareCrtSrl \ $__1__softwareCrlSrl makeSigningCa \ ${LEVEL1[domain]} \ ${LEVEL1[path]} \ $__1__softwareConfig \ $__1__softwareCsr \ $__1__softwareKey \ $__1__softwarePwd \ $__1__softwareCrt \ $__1__softwareCrl \ $__1__softwareChainPem \ $__1__caConfig \ $__1__caPwd \ $__1__caChainPem publishCrt $__1__softwareCrt $__1__softwareCrtDer publishCACrl $__1__softwareCrl $__1__softwareCrlDer publishCAChain $__1__softwareChainPem $__1__softwareChainP7c # # LEVEL 2 (subdomains) # # intermediate intermediate CA for subdomain level # ./intermediate/domain/intermediate if [ ! -z "$subDomainNameList" ]; then level2domains=$(echo $subDomainNameList | tr ";" "\n") for level2domain in $level2domains do # # LEVEL 2 (subs) # # I don't split anything by '.' - a mail.foo.tld is like bob.mail.foo.tld. # feel free to create the third level for bob. # # in that case # - intermediate CA @ level 3: # - you MUST fork the makeIntermediateIntermediateCa function as makeIntermediateIntermediateIntermediateCa (or whatever); # - you MUST redefine export CA_2_SCRIPT_PATH="$baseDir" and export CA_1_SCRIPT_PATH="$rootBaseDir" # as export CA_3_SCRIPT_PATH="$baseDir" and export CA_2_SCRIPT_PATH="$rootBaseDir" # - you MUST call makeConfigFile with '4' as the fourth parameter # otherwise openssl fails on relative paths. you can walk through the directories - but that's also nasty. # @see makeModulCaConfigBlock_default::$level # - signing CAs @ level 3 are fun: s/2/3/ && s/1/2/ # declare -A LEVEL2 LEVEL2[domain]="$level2domain.${LEVEL1[domain]}" LEVEL2[path]="${LEVEL1_PATH[intermediatePath]}/$level2domain" declare -A LEVEL2_PATH # sub sub root ca LEVEL2_PATH[caPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[caPath]} LEVEL2_PATH[caDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[dbPath]} LEVEL2_PATH[caCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[cnfPath]} LEVEL2_PATH[caPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[privatePath]} # email ca LEVEL2_PATH[caEmailPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[caPath]} LEVEL2_PATH[caEmailDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[dbPath]} LEVEL2_PATH[caEmailCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[cnfPath]} LEVEL2_PATH[caEmailPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[privatePath]} # software ca LEVEL2_PATH[caSoftwarePath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[caPath]} LEVEL2_PATH[caSoftwareDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[dbPath]} LEVEL2_PATH[caSoftwareCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[cnfPath]} LEVEL2_PATH[caSoftwarePrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[privatePath]} # tls ca LEVEL2_PATH[caTlsPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[caPath]} LEVEL2_PATH[caTlsDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[dbPath]} LEVEL2_PATH[caTlsCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[cnfPath]} LEVEL2_PATH[caTlsPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[privatePath]} # email crt LEVEL2_PATH[crtEmailPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_EMAIL[crtPath]} LEVEL2_PATH[crtEmailCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_EMAIL[cnfPath]} LEVEL2_PATH[crtEmailPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_EMAIL[privatePath]} # software crt LEVEL2_PATH[crtSoftwarePath]=${LEVEL2[path]}/${DIRECTORIES_CRT_SOFTWARE[crtPath]} LEVEL2_PATH[crtSoftwareCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_SOFTWARE[cnfPath]} LEVEL2_PATH[crtSoftwarePrvPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_SOFTWARE[privatePath]} # tls crt LEVEL2_PATH[crtTlsPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_TLS[crtPath]} LEVEL2_PATH[crtTlsCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_TLS[cnfPath]} LEVEL2_PATH[crtTlsPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_TLS[privatePath]} # pub LEVEL2_PATH[pub]=${LEVEL2[path]}/${DIR_NAME[public]} LEVEL2_PATH[pubTls]=${LEVEL2[path]}/${DIRECTORIES_PUB[tls]} LEVEL2_PATH[pubSoftware]=${LEVEL2[path]}/${DIRECTORIES_PUB[software]} LEVEL2_PATH[pubEmail]=${LEVEL2[path]}/${DIRECTORIES_PUB[email]} writeNewCert ${LEVEL2[domain]} writeNewType 'directories' for index in "${!LEVEL2_PATH[@]}" do writeNewItem ${LEVEL1_PATH[$index]} mkdir -p "${LEVEL2_PATH[$index]}" > /dev/null 2>&1 check_result $? 'unable to create directory' done writeNewType 'lookup' lookupAdd ${LEVEL2[domain]} ${LEVEL2[path]} writeNewType 'user request configs' makeUserSoftwareCsrFiles \ ${LEVEL2[domain]} \ ${LEVEL2_PATH[crtSoftwareCnfPath]} makeUserEmailCsrFiles \ ${LEVEL2[domain]} \ ${LEVEL2_PATH[crtEmailCnfPath]} makeUserTlsCsrFiles \ ${LEVEL2[domain]} \ ${LEVEL2_PATH[crtTlsCnfPath]} # # sub sub root CA # writeNewType 'Intermediate CA' # ./ local __2__caCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) # ./ca/db local __2__caCrtDb=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caCrtSrl=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caCrlSrl=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caCrl=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) # ./ca/etc local __2__caConfig=${LEVEL2_PATH[caCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) # ./ca/private local __2__caPwd=${LEVEL2_PATH[caPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caKey=${LEVEL2_PATH[caPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) # ./public local __2__caChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) local __2__caCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]}) makeConfigFile \ ${LEVEL2[domain]} \ 'modulCaConfig' \ $__2__caConfig \ '2' makePasswordFile \ ${LEVEL2[domain]} \ $__2__caPwd makeKeyFile \ ${LEVEL2[domain]} \ $__2__caKey \ $__2__caPwd makeDbFiles \ ${LEVEL2[domain]} \ $__2__caCrtDb \ $__2__caCrtSrl \ $__2__caCrlSrl makeIntermediateIntermediateCa \ ${LEVEL2[domain]} \ ${LEVEL2[path]} \ $__2__caConfig \ $__2__caCsr \ $__2__caKey \ $__2__caPwd \ $__2__caCrt \ $__2__caCrl \ $__2__caChainPem \ ${LEVEL1[path]} \ $__1__caConfig \ $__1__caPwd \ $__1__caChainPem publishCrt $__2__caCrt $__2__caCrtDer publishCACrl $__2__caCrl $__2__caCrlDer publishCAChain $__2__caChainPem $__2__caChainP7c # # tls CA # writeNewType 'TLS CA' # ./ local __2__tlsCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/db local __2__tlsCrtDb=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsCrtSrl=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsCrlSrl=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsCrl=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/etc local __2__tlsConfig=${LEVEL2_PATH[caTlsCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) # ./ca-tls/private local __2__tlsPwd=${LEVEL2_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsKey=${LEVEL2_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) # ./public local __2__tlsChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) local __2__tlsCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]}) makeConfigFile \ ${LEVEL2[domain]} \ 'modulCaTlsConfig' \ $__2__tlsConfig \ '2' makePasswordFile \ ${LEVEL2[domain]} \ $__2__tlsPwd makeKeyFile \ ${LEVEL2[domain]} \ $__2__tlsKey \ $__2__tlsPwd makeDbFiles \ ${LEVEL2[domain]} \ $__2__tlsCrtDb \ $__2__tlsCrtSrl \ $__2__tlsCrlSrl makeSigningCa \ ${LEVEL2[domain]} \ ${LEVEL2[path]} \ $__2__tlsConfig \ $__2__tlsCsr \ $__2__tlsKey \ $__2__tlsPwd \ $__2__tlsCrt \ $__2__tlsCrl \ $__2__tlsChainPem \ $__2__caConfig \ $__2__caPwd \ $__2__caChainPem publishCrt $__2__tlsCrt $__2__tlsCrtDer publishCACrl $__2__tlsCrl $__2__tlsCrlDer publishCAChain $__2__tlsChainPem $__2__tlsChainP7c certificate ${LEVEL0[domain]} ${LEVEL2[domain]} create tls-server ssl # # email CA # writeNewType 'Email CA' # ./ local __2__emailCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) # ./ca-email/db local __2__emailCrtDb=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailCrtSrl=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailCrlSrl=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailCrl=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) # ./ca-email/etc local __2__emailConfig=${LEVEL2_PATH[caEmailCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) # ./ca-email/private local __2__emailPwd=${LEVEL2_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailKey=${LEVEL2_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) # ./public local __2__emailChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) local __2__emailCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]}) makeConfigFile \ ${LEVEL2[domain]} \ 'modulCaEmailConfig' \ $__2__emailConfig \ '2' makePasswordFile \ ${LEVEL2[domain]} \ $__2__emailPwd makeKeyFile \ ${LEVEL2[domain]} \ $__2__emailKey \ $__2__emailPwd makeDbFiles \ ${LEVEL2[domain]} \ $__2__emailCrtDb \ $__2__emailCrtSrl \ $__2__emailCrlSrl makeSigningCa \ ${LEVEL2[domain]} \ ${LEVEL2[path]} \ $__2__emailConfig \ $__2__emailCsr \ $__2__emailKey \ $__2__emailPwd \ $__2__emailCrt \ $__2__emailCrl \ $__2__emailChainPem \ $__2__caConfig \ $__2__caPwd \ $__2__caChainPem publishCrt $__2__emailCrt $__2__emailCrtDer publishCACrl $__2__emailCrl $__2__emailCrlDer publishCAChain $__2__emailChainPem $__2__emailChainP7c # # software CA # writeNewType 'Software CA' # ./ local __2__softwareCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) # ./ca-software/db local __2__softwareCrtDb=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareCrtSrl=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareCrlSrl=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareCrl=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) # ./ca-software/etc local __2__softwareConfig=${LEVEL2_PATH[caSoftwareCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) # ./ca-software/private local __2__softwarePwd=${LEVEL2_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareKey=${LEVEL2_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) # ./public local __2__softwareChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) local __2__softwareCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]}) makeConfigFile \ ${LEVEL2[domain]} \ 'modulCaSoftwareConfig' \ $__2__softwareConfig \ '2' makePasswordFile \ ${LEVEL2[domain]} \ $__2__softwarePwd makeKeyFile \ ${LEVEL2[domain]} \ $__2__softwareKey \ $__2__softwarePwd makeDbFiles \ ${LEVEL2[domain]} \ $__2__softwareCrtDb \ $__2__softwareCrtSrl \ $__2__softwareCrlSrl makeSigningCa \ ${LEVEL2[domain]} \ ${LEVEL2[path]} \ $__2__softwareConfig \ $__2__softwareCsr \ $__2__softwareKey \ $__2__softwarePwd \ $__2__softwareCrt \ $__2__softwareCrl \ $__2__softwareChainPem \ $__2__caConfig \ $__2__caPwd \ $__2__caChainPem publishCrt $__2__softwareCrt $__2__softwareCrtDer publishCACrl $__2__softwareCrl $__2__softwareCrlDer publishCAChain $__2__softwareChainPem $__2__softwareChainP7c done fi done fi do_unlock } demo() { local pass='UDUslpOy:lsp.amsCw,Z09o&ooYx:lko123---0' root_ca $DEFAULT_DOMAIN 'example.com;example2.com' 'mail;smtp' certificate $DEFAULT_DOMAIN example.com create code-signing fruffi -CN 'fruffi IRC BOT' -password $pass certificate $DEFAULT_DOMAIN example.com create email lucas -password $pass -CN 'lucas' -emailAddress 'lucas@example.com' certificate $DEFAULT_DOMAIN example.com create tls-client lucas -CN 'Luc' -password $pass certificate $DEFAULT_DOMAIN example.com create tls-client-external luc-external -CN 'Luc' -O 'frufflwochen' -C 'NL' -password $pass certificate $DEFAULT_DOMAIN example.com create tls-server 1337 certificate $DEFAULT_DOMAIN example.com create tls-server-external example.com -CN 'external.com' -O 'frufflwochen' -C 'NL' -password $pass }