#!/bin/bash export SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P ) DEFAULT_DOMAIN='reverse.com' DEFAULT_IP='123.123.123.123' # debug #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" } writeNewItem() { 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" } writeNewItem2() { local item=$1 echo -e "\e[90m \e[92m+\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 } warn_result() { if [ $1 -ne 0 ]; then echo -e "\e[93m Warning\e[39m $2" fi } check_prompt() { if [ $1 -ne 0 ]; then warn_result "$@" read -p 'Would you like to continue [y/n]: ' answer if [ "$answer" != 'y' ] && [ "$answer" != 'Y' ]; then echo 'Goodbye' do_exit "$1" fi fi } ############################################################## # # 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 #local DEFAULT_CA_RSA_KEYSIZE_PASSWORD=8192 #local DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY=8192 #local DEFAULT_CA_RSA_KEYSIZE_REQUEST=4096 # the size of the password for CA private key local DEFAULT_CA_RSA_KEYSIZE_PASSWORD=4096 # the size of the CA private key local DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY=4096 # the size of the RSA key size for CA requests local DEFAULT_CA_RSA_KEYSIZE_REQUEST=4096 # misc local DEFAULT_CA_PWD_GEN_PUBEXP=7s local DEFAULT_CA_MD=sha512 local DEFAULT_CA_MD_REQUEST=sha512 ############################################################## # # CRT config partial factories # ############################################################## makeModulCsrConfigBlock_title() { local outputFile=$1 local domain=$2 local title=$3 { echo "# $title certificate request for $domain" echo '' } >> $outputFile } makeModulCsrConfigBlock_csr_dn() { local outputFile=$1 local domain=$2 local defaultDn=$3 { echo "[ $defaultDn ]" 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 = \""### Network $domain\""" echo 'emailAddress = "7. Email Address (eg, name@fqdn)"' echo 'emailAddress_max = 40' echo '' } >> $outputFile } makeModulCsrConfigBlock_csr_dn_external() { local outputFile=$1 local domain=$2 local defaultDn=$3 { echo "[ $defaultDn ]" 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 '' } >> $outputFile } ############################################################## # # CRT config factories # ############################################################## modulCsrEmailConfig() { local outputFile=$1 local domain=$2 { makeModulCsrConfigBlock_title $outputFile $domain 'Email' echo '[ req ]' echo 'default_bits = 4096 # RSA key size' echo 'encrypt_key = yes # Protect private key' echo 'default_md = sha256 # 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 '' makeModulCsrConfigBlock_csr_dn $outputFile $domain 'email_dn' 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 = 4096 # RSA key size' echo 'encrypt_key = yes # Protect private key' echo 'default_md = sha256 # 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 = 4096 # RSA key size' echo 'encrypt_key = yes # Protect private key' echo 'default_md = sha256 # 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 = 4096 # RSA key size' echo 'encrypt_key = no # Protect private key' echo 'default_md = sha256 # 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 = 4096 # RSA key size' echo 'encrypt_key = no # Protect private key' echo 'default_md = sha256 # 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 = 4096 # RSA key size' echo 'encrypt_key = yes # Protect private key' echo 'default_md = sha256 # 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='CA' if [ $level == '0' ]; then suffix='Root CA' 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 CA" makeModulCaConfigBlock_default $outputFile $domain $level 'ca-tls' makeModulCaConfigBlock_section $outputFile 'CA certificate request' makeModulCaConfigBlock_req $outputFile makeModulCaConfigBlock_ca_dn $outputFile $domain "$domain TLS CA" 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 CA" makeModulCaConfigBlock_default $outputFile $domain $level 'ca-email' makeModulCaConfigBlock_section $outputFile 'CA certificate request' makeModulCaConfigBlock_req $outputFile makeModulCaConfigBlock_ca_dn $outputFile $domain "$domain Email CA" 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 CA" makeModulCaConfigBlock_default $outputFile $domain $level 'ca-software' makeModulCaConfigBlock_section $outputFile 'CA certificate request' makeModulCaConfigBlock_req $outputFile makeModulCaConfigBlock_ca_dn $outputFile $domain "$domain Software CA" 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 echo "create dir ${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 # # 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 mkdir -p "${LEVEL1_PATH[$index]}" > /dev/null 2>&1 done check_result $? 'unable to create directory' 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 # # 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 mkdir -p "${LEVEL2_PATH[$index]}" > /dev/null 2>&1 done check_result $? 'unable to create directory' 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 # # 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 }