fruffl

Certificate Factory

Nov 15th, 2015
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 108.34 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. export SCRIPT_PATH=$( cd "$(dirname "${BASH_SOURCE}")" ; pwd -P )
  4.  
  5. # create an empty directory and execute this script.
  6. # the initializer is demo(); @see end of this file
  7.  
  8. DEFAULT_DOMAIN='reverse.com'
  9. DEFAULT_IP='192.168.0.42'
  10.  
  11. #local DEFAULT_CA_RSA_KEYSIZE_PASSWORD=8192
  12. #local DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY=8192
  13. #local DEFAULT_CA_RSA_KEYSIZE_REQUEST=4096
  14.  
  15. DEFAULT_CA_RSA_KEYSIZE_PASSWORD=4096
  16. DEFAULT_CA_PWD_GEN_PUBEXP=7
  17. DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY=8192
  18. DEFAULT_CA_RSA_KEYSIZE_REQUEST=8192
  19. DEFAULT_CA_MD_REQUEST=sha512
  20. DEFAULT_CA_MD=sha512
  21.  
  22. DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY=4096
  23. DEFAULT_CRT_PWD_GEN_PUBEXP=7
  24. DEFAULT_CRT_RSA_KEYSIZE_REQUEST=2048
  25. DEFAULT_CRT_MD_REQUEST=sha512
  26.  
  27. #rm -rf $SCRIPT_PATH/$DEFAULT_DOMAIN/* > /dev/null 2>&1
  28. #exit 1
  29. #find $SCRIPT_PATH/$DEFAULT_DOMAIN/ -name "*.*" -type f|xargs rm -f
  30.  
  31. ##############################################################
  32. #
  33. # constants
  34. #
  35. ##############################################################
  36.  
  37. declare -A DIR_NAME
  38. DIR_NAME[cnf]='etc'
  39. DIR_NAME[db]='db'
  40. DIR_NAME[private]='private'
  41. DIR_NAME[public]='public'
  42. DIR_NAME[intermediateDir]='intermediate'
  43. DIR_NAME[lookup]='lookup'
  44. DIR_NAME[caRoot]='ca'
  45. DIR_NAME[caEmail]='ca-email'
  46. DIR_NAME[caSoftware]='ca-software'
  47. DIR_NAME[caTls]='ca-tls'
  48. DIR_NAME[crtEmail]='crt-email'
  49. DIR_NAME[crtSoftware]='crt-software'
  50. DIR_NAME[crtTls]='crt-tls'
  51. DIR_NAME[email]='email'
  52. DIR_NAME[software]='software'
  53. DIR_NAME[tls]='tls'
  54. declare -r DIR_NAME
  55.  
  56. declare -A FILE_NAME
  57. FILE_NAME[cnf]='%s.%s.cnf'
  58. FILE_NAME[csr]='%s.%s.csr'
  59. FILE_NAME[p12]='%s.%s.p12'
  60. FILE_NAME[crt]='%s.%s.crt'
  61. FILE_NAME[crtPem]='%s.%s.crt.pem'
  62. FILE_NAME[cer]='%s.%s.cer'
  63. FILE_NAME[chainPem]='%s.%s.chain.pem'
  64. FILE_NAME[chainP7c]='%s.%s.chain.p7c'
  65. FILE_NAME[crtDb]='%s.%s.crt.db'
  66. FILE_NAME[crtSrl]='%s.%s.crt.srl'
  67. FILE_NAME[crl]='%s.%s.crl'
  68. FILE_NAME[crlPem]='%s.%s.crl.pem'
  69. FILE_NAME[crlSrl]='%s.%s.crl.srl'
  70. FILE_NAME[key]='%s.%s.key'
  71. FILE_NAME[keyPem]='%s.%s.key.pem'
  72. FILE_NAME[password]='%s.%s.pwd'
  73. declare -r FILE_NAME
  74.  
  75. declare -A DIRECTORIES_CA_ROOT
  76. DIRECTORIES_CA_ROOT[caPath]=${DIR_NAME[caRoot]}
  77. DIRECTORIES_CA_ROOT[dbPath]=${DIR_NAME[caRoot]}/${DIR_NAME[db]}
  78. DIRECTORIES_CA_ROOT[cnfPath]=${DIR_NAME[caRoot]}/${DIR_NAME[cnf]}
  79. DIRECTORIES_CA_ROOT[privatePath]=${DIR_NAME[caRoot]}/${DIR_NAME[private]}
  80. declare -r DIRECTORIES_CA_ROOT
  81.  
  82. declare -A DIRECTORIES_CA_EMAIL
  83. DIRECTORIES_CA_EMAIL[caPath]=${DIR_NAME[caEmail]}
  84. DIRECTORIES_CA_EMAIL[dbPath]=${DIR_NAME[caEmail]}/${DIR_NAME[db]}
  85. DIRECTORIES_CA_EMAIL[cnfPath]=${DIR_NAME[caEmail]}/${DIR_NAME[cnf]}
  86. DIRECTORIES_CA_EMAIL[privatePath]=${DIR_NAME[caEmail]}/${DIR_NAME[private]}
  87. declare -r DIRECTORIES_CA_EMAIL
  88.  
  89. declare -A DIRECTORIES_CRT_EMAIL
  90. DIRECTORIES_CRT_EMAIL[crtPath]=${DIR_NAME[crtEmail]}
  91. DIRECTORIES_CRT_EMAIL[cnfPath]=${DIR_NAME[crtEmail]}/${DIR_NAME[cnf]}
  92. DIRECTORIES_CRT_EMAIL[privatePath]=${DIR_NAME[crtEmail]}/${DIR_NAME[private]}
  93. declare -r DIRECTORIES_CRT_EMAIL
  94.  
  95. declare -A DIRECTORIES_CA_SOFTWARE
  96. DIRECTORIES_CA_SOFTWARE[caPath]=${DIR_NAME[caSoftware]}
  97. DIRECTORIES_CA_SOFTWARE[dbPath]=${DIR_NAME[caSoftware]}/${DIR_NAME[db]}
  98. DIRECTORIES_CA_SOFTWARE[cnfPath]=${DIR_NAME[caSoftware]}/${DIR_NAME[cnf]}
  99. DIRECTORIES_CA_SOFTWARE[privatePath]=${DIR_NAME[caSoftware]}/${DIR_NAME[private]}
  100. declare -r DIRECTORIES_CA_SOFTWARE
  101.  
  102. declare -A DIRECTORIES_CRT_SOFTWARE
  103. DIRECTORIES_CRT_SOFTWARE[crtPath]=${DIR_NAME[crtSoftware]}
  104. DIRECTORIES_CRT_SOFTWARE[cnfPath]=${DIR_NAME[crtSoftware]}/${DIR_NAME[cnf]}
  105. DIRECTORIES_CRT_SOFTWARE[privatePath]=${DIR_NAME[crtSoftware]}/${DIR_NAME[private]}
  106. declare -r DIRECTORIES_CRT_SOFTWARE
  107.  
  108. declare -A DIRECTORIES_CA_TLS
  109. DIRECTORIES_CA_TLS[caPath]=${DIR_NAME[caTls]}
  110. DIRECTORIES_CA_TLS[dbPath]=${DIR_NAME[caTls]}/${DIR_NAME[db]}
  111. DIRECTORIES_CA_TLS[cnfPath]=${DIR_NAME[caTls]}/${DIR_NAME[cnf]}
  112. DIRECTORIES_CA_TLS[privatePath]=${DIR_NAME[caTls]}/${DIR_NAME[private]}
  113. declare -r DIRECTORIES_CA_TLS
  114.  
  115. declare -A DIRECTORIES_CRT_TLS
  116. DIRECTORIES_CRT_TLS[crtPath]=${DIR_NAME[crtTls]}
  117. DIRECTORIES_CRT_TLS[cnfPath]=${DIR_NAME[crtTls]}/${DIR_NAME[cnf]}
  118. DIRECTORIES_CRT_TLS[privatePath]=${DIR_NAME[crtTls]}/${DIR_NAME[private]}
  119. declare -r DIRECTORIES_CRT_TLS
  120.  
  121. declare -A DIRECTORIES_PUB
  122. DIRECTORIES_PUB[email]=${DIR_NAME[public]}/${DIR_NAME[email]}
  123. DIRECTORIES_PUB[software]=${DIR_NAME[public]}/${DIR_NAME[software]}
  124. DIRECTORIES_PUB[tls]=${DIR_NAME[public]}/${DIR_NAME[tls]}
  125. declare -r DIRECTORIES_PUB
  126.  
  127.    
  128. ##############################################################
  129. #
  130. # consolol
  131. #
  132. ##############################################################
  133. writeNewCert()
  134. {
  135.     local domain=$1
  136.     local x=$(printf '%-64s' "create certificates for")
  137.     local y=$(printf '%-64s' "$domain")
  138.     local z=$(printf '%-64s' '')
  139.    
  140.     echo -e "\e[90m$z\e[39m"
  141.     echo -e "\e[92m$x\e[39m"
  142.     echo -e "\e[96m$y\e[39m"
  143.     echo -e "\e[90m$z\e[39m"
  144. }
  145.  
  146. writeDelCert()
  147. {
  148.     local domain=$1
  149.     local x=$(printf '%-64s' "delete certificates for")
  150.     local y=$(printf '%-64s' "$domain")
  151.     local z=$(printf '%-64s' '')
  152.    
  153.     echo -e "\e[90m$z\e[39m"
  154.     echo -e "\e[91m$x\e[39m"
  155.     echo -e "\e[96m$y\e[39m"
  156.     echo -e "\e[90m$z\e[39m"
  157. }
  158.  
  159. writeRevCert()
  160. {
  161.     local domain=$1
  162.     local x=$(printf '%-64s' "revoke certificates for")
  163.     local y=$(printf '%-64s' "$domain")
  164.     local z=$(printf '%-64s' '')
  165.    
  166.     echo -e "\e[90m$z\e[39m"
  167.     echo -e "\e[93m$x\e[39m"
  168.     echo -e "\e[96m$y\e[39m"
  169.     echo -e "\e[90m$z\e[39m"
  170. }
  171.  
  172. writeNewType()
  173. {
  174.     local type=$1
  175.     echo -e "\e[97m• \e[92mcreate\e[97m $type\e[39m"
  176. }
  177. writeDelType()
  178. {
  179.     local type=$1
  180.     echo -e "\e[97m• \e[91mdelete\e[97m $type\e[39m"
  181. }
  182. writeRevType()
  183. {
  184.     local type=$1
  185.     echo -e "\e[97m• \e[93mrevoke\e[97m $type\e[39m"
  186. }
  187.  
  188. writeNewItem()
  189. {
  190.     local item=$1
  191.     echo -e "\e[90m  \e[92m+\e[90m $item\e[39m"
  192. }
  193.  
  194. writeNewItem2()
  195. {
  196.     local item=$1
  197.     echo -e "\e[90m    \e[92m+\e[90m $item\e[39m"
  198. }
  199.  
  200. writeDelItem()
  201. {
  202.     local item=$1
  203.     echo -e "\e[90m  \e[91m-\e[90m $item\e[39m"
  204. }
  205.  
  206. writeDelItem2()
  207. {
  208.     local item=$1
  209.     echo -e "\e[90m    \e[91m-\e[90m $item\e[39m"
  210. }
  211.  
  212. do_unlock()
  213. {
  214.     rm -rf "/var/lock/$DEFAULT_DOMAIN"
  215. }
  216.  
  217. do_exit()
  218. {
  219.     if [ $1 -ne 30 ]; then
  220.         do_unlock
  221.     fi
  222.     exit $1
  223. }
  224.  
  225. check_result()
  226. {
  227.     if [ $1 -ne 0 ]; then
  228.         echo -e "\e[91m        Error\e[39m $2"
  229.         do_exit "$1"
  230.     else
  231.         echo -e "\e[92m        OK\e[39m"
  232.     fi
  233. }
  234.  
  235. idle_result()
  236. {
  237.     if [ $1 -ne 0 ]; then
  238.         echo -e "\e[93m     Nothing to do.\e[39m $2"
  239.         return $1
  240.     fi
  241.     echo -e "\e[92m     Ok\e[39m"
  242. }
  243.  
  244. warn_result()
  245. {
  246.     if [ $1 -ne 0 ]; then
  247.         echo -e "\e[93mWarning\e[39m $2"
  248.     fi
  249. }
  250.  
  251. check_prompt()
  252. {
  253.     if [ $1 -ne 0 ]; then
  254.         warn_result "$@"
  255.         read -p 'Would you like to continue [y/n]: ' answer
  256.         if [ "$answer" != 'y' ] && [ "$answer" != 'Y'  ]; then
  257.             echo 'Goodbye'
  258.             do_exit "$1"
  259.         fi
  260.     fi
  261. }
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268. certificate()
  269. {
  270.     # entry point
  271.     local reverseDomain=$1
  272.     # registered domain; MUST avail in lookup folder
  273.     local domain=$2
  274.     # what you want to do; {create|delete|revoke}
  275.     local action=$3
  276.     # the certificate type; {email|tls-client|tls-client-external|tls-server|tls-server-external|code-signing}
  277.     local configType=$4
  278.     # infix/prefix... for new files.
  279.     # the given name should be related to the cert; e.g. foo.com for tls-server-external
  280.     local fileNameInfix=$5
  281.    
  282.     # optional named arg san
  283.     # used for $ENV:SAN=$envVar in tls-server-external; if not present: $ENV:SAN="DNS:$fileNameInfix,DNS:*.$fileNameInfix"
  284.     local san
  285.     # optional named arg password
  286.     # used for personal certificates and is required for email, tls-client, and tls-client-external
  287.     local password
  288.    
  289.     # subj defaults
  290.     # we have to redefine the common name in tls-server as $domain
  291.     declare -A SUBJ_DEFAULT
  292.     SUBJ_DEFAULT[C]='BE'
  293.     SUBJ_DEFAULT[ST]='Antwerp'
  294.     SUBJ_DEFAULT[L]='Antwerp'
  295.     SUBJ_DEFAULT[O]="### Network $domain"
  296.     SUBJ_DEFAULT[OU]=''
  297.     SUBJ_DEFAULT[CN]="### Network $domain"
  298.    
  299.     # subjects cust
  300.     declare -A SUBJ
  301.    
  302.     while [[ ${6} ]]; do
  303.         case "${6}" in
  304.             -san)
  305.                 # used for $ENV:SAN=$envVar in tls-server-external; if not present: $ENV:SAN="DNS:$fileNameInfix,DNS:*.$fileNameInfix"
  306.                 local san=${7}
  307.                 shift
  308.             ;;
  309.             -password)
  310.                 # used for personal certificates and is required for email, tls-client, and tls-client-external
  311.                 local password=${7}
  312.                 shift
  313.             ;;
  314.             # certificate subjects
  315.             -C)
  316.                 SUBJ[C]=${7}
  317.                 shift
  318.             ;;
  319.             -ST)
  320.                 SUBJ[ST]=${7}
  321.                 shift
  322.             ;;
  323.             -L)
  324.                 SUBJ[L]=${7}
  325.                 shift
  326.             ;;
  327.             -O)
  328.                 SUBJ[O]=${7}
  329.                 shift
  330.             ;;
  331.             -OU)
  332.                 SUBJ[OU]=${7}
  333.                 shift
  334.             ;;
  335.             -CN)
  336.                 SUBJ[CN]=${7}
  337.                 shift
  338.             ;;
  339.             -emailAddress)
  340.                 SUBJ[emailAddress]=${7}
  341.                 shift
  342.             ;;
  343.             *)
  344.             echo "Unknown parameter: ${6}" >&2
  345.                 return 1
  346.         esac
  347.        
  348.         if ! shift; then
  349.                 echo 'Missing parameter argument.' >&2
  350.                 return 1
  351.         fi
  352.     done
  353.    
  354.     local lookupPath="$SCRIPT_PATH/$reverseDomain/lookup"
  355.    
  356.     if [ ! -d $lookupPath ]; then
  357.         check_result 1 "Lookup directory for $reverseDomain is not here."
  358.     fi
  359.    
  360.     if [ ! -f "$lookupPath/$domain" ]; then
  361.         check_result 1 "$domain is not here :("
  362.     fi
  363.    
  364.     ##############################################################
  365.     #
  366.     # bootstrap
  367.     #
  368.     ##############################################################
  369.    
  370.     local fileName="$fileNameInfix;;$domain"
  371.        
  372.     getDomainPath()
  373.     {
  374.         local lookupPath=$1
  375.         local domain=$2
  376.         echo $(head -n 1 $lookupPath/$domain)
  377.     }
  378.    
  379.     getBaseType()
  380.     {
  381.         local type=$1
  382.         case "$type" in
  383.                 email)
  384.                     echo 'email'
  385.                     ;;
  386.                 tls-server|tls-server-external|tls-client|tls-client-external)
  387.                     echo 'tls'
  388.                     ;;
  389.                 code-signing)
  390.                     echo 'software'
  391.                     ;;
  392.                 *)
  393.                     check_result 1 "invalid request type $type; {email|tls-client|tls-client-external|tls-server|tls-server-external|code-signing}"
  394.         esac
  395.     }
  396.    
  397.     declare -A FILES
  398.     declare -A DIRS
  399.     getFiles()
  400.     {
  401.         local domain=$1
  402.         local domainPath=$2
  403.         local baseType=$3
  404.         local configType=$4
  405.         local fileName=$5
  406.        
  407.         local caType
  408.         local crtType
  409.        
  410.         DIRS[ca]=$domainPath
  411.         DIRS[pub]=$domainPath/${DIR_NAME[public]}
  412.        
  413.         case "$baseType" in
  414.                 email)
  415.                     local caType=${DIR_NAME[caEmail]}
  416.                     local crtType=${DIR_NAME[crtEmail]}
  417.                    
  418.                     DIRS[caDb]=$domainPath/${DIRECTORIES_CA_EMAIL[dbPath]}
  419.                     DIRS[caCnf]=$domainPath/${DIRECTORIES_CA_EMAIL[cnfPath]}
  420.                     DIRS[caPrivate]=$domainPath/${DIRECTORIES_CA_EMAIL[privatePath]}
  421.                    
  422.                     DIRS[crt]=$domainPath/${DIRECTORIES_CRT_EMAIL[crtPath]}
  423.                     DIRS[crtCnf]=$domainPath/${DIRECTORIES_CRT_EMAIL[cnfPath]}
  424.                     DIRS[crtPrivate]=$domainPath/${DIRECTORIES_CRT_EMAIL[privatePath]}
  425.                    
  426.                     DIRS[pubCrt]=$domainPath/${DIRECTORIES_PUB[email]}
  427.                 ;;
  428.                 tls)
  429.                     local caType=${DIR_NAME[caTls]}
  430.                     local crtType=${DIR_NAME[crtTls]}
  431.                    
  432.                     DIRS[caDb]=$domainPath/${DIRECTORIES_CA_TLS[dbPath]}
  433.                     DIRS[caCnf]=$domainPath/${DIRECTORIES_CA_TLS[cnfPath]}
  434.                     DIRS[caPrivate]=$domainPath/${DIRECTORIES_CA_TLS[privatePath]}
  435.                    
  436.                     DIRS[crt]=$domainPath/${DIRECTORIES_CRT_TLS[crtPath]}
  437.                     DIRS[crtCnf]=$domainPath/${DIRECTORIES_CRT_TLS[cnfPath]}
  438.                     DIRS[crtPrivate]=$domainPath/${DIRECTORIES_CRT_TLS[privatePath]}
  439.                    
  440.                     DIRS[pubCrt]=$domainPath/${DIRECTORIES_PUB[tls]}
  441.                 ;;
  442.                 software)
  443.                     local caType=${DIR_NAME[caSoftware]}
  444.                     local crtType=${DIR_NAME[crtSoftware]}
  445.                    
  446.                     DIRS[caDb]=$domainPath/${DIRECTORIES_CA_SOFTWARE[dbPath]}
  447.                     DIRS[caCnf]=$domainPath/${DIRECTORIES_CA_SOFTWARE[cnfPath]}
  448.                     DIRS[caPrivate]=$domainPath/${DIRECTORIES_CA_SOFTWARE[privatePath]}
  449.                    
  450.                     DIRS[crt]=$domainPath/${DIRECTORIES_CRT_SOFTWARE[crtPath]}
  451.                     DIRS[crtCnf]=$domainPath/${DIRECTORIES_CRT_SOFTWARE[cnfPath]}
  452.                     DIRS[crtPrivate]=$domainPath/${DIRECTORIES_CRT_SOFTWARE[privatePath]}
  453.                    
  454.                     DIRS[pubCrt]=$domainPath/${DIRECTORIES_PUB[software]}
  455.                 ;;
  456.                 *)
  457.                     check_result 1 "invalid request baseType '$baseType' {email|tls|software}"
  458.         esac
  459.        
  460.         # the directories are always present
  461.         for index in "${!DIRS[@]}"
  462.         do
  463.             if [ ! -d "${DIRS[$index]}" ]; then
  464.                 check_result 1 'directory not found'
  465.             fi
  466.         done
  467.        
  468.         FILES[caChainPem]=${DIRS[ca]}/$(printf ${FILE_NAME[chainPem]} $domain $caType)
  469.         FILES[caCrl]=${DIRS[caDb]}/$(printf ${FILE_NAME[crl]} $domain $caType)
  470.         FILES[caCnf]=${DIRS[caCnf]}/$(printf ${FILE_NAME[cnf]} $domain $caType)
  471.         FILES[caPwd]=${DIRS[caPrivate]}/$(printf ${FILE_NAME[password]} $domain $caType)
  472.        
  473.         # the CA files are always present
  474.         for index in "${!FILES[@]}"
  475.         do
  476.             if [ ! -f "${FILES[$index]}" ]; then
  477.                 check_result 1 "Required CA file ${FILES[$index]} not found"
  478.             fi
  479.         done
  480.        
  481.         FILES[crt]=${DIRS[crt]}/$(printf ${FILE_NAME[crt]} $fileName $configType)
  482.         FILES[crtCsr]=${DIRS[crt]}/$(printf ${FILE_NAME[csr]} $fileName $configType)
  483.         FILES[crtP12]=${DIRS[crt]}/$(printf ${FILE_NAME[p12]} $fileName $configType)
  484.         FILES[crtChainPem]=${DIRS[crt]}/$(printf ${FILE_NAME[chainPem]} $fileName $configType)
  485.         FILES[crtCnf]=${DIRS[crtCnf]}/$(printf ${FILE_NAME[cnf]} $domain $configType)
  486.         FILES[crtKey]=${DIRS[crtPrivate]}/$(printf ${FILE_NAME[key]} $fileName $configType)
  487.        
  488.         FILES[pubCaCrl]=${DIRS[pub]}/$(printf ${FILE_NAME[crl]} $domain $caType)
  489.        
  490.         FILES[pubCer]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[cer]} $fileName $configType)
  491.         FILES[pubChainP7c]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[chainP7c]} $fileName $configType)
  492.         FILES[pubKeyPem]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[keyPem]} $fileName $configType)
  493.         FILES[pubCrtPem]=${DIRS[pubCrt]}/$(printf ${FILE_NAME[crtPem]} $fileName $configType)
  494.     }
  495.    
  496.     local domainPath=$(getDomainPath $lookupPath $domain)
  497.     local baseType=$(getBaseType $configType)
  498.    
  499.     getFiles $domain $domainPath $baseType $configType $fileName
  500.    
  501.     local lvl=$(grep -o '/intermediate/' <<< "$domainPath" | wc -l)
  502.     case "$lvl" in
  503.         0)
  504.             export CA_0_SCRIPT_PATH="$domainPath"
  505.         ;;
  506.         1)
  507.             export CA_1_SCRIPT_PATH="$domainPath"
  508.         ;;
  509.         2)
  510.             export CA_2_SCRIPT_PATH="$domainPath"
  511.         ;;
  512.     esac
  513.    
  514.     testPassword()
  515.     {
  516.         local password=$1
  517.         if [ -z "$password" ]; then
  518.             check_result 1 "A password is required but was not set or ist empty.\n You can add it with parameter -password"
  519.         fi
  520.     }
  521.    
  522.     testSubject()
  523.     {
  524.         local type=$1
  525.         local name=$2
  526.         local insert=$3
  527.         local default=$4
  528.        
  529.         case "$type" in
  530.             match)
  531.                 if [ ! -z "$insert" ]; then
  532.                     if [ "$default" != "$insert" ]; then
  533.                         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."
  534.                     fi
  535.                 fi
  536.             ;;
  537.             supplied)
  538.                 if [ -z "$insert" ]; then
  539.                     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"
  540.                 fi
  541.             ;;
  542.         esac
  543.     }
  544.    
  545.     concatSubj()
  546.     {
  547.         declare -A MERGED
  548.         local result=""
  549.        
  550.         for index in "${!SUBJ_DEFAULT[@]}"
  551.         do
  552.             MERGED[$index]=${SUBJ_DEFAULT[$index]}
  553.         done
  554.        
  555.         for index in "${!SUBJ[@]}"
  556.         do
  557.             MERGED[$index]=${SUBJ[$index]}
  558.         done
  559.        
  560.         for index in "${!MERGED[@]}"
  561.         do
  562.             result="${result}/${index}=${MERGED[$index]}"
  563.         done
  564.        
  565.         echo $result
  566.     }
  567.    
  568.     ##############################################################
  569.     #
  570.     # actions
  571.     #
  572.     ##############################################################
  573.    
  574.     case "$action" in
  575.         create)
  576.             local subject=$(concatSubj)
  577.            
  578.             writeNewCert "$configType: $fileNameInfix"
  579.            
  580.             revokeAfterValidation()
  581.             {
  582.                 if [ -e ${FILES[crt]} ]; then
  583.                     writeRevType "This certificate exists. We have to revoke it."
  584.                     certificate "$reverseDomain" "$domain" revoke "$configType" "$fileNameInfix"
  585.                     writeNewType "$subject"
  586.                 fi
  587.             }
  588.            
  589.             writeNewType "new $subject"
  590.             case "$configType" in
  591.                 code-signing)
  592.                     # see CA policy
  593.                     testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}"
  594.                     testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}"
  595.                     testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}"
  596.                     testPassword $password
  597.                    
  598.                     revokeAfterValidation
  599.                    
  600.                     writeNewItem 'key'
  601.                     openssl genpkey \
  602.                         -algorithm RSA \
  603.                         -out ${FILES[crtKey]} \
  604.                         -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \
  605.                         -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP
  606.                     check_result $? 'unable to create key'
  607.                    
  608.                     writeNewItem 'csr'
  609.                     openssl req -new \
  610.                         -config ${FILES[crtCnf]} \
  611.                         -out ${FILES[crtCsr]} \
  612.                         -key ${FILES[crtKey]} \
  613.                         -subj "$subject" \
  614.                         -passout pass:$password
  615.                     check_result $? 'unable to create csr'
  616.                    
  617.                     writeNewItem 'create crt'
  618.                     openssl ca \
  619.                         -batch \
  620.                         -config ${FILES[caCnf]} \
  621.                         -in ${FILES[crtCsr]} \
  622.                         -out ${FILES[crt]} \
  623.                         -passin file:${FILES[caPwd]} \
  624.                         -extensions codesign_ext \
  625.                             > /dev/null 2>&1
  626.                     check_result $? 'unable to create crt'
  627.                    
  628.                     writeNewItem 'verify sslclient'
  629.                     openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]}
  630.                    
  631.                     writeNewItem 'publish as p12'
  632.                     openssl pkcs12 -export \
  633.                         -name "$domain: $fileNameInfix (Software Certificate)" \
  634.                         -inkey ${FILES[crtKey]} \
  635.                         -in ${FILES[crt]} \
  636.                         -certfile ${FILES[caChainPem]} \
  637.                         -out ${FILES[crtP12]} \
  638.                         -passout pass:$password \
  639.                         -passin pass:$password \
  640.                             > /dev/null 2>&1
  641.                     check_result $? 'unable to create p12'
  642.                 ;;
  643.                 email)
  644.                     # see CA policy
  645.                     testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}"
  646.                     testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}"
  647.                     testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}"
  648.                     testSubject 'supplied' 'emailAddress' "${SUBJ[emailAddress]}"
  649.                     testPassword $password
  650.                    
  651.                     revokeAfterValidation
  652.                    
  653.                     writeNewItem 'key'
  654.                     openssl genpkey \
  655.                         -algorithm RSA \
  656.                         -out ${FILES[crtKey]} \
  657.                         -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \
  658.                         -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP
  659.                     check_result $? 'unable to create key'
  660.                    
  661.                     writeNewItem 'csr'
  662.                     openssl req -new \
  663.                         -config ${FILES[crtCnf]} \
  664.                         -out ${FILES[crtCsr]} \
  665.                         -key ${FILES[crtKey]} \
  666.                         -subj "$subject" \
  667.                         -passout pass:$password
  668.                     check_result $? 'unable to create csr'
  669.                    
  670.                     writeNewItem 'create crt'
  671.                     openssl ca \
  672.                         -batch \
  673.                         -config ${FILES[caCnf]} \
  674.                         -notext \
  675.                         -in ${FILES[crtCsr]} \
  676.                         -out ${FILES[crt]} \
  677.                         -passin file:${FILES[caPwd]} \
  678.                         -extensions email_ext
  679.                     check_result $? 'unable to create crt'
  680.                    
  681.                     writeNewItem 'verify sslclient'
  682.                     openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]}
  683.                    
  684.                     writeNewItem 'publish as p12'
  685.                     openssl pkcs12 -export \
  686.                         -name "${SUBJ[emailAddress]} (Email Address)" \
  687.                         -inkey ${FILES[crtKey]} \
  688.                         -in ${FILES[crt]} \
  689.                         -certfile ${FILES[caChainPem]} \
  690.                         -out ${FILES[crtP12]} \
  691.                         -passout pass:$password \
  692.                         -passin pass:$password \
  693.                             > /dev/null 2>&1
  694.                     check_result $? 'unable to create p12'
  695.                 ;;
  696.                 tls-client|tls-client-external)
  697.                    
  698.                     case "$configType" in
  699.                         tls-client)
  700.                             # see CA policy
  701.                             testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}"
  702.                             testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}"
  703.                             testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}"
  704.                             testPassword $password
  705.                            
  706.                             revokeAfterValidation
  707.                            
  708.                             writeNewItem 'key'
  709.                             openssl genpkey \
  710.                                 -algorithm RSA \
  711.                                 -out ${FILES[crtKey]} \
  712.                                 -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \
  713.                                 -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP
  714.                             check_result $? 'unable to create key'
  715.                            
  716.                             writeNewItem 'csr'
  717.                             openssl req -new \
  718.                                 -config ${FILES[crtCnf]} \
  719.                                 -out ${FILES[crtCsr]} \
  720.                                 -key ${FILES[crtKey]} \
  721.                                 -subj "$subject" \
  722.                                 -passout pass:$password
  723.                             check_result $? 'unable to create csr'
  724.                            
  725.                             writeNewItem 'create crt'
  726.                             openssl ca \
  727.                                 -batch \
  728.                                 -config ${FILES[caCnf]} \
  729.                                 -in ${FILES[crtCsr]} \
  730.                                 -out ${FILES[crt]} \
  731.                                 -passin file:${FILES[caPwd]} \
  732.                                 -extensions client_ext \
  733.                                     > /dev/null 2>&1
  734.                             check_result $? 'unable to create crt'
  735.                         ;;
  736.                         tls-client-external)
  737.                             # see CA policy
  738.                             testSubject 'supplied' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}"
  739.                             testSubject 'supplied' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}"
  740.                             testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}"
  741.                             testPassword $password
  742.                            
  743.                             revokeAfterValidation
  744.                            
  745.                             writeNewItem 'key'
  746.                             openssl genpkey \
  747.                                 -algorithm RSA \
  748.                                 -out ${FILES[crtKey]} \
  749.                                 -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \
  750.                                 -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP
  751.                             check_result $? 'unable to create key'
  752.                            
  753.                             writeNewItem 'csr'
  754.                             openssl req -new \
  755.                                 -config ${FILES[crtCnf]} \
  756.                                 -out ${FILES[crtCsr]} \
  757.                                 -key ${FILES[crtKey]} \
  758.                                 -subj "$subject" \
  759.                                 -passout pass:$password
  760.                             check_result $? 'unable to create csr'
  761.                            
  762.                             writeNewItem 'create crt'
  763.                             openssl ca \
  764.                                 -batch \
  765.                                 -config ${FILES[caCnf]} \
  766.                                 -in ${FILES[crtCsr]} \
  767.                                 -out ${FILES[crt]} \
  768.                                 -passin file:${FILES[caPwd]} \
  769.                                 -extensions client_ext \
  770.                                 -policy extern_pol \
  771.                                     > /dev/null 2>&1
  772.                             check_result $? 'unable to create crt'
  773.                         ;;
  774.                     esac
  775.                    
  776.                     writeNewItem 'verify sslclient'
  777.                     openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]}
  778.                    
  779.                     writeNewItem 'publish as p12'
  780.                     openssl pkcs12 -export \
  781.                         -name "$fileNameInfix (TLS Network Access)" \
  782.                         -inkey ${FILES[crtKey]} \
  783.                         -in ${FILES[crt]} \
  784.                         -certfile ${FILES[caChainPem]} \
  785.                         -out ${FILES[crtP12]} \
  786.                         -passout pass:$password \
  787.                         -passin pass:$password \
  788.                             > /dev/null 2>&1
  789.                     check_result $? 'unable to create p12'
  790.                    
  791.                     #???
  792.                     #writeNewItem 'pem key from p12'
  793.                     #openssl pkcs12 -nocerts \
  794.                     #   -in ${FILES[crtP12]} \
  795.                     #   -out ${FILES[pubKeyPem]} \
  796.                     #       > /dev/null 2>&1
  797.                     #check_result $? 'unable to create pem key'
  798.                     #
  799.                     #writeNewItem 'pem crt from p12'
  800.                     #openssl pkcs12 -clcerts -nokeys \
  801.                     #   -in ${FILES[crtP12]} \
  802.                     #   -out ${FILES[pubCrtPem]} \
  803.                     #       > /dev/null 2>&1
  804.                     #check_result $? 'unable to create p12'
  805.                 ;;
  806.                 tls-server|tls-server-external)
  807.                     case "$configType" in
  808.                         tls-server)
  809.                             SUBJ_DEFAULT[CN]=$domain
  810.                             # see CA policy
  811.                             testSubject 'match' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}"
  812.                             testSubject 'match' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}"
  813.                             testSubject 'match' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}"
  814.                            
  815.                             revokeAfterValidation
  816.                            
  817.                             export SAN="DNS:$domain,DNS:*.$domain"
  818.                            
  819.                             writeNewItem 'key'
  820.                             openssl genpkey \
  821.                                 -algorithm RSA \
  822.                                 -out ${FILES[crtKey]} \
  823.                                 -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \
  824.                                 -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP
  825.                             check_result $? 'unable to create key'
  826.                            
  827.                             writeNewItem 'csr'
  828.                             openssl req -new \
  829.                                 -config ${FILES[crtCnf]} \
  830.                                 -out ${FILES[crtCsr]} \
  831.                                 -key ${FILES[crtKey]} \
  832.                                 -subj "$subject"
  833.                             check_result $? 'unable to create csr'
  834.                            
  835.                             writeNewItem 'create crt'
  836.                             openssl ca \
  837.                                 -batch \
  838.                                 -config ${FILES[caCnf]} \
  839.                                 -in ${FILES[crtCsr]} \
  840.                                 -out ${FILES[crt]} \
  841.                                 -passin file:${FILES[caPwd]} \
  842.                                 -extensions server_ext
  843.                             check_result $? 'unable to create crt'
  844.                         ;;
  845.                         tls-server-external)
  846.                             # see CA policy
  847.                             testSubject 'supplied' 'C' "${SUBJ[C]}" "${SUBJ_DEFAULT[C]}"
  848.                             testSubject 'supplied' 'O' "${SUBJ[O]}" "${SUBJ_DEFAULT[O]}"
  849.                             testSubject 'supplied' 'CN' "${SUBJ[CN]}" "${SUBJ_DEFAULT[CN]}"
  850.                            
  851.                             revokeAfterValidation
  852.                            
  853.                             if [ -z $san ]; then
  854.                                 local san="DNS:$fileNameInfix,DNS:*.$fileNameInfix"
  855.                             fi
  856.                             export SAN="$san"
  857.                            
  858.                             writeNewItem 'key'
  859.                             openssl genpkey \
  860.                                 -algorithm RSA \
  861.                                 -out ${FILES[crtKey]} \
  862.                                 -pkeyopt rsa_keygen_bits:$DEFAULT_CRT_RSA_KEYSIZE_PRIVATE_KEY \
  863.                                 -pkeyopt rsa_keygen_pubexp:$DEFAULT_CRT_PWD_GEN_PUBEXP
  864.                             check_result $? 'unable to create key'
  865.                            
  866.                             writeNewItem 'csr'
  867.                             openssl req -new \
  868.                                 -config ${FILES[crtCnf]} \
  869.                                 -out ${FILES[crtCsr]} \
  870.                                 -key ${FILES[crtKey]} \
  871.                                 -subj "$subject"
  872.                             check_result $? 'unable to create csr'
  873.                            
  874.                             writeNewItem 'create crt'
  875.                             openssl ca \
  876.                                 -batch \
  877.                                 -config ${FILES[caCnf]} \
  878.                                 -in ${FILES[crtCsr]} \
  879.                                 -out ${FILES[crt]} \
  880.                                 -passin file:${FILES[caPwd]} \
  881.                                 -extensions server_ext \
  882.                                 -policy extern_pol \
  883.                                     > /dev/null 2>&1
  884.                             check_result $? 'unable to create crt'
  885.                         ;;
  886.                     esac
  887.                    
  888.                     writeNewItem 'verify sslclient'
  889.                     openssl verify -purpose sslclient -CAfile ${FILES[caChainPem]} ${FILES[crt]}
  890.                    
  891.                     writeNewItem 'publish as p12'
  892.                     openssl pkcs12 -export \
  893.                         -name "$fileNameInfix (TLS Network Component)" \
  894.                         -inkey ${FILES[crtKey]} \
  895.                         -passout pass:\
  896.                         -in ${FILES[crt]} \
  897.                         -certfile ${FILES[caChainPem]} \
  898.                         -out ${FILES[crtP12]} \
  899.                             > /dev/null 2>&1
  900.                     check_result $? 'unable to create p12'
  901.                    
  902.                     writeNewItem 'pem key from p12'
  903.                     openssl pkcs12 -nocerts -nodes \
  904.                         -in ${FILES[crtP12]} \
  905.                         -passin pass:\
  906.                         -out ${FILES[pubKeyPem]} \
  907.                             > /dev/null 2>&1
  908.                     check_result $? 'unable to create pem key'
  909.                    
  910.                     writeNewItem 'passfree pem key'
  911.                     openssl rsa \
  912.                         -in ${FILES[pubKeyPem]} \
  913.                         -out ${FILES[pubKeyPem]} \
  914.                             > /dev/null 2>&1
  915.                     check_result $? 'unable to create passfree pem key'
  916.                    
  917.                     writeNewItem 'pem crt from p12'
  918.                     openssl pkcs12 -clcerts -nokeys \
  919.                         -in ${FILES[crtP12]} \
  920.                         -passin pass:\
  921.                         -out ${FILES[pubCrtPem]} \
  922.                             > /dev/null 2>&1
  923.                     check_result $? 'unable to create p12'
  924.                    
  925.                     cat ${FILES[crt]} ${FILES[caChainPem]} > ${FILES[crtChainPem]}
  926.                
  927.                     writeNewItem 'publish crt as application/pkix-cert'
  928.                     openssl x509 \
  929.                         -in ${FILES[crt]} \
  930.                         -out ${FILES[pubCer]} \
  931.                         -outform der
  932.                
  933.                     writeNewItem 'publish pem chain as application/pkcs7-mime'
  934.                     openssl crl2pkcs7 -nocrl \
  935.                         -certfile ${FILES[crtChainPem]} \
  936.                         -out ${FILES[pubChainP7c]} \
  937.                         -outform der
  938.                    
  939.                 ;;
  940.             esac
  941.         ;;
  942.         delete)
  943.             writeDelCert "$configType: $fileNameInfix"
  944.             declare -A REMOVE
  945.            
  946.             for type in crt crtCsr crtP12 crtKey pubCrtPem pubKeyPem pubCer pubChainP7c
  947.             do
  948.                 if [ -e ${FILES[$type]} ]; then
  949.                     writeDelItem ${FILES[$type]}
  950.                     REMOVE[$type]=${FILES[$type]}
  951.                 fi
  952.             done
  953.            
  954.             check_prompt 1 'Files will be permanently removed from disk!'
  955.            
  956.             if [ -e ${FILES[crt]} ]; then
  957.                 writeRevType "existing $configType: $fileNameInfix"
  958.                 certificate "$reverseDomain" "$domain" revoke "$configType" "$fileNameInfix"
  959.             fi
  960.            
  961.             writeDelType 'files'
  962.             for index in "${!REMOVE[@]}"
  963.             do
  964.                 writeDelItem ${REMOVE[$index]}
  965.                 rm ${REMOVE[$index]} > /dev/null 2>&1
  966.                 check_result $? 'unable to delete file'
  967.             done
  968.         ;;
  969.         revoke)
  970.             writeRevCert "$configType: $fileNameInfix"
  971.             if [ -e ${FILES[crt]} ]; then
  972.                 local lastSrl=$(openssl x509 -in ${FILES[crt]} -serial -noout)
  973.                 local lastFnr=$(openssl x509 -in ${FILES[crt]} -fingerprint -noout)
  974.                 local revokationReason
  975.                
  976.                 case "$configType" in
  977.                     email)
  978.                         local revokationReason=affiliationChanged
  979.                     ;;
  980.                     tls-server|tls-server-external|tls-client|tls-client-external)
  981.                         local revokationReason=affiliationChanged
  982.                     ;;
  983.                     code-signing)
  984.                         local revokationReason=affiliationChanged
  985.                     ;;
  986.                 esac
  987.                
  988.                 check_prompt 1 "certificate $fileName.$configType.crt exists as \n\t$lastSrl\n\t$lastFnr\n"
  989.                
  990.                 echo ""
  991.                 echo -e "Please set the revokation reason. Default CRL reason for type $configType is $revokationReason."
  992.                 echo -e "   [1] unspecified"
  993.                 echo -e "   [2] keyCompromise"
  994.                 echo -e "   [3] CACompromise"
  995.                 echo -e "   [4] affiliationChanged"
  996.                 echo -e "   [5] superseded"
  997.                 echo -e "   [6] cessationOfOperation"
  998.                 echo -e "   [7] certificateHold"
  999.                 echo -e "   [8] removeFromCRL"
  1000.                 echo -e "   [n] set no reason"
  1001.                 echo ""
  1002.                 read -p "Please set the revokation reason or nothing for default: " answer
  1003.                 echo ""
  1004.                
  1005.                 case "$answer" in
  1006.                     1)
  1007.                         local revokationReason=unspecified
  1008.                     ;;
  1009.                     2)
  1010.                         local revokationReason=keyCompromise
  1011.                     ;;
  1012.                     3)
  1013.                         local revokationReason=CACompromise
  1014.                     ;;
  1015.                     4)
  1016.                         local revokationReason=affiliationChanged
  1017.                     ;;
  1018.                     5)
  1019.                         local revokationReason=superseded
  1020.                     ;;
  1021.                     6)
  1022.                         local revokationReason=cessationOfOperation
  1023.                     ;;
  1024.                     7)
  1025.                         local revokationReason=certificateHold
  1026.                     ;;
  1027.                     8)
  1028.                         local revokationReason=removeFromCRL
  1029.                     ;;
  1030.                     'n'|'N')
  1031.                         local revokationReason=no
  1032.                     ;;
  1033.                 esac
  1034.                
  1035.                 writeNewType 'revokation'
  1036.                 if [ $revokationReason == 'no' ]; then
  1037.                     writeNewItem "revoke without reason"
  1038.                     openssl ca \
  1039.                         -config ${FILES[caCnf]} \
  1040.                         -revoke ${FILES[crt]} \
  1041.                         -passin file:${FILES[caPwd]} \
  1042.                              > /dev/null 2>&1
  1043.                     idle_result $? 'unable to revoke'
  1044.                 else
  1045.                     writeNewItem "revoke with $revokationReason"
  1046.                     openssl ca \
  1047.                         -config ${FILES[caCnf]} \
  1048.                         -revoke ${FILES[crt]} \
  1049.                         -passin file:${FILES[caPwd]} \
  1050.                         -crl_reason $revokationReason \
  1051.                              > /dev/null 2>&1
  1052.                     idle_result $? 'unable to revoke'
  1053.                 fi
  1054.                
  1055.                 writeNewItem 'update crl'
  1056.                 openssl ca -gencrl \
  1057.                     -config ${FILES[caCnf]} \
  1058.                     -out ${FILES[caCrl]} \
  1059.                     -passin file:${FILES[caPwd]} \
  1060.                         > /dev/null 2>&1
  1061.                 check_result $? 'unable to update crl'
  1062.                    
  1063.                 writeNewItem 'publish crl as application/pkix-crl'
  1064.                 openssl crl \
  1065.                     -in ${FILES[caCrl]} \
  1066.                     -out ${FILES[pubCaCrl]} \
  1067.                     -outform der \
  1068.                         > /dev/null 2>&1
  1069.                 check_result $? 'unable to publish crl'
  1070.             fi
  1071.         ;;
  1072.         *)
  1073.             check_result 1 "invalid action '$action' {create|delete|revoke}"
  1074.     esac
  1075. }
  1076.  
  1077.  
  1078.  
  1079.  
  1080.  
  1081.  
  1082.  
  1083.  
  1084. ##############################################################
  1085. #
  1086. # asynch?
  1087. #
  1088. ##############################################################
  1089. if [ -d "/var/lock/$DEFAULT_DOMAIN" ]; then
  1090.     check_result 30 "Already locked"
  1091. fi
  1092.  
  1093. mkdir "/var/lock/$DEFAULT_DOMAIN"
  1094. check_result $? "Lock failed"
  1095.  
  1096.  
  1097.  
  1098. ##
  1099. # Create a simple CA-chain.
  1100. #
  1101. # create some CAs
  1102. # root_ca 'reverse.com' 'domain1.com;domain2.com' 'sub1;sub2'
  1103. # root_ca 'reverse.com' 'domain1.com' 'sub3'
  1104. # root_ca 'reverse.com' 'domain2.com' 'sub4'
  1105. # root_ca 'reverse.com' 'domain3.com'
  1106. #
  1107. # result
  1108. #   - ./reverse.com
  1109. #       - reverse.com.ca.crt (root CA)
  1110. #       - reverse.com.ca-tls.crt
  1111. #       - ./intermediate
  1112. #           - ./domain1.com
  1113. #               - domain1.com.ca.crt (sub root CA)
  1114. #               - domain1.com.ca-tls.crt
  1115. #               - domain1.com.ca-email.crt
  1116. #               - domain1.com.ca-software.crt
  1117. #               - ./intermediate
  1118. #                   - ./sub1.domain1.com
  1119. #                       - sub1.domain1.com.ca.crt (sub sub root CA)
  1120. #                       - sub1.domain1.com.ca-tls.crt
  1121. #                       - sub1.domain1.com.ca-email.crt
  1122. #                       - sub1.domain1.com.ca-software.crt
  1123. #                   - ./sub2.domain1.com
  1124. #                       - sub2.domain1.com.ca.crt (sub sub root CA)
  1125. #                       - sub2.domain1.com.ca-tls.crt
  1126. #                       - sub2.domain1.com.ca-email.crt
  1127. #                       - sub2.domain1.com.ca-software.crt
  1128. #                   - ./sub3.domain1.com
  1129. #                       - sub3.domain1.com.ca.crt (sub sub root CA)
  1130. #                       - sub3.domain1.com.ca-tls.crt
  1131. #                       - sub3.domain1.com.ca-email.crt
  1132. #                       - sub3.domain1.com.ca-software.crt
  1133. #           - ./domain2.com
  1134. #               - domain2.com.ca.crt (sub root CA)
  1135. #               - domain2.com.ca-tls.crt
  1136. #               - domain2.com.ca-email.crt
  1137. #               - domain2.com.ca-software.crt
  1138. #               - ./intermediate
  1139. #                   - ./sub1.domain1.com
  1140. #                       - sub1.domain2.com.ca.crt (sub sub root CA)
  1141. #                       - sub1.domain2.com.ca-tls.crt
  1142. #                       - sub1.domain2.com.ca-email.crt
  1143. #                       - sub1.domain2.com.ca-software.crt
  1144. #                   - ./sub2.domain1.com
  1145. #                       - sub2.domain2.com.ca.crt (sub sub root CA)
  1146. #                       - sub2.domain2.com.ca-tls.crt
  1147. #                       - sub2.domain2.com.ca-email.crt
  1148. #                       - sub2.domain2.com.ca-software.crt
  1149. #                   - ./sub4.domain1.com
  1150. #                       - sub4.domain2.com.ca.crt (sub sub root CA)
  1151. #                       - sub4.domain2.com.ca-tls.crt
  1152. #                       - sub4.domain2.com.ca-email.crt
  1153. #                       - sub4.domain2.com.ca-software.crt
  1154. #           - ./domain3.com
  1155. #               - domain3.com.ca.crt (sub root CA)
  1156. #               - domain3.com.ca-tls.crt
  1157. #               - domain3.com.ca-email.crt
  1158. #               - domain3.com.ca-software.crt
  1159. #
  1160. #
  1161. #
  1162. # root_ca reverse-domain [public-domain [subdomain-prefix]]
  1163. root_ca()
  1164. {
  1165.     # the base; the IP or reverse host address.
  1166.     # this allows us to use this function for multiple servers on same host.
  1167.     # this is the network root CA.
  1168.     # this function creates also the reverse host based CA for TLS - signed by the root CA.
  1169.     local reverseHost=$1
  1170.    
  1171.     # list of domains separated by ;
  1172.     #   root_ca reverse.tld foo.tld;bar.tld;alice.tld   - for foo.tld, bar.tld, and alice.tld
  1173.     #
  1174.     # this function creates an intermediate CA for each domain.
  1175.     # the intermediate CAs will be signed by the Root CA of reverse host.
  1176.     # this function creates also domain based CAs for TLS, email and code signing - signed by the domain based intermediate CA.
  1177.     local domainList=$2
  1178.    
  1179.     # list of subdomain names separated by ;
  1180.     #   mail;smtp
  1181.     #
  1182.     # note that all names in this list will be applied to each given domain.
  1183.     # to avoid this you must call this function multiple times.
  1184.     # root_ca will not destroy, delete or override previous created CAs
  1185.     #   root_ca reverse.tld foo.tld;bar.tld mail;smtp   - for mail.foo.tld, smtp.foo.tld, mail.bar.tld, and smtp.bar.tld
  1186.     #   root_ca reverse.tld foo.tld;alice.tld imap      - for imap.foo.tld, and imap.alice.tld
  1187.     #
  1188.     # this function creates an intermediate CA for each subdomain.
  1189.     # the intermediate CAs will be signed by the intermediate CA of their owner domain
  1190.     # this function creates also sub domain based CAs for TLS, email and code signing - signed by the subdomain based intermediate CA.
  1191.     local subDomainNameList=$3
  1192.  
  1193.    
  1194.     ##############################################################
  1195.     #
  1196.     # CRT config partial factories
  1197.     #
  1198.     ##############################################################
  1199.    
  1200.     makeModulCsrConfigBlock_title()
  1201.     {
  1202.         local outputFile=$1
  1203.         local domain=$2
  1204.         local title=$3
  1205.        
  1206.         {
  1207.             echo "# $title certificate request for $domain"
  1208.             echo ''
  1209.         } >> $outputFile
  1210.     }
  1211.    
  1212.     ##############################################################
  1213.     #
  1214.     # CRT config factories
  1215.     #
  1216.     ##############################################################
  1217.    
  1218.     modulCsrEmailConfig()
  1219.     {
  1220.         local outputFile=$1
  1221.         local domain=$2
  1222.        
  1223.         {
  1224.             makeModulCsrConfigBlock_title $outputFile $domain 'Email'
  1225.             echo '[ req ]'
  1226.             echo "default_bits            = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST                  # RSA key size"
  1227.             echo 'encrypt_key             = yes                   # Protect private key'
  1228.             echo "default_md              = $DEFAULT_CRT_MD_REQUEST                # MD to use"
  1229.             echo 'utf8                    = yes                   # Input is UTF-8'
  1230.             echo 'string_mask             = utf8only              # Emit UTF-8 strings'
  1231.             echo 'prompt                  = yes                   # Prompt for DN'
  1232.             echo 'distinguished_name      = email_dn              # DN template'
  1233.             echo 'req_extensions          = email_reqext          # Desired extensions'
  1234.             echo ''
  1235.             echo "[ email_dn ]"
  1236.             echo 'countryName             = "1. Country Name (2 letters) (eg, US)       "'
  1237.             echo 'countryName_max         = 2'
  1238.             echo 'countryName_default     = "BE"'
  1239.             echo 'stateOrProvinceName     = "2. State or Province Name   (eg, region)   "'
  1240.             echo 'localityName            = "3. Locality Name            (eg, city)     "'
  1241.             echo 'organizationName        = "4. Organization Name        (eg, company)  "'
  1242.             echo "organizationName_default = \""### Network $domain\"""
  1243.             echo 'organizationalUnitName  = "5. Organizational Unit Name (eg, section)  "'
  1244.             echo 'commonName              = "6. Common Name              (eg, full name)"'
  1245.             echo 'commonName_max          = 64'
  1246.             echo 'emailAddress            = "7. Email Address            (eg, name@fqdn)"'
  1247.             echo 'emailAddress_max        = 40'
  1248.             echo ''
  1249.             echo '[ email_reqext ]'
  1250.             echo 'keyUsage                = critical,digitalSignature,keyEncipherment'
  1251.             echo 'extendedKeyUsage        = critical,emailProtection,clientAuth'
  1252.             echo 'subjectKeyIdentifier    = hash'
  1253.             echo 'subjectAltName          = email:move'
  1254.         } >> $outputFile
  1255.     }
  1256.    
  1257.     modulCsrTlsClientConfig()
  1258.     {
  1259.         local outputFile=$1
  1260.         local domain=$2
  1261.        
  1262.         {
  1263.             makeModulCsrConfigBlock_title $outputFile $domain 'TLS Client'
  1264.             echo '[ req ]'
  1265.             echo "default_bits            = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST                  # RSA key size"
  1266.             echo 'encrypt_key             = yes                   # Protect private key'
  1267.             echo "default_md              = $DEFAULT_CRT_MD_REQUEST                # MD to use"
  1268.             echo 'utf8                    = yes                   # Input is UTF-8'
  1269.             echo 'string_mask             = utf8only              # Emit UTF-8 strings'
  1270.             echo 'prompt                  = yes                   # Prompt for DN'
  1271.             echo 'distinguished_name      = client_dn             # DN template'
  1272.             echo 'req_extensions          = client_reqext         # Desired extensions'
  1273.             echo ''
  1274.             echo "[ client_dn ]"
  1275.             echo 'countryName             = "1. Country Name (2 letters) (eg, US)       "'
  1276.             echo 'countryName_max         = 2'
  1277.             echo 'countryName_default     = "BE"'
  1278.             echo 'stateOrProvinceName     = "2. State or Province Name   (eg, region)   "'
  1279.             echo 'localityName            = "3. Locality Name            (eg, city)     "'
  1280.             echo 'organizationName        = "4. Organization Name        (eg, company)  "'
  1281.             echo "organizationName_default = \""### Network $domain\"""
  1282.             echo 'organizationalUnitName  = "5. Organizational Unit Name (eg, section)  "'
  1283.             echo 'commonName              = "6. Common Name              (eg, full name)"'
  1284.             echo 'commonName_max          = 64'
  1285.             echo 'emailAddress            = "7. Email Address            (eg, name@fqdn)"'
  1286.             echo 'emailAddress_max        = 40'
  1287.             echo ''
  1288.             echo '[ client_reqext ]'
  1289.             echo 'keyUsage                = critical,digitalSignature'
  1290.             echo 'extendedKeyUsage        = critical,clientAuth'
  1291.             echo 'subjectKeyIdentifier    = hash'
  1292.             echo 'subjectAltName          = email:move'
  1293.         } >> $outputFile
  1294.     }
  1295.    
  1296.     modulCsrTlsClientExternalConfig()
  1297.     {
  1298.         local outputFile=$1
  1299.         local domain=$2
  1300.        
  1301.         {
  1302.             makeModulCsrConfigBlock_title $outputFile $domain 'TLS External Client'
  1303.             echo '[ req ]'
  1304.             echo "default_bits            = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST                  # RSA key size"
  1305.             echo 'encrypt_key             = yes                   # Protect private key'
  1306.             echo "default_md              = $DEFAULT_CRT_MD_REQUEST                # MD to use"
  1307.             echo 'utf8                    = yes                   # Input is UTF-8'
  1308.             echo 'string_mask             = utf8only              # Emit UTF-8 strings'
  1309.             echo 'prompt                  = yes                   # Prompt for DN'
  1310.             echo 'distinguished_name      = client_dn             # DN template'
  1311.             echo 'req_extensions          = client_reqext         # Desired extensions'
  1312.             echo ''
  1313.             echo "[ client_dn ]"
  1314.             echo 'countryName             = "1. Country Name (2 letters) (eg, US)       "'
  1315.             echo 'countryName_max         = 2'
  1316.             echo 'stateOrProvinceName     = "2. State or Province Name   (eg, region)   "'
  1317.             echo 'localityName            = "3. Locality Name            (eg, city)     "'
  1318.             echo 'organizationName        = "4. Organization Name        (eg, company)  "'
  1319.             echo 'organizationalUnitName  = "5. Organizational Unit Name (eg, section)  "'
  1320.             echo 'commonName              = "6. Common Name              (eg, full name)"'
  1321.             echo 'commonName_max          = 64'
  1322.             echo 'emailAddress            = "7. Email Address            (eg, name@fqdn)"'
  1323.             echo 'emailAddress_max        = 40'
  1324.             echo ''
  1325.             echo '[ client_reqext ]'
  1326.             echo 'keyUsage                = critical,digitalSignature'
  1327.             echo 'extendedKeyUsage        = critical,clientAuth'
  1328.             echo 'subjectKeyIdentifier    = hash'
  1329.             echo 'subjectAltName          = email:move'
  1330.         } >> $outputFile
  1331.     }
  1332.    
  1333.     modulCsrTlsServerConfig()
  1334.     {
  1335.         local outputFile=$1
  1336.         local domain=$2
  1337.        
  1338.         {
  1339.             makeModulCsrConfigBlock_title $outputFile $domain 'TLS Server'
  1340.             echo '[ req ]'
  1341.             echo "default_bits            = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST                  # RSA key size"
  1342.             echo 'encrypt_key             = no                    # Protect private key'
  1343.             echo "default_md              = $DEFAULT_CRT_MD_REQUEST                # MD to use"
  1344.             echo 'utf8                    = yes                   # Input is UTF-8'
  1345.             echo 'string_mask             = utf8only              # Emit UTF-8 strings'
  1346.             echo 'prompt                  = yes                   # Prompt for DN'
  1347.             echo 'distinguished_name      = server_dn             # DN template'
  1348.             echo 'req_extensions          = server_reqext         # Desired extensions'
  1349.             echo ''
  1350.             echo "[ server_dn ]"
  1351.             echo 'countryName             = "1. Country Name (2 letters) (eg, US)       "'
  1352.             echo 'countryName_max         = 2'
  1353.             echo 'countryName_default     = "BE"'
  1354.             echo 'stateOrProvinceName     = "2. State or Province Name   (eg, region)   "'
  1355.             echo 'localityName            = "3. Locality Name            (eg, city)     "'
  1356.             echo 'organizationName        = "4. Organization Name        (eg, company)  "'
  1357.             echo "organizationName_default = \""### Network $domain\"""
  1358.             echo 'organizationalUnitName  = "5. Organizational Unit Name (eg, section)  "'
  1359.             echo 'commonName              = "6. Common Name              (eg, full name)"'
  1360.             echo 'commonName_max          = 64'
  1361.             echo "commonName_default      = \""$domain\"""
  1362.             echo 'emailAddress            = "7. Email Address            (eg, name@fqdn)"'
  1363.             echo 'emailAddress_max        = 40'
  1364.             echo ''
  1365.             echo '[ server_reqext ]'
  1366.             echo 'keyUsage                = critical,digitalSignature,keyEncipherment'
  1367.             echo 'extendedKeyUsage        = serverAuth,clientAuth'
  1368.             echo 'subjectKeyIdentifier    = hash'
  1369.             echo 'subjectAltName          = $ENV::SAN'
  1370.         } >> $outputFile
  1371.     }
  1372.    
  1373.     modulCsrTlsServerExternalConfig()
  1374.     {
  1375.         local outputFile=$1
  1376.         local domain=$2
  1377.        
  1378.         {
  1379.             makeModulCsrConfigBlock_title $outputFile $domain 'TLS External Server'
  1380.             echo '[ req ]'
  1381.             echo "default_bits            = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST                  # RSA key size"
  1382.             echo 'encrypt_key             = no                    # Protect private key'
  1383.             echo "default_md              = $DEFAULT_CRT_MD_REQUEST                # MD to use"
  1384.             echo 'utf8                    = yes                   # Input is UTF-8'
  1385.             echo 'string_mask             = utf8only              # Emit UTF-8 strings'
  1386.             echo 'prompt                  = yes                   # Prompt for DN'
  1387.             echo 'distinguished_name      = server_dn             # DN template'
  1388.             echo 'req_extensions          = server_reqext         # Desired extensions'
  1389.             echo ''
  1390.             echo "[ server_dn ]"
  1391.             echo 'countryName             = "1. Country Name (2 letters) (eg, US)       "'
  1392.             echo 'countryName_max         = 2'
  1393.             echo 'stateOrProvinceName     = "2. State or Province Name   (eg, region)   "'
  1394.             echo 'localityName            = "3. Locality Name            (eg, city)     "'
  1395.             echo 'organizationName        = "4. Organization Name        (eg, company)  "'
  1396.             echo 'organizationalUnitName  = "5. Organizational Unit Name (eg, section)  "'
  1397.             echo 'commonName              = "6. Common Name              (eg, full name)"'
  1398.             echo 'commonName_max          = 64'
  1399.             echo 'emailAddress            = "7. Email Address            (eg, name@fqdn)"'
  1400.             echo 'emailAddress_max        = 40'
  1401.             echo ''
  1402.             echo '[ server_reqext ]'
  1403.             echo 'keyUsage                = critical,digitalSignature,keyEncipherment'
  1404.             echo 'extendedKeyUsage        = serverAuth,clientAuth'
  1405.             echo 'subjectKeyIdentifier    = hash'
  1406.             echo 'subjectAltName          = $ENV::SAN'
  1407.         } >> $outputFile
  1408.     }
  1409.        
  1410.    
  1411.     modulCsrSoftwareConfig()
  1412.     {
  1413.         local outputFile=$1
  1414.         local domain=$2
  1415.        
  1416.         {
  1417.             makeModulCsrConfigBlock_title $outputFile $domain 'Software'
  1418.             echo '[ req ]'
  1419.             echo "default_bits            = $DEFAULT_CRT_RSA_KEYSIZE_REQUEST                  # RSA key size"
  1420.             echo 'encrypt_key             = yes                   # Protect private key'
  1421.             echo "default_md              = $DEFAULT_CRT_MD_REQUEST                # MD to use"
  1422.             echo 'utf8                    = yes                   # Input is UTF-8'
  1423.             echo 'string_mask             = utf8only              # Emit UTF-8 strings'
  1424.             echo 'prompt                  = yes                   # Prompt for DN'
  1425.             echo 'distinguished_name      = codesign_dn           # DN template'
  1426.             echo 'req_extensions          = codesign_reqext       # Desired extensions'
  1427.             echo ''
  1428.             echo '[ codesign_dn ]'
  1429.             echo 'countryName             = "1. Country Name (2 letters) (eg, US)       "'
  1430.             echo 'countryName_max         = 2'
  1431.             echo 'stateOrProvinceName     = "2. State or Province Name   (eg, region)   "'
  1432.             echo 'localityName            = "3. Locality Name            (eg, city)     "'
  1433.             echo 'organizationName        = "4. Organization Name        (eg, company)  "'
  1434.             echo 'organizationalUnitName  = "5. Organizational Unit Name (eg, section)  "'
  1435.             echo 'commonName              = "6. Common Name              (eg, full name)"'
  1436.             echo 'commonName_max          = 64'
  1437.             echo ''
  1438.             echo '[ codesign_reqext ]'
  1439.             echo 'keyUsage                = critical,digitalSignature'
  1440.             echo 'extendedKeyUsage        = critical,codeSigning'
  1441.             echo 'subjectKeyIdentifier    = hash'
  1442.         } >> $outputFile
  1443.     }
  1444.    
  1445.     ##############################################################
  1446.     #
  1447.     # CA config partial factories
  1448.     #
  1449.     ##############################################################
  1450.    
  1451.     makeModulCaConfigBlock_title()
  1452.     {
  1453.         local outputFile=$1
  1454.         local title=$2
  1455.        
  1456.         {
  1457.             echo "# $title"
  1458.             echo ''
  1459.         } >> $outputFile
  1460.     }
  1461.    
  1462.     makeModulCaConfigBlock_section()
  1463.     {
  1464.         local outputFile=$1
  1465.         local title=$2
  1466.        
  1467.         {
  1468.             echo ''
  1469.             echo ''
  1470.             echo "# $title"
  1471.             echo ''
  1472.         } >> $outputFile
  1473.     }
  1474.    
  1475.     makeModulCaConfigBlock_default()
  1476.     {
  1477.         local outputFile=$1
  1478.         local domain=$2
  1479.         local level=$3
  1480.         local type=$4
  1481.        
  1482.         {
  1483.             echo '[ default ]'
  1484.             echo "ca                      = $domain"
  1485.             echo "ca_type                 = $type"
  1486.             echo 'ca_dir                  = $ca_type'
  1487.             echo "db_dir                  = \$ca_dir/${DIR_NAME[db]}"
  1488.             echo "private_dir             = \$ca_dir/${DIR_NAME[private]}"
  1489.             echo "dir                     = \$ENV::CA_${level}_SCRIPT_PATH  # Top dir"
  1490.             echo "base_url                = http://$domain # CA base URL"
  1491.             echo "ip_url                  = http://$DEFAULT_IP # CA base URL on IP"
  1492.             echo 'aia_url                 = $base_url/$ca.$ca_type.cer       # CA certificate URL'
  1493.             echo 'ip_aia_url              = $ip_url/$ca.$ca_type.cer         # CA certificate URL'
  1494.             echo 'crl_url                 = $base_url/$ca.$ca_type.crl       # CRL distribution point'
  1495.             echo 'ip_crl_url              = $ip_url/$ca.$ca_type.cer         # CRL distribution point'
  1496.             echo 'name_opt                = multiline,-esc_msb,utf8 # Display UTF-8 characters'
  1497.             echo ''
  1498.         } >> $outputFile
  1499.     }
  1500.    
  1501.    
  1502.     makeModulCaConfigBlock_req()
  1503.     {
  1504.         local outputFile=$1
  1505.        
  1506.         {
  1507.             echo '[ req ]'
  1508.             echo "default_bits            = $DEFAULT_CA_RSA_KEYSIZE_REQUEST                 # RSA key size"
  1509.             echo 'encrypt_key             = yes                   # Protect private key'
  1510.             echo "default_md              = $DEFAULT_CA_MD_REQUEST                # MD to use"
  1511.             echo 'utf8                    = yes                   # Input is UTF-8'
  1512.             echo 'string_mask             = utf8only              # Emit UTF-8 strings'
  1513.             echo 'prompt                  = no                    # Dont prompt for DN'
  1514.             echo 'distinguished_name      = ca_dn                 # DN section'
  1515.             echo 'req_extensions          = ca_reqext             # Desired extensions'
  1516.             echo ''
  1517.         } >> $outputFile
  1518.     }
  1519.    
  1520.     makeModulCaConfigBlock_ca_dn()
  1521.     {
  1522.         local outputFile=$1
  1523.         local oN=$2
  1524.         local cN=$3
  1525.        
  1526.         {
  1527.             echo '[ ca_dn ]'
  1528.             echo 'countryName             = "BE"'
  1529.             echo "organizationName        = \""### Network $oN\"""
  1530.             echo 'organizationalUnitName  = "interop"'
  1531.             echo "commonName              = \""### Network $cN\"""
  1532.             echo ''
  1533.         } >> $outputFile
  1534.     }
  1535.    
  1536.     makeModulCaConfigBlock_ca_reqext()
  1537.     {
  1538.         local outputFile=$1
  1539.         local case=$2
  1540.        
  1541.         if [ "$case" == 'signing' ]; then
  1542.             {
  1543.                 echo '[ ca_reqext ]'
  1544.                 echo 'keyUsage                = critical,keyCertSign,cRLSign'
  1545.                 echo 'basicConstraints        = critical,CA:true,pathlen:0'
  1546.                 echo 'subjectKeyIdentifier    = hash'
  1547.                 echo ''
  1548.             } >> $outputFile
  1549.         else
  1550.             {
  1551.                 echo '[ ca_reqext ]'
  1552.                 echo 'keyUsage                = critical,keyCertSign,cRLSign'
  1553.                 echo 'basicConstraints        = critical,CA:true'
  1554.                 echo 'subjectKeyIdentifier    = hash'
  1555.                 echo ''
  1556.             } >> $outputFile
  1557.         fi
  1558.     }
  1559.    
  1560.     makeModulCaConfigBlock_ca()
  1561.     {
  1562.         local outputFile=$1
  1563.         local defaultCa=$2
  1564.         local x509_extensions=$3
  1565.         local copy_extensions=$4
  1566.         local policy=$5
  1567.         local days=$6
  1568.         local crlDays=$7
  1569.        
  1570.         local keyFileFormat=$(printf ${FILE_NAME[key]} '$ca' '$ca_type')
  1571.         local crtSrlFileFormat=$(printf ${FILE_NAME[crtSrl]} '$ca' '$ca_type')
  1572.         local crlSrlFileFormat=$(printf ${FILE_NAME[crlSrl]} '$ca' '$ca_type')
  1573.         local crtDbFileFormat=$(printf ${FILE_NAME[crtDb]} '$ca' '$ca_type')
  1574.         local crtFileFormat=$(printf ${FILE_NAME[crt]} '$ca' '$ca_type')
  1575.        
  1576.         local pDir='$dir/$private_dir'
  1577.         local dDir='$dir/$db_dir'
  1578.        
  1579.         {
  1580.             echo '[ ca ]'
  1581.             echo "default_ca              = $defaultCa # The default CA section"
  1582.             echo ''
  1583.             echo "[ $defaultCa ]"
  1584.             echo "certificate             = \$dir/$crtFileFormat                   # The CA cert"
  1585.             echo 'new_certs_dir           = $dir/$ca_dir                            # Certificate archive'
  1586.             echo "private_key             = $pDir/$keyFileFormat        # CA private key"
  1587.             echo "serial                  = $dDir/$crtSrlFileFormat       # Serial number file"
  1588.             echo "crlnumber               = $dDir/$crlSrlFileFormat       # CRL number file"
  1589.             echo "database                = $dDir/$crtDbFileFormat        # Index file"
  1590.             echo 'unique_subject          = yes                  # Require unique subject'
  1591.             echo "default_days            = $days          # How long to certify for"
  1592.             echo "default_md              = $DEFAULT_CA_MD                  # MD to use"
  1593.             echo "policy                  = $policy             # Default naming policy"
  1594.             echo 'email_in_dn             = no                    # Add email to cert DN'
  1595.             echo 'preserve                = yes                    # Keep passed DN ordering'
  1596.             echo 'name_opt                = $name_opt             # Subject DN display options'
  1597.             echo 'cert_opt                = ca_default            # Certificate display options'
  1598.             echo "copy_extensions         = $copy_extensions                  # Copy extensions from CSR"
  1599.             echo "x509_extensions         = $x509_extensions          # Default cert extensions"
  1600.             echo "default_crl_days        = $crlDays                    # How long before next CRL"
  1601.             echo 'crl_extensions          = crl_ext               # CRL extensions'
  1602.             echo ''
  1603.         } >> $outputFile
  1604.     }
  1605.    
  1606.    
  1607.    
  1608.     ##############################################################
  1609.     #
  1610.     # CA config factories
  1611.     #
  1612.     ##############################################################
  1613.    
  1614.     # args: out file, domain, nesting level (required for $ENV)
  1615.     modulCaConfig()
  1616.     {
  1617.         local outputFile=$1
  1618.         local domain=$2
  1619.         local level=$3
  1620.        
  1621.         if [ -z "$3" ]; then
  1622.             level=0
  1623.         fi
  1624.        
  1625.         local suffix='Certificate Authority'
  1626.         if [ $level == '0' ]; then
  1627.             suffix="Root $suffix"
  1628.         fi
  1629.        
  1630.         makeModulCaConfigBlock_title            $outputFile "Network $domain $suffix"
  1631.         makeModulCaConfigBlock_default          $outputFile $domain $level 'ca'
  1632.         makeModulCaConfigBlock_section          $outputFile 'CA certificate request'
  1633.         makeModulCaConfigBlock_req              $outputFile
  1634.         makeModulCaConfigBlock_ca_dn            $outputFile $domain "$domain $suffix"
  1635.         makeModulCaConfigBlock_ca_reqext        $outputFile
  1636.         makeModulCaConfigBlock_section          $outputFile 'CA operational settings'
  1637.         makeModulCaConfigBlock_ca               $outputFile 'root_ca' 'server_ext' 'none' 'root_ca_pol' '730' '365'
  1638.        
  1639.         {
  1640.             echo '[ root_ca_pol ]'
  1641.             echo 'countryName             = match                 # Must match'
  1642.             echo 'stateOrProvinceName     = optional              # Included if present'
  1643.             echo 'localityName            = optional              # Included if present'
  1644.             echo 'organizationName        = match                 # Must match'
  1645.             echo 'organizationalUnitName  = optional              # Included if present'
  1646.             echo 'commonName              = match                 # Must match'
  1647.             echo ''
  1648.             echo '[ extension_ca_pol ]'
  1649.             echo 'countryName             = match                 # Must match'
  1650.             echo 'stateOrProvinceName     = optional              # Included if present'
  1651.             echo 'localityName            = optional              # Included if present'
  1652.             echo 'organizationName        = match                 # Must match'
  1653.             echo 'organizationalUnitName  = optional              # Included if present'
  1654.             echo 'commonName              = supplied              # Must be present'
  1655.             echo ''
  1656.             echo '[ intermediate_ca_pol ]'
  1657.             echo 'countryName             = supplied              # Must be present'
  1658.             echo 'stateOrProvinceName     = optional              # Included if present'
  1659.             echo 'localityName            = optional              # Included if present'
  1660.             echo 'organizationName        = supplied              # Must be present'
  1661.             echo 'organizationalUnitName  = optional              # Included if present'
  1662.             echo 'commonName              = supplied              # Must be present'
  1663.             echo ''
  1664.             echo ''
  1665.             echo '# Extensions'
  1666.             echo ''
  1667.             echo '[ root_ca_ext ]'
  1668.             echo 'keyUsage                = critical,keyCertSign,cRLSign'
  1669.             echo 'basicConstraints        = critical,CA:true'
  1670.             echo 'subjectKeyIdentifier    = hash'
  1671.             echo 'authorityKeyIdentifier  = keyid:always'
  1672.             echo ''
  1673.             echo '[ signing_ca_ext ]'
  1674.             echo 'keyUsage                = critical,keyCertSign,cRLSign'
  1675.             echo 'basicConstraints        = critical,CA:true,pathlen:0'
  1676.             echo 'subjectKeyIdentifier    = hash'
  1677.             echo 'authorityKeyIdentifier  = keyid:always'
  1678.             echo 'authorityInfoAccess     = @issuer_info'
  1679.             echo 'crlDistributionPoints   = @crl_info'
  1680.             echo ''
  1681.             echo '[ crl_ext ]'
  1682.             echo 'authorityKeyIdentifier  = keyid:always'
  1683.             echo 'authorityInfoAccess     = @issuer_info'
  1684.             echo ''
  1685.             echo '[ issuer_info ]'
  1686.             echo 'caIssuers;URI.0         = $aia_url'
  1687.             echo 'caIssuers;URI.1         = $ip_aia_url'
  1688.             echo ''
  1689.             echo '[ crl_info ]'
  1690.             echo 'URI.0                   = $crl_url'
  1691.             echo 'URI.1                   = $ip_crl_url'
  1692.         } >> $outputFile
  1693.     }
  1694.    
  1695.     # args: out file, domain, nesting level (required for $ENV)
  1696.     modulCaTlsConfig()
  1697.     {
  1698.         local outputFile=$1
  1699.         local domain=$2
  1700.         local level=$3
  1701.        
  1702.         makeModulCaConfigBlock_title            $outputFile "Network $domain TLS Registration Authority"
  1703.         makeModulCaConfigBlock_default          $outputFile $domain $level 'ca-tls'
  1704.         makeModulCaConfigBlock_section          $outputFile 'CA certificate request'
  1705.         makeModulCaConfigBlock_req              $outputFile
  1706.         makeModulCaConfigBlock_ca_dn            $outputFile $domain "$domain TLS Registration Authority"
  1707.         makeModulCaConfigBlock_ca_reqext        $outputFile 'signing'
  1708.         makeModulCaConfigBlock_section          $outputFile 'CA operational settings'
  1709.         makeModulCaConfigBlock_ca               $outputFile 'tls_ca' 'server_ext' 'copy' 'match_pol' '730' '1'
  1710.        
  1711.         {
  1712.             echo '[ match_pol ]'
  1713.             echo 'countryName             = match                 # Must match NO'
  1714.             echo 'stateOrProvinceName     = optional              # Included if present'
  1715.             echo 'localityName            = optional              # Included if present'
  1716.             echo 'organizationName        = match                 # Must match Green AS'
  1717.             echo 'organizationalUnitName  = optional              # Included if present'
  1718.             echo 'commonName              = supplied              # Must be present'
  1719.             echo ''
  1720.             echo '[ extern_pol ]'
  1721.             echo 'countryName             = supplied              # Must be present'
  1722.             echo 'stateOrProvinceName     = optional              # Included if present'
  1723.             echo 'localityName            = optional              # Included if present'
  1724.             echo 'organizationName        = supplied              # Must be present'
  1725.             echo 'organizationalUnitName  = optional              # Included if present'
  1726.             echo 'commonName              = supplied              # Must be present'
  1727.             echo ''
  1728.             echo '[ any_pol ]'
  1729.             echo 'domainComponent         = optional'
  1730.             echo 'countryName             = optional'
  1731.             echo 'stateOrProvinceName     = optional'
  1732.             echo 'localityName            = optional'
  1733.             echo 'organizationName        = optional'
  1734.             echo 'organizationalUnitName  = optional'
  1735.             echo 'commonName              = optional'
  1736.             echo 'emailAddress            = optional'
  1737.             echo ''
  1738.             echo ''
  1739.             echo '# Extensions'
  1740.             echo ''
  1741.             echo '[ server_ext ]'
  1742.             echo 'keyUsage                = critical,digitalSignature,keyEncipherment'
  1743.             echo 'basicConstraints        = critical,CA:false'
  1744.             echo 'extendedKeyUsage        = serverAuth,clientAuth'
  1745.             echo 'subjectKeyIdentifier    = hash'
  1746.             echo 'authorityKeyIdentifier  = keyid:always'
  1747.             echo 'authorityInfoAccess     = @issuer_info'
  1748.             echo 'crlDistributionPoints   = @crl_info'
  1749.             echo ''
  1750.             echo '[ client_ext ]'
  1751.             echo 'keyUsage                = critical,digitalSignature'
  1752.             echo 'basicConstraints        = critical,CA:false'
  1753.             echo 'extendedKeyUsage        = clientAuth'
  1754.             echo 'subjectKeyIdentifier    = hash'
  1755.             echo 'authorityKeyIdentifier  = keyid:always'
  1756.             echo 'authorityInfoAccess     = @issuer_info'
  1757.             echo 'crlDistributionPoints   = @crl_info'
  1758.             echo ''
  1759.             echo '[ crl_ext ]'
  1760.             echo 'authorityKeyIdentifier  = keyid:always'
  1761.             echo 'authorityInfoAccess     = @issuer_info'
  1762.             echo ''
  1763.             echo '[ issuer_info ]'
  1764.             echo 'caIssuers;URI.0         = $aia_url'
  1765.             echo ''
  1766.             echo '[ crl_info ]'
  1767.             echo 'URI.0                   = $crl_url'
  1768.         } >> $outputFile
  1769.     }
  1770.    
  1771.     # args: out file, domain, nesting level (required for $ENV)
  1772.     modulCaEmailConfig()
  1773.     {
  1774.         local outputFile=$1
  1775.         local domain=$2
  1776.         local level=$3
  1777.        
  1778.         makeModulCaConfigBlock_title            $outputFile "Network $domain Email Registration Authority"
  1779.         makeModulCaConfigBlock_default          $outputFile $domain $level 'ca-email'
  1780.         makeModulCaConfigBlock_section          $outputFile 'CA certificate request'
  1781.         makeModulCaConfigBlock_req              $outputFile
  1782.         makeModulCaConfigBlock_ca_dn            $outputFile $domain "$domain Email Registration Authority"
  1783.         makeModulCaConfigBlock_ca_reqext        $outputFile 'signing'
  1784.         makeModulCaConfigBlock_section          $outputFile 'CA operational settings'
  1785.         makeModulCaConfigBlock_ca               $outputFile 'email_ca' 'email_ext' 'copy' 'match_pol' '730' '1'
  1786.        
  1787.         {
  1788.             echo '[ match_pol ]'
  1789.             echo 'countryName             = match                 # Must match NO'
  1790.             echo 'stateOrProvinceName     = optional              # Included if present'
  1791.             echo 'localityName            = optional              # Included if present'
  1792.             echo 'organizationName        = match                 # Must match Green AS'
  1793.             echo 'organizationalUnitName  = optional              # Included if present'
  1794.             echo 'commonName              = supplied              # Must be present'
  1795.             echo ''
  1796.             echo '[ any_pol ]'
  1797.             echo 'domainComponent         = optional'
  1798.             echo 'countryName             = optional'
  1799.             echo 'stateOrProvinceName     = optional'
  1800.             echo 'localityName            = optional'
  1801.             echo 'organizationName        = optional'
  1802.             echo 'organizationalUnitName  = optional'
  1803.             echo 'commonName              = optional'
  1804.             echo 'emailAddress            = optional'
  1805.             echo ''
  1806.             echo ''
  1807.             echo '# Extensions'
  1808.             echo ''
  1809.             echo '[ email_ext ]'
  1810.             echo 'keyUsage                = critical,digitalSignature,keyEncipherment'
  1811.             echo 'basicConstraints        = CA:false'
  1812.             echo 'extendedKeyUsage        = emailProtection,clientAuth,anyExtendedKeyUsage'
  1813.             echo 'subjectKeyIdentifier    = hash'
  1814.             echo 'authorityKeyIdentifier  = keyid:always'
  1815.             echo 'authorityInfoAccess     = @issuer_info'
  1816.             echo 'crlDistributionPoints   = @crl_info'
  1817.             echo ''
  1818.             echo '[ crl_ext ]'
  1819.             echo 'authorityKeyIdentifier  = keyid:always'
  1820.             echo 'authorityInfoAccess     = @issuer_info'
  1821.             echo ''
  1822.             echo '[ issuer_info ]'
  1823.             echo 'caIssuers;URI.0         = $aia_url'
  1824.             echo ''
  1825.             echo '[ crl_info ]'
  1826.             echo 'URI.0                   = $crl_url'
  1827.         } >> $outputFile
  1828.     }
  1829.    
  1830.     # args: out file, domain, nesting level (required for $ENV)
  1831.     modulCaSoftwareConfig()
  1832.     {
  1833.         local outputFile=$1
  1834.         local domain=$2
  1835.         local level=$3
  1836.        
  1837.         makeModulCaConfigBlock_title            $outputFile "Network $domain Software Registration Authority"
  1838.         makeModulCaConfigBlock_default          $outputFile $domain $level 'ca-software'
  1839.         makeModulCaConfigBlock_section          $outputFile 'CA certificate request'
  1840.         makeModulCaConfigBlock_req              $outputFile
  1841.         makeModulCaConfigBlock_ca_dn            $outputFile $domain "$domain Software Registration Authority"
  1842.         makeModulCaConfigBlock_ca_reqext        $outputFile 'signing'
  1843.         makeModulCaConfigBlock_section          $outputFile 'CA operational settings'
  1844.         makeModulCaConfigBlock_ca               $outputFile 'software_ca' 'codesign_ext' 'copy' 'match_pol' '1826' '30'
  1845.        
  1846.         {
  1847.             echo '[ match_pol ]'
  1848.             echo 'countryName             = match                 # Must match NO'
  1849.             echo 'stateOrProvinceName     = optional              # Included if present'
  1850.             echo 'localityName            = optional              # Included if present'
  1851.             echo 'organizationName        = match                 # Must match Green AS'
  1852.             echo 'organizationalUnitName  = optional              # Included if present'
  1853.             echo 'commonName              = supplied              # Must be present'
  1854.             echo ''
  1855.             echo '[ any_pol ]'
  1856.             echo 'domainComponent         = optional'
  1857.             echo 'countryName             = optional'
  1858.             echo 'stateOrProvinceName     = optional'
  1859.             echo 'localityName            = optional'
  1860.             echo 'organizationName        = optional'
  1861.             echo 'organizationalUnitName  = optional'
  1862.             echo 'commonName              = optional'
  1863.             echo 'emailAddress            = optional'
  1864.             echo ''
  1865.             echo ''
  1866.             echo '# Extensions'
  1867.             echo ''
  1868.             echo '[ codesign_ext ]'
  1869.             echo 'keyUsage                = critical,digitalSignature'
  1870.             echo 'basicConstraints        = CA:false'
  1871.             echo 'extendedKeyUsage        = critical,codeSigning'
  1872.             echo 'subjectKeyIdentifier    = hash'
  1873.             echo 'authorityKeyIdentifier  = keyid:always'
  1874.             echo 'authorityInfoAccess     = @issuer_info'
  1875.             echo 'crlDistributionPoints   = @crl_info'
  1876.             echo ''
  1877.             echo '[ crl_ext ]'
  1878.             echo 'authorityKeyIdentifier  = keyid:always'
  1879.             echo 'authorityInfoAccess     = @issuer_info'
  1880.             echo ''
  1881.             echo '[ issuer_info ]'
  1882.             echo 'caIssuers;URI.0         = $aia_url'
  1883.             echo ''
  1884.             echo '[ crl_info ]'
  1885.             echo 'URI.0                   = $crl_url'
  1886.         } >> $outputFile
  1887.     }
  1888.    
  1889.     ##############################################################
  1890.     #
  1891.     # more factories!!!
  1892.     #
  1893.     ##############################################################
  1894.    
  1895.     makeConfigFile()
  1896.     {
  1897.         local domain=$1
  1898.         local modul=$2
  1899.         local outputFile=$3
  1900.         local level=$4
  1901.        
  1902.         if [ ! -e "$outputFile" ]; then
  1903.             writeNewItem "CA config $modul"
  1904.             eval $modul $outputFile $domain $level
  1905.             check_result $? 'unable to create config'
  1906.         fi
  1907.     }
  1908.    
  1909.     makeCsrConfigFile()
  1910.     {
  1911.         local domain=$1
  1912.         local modul=$2
  1913.         local outputFile=$3
  1914.        
  1915.         if [ ! -e "$outputFile" ]; then
  1916.             writeNewItem "certificate request config $modul"
  1917.             eval $modul $outputFile $domain
  1918.             check_result $? 'unable to create config'
  1919.         fi
  1920.     }
  1921.    
  1922.     makeUserTlsCsrFiles()
  1923.     {
  1924.         local domain=$1
  1925.         local cnfPath=$2
  1926.        
  1927.         makeCsrConfigFile \
  1928.             $domain \
  1929.             'modulCsrTlsClientConfig' \
  1930.             $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-client')
  1931.        
  1932.         makeCsrConfigFile \
  1933.             $domain \
  1934.             'modulCsrTlsClientExternalConfig' \
  1935.             $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-client-external')
  1936.            
  1937.         makeCsrConfigFile \
  1938.             $domain \
  1939.             'modulCsrTlsServerConfig' \
  1940.             $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-server')
  1941.            
  1942.         makeCsrConfigFile \
  1943.             $domain \
  1944.             'modulCsrTlsServerExternalConfig' \
  1945.             $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'tls-server-external')
  1946.     }
  1947.    
  1948.     makeUserSoftwareCsrFiles()
  1949.     {
  1950.         local domain=$1
  1951.         local cnfPath=$2
  1952.        
  1953.         makeCsrConfigFile \
  1954.             $domain \
  1955.             'modulCsrSoftwareConfig' \
  1956.             $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'code-signing')
  1957.     }
  1958.    
  1959.     makeUserEmailCsrFiles()
  1960.     {
  1961.         local domain=$1
  1962.         local cnfPath=$2
  1963.        
  1964.         makeCsrConfigFile \
  1965.             $domain \
  1966.             'modulCsrEmailConfig' \
  1967.             $cnfPath/$(printf ${FILE_NAME[cnf]} $domain 'email')
  1968.     }
  1969.    
  1970.     makePasswordFile()
  1971.     {
  1972.         local domain=$1
  1973.         local pwdFile=$2
  1974.        
  1975.         if [ ! -e $pwdFile ]; then
  1976.             writeNewItem 'pass'
  1977.             openssl genpkey \
  1978.                 -algorithm RSA \
  1979.                 -out $pwdFile \
  1980.                 -pkeyopt rsa_keygen_bits:$DEFAULT_CA_RSA_KEYSIZE_PASSWORD \
  1981.                 -pkeyopt rsa_keygen_pubexp:$DEFAULT_CA_PWD_GEN_PUBEXP
  1982.             check_result $? 'unable to create password'
  1983.         fi
  1984.     }
  1985.    
  1986.     makeKeyFile()
  1987.     {
  1988.         local domain=$1
  1989.         local keyFile=$2
  1990.         local pwdFile=$3
  1991.        
  1992.         if [ ! -e $keyFile ]; then
  1993.             writeNewItem 'key'
  1994.             openssl genrsa -aes256 \
  1995.                 -passout file:$pwdFile \
  1996.                 -out $keyFile $DEFAULT_CA_RSA_KEYSIZE_PRIVATE_KEY
  1997.             check_result $? 'unable to create private key'
  1998.         fi
  1999.     }
  2000.    
  2001.     makeDbFiles()
  2002.     {
  2003.         local domain=$1
  2004.         local database=$2
  2005.         local crtSerial=$3
  2006.         local crlSerial=$4
  2007.        
  2008.         local time=$(date +%Y%m%d%H%M%S)001
  2009.         local hex=$(echo "obase=16; $time" | bc)
  2010.        
  2011.         if [ ! -e $database ]; then
  2012.             writeNewItem 'database files'
  2013.             touch $database
  2014.             check_result $? 'unable to create database index'
  2015.             writeNewItem 'crt serial'
  2016.             echo $hex > $crtSerial
  2017.             check_result $? 'unable to create crt serial'
  2018.             writeNewItem 'crl serial'
  2019.             echo $hex > $crlSerial
  2020.             check_result $? 'unable to create crl serial'
  2021.         fi
  2022.     }
  2023.    
  2024.     makeCsrFile()
  2025.     {
  2026.         local domain=$1
  2027.         local cnfFile=$2
  2028.         local csrFile=$3
  2029.         local keyFile=$4
  2030.         local pwdFile=$5
  2031.        
  2032.         if [ ! -e $csrFile ]; then
  2033.             writeNewItem 'csr'
  2034.             openssl req -new \
  2035.                 -config $cnfFile \
  2036.                 -out $csrFile \
  2037.                 -key $keyFile -passin file:$pwdFile \
  2038.                     > /dev/null 2>&1
  2039.             check_result $? 'unable to create csr'
  2040.         fi
  2041.     }
  2042.    
  2043.     makeCrtFile()
  2044.     {
  2045.         local domain=$1
  2046.         local cnfFile=$2
  2047.         local csrFile=$3
  2048.         local crtFile=$4
  2049.         local pwdFile=$5
  2050.         local case=$6
  2051.        
  2052.         if [ ! -e $crtFile ]; then
  2053.             writeNewItem 'crt'
  2054.            
  2055.             if [ "$case" == 'root_ca' ]; then
  2056.                 openssl ca -selfsign -batch \
  2057.                     -config $cnfFile \
  2058.                     -in $csrFile \
  2059.                     -passin file:$pwdFile \
  2060.                     -out $crtFile \
  2061.                     -extensions root_ca_ext \
  2062.                     -enddate 20820508235959Z \
  2063.                         > /dev/null 2>&1
  2064.                 check_result $? 'unable to create crt'
  2065.             fi
  2066.            
  2067.             if [ "$case" == 'intermediate_ca' ]; then
  2068.                 openssl ca -batch \
  2069.                     -config $cnfFile \
  2070.                     -in $csrFile \
  2071.                     -passin file:$pwdFile \
  2072.                     -out $crtFile \
  2073.                     -extensions root_ca_ext \
  2074.                     -policy intermediate_ca_pol \
  2075.                     -enddate 20820508235959Z \
  2076.                         > /dev/null 2>&1
  2077.                 check_result $? 'unable to create crt'
  2078.             fi
  2079.            
  2080.             if [ "$case" == 'signing_ca' ]; then
  2081.                 openssl ca -batch \
  2082.                     -config $cnfFile \
  2083.                     -in $csrFile \
  2084.                     -passin file:$pwdFile \
  2085.                     -out $crtFile \
  2086.                     -extensions signing_ca_ext \
  2087.                     -policy extension_ca_pol \
  2088.                     -enddate 20820508235959Z \
  2089.                         > /dev/null 2>&1
  2090.                 check_result $? 'unable to create crt'
  2091.             fi
  2092.         fi
  2093.     }
  2094.    
  2095.     makeCrlFile()
  2096.     {
  2097.         local domain=$1
  2098.         local cnfFile=$2
  2099.         local crlFile=$3
  2100.         local pwdFile=$4
  2101.        
  2102.         if [ ! -e $crlFile ]; then
  2103.             writeNewItem 'crl'
  2104.             openssl ca -gencrl \
  2105.                 -config $cnfFile \
  2106.                 -passin file:$pwdFile \
  2107.                 -out $crlFile \
  2108.                     > /dev/null 2>&1
  2109.                 check_result $? 'unable to create crl'
  2110.            
  2111.         fi
  2112.     }
  2113.    
  2114.     makeChain()
  2115.     {
  2116.         local domain=$1
  2117.         local child=$2
  2118.         local parents=$3
  2119.         local chainPemFile=$4
  2120.         local chainP7cFile=$5
  2121.        
  2122.         if [ ! -e $chainPemFile ]; then
  2123.             writeNewItem 'pem chain'
  2124.             cat $child $parents > $chainPemFile
  2125.             check_result $? 'unable to create pem chain'
  2126.         fi
  2127.        
  2128.     }
  2129.    
  2130.     # All published certificates must be in DER format.
  2131.     # MIME type: application/pkix-cert. [RFC 2585#section-4.1]
  2132.     publishCrt()
  2133.     {
  2134.         local fromCrt=$1
  2135.         local toDer=$2
  2136.        
  2137.         rm $toDer > /dev/null 2>&1
  2138.        
  2139.         writeNewItem 'publish crt as application/pkix-cert'
  2140.         openssl x509 \
  2141.             -in $fromCrt \
  2142.             -out $toDer \
  2143.             -outform der
  2144.         check_result $? 'unable to create cer file'
  2145.     }
  2146.    
  2147.     # All published CRLs must be in DER format.
  2148.     # MIME type: application/pkix-crl. [RFC 2585#section-4.2]
  2149.     publishCACrl()
  2150.     {
  2151.         local fromCrl=$1
  2152.         local toDer=$2
  2153.        
  2154.         rm $toDer > /dev/null 2>&1
  2155.        
  2156.         writeNewItem 'publish crl as application/pkix-crl'
  2157.         openssl crl \
  2158.                 -in $fromCrl \
  2159.                 -out $toDer \
  2160.                 -outform der
  2161.         check_result $? 'unable to create der crl file'
  2162.     }
  2163.    
  2164.     # PKCS#7 is used to bundle two or more certificates.
  2165.     # MIME type: application/pkcs7-mime. [RFC 5273#page-3]
  2166.     publishCAChain()
  2167.     {
  2168.         local fromChainPem=$1
  2169.         local toChainP7c=$2
  2170.        
  2171.         rm $toChainP7c > /dev/null 2>&1
  2172.        
  2173.         writeNewItem 'publish pem chain as application/pkcs7-mime'
  2174.         openssl crl2pkcs7 -nocrl \
  2175.             -certfile $fromChainPem \
  2176.             -out $toChainP7c \
  2177.             -outform der
  2178.         check_result $? 'unable to create p7c chain file'
  2179.     }
  2180.    
  2181.     ##############################################################
  2182.     #
  2183.     # CA factories
  2184.     #
  2185.     ##############################################################
  2186.    
  2187.     #
  2188.     # the root! rooooooooooot!
  2189.     #
  2190.     # note: we need the env var for openssl config
  2191.     #
  2192.     # ./reverse root CA
  2193.     #
  2194.     makeRootCa()
  2195.     {
  2196.         local domain=$1
  2197.         local baseDir=$2
  2198.         local cnfFile=$3
  2199.         local csrFile=$4
  2200.         local keyFile=$5
  2201.         local pwdFile=$6
  2202.         local crtFile=$7
  2203.         local crlFile=$8
  2204.        
  2205.         export CA_0_SCRIPT_PATH="$baseDir"
  2206.        
  2207.         makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile
  2208.         makeCrtFile $domain $cnfFile $csrFile $crtFile $pwdFile 'root_ca'
  2209.         makeCrlFile $domain $cnfFile $crlFile $pwdFile
  2210.     }
  2211.    
  2212.     #
  2213.     # intermediate CA level 1
  2214.     #
  2215.     # note: we need the env vars for openssl config
  2216.     #
  2217.     # ./reverse/domain root CA
  2218.     #
  2219.     makeIntermediateCa()
  2220.     {
  2221.         local domain=$1
  2222.         local baseDir=$2
  2223.         local cnfFile=$3
  2224.         local csrFile=$4
  2225.         local keyFile=$5
  2226.         local pwdFile=$6
  2227.         local crtFile=$7
  2228.         local crlFile=$8
  2229.         local chainPemFile=$9
  2230.         local rootBaseDir=${10}
  2231.         local rootCnfFile=${11}
  2232.         local rootPwdFile=${12}
  2233.         local rootCrtFile=${13}
  2234.        
  2235.         export CA_1_SCRIPT_PATH="$baseDir"
  2236.         export CA_0_SCRIPT_PATH="$rootBaseDir"
  2237.        
  2238.         makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile
  2239.         makeCrtFile $domain $rootCnfFile $csrFile $crtFile $rootPwdFile 'intermediate_ca'
  2240.         makeCrlFile $domain $cnfFile $crlFile $pwdFile
  2241.         makeChain   $domain $crtFile $rootCrtFile $chainPemFile
  2242.     }
  2243.    
  2244.     #
  2245.     # intermediate CA level 2
  2246.     #
  2247.     # note: we need the env vars for openssl config
  2248.     #
  2249.     # ./reverse/domain/subdomain root CA
  2250.     #
  2251.     makeIntermediateIntermediateCa()
  2252.     {
  2253.         local domain=$1
  2254.         local baseDir=$2
  2255.         local cnfFile=$3
  2256.         local csrFile=$4
  2257.         local keyFile=$5
  2258.         local pwdFile=$6
  2259.         local crtFile=$7
  2260.         local crlFile=$8
  2261.         local chainPemFile=$9
  2262.         local rootBaseDir=${10}
  2263.         local rootCnfFile=${11}
  2264.         local rootPwdFile=${12}
  2265.         local rootCrtFile=${13}
  2266.        
  2267.         export CA_2_SCRIPT_PATH="$baseDir"
  2268.         export CA_1_SCRIPT_PATH="$rootBaseDir"
  2269.        
  2270.         makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile
  2271.         makeCrtFile $domain $rootCnfFile $csrFile $crtFile $rootPwdFile 'intermediate_ca'
  2272.         makeCrlFile $domain $cnfFile $crlFile $pwdFile
  2273.         makeChain   $domain $crtFile $rootCrtFile $chainPemFile
  2274.     }
  2275.    
  2276.     #
  2277.     # signing CA
  2278.     #
  2279.     # note: we need the env var for openssl config
  2280.     #
  2281.     # ./reverse-tls
  2282.     # ./reverse/domain-[tls|email|software]
  2283.     # ./reverse/domain/subdomain-[tls|email|software]
  2284.     #
  2285.     makeSigningCa()
  2286.     {
  2287.         local domain=$1
  2288.         local baseDir=$2
  2289.         local cnfFile=$3
  2290.         local csrFile=$4
  2291.         local keyFile=$5
  2292.         local pwdFile=$6
  2293.         local crtFile=$7
  2294.         local crlFile=$8
  2295.         local chainPemFile=$9
  2296.         local rootCnfFile=${10}
  2297.         local rootPwdFile=${11}
  2298.         local rootCrtFile=${12}
  2299.        
  2300.         export CA_0_SCRIPT_PATH="$baseDir"
  2301.        
  2302.         makeCsrFile $domain $cnfFile $csrFile $keyFile $pwdFile
  2303.         makeCrtFile $domain $rootCnfFile $csrFile $crtFile $rootPwdFile 'signing_ca'
  2304.         makeCrlFile $domain $cnfFile $crlFile $pwdFile
  2305.         makeChain   $domain $crtFile $rootCrtFile $chainPemFile
  2306.     }
  2307.    
  2308.    
  2309.     ##############################################################
  2310.     #
  2311.     # output
  2312.     #
  2313.     ##############################################################
  2314.    
  2315.     #
  2316.     # LEVEL 0 (reverse)
  2317.     #
  2318.    
  2319.     declare -A LEVEL0
  2320.     LEVEL0[domain]=$reverseHost
  2321.     LEVEL0[path]="$SCRIPT_PATH/$reverseHost"
  2322.    
  2323.     declare -A LEVEL0_PATH
  2324.     # lookup table
  2325.     LEVEL0_PATH[lookup]=${LEVEL0[path]}/${DIR_NAME[lookup]}
  2326.     # root ca
  2327.     LEVEL0_PATH[caPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[caPath]}
  2328.     LEVEL0_PATH[caDbPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[dbPath]}
  2329.     LEVEL0_PATH[caCnfPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[cnfPath]}
  2330.     LEVEL0_PATH[caPrvPath]=${LEVEL0[path]}/${DIRECTORIES_CA_ROOT[privatePath]}
  2331.     # tls ca
  2332.     LEVEL0_PATH[caTlsPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[caPath]}
  2333.     LEVEL0_PATH[caTlsDbPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[dbPath]}
  2334.     LEVEL0_PATH[caTlsCnfPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[cnfPath]}
  2335.     LEVEL0_PATH[caTlsPrvPath]=${LEVEL0[path]}/${DIRECTORIES_CA_TLS[privatePath]}
  2336.     # domains
  2337.     LEVEL0_PATH[intermediatePath]=${LEVEL0[path]}/${DIR_NAME[intermediateDir]}
  2338.     # tls crt
  2339.     LEVEL0_PATH[crtTlsPath]=${LEVEL0[path]}/${DIRECTORIES_CRT_TLS[crtPath]}
  2340.     LEVEL0_PATH[crtTlsCnfPath]=${LEVEL0[path]}/${DIRECTORIES_CRT_TLS[cnfPath]}
  2341.     LEVEL0_PATH[crtTlsPrvPath]=${LEVEL0[path]}/${DIRECTORIES_CRT_TLS[privatePath]}
  2342.     # pub
  2343.     LEVEL0_PATH[pub]=${LEVEL0[path]}/${DIR_NAME[public]}
  2344.     LEVEL0_PATH[pubTls]=${LEVEL0[path]}/${DIRECTORIES_PUB[tls]}
  2345.    
  2346.     writeNewCert ${LEVEL0[domain]}
  2347.    
  2348.     writeNewType 'directories'
  2349.     for index in "${!LEVEL0_PATH[@]}"
  2350.     do
  2351.         writeNewItem ${LEVEL0_PATH[$index]}
  2352.         mkdir -p "${LEVEL0_PATH[$index]}" > /dev/null 2>&1
  2353.         check_result $? 'unable to create directory'
  2354.     done
  2355.    
  2356.     ##############################################################
  2357.     #
  2358.     # lookup
  2359.     #
  2360.     # ca=$(head -n 1 $lookup/$domain)
  2361.     #
  2362.     ##############################################################
  2363.     lookupAdd()
  2364.     {
  2365.         local domain=$1
  2366.         local path=$2
  2367.         local lookup=${LEVEL0_PATH[lookup]}
  2368.        
  2369.         writeNewItem "add $domain"
  2370.         rm $lookup/$domain > /dev/null 2>&1
  2371.         echo $path >> $lookup/$domain
  2372.         check_result $? 'unable to add $domain'
  2373.     }
  2374.    
  2375.    
  2376.     writeNewType 'lookup'
  2377.     lookupAdd ${LEVEL0[domain]} ${LEVEL0[path]}
  2378.  
  2379.     writeNewType 'user request configs'
  2380.     makeUserTlsCsrFiles \
  2381.         ${LEVEL0[domain]} \
  2382.         ${LEVEL0_PATH[crtTlsCnfPath]}
  2383.    
  2384.     #
  2385.     # The following part is the worst thing you've ever seen. \o/
  2386.     # Thanks to openssl's path party.
  2387.     #
  2388.    
  2389.     #
  2390.     # root CA
  2391.     #
  2392.     writeNewType 'Root CA'
  2393.     # ./
  2394.     local __0__caCsr=${LEVEL0[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2395.     local __0__caCrt=${LEVEL0[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2396.     # ./ca/db
  2397.     local __0__caCrtDb=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2398.     local __0__caCrtSrl=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2399.     local __0__caCrlSrl=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2400.     local __0__caCrl=${LEVEL0_PATH[caDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2401.     # ./ca/etc
  2402.     local __0__caConfig=${LEVEL0_PATH[caCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2403.     # ./ca/private
  2404.     local __0__caPwd=${LEVEL0_PATH[caPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2405.     local __0__caKey=${LEVEL0_PATH[caPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2406.     # ./public
  2407.     local __0__caCrtDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2408.     local __0__caCrlDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caRoot]})
  2409.    
  2410.     makeConfigFile \
  2411.         ${LEVEL0[domain]} \
  2412.         'modulCaConfig' \
  2413.         $__0__caConfig \
  2414.         '0'
  2415.    
  2416.     makePasswordFile \
  2417.         ${LEVEL0[domain]} \
  2418.         $__0__caPwd
  2419.    
  2420.     makeKeyFile \
  2421.         ${LEVEL0[domain]} \
  2422.         $__0__caKey \
  2423.         $__0__caPwd
  2424.        
  2425.     makeDbFiles \
  2426.         ${LEVEL0[domain]} \
  2427.         $__0__caCrtDb \
  2428.         $__0__caCrtSrl \
  2429.         $__0__caCrlSrl
  2430.        
  2431.     makeRootCa \
  2432.         ${LEVEL0[domain]} \
  2433.         ${LEVEL0[path]} \
  2434.         $__0__caConfig \
  2435.         $__0__caCsr \
  2436.         $__0__caKey \
  2437.         $__0__caPwd \
  2438.         $__0__caCrt \
  2439.         $__0__caCrl
  2440.    
  2441.     publishCrt      $__0__caCrt         $__0__caCrtDer
  2442.     publishCACrl    $__0__caCrl         $__0__caCrlDer
  2443.    
  2444.     #
  2445.     # tls CA
  2446.     #
  2447.     writeNewType 'TLS CA'
  2448.     # ./
  2449.     local __0__tlsCsr=${LEVEL0[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2450.     local __0__tlsCrt=${LEVEL0[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2451.     local __0__tlsChainPem=${LEVEL0[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2452.     # ./ca-tls/db
  2453.     local __0__tlsCrtDb=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2454.     local __0__tlsCrtSrl=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2455.     local __0__tlsCrlSrl=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2456.     local __0__tlsCrl=${LEVEL0_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2457.     # ./ca-tls/etc
  2458.     local __0__tlsConfig=${LEVEL0_PATH[caTlsCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2459.     # ./ca-tls/private
  2460.     local __0__tlsPwd=${LEVEL0_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2461.     local __0__tlsKey=${LEVEL0_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2462.     # ./public
  2463.     local __0__tlsChainP7c=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2464.     local __0__tlsCrtDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2465.     local __0__tlsCrlDer=${LEVEL0_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL0[domain]} ${DIR_NAME[caTls]})
  2466.    
  2467.     makeConfigFile \
  2468.         ${LEVEL0[domain]} \
  2469.         'modulCaTlsConfig' \
  2470.         $__0__tlsConfig \
  2471.         '0'
  2472.    
  2473.     makePasswordFile \
  2474.         ${LEVEL0[domain]} \
  2475.         $__0__tlsPwd
  2476.    
  2477.     makeKeyFile \
  2478.         ${LEVEL0[domain]} \
  2479.         $__0__tlsKey \
  2480.         $__0__tlsPwd
  2481.        
  2482.     makeDbFiles \
  2483.         ${LEVEL0[domain]} \
  2484.         $__0__tlsCrtDb \
  2485.         $__0__tlsCrtSrl \
  2486.         $__0__tlsCrlSrl
  2487.    
  2488.     makeSigningCa \
  2489.         ${LEVEL0[domain]} \
  2490.         ${LEVEL0[path]} \
  2491.         $__0__tlsConfig \
  2492.         $__0__tlsCsr \
  2493.         $__0__tlsKey \
  2494.         $__0__tlsPwd \
  2495.         $__0__tlsCrt \
  2496.         $__0__tlsCrl \
  2497.         $__0__tlsChainPem \
  2498.         $__0__caConfig \
  2499.         $__0__caPwd \
  2500.         $__0__caCrt
  2501.    
  2502.     publishCrt      $__0__tlsCrt        $__0__tlsCrtDer
  2503.     publishCACrl    $__0__tlsCrl        $__0__tlsCrlDer
  2504.     publishCAChain  $__0__tlsChainPem   $__0__tlsChainP7c
  2505.    
  2506.     certificate ${LEVEL0[domain]} ${LEVEL0[domain]} create tls-server ssl
  2507.    
  2508.     #
  2509.     # LEVEL 1 (domain)
  2510.     #
  2511.    
  2512.     # intermediate CA for domain level
  2513.     # ./intermediate
  2514.     if [ ! -z "$domainList" ]; then
  2515.         level1domains=$(echo $domainList | tr ";" "\n")
  2516.         for level1domain in $level1domains
  2517.         do
  2518.             #
  2519.             # LEVEL 1 (domain)
  2520.             #
  2521.             declare -A LEVEL1
  2522.             LEVEL1[domain]=$level1domain
  2523.             LEVEL1[path]="${LEVEL0_PATH[intermediatePath]}/$level1domain"
  2524.            
  2525.             declare -A LEVEL1_PATH
  2526.             # sub root ca
  2527.             LEVEL1_PATH[caPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[caPath]}
  2528.             LEVEL1_PATH[caDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[dbPath]}
  2529.             LEVEL1_PATH[caCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[cnfPath]}
  2530.             LEVEL1_PATH[caPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_ROOT[privatePath]}
  2531.             # email ca
  2532.             LEVEL1_PATH[caEmailPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[caPath]}
  2533.             LEVEL1_PATH[caEmailDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[dbPath]}
  2534.             LEVEL1_PATH[caEmailCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[cnfPath]}
  2535.             LEVEL1_PATH[caEmailPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_EMAIL[privatePath]}
  2536.             # software ca
  2537.             LEVEL1_PATH[caSoftwarePath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[caPath]}
  2538.             LEVEL1_PATH[caSoftwareDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[dbPath]}
  2539.             LEVEL1_PATH[caSoftwareCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[cnfPath]}
  2540.             LEVEL1_PATH[caSoftwarePrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_SOFTWARE[privatePath]}
  2541.             # tls ca
  2542.             LEVEL1_PATH[caTlsPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[caPath]}
  2543.             LEVEL1_PATH[caTlsDbPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[dbPath]}
  2544.             LEVEL1_PATH[caTlsCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[cnfPath]}
  2545.             LEVEL1_PATH[caTlsPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CA_TLS[privatePath]}
  2546.             # email crt
  2547.             LEVEL1_PATH[crtEmailPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_EMAIL[crtPath]}
  2548.             LEVEL1_PATH[crtEmailCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_EMAIL[cnfPath]}
  2549.             LEVEL1_PATH[crtEmailPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_EMAIL[privatePath]}
  2550.             # software crt
  2551.             LEVEL1_PATH[crtSoftwarePath]=${LEVEL1[path]}/${DIRECTORIES_CRT_SOFTWARE[crtPath]}
  2552.             LEVEL1_PATH[crtSoftwareCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_SOFTWARE[cnfPath]}
  2553.             LEVEL1_PATH[crtSoftwarePrvPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_SOFTWARE[privatePath]}
  2554.             # tls crt
  2555.             LEVEL1_PATH[crtTlsPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_TLS[crtPath]}
  2556.             LEVEL1_PATH[crtTlsCnfPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_TLS[cnfPath]}
  2557.             LEVEL1_PATH[crtTlsPrvPath]=${LEVEL1[path]}/${DIRECTORIES_CRT_TLS[privatePath]}
  2558.             # subdomains
  2559.             LEVEL1_PATH[intermediatePath]=${LEVEL1[path]}/${DIR_NAME[intermediateDir]}
  2560.             # pub
  2561.             LEVEL1_PATH[pub]=${LEVEL1[path]}/${DIR_NAME[public]}
  2562.             LEVEL1_PATH[pubTls]=${LEVEL1[path]}/${DIRECTORIES_PUB[tls]}
  2563.             LEVEL1_PATH[pubSoftware]=${LEVEL1[path]}/${DIRECTORIES_PUB[software]}
  2564.             LEVEL1_PATH[pubEmail]=${LEVEL1[path]}/${DIRECTORIES_PUB[email]}
  2565.            
  2566.             writeNewCert ${LEVEL1[domain]}
  2567.            
  2568.             writeNewType 'directories'
  2569.             for index in "${!LEVEL1_PATH[@]}"
  2570.             do
  2571.                 writeNewItem ${LEVEL1_PATH[$index]}
  2572.                 mkdir -p "${LEVEL1_PATH[$index]}" > /dev/null 2>&1
  2573.                 check_result $? 'unable to create directory'
  2574.             done
  2575.            
  2576.             writeNewType 'lookup'
  2577.             lookupAdd ${LEVEL1[domain]} ${LEVEL1[path]}
  2578.            
  2579.             writeNewType 'user request configs'
  2580.             makeUserSoftwareCsrFiles \
  2581.                 ${LEVEL1[domain]} \
  2582.                 ${LEVEL1_PATH[crtSoftwareCnfPath]}
  2583.                
  2584.             makeUserEmailCsrFiles \
  2585.                 ${LEVEL1[domain]} \
  2586.                 ${LEVEL1_PATH[crtEmailCnfPath]}
  2587.            
  2588.             makeUserTlsCsrFiles \
  2589.                 ${LEVEL1[domain]} \
  2590.                 ${LEVEL1_PATH[crtTlsCnfPath]}
  2591.            
  2592.             #
  2593.             # sub root CA
  2594.             #
  2595.             writeNewType 'Intermediate CA'
  2596.             # ./
  2597.             local __1__caCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2598.             local __1__caCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2599.             local __1__caChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2600.             # ./ca/db
  2601.             local __1__caCrtDb=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2602.             local __1__caCrtSrl=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2603.             local __1__caCrlSrl=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2604.             local __1__caCrl=${LEVEL1_PATH[caDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2605.             # ./ca/etc
  2606.             local __1__caConfig=${LEVEL1_PATH[caCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2607.             # ./ca/private
  2608.             local __1__caPwd=${LEVEL1_PATH[caPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2609.             local __1__caKey=${LEVEL1_PATH[caPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2610.             # ./public
  2611.             local __1__caChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2612.             local __1__caCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2613.             local __1__caCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caRoot]})
  2614.            
  2615.             makeConfigFile \
  2616.                 ${LEVEL1[domain]} \
  2617.                 'modulCaConfig' \
  2618.                 $__1__caConfig \
  2619.                 '1'
  2620.            
  2621.             makePasswordFile \
  2622.                 ${LEVEL1[domain]} \
  2623.                 $__1__caPwd
  2624.            
  2625.             makeKeyFile \
  2626.                 ${LEVEL1[domain]} \
  2627.                 $__1__caKey \
  2628.                 $__1__caPwd
  2629.                
  2630.             makeDbFiles \
  2631.                 ${LEVEL1[domain]} \
  2632.                 $__1__caCrtDb \
  2633.                 $__1__caCrtSrl \
  2634.                 $__1__caCrlSrl
  2635.            
  2636.             makeIntermediateCa \
  2637.                 ${LEVEL1[domain]} \
  2638.                 ${LEVEL1[path]} \
  2639.                 $__1__caConfig \
  2640.                 $__1__caCsr \
  2641.                 $__1__caKey \
  2642.                 $__1__caPwd \
  2643.                 $__1__caCrt \
  2644.                 $__1__caCrl \
  2645.                 $__1__caChainPem \
  2646.                 ${LEVEL0[path]} \
  2647.                 $__0__caConfig \
  2648.                 $__0__caPwd \
  2649.                 $__0__caCrt
  2650.                
  2651.             publishCrt      $__1__caCrt             $__1__caCrtDer
  2652.             publishCACrl    $__1__caCrl             $__1__caCrlDer
  2653.             publishCAChain  $__1__caChainPem        $__1__caChainP7c
  2654.                
  2655.             #
  2656.             # tls CA
  2657.             #
  2658.             writeNewType 'TLS CA'
  2659.             # ./
  2660.             local __1__tlsCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2661.             local __1__tlsCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2662.             local __1__tlsChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2663.             # ./ca-tls/db
  2664.             local __1__tlsCrtDb=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2665.             local __1__tlsCrtSrl=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2666.             local __1__tlsCrlSrl=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2667.             local __1__tlsCrl=${LEVEL1_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2668.             # ./ca-tls/etc
  2669.             local __1__tlsConfig=${LEVEL1_PATH[caTlsCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2670.             # ./ca-tls/private
  2671.             local __1__tlsPwd=${LEVEL1_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2672.             local __1__tlsKey=${LEVEL1_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2673.             # ./public
  2674.             local __1__tlsChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2675.             local __1__tlsCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2676.             local __1__tlsCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caTls]})
  2677.            
  2678.             makeConfigFile \
  2679.                 ${LEVEL1[domain]} \
  2680.                 'modulCaTlsConfig' \
  2681.                 $__1__tlsConfig \
  2682.                 '1'
  2683.            
  2684.             makePasswordFile \
  2685.                 ${LEVEL1[domain]} \
  2686.                 $__1__tlsPwd
  2687.            
  2688.             makeKeyFile \
  2689.                 ${LEVEL1[domain]} \
  2690.                 $__1__tlsKey \
  2691.                 $__1__tlsPwd
  2692.                
  2693.             makeDbFiles \
  2694.                 ${LEVEL1[domain]} \
  2695.                 $__1__tlsCrtDb \
  2696.                 $__1__tlsCrtSrl \
  2697.                 $__1__tlsCrlSrl
  2698.            
  2699.             makeSigningCa \
  2700.                 ${LEVEL1[domain]} \
  2701.                 ${LEVEL1[path]} \
  2702.                 $__1__tlsConfig \
  2703.                 $__1__tlsCsr \
  2704.                 $__1__tlsKey \
  2705.                 $__1__tlsPwd \
  2706.                 $__1__tlsCrt \
  2707.                 $__1__tlsCrl \
  2708.                 $__1__tlsChainPem \
  2709.                 $__1__caConfig \
  2710.                 $__1__caPwd \
  2711.                 $__1__caChainPem
  2712.            
  2713.             publishCrt      $__1__tlsCrt            $__1__tlsCrtDer
  2714.             publishCACrl    $__1__tlsCrl            $__1__tlsCrlDer
  2715.             publishCAChain  $__1__tlsChainPem       $__1__tlsChainP7c
  2716.            
  2717.             certificate ${LEVEL0[domain]} ${LEVEL1[domain]} create tls-server ssl
  2718.    
  2719.             #
  2720.             # email CA
  2721.             #
  2722.             writeNewType 'Email CA'
  2723.             # ./
  2724.             local __1__emailCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2725.             local __1__emailCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2726.             local __1__emailChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2727.             # ./ca-email/db
  2728.             local __1__emailCrtDb=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2729.             local __1__emailCrtSrl=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2730.             local __1__emailCrlSrl=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2731.             local __1__emailCrl=${LEVEL1_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2732.             # ./ca-email/etc
  2733.             local __1__emailConfig=${LEVEL1_PATH[caEmailCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2734.             # ./ca-email/private
  2735.             local __1__emailPwd=${LEVEL1_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2736.             local __1__emailKey=${LEVEL1_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2737.             # ./public
  2738.             local __1__emailChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2739.             local __1__emailCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2740.             local __1__emailCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caEmail]})
  2741.            
  2742.             makeConfigFile \
  2743.                 ${LEVEL1[domain]} \
  2744.                 'modulCaEmailConfig' \
  2745.                 $__1__emailConfig \
  2746.                 '1'
  2747.            
  2748.             makePasswordFile \
  2749.                 ${LEVEL1[domain]} \
  2750.                 $__1__emailPwd
  2751.            
  2752.             makeKeyFile \
  2753.                 ${LEVEL1[domain]} \
  2754.                 $__1__emailKey \
  2755.                 $__1__emailPwd
  2756.                
  2757.             makeDbFiles \
  2758.                 ${LEVEL1[domain]} \
  2759.                 $__1__emailCrtDb \
  2760.                 $__1__emailCrtSrl \
  2761.                 $__1__emailCrlSrl
  2762.            
  2763.             makeSigningCa \
  2764.                 ${LEVEL1[domain]} \
  2765.                 ${LEVEL1[path]} \
  2766.                 $__1__emailConfig \
  2767.                 $__1__emailCsr \
  2768.                 $__1__emailKey \
  2769.                 $__1__emailPwd \
  2770.                 $__1__emailCrt \
  2771.                 $__1__emailCrl \
  2772.                 $__1__emailChainPem \
  2773.                 $__1__caConfig \
  2774.                 $__1__caPwd \
  2775.                 $__1__caChainPem
  2776.            
  2777.             publishCrt      $__1__emailCrt          $__1__emailCrtDer
  2778.             publishCACrl    $__1__emailCrl          $__1__emailCrlDer          
  2779.             publishCAChain  $__1__emailChainPem     $__1__emailChainP7c
  2780.  
  2781.             #
  2782.             # software CA
  2783.             #
  2784.             writeNewType 'Software CA'
  2785.             # ./
  2786.             local __1__softwareCsr=${LEVEL1[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2787.             local __1__softwareCrt=${LEVEL1[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2788.             local __1__softwareChainPem=${LEVEL1[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2789.             # ./ca-software/db
  2790.             local __1__softwareCrtDb=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2791.             local __1__softwareCrtSrl=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2792.             local __1__softwareCrlSrl=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2793.             local __1__softwareCrl=${LEVEL1_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2794.             # ./ca-software/etc
  2795.             local __1__softwareConfig=${LEVEL1_PATH[caSoftwareCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2796.             # ./ca-software/private
  2797.             local __1__softwarePwd=${LEVEL1_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2798.             local __1__softwareKey=${LEVEL1_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2799.             # ./public
  2800.             local __1__softwareChainP7c=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2801.             local __1__softwareCrtDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2802.             local __1__softwareCrlDer=${LEVEL1_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL1[domain]} ${DIR_NAME[caSoftware]})
  2803.            
  2804.             makeConfigFile \
  2805.                 ${LEVEL1[domain]} \
  2806.                 'modulCaSoftwareConfig' \
  2807.                 $__1__softwareConfig \
  2808.                 '1'
  2809.            
  2810.             makePasswordFile \
  2811.                 ${LEVEL1[domain]} \
  2812.                 $__1__softwarePwd
  2813.            
  2814.             makeKeyFile \
  2815.                 ${LEVEL1[domain]} \
  2816.                 $__1__softwareKey \
  2817.                 $__1__softwarePwd
  2818.                
  2819.             makeDbFiles \
  2820.                 ${LEVEL1[domain]} \
  2821.                 $__1__softwareCrtDb \
  2822.                 $__1__softwareCrtSrl \
  2823.                 $__1__softwareCrlSrl
  2824.            
  2825.             makeSigningCa \
  2826.                 ${LEVEL1[domain]} \
  2827.                 ${LEVEL1[path]} \
  2828.                 $__1__softwareConfig \
  2829.                 $__1__softwareCsr \
  2830.                 $__1__softwareKey \
  2831.                 $__1__softwarePwd \
  2832.                 $__1__softwareCrt \
  2833.                 $__1__softwareCrl \
  2834.                 $__1__softwareChainPem \
  2835.                 $__1__caConfig \
  2836.                 $__1__caPwd \
  2837.                 $__1__caChainPem
  2838.  
  2839.             publishCrt      $__1__softwareCrt       $__1__softwareCrtDer
  2840.             publishCACrl    $__1__softwareCrl       $__1__softwareCrlDer
  2841.             publishCAChain  $__1__softwareChainPem  $__1__softwareChainP7c
  2842.  
  2843.             #
  2844.             # LEVEL 2 (subdomains)
  2845.             #
  2846.            
  2847.             # intermediate intermediate CA for subdomain level
  2848.             # ./intermediate/domain/intermediate
  2849.             if [ ! -z "$subDomainNameList" ]; then
  2850.                 level2domains=$(echo $subDomainNameList | tr ";" "\n")
  2851.                 for level2domain in $level2domains
  2852.                 do
  2853.                     #
  2854.                     # LEVEL 2 (subs)
  2855.                     #
  2856.                     # I don't split anything by '.' - a mail.foo.tld is like bob.mail.foo.tld.
  2857.                     # feel free to create the third level for bob.
  2858.                     #
  2859.                     # in that case
  2860.                     # - intermediate CA @ level 3:
  2861.                     #   - you MUST fork the makeIntermediateIntermediateCa function as makeIntermediateIntermediateIntermediateCa (or whatever);
  2862.                     #   - you MUST redefine export CA_2_SCRIPT_PATH="$baseDir" and export CA_1_SCRIPT_PATH="$rootBaseDir"
  2863.                     #                    as export CA_3_SCRIPT_PATH="$baseDir" and export CA_2_SCRIPT_PATH="$rootBaseDir"
  2864.                     #   - you MUST call makeConfigFile with '4' as the fourth parameter
  2865.                     #   otherwise openssl fails on relative paths. you can walk through the directories - but that's also nasty.
  2866.                     #   @see makeModulCaConfigBlock_default::$level
  2867.                     # - signing CAs @ level 3 are fun: s/2/3/ && s/1/2/
  2868.                     #
  2869.                     declare -A LEVEL2
  2870.                     LEVEL2[domain]="$level2domain.${LEVEL1[domain]}"
  2871.                     LEVEL2[path]="${LEVEL1_PATH[intermediatePath]}/$level2domain"
  2872.                    
  2873.                     declare -A LEVEL2_PATH
  2874.                     # sub sub root ca
  2875.                     LEVEL2_PATH[caPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[caPath]}
  2876.                     LEVEL2_PATH[caDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[dbPath]}
  2877.                     LEVEL2_PATH[caCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[cnfPath]}
  2878.                     LEVEL2_PATH[caPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_ROOT[privatePath]}
  2879.                     # email ca
  2880.                     LEVEL2_PATH[caEmailPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[caPath]}
  2881.                     LEVEL2_PATH[caEmailDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[dbPath]}
  2882.                     LEVEL2_PATH[caEmailCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[cnfPath]}
  2883.                     LEVEL2_PATH[caEmailPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_EMAIL[privatePath]}
  2884.                     # software ca
  2885.                     LEVEL2_PATH[caSoftwarePath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[caPath]}
  2886.                     LEVEL2_PATH[caSoftwareDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[dbPath]}
  2887.                     LEVEL2_PATH[caSoftwareCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[cnfPath]}
  2888.                     LEVEL2_PATH[caSoftwarePrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_SOFTWARE[privatePath]}
  2889.                     # tls ca
  2890.                     LEVEL2_PATH[caTlsPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[caPath]}
  2891.                     LEVEL2_PATH[caTlsDbPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[dbPath]}
  2892.                     LEVEL2_PATH[caTlsCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[cnfPath]}
  2893.                     LEVEL2_PATH[caTlsPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CA_TLS[privatePath]}
  2894.                     # email crt
  2895.                     LEVEL2_PATH[crtEmailPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_EMAIL[crtPath]}
  2896.                     LEVEL2_PATH[crtEmailCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_EMAIL[cnfPath]}
  2897.                     LEVEL2_PATH[crtEmailPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_EMAIL[privatePath]}
  2898.                     # software crt
  2899.                     LEVEL2_PATH[crtSoftwarePath]=${LEVEL2[path]}/${DIRECTORIES_CRT_SOFTWARE[crtPath]}
  2900.                     LEVEL2_PATH[crtSoftwareCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_SOFTWARE[cnfPath]}
  2901.                     LEVEL2_PATH[crtSoftwarePrvPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_SOFTWARE[privatePath]}
  2902.                     # tls crt
  2903.                     LEVEL2_PATH[crtTlsPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_TLS[crtPath]}
  2904.                     LEVEL2_PATH[crtTlsCnfPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_TLS[cnfPath]}
  2905.                     LEVEL2_PATH[crtTlsPrvPath]=${LEVEL2[path]}/${DIRECTORIES_CRT_TLS[privatePath]}
  2906.                     # pub
  2907.                     LEVEL2_PATH[pub]=${LEVEL2[path]}/${DIR_NAME[public]}
  2908.                     LEVEL2_PATH[pubTls]=${LEVEL2[path]}/${DIRECTORIES_PUB[tls]}
  2909.                     LEVEL2_PATH[pubSoftware]=${LEVEL2[path]}/${DIRECTORIES_PUB[software]}
  2910.                     LEVEL2_PATH[pubEmail]=${LEVEL2[path]}/${DIRECTORIES_PUB[email]}
  2911.            
  2912.                     writeNewCert ${LEVEL2[domain]}
  2913.                    
  2914.                     writeNewType 'directories'
  2915.                     for index in "${!LEVEL2_PATH[@]}"
  2916.                     do
  2917.                         writeNewItem ${LEVEL1_PATH[$index]}
  2918.                         mkdir -p "${LEVEL2_PATH[$index]}" > /dev/null 2>&1
  2919.                         check_result $? 'unable to create directory'
  2920.                     done
  2921.                    
  2922.                     writeNewType 'lookup'
  2923.                     lookupAdd ${LEVEL2[domain]} ${LEVEL2[path]}
  2924.            
  2925.                     writeNewType 'user request configs'
  2926.                     makeUserSoftwareCsrFiles \
  2927.                         ${LEVEL2[domain]} \
  2928.                         ${LEVEL2_PATH[crtSoftwareCnfPath]}
  2929.                        
  2930.                     makeUserEmailCsrFiles \
  2931.                         ${LEVEL2[domain]} \
  2932.                         ${LEVEL2_PATH[crtEmailCnfPath]}
  2933.                    
  2934.                     makeUserTlsCsrFiles \
  2935.                         ${LEVEL2[domain]} \
  2936.                         ${LEVEL2_PATH[crtTlsCnfPath]}
  2937.                    
  2938.                     #
  2939.                     # sub sub root CA
  2940.                     #
  2941.                     writeNewType 'Intermediate CA'
  2942.                     # ./
  2943.                     local __2__caCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2944.                     local __2__caCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2945.                     local __2__caChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2946.                     # ./ca/db
  2947.                     local __2__caCrtDb=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2948.                     local __2__caCrtSrl=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2949.                     local __2__caCrlSrl=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2950.                     local __2__caCrl=${LEVEL2_PATH[caDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2951.                     # ./ca/etc
  2952.                     local __2__caConfig=${LEVEL2_PATH[caCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2953.                     # ./ca/private
  2954.                     local __2__caPwd=${LEVEL2_PATH[caPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2955.                     local __2__caKey=${LEVEL2_PATH[caPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2956.                     # ./public
  2957.                     local __2__caChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2958.                     local __2__caCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2959.                     local __2__caCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caRoot]})
  2960.                    
  2961.                     makeConfigFile \
  2962.                         ${LEVEL2[domain]} \
  2963.                         'modulCaConfig' \
  2964.                         $__2__caConfig \
  2965.                         '2'
  2966.                    
  2967.                     makePasswordFile \
  2968.                         ${LEVEL2[domain]} \
  2969.                         $__2__caPwd
  2970.                    
  2971.                     makeKeyFile \
  2972.                         ${LEVEL2[domain]} \
  2973.                         $__2__caKey \
  2974.                         $__2__caPwd
  2975.                        
  2976.                     makeDbFiles \
  2977.                         ${LEVEL2[domain]} \
  2978.                         $__2__caCrtDb \
  2979.                         $__2__caCrtSrl \
  2980.                         $__2__caCrlSrl
  2981.                    
  2982.                     makeIntermediateIntermediateCa \
  2983.                         ${LEVEL2[domain]} \
  2984.                         ${LEVEL2[path]} \
  2985.                         $__2__caConfig \
  2986.                         $__2__caCsr \
  2987.                         $__2__caKey \
  2988.                         $__2__caPwd \
  2989.                         $__2__caCrt \
  2990.                         $__2__caCrl \
  2991.                         $__2__caChainPem \
  2992.                         ${LEVEL1[path]} \
  2993.                         $__1__caConfig \
  2994.                         $__1__caPwd \
  2995.                         $__1__caChainPem
  2996.                    
  2997.                     publishCrt      $__2__caCrt             $__2__caCrtDer
  2998.                     publishCACrl    $__2__caCrl             $__2__caCrlDer
  2999.                     publishCAChain  $__2__caChainPem        $__2__caChainP7c
  3000.                    
  3001.                     #
  3002.                     # tls CA
  3003.                     #
  3004.                     writeNewType 'TLS CA'
  3005.                     # ./
  3006.                     local __2__tlsCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3007.                     local __2__tlsCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3008.                     local __2__tlsChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3009.                     # ./ca-tls/db
  3010.                     local __2__tlsCrtDb=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3011.                     local __2__tlsCrtSrl=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3012.                     local __2__tlsCrlSrl=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3013.                     local __2__tlsCrl=${LEVEL2_PATH[caTlsDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3014.                     # ./ca-tls/etc
  3015.                     local __2__tlsConfig=${LEVEL2_PATH[caTlsCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3016.                     # ./ca-tls/private
  3017.                     local __2__tlsPwd=${LEVEL2_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3018.                     local __2__tlsKey=${LEVEL2_PATH[caTlsPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3019.                     # ./public
  3020.                     local __2__tlsChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3021.                     local __2__tlsCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3022.                     local __2__tlsCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caTls]})
  3023.                    
  3024.                     makeConfigFile \
  3025.                         ${LEVEL2[domain]} \
  3026.                         'modulCaTlsConfig' \
  3027.                         $__2__tlsConfig \
  3028.                         '2'
  3029.                    
  3030.                     makePasswordFile \
  3031.                         ${LEVEL2[domain]} \
  3032.                         $__2__tlsPwd
  3033.                    
  3034.                     makeKeyFile \
  3035.                         ${LEVEL2[domain]} \
  3036.                         $__2__tlsKey \
  3037.                         $__2__tlsPwd
  3038.                        
  3039.                     makeDbFiles \
  3040.                         ${LEVEL2[domain]} \
  3041.                         $__2__tlsCrtDb \
  3042.                         $__2__tlsCrtSrl \
  3043.                         $__2__tlsCrlSrl
  3044.                    
  3045.                     makeSigningCa \
  3046.                         ${LEVEL2[domain]} \
  3047.                         ${LEVEL2[path]} \
  3048.                         $__2__tlsConfig \
  3049.                         $__2__tlsCsr \
  3050.                         $__2__tlsKey \
  3051.                         $__2__tlsPwd \
  3052.                         $__2__tlsCrt \
  3053.                         $__2__tlsCrl \
  3054.                         $__2__tlsChainPem \
  3055.                         $__2__caConfig \
  3056.                         $__2__caPwd \
  3057.                         $__2__caChainPem
  3058.                    
  3059.                     publishCrt      $__2__tlsCrt            $__2__tlsCrtDer
  3060.                     publishCACrl    $__2__tlsCrl            $__2__tlsCrlDer
  3061.                     publishCAChain  $__2__tlsChainPem       $__2__tlsChainP7c
  3062.            
  3063.                     certificate ${LEVEL0[domain]} ${LEVEL2[domain]} create tls-server ssl
  3064.                    
  3065.                     #
  3066.                     # email CA
  3067.                     #
  3068.                     writeNewType 'Email CA'
  3069.                     # ./
  3070.                     local __2__emailCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3071.                     local __2__emailCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3072.                     local __2__emailChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3073.                     # ./ca-email/db
  3074.                     local __2__emailCrtDb=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3075.                     local __2__emailCrtSrl=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3076.                     local __2__emailCrlSrl=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3077.                     local __2__emailCrl=${LEVEL2_PATH[caEmailDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3078.                     # ./ca-email/etc
  3079.                     local __2__emailConfig=${LEVEL2_PATH[caEmailCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3080.                     # ./ca-email/private
  3081.                     local __2__emailPwd=${LEVEL2_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3082.                     local __2__emailKey=${LEVEL2_PATH[caEmailPrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3083.                     # ./public
  3084.                     local __2__emailChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3085.                     local __2__emailCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3086.                     local __2__emailCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caEmail]})
  3087.                    
  3088.                     makeConfigFile \
  3089.                         ${LEVEL2[domain]} \
  3090.                         'modulCaEmailConfig' \
  3091.                         $__2__emailConfig \
  3092.                         '2'
  3093.                    
  3094.                     makePasswordFile \
  3095.                         ${LEVEL2[domain]} \
  3096.                         $__2__emailPwd
  3097.                    
  3098.                     makeKeyFile \
  3099.                         ${LEVEL2[domain]} \
  3100.                         $__2__emailKey \
  3101.                         $__2__emailPwd
  3102.                        
  3103.                     makeDbFiles \
  3104.                         ${LEVEL2[domain]} \
  3105.                         $__2__emailCrtDb \
  3106.                         $__2__emailCrtSrl \
  3107.                         $__2__emailCrlSrl
  3108.                    
  3109.                     makeSigningCa \
  3110.                         ${LEVEL2[domain]} \
  3111.                         ${LEVEL2[path]} \
  3112.                         $__2__emailConfig \
  3113.                         $__2__emailCsr \
  3114.                         $__2__emailKey \
  3115.                         $__2__emailPwd \
  3116.                         $__2__emailCrt \
  3117.                         $__2__emailCrl \
  3118.                         $__2__emailChainPem \
  3119.                         $__2__caConfig \
  3120.                         $__2__caPwd \
  3121.                         $__2__caChainPem
  3122.                    
  3123.                     publishCrt      $__2__emailCrt          $__2__emailCrtDer
  3124.                     publishCACrl    $__2__emailCrl          $__2__emailCrlDer                  
  3125.                     publishCAChain  $__2__emailChainPem     $__2__emailChainP7c
  3126.  
  3127.                     #
  3128.                     # software CA
  3129.                     #
  3130.                     writeNewType 'Software CA'
  3131.                     # ./
  3132.                     local __2__softwareCsr=${LEVEL2[path]}/$(printf ${FILE_NAME[csr]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3133.                     local __2__softwareCrt=${LEVEL2[path]}/$(printf ${FILE_NAME[crt]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3134.                     local __2__softwareChainPem=${LEVEL2[path]}/$(printf ${FILE_NAME[chainPem]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3135.                     # ./ca-software/db
  3136.                     local __2__softwareCrtDb=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtDb]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3137.                     local __2__softwareCrtSrl=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crtSrl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3138.                     local __2__softwareCrlSrl=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crlSrl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3139.                     local __2__softwareCrl=${LEVEL2_PATH[caSoftwareDbPath]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3140.                     # ./ca-software/etc
  3141.                     local __2__softwareConfig=${LEVEL2_PATH[caSoftwareCnfPath]}/$(printf ${FILE_NAME[cnf]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3142.                     # ./ca-software/private
  3143.                     local __2__softwarePwd=${LEVEL2_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[password]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3144.                     local __2__softwareKey=${LEVEL2_PATH[caSoftwarePrvPath]}/$(printf ${FILE_NAME[key]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3145.                     # ./public
  3146.                     local __2__softwareChainP7c=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[chainP7c]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3147.                     local __2__softwareCrtDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[cer]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3148.                     local __2__softwareCrlDer=${LEVEL2_PATH[pub]}/$(printf ${FILE_NAME[crl]} ${LEVEL2[domain]} ${DIR_NAME[caSoftware]})
  3149.                    
  3150.                     makeConfigFile \
  3151.                         ${LEVEL2[domain]} \
  3152.                         'modulCaSoftwareConfig' \
  3153.                         $__2__softwareConfig \
  3154.                         '2'
  3155.                    
  3156.                     makePasswordFile \
  3157.                         ${LEVEL2[domain]} \
  3158.                         $__2__softwarePwd
  3159.                    
  3160.                     makeKeyFile \
  3161.                         ${LEVEL2[domain]} \
  3162.                         $__2__softwareKey \
  3163.                         $__2__softwarePwd
  3164.                        
  3165.                     makeDbFiles \
  3166.                         ${LEVEL2[domain]} \
  3167.                         $__2__softwareCrtDb \
  3168.                         $__2__softwareCrtSrl \
  3169.                         $__2__softwareCrlSrl
  3170.                    
  3171.                     makeSigningCa \
  3172.                         ${LEVEL2[domain]} \
  3173.                         ${LEVEL2[path]} \
  3174.                         $__2__softwareConfig \
  3175.                         $__2__softwareCsr \
  3176.                         $__2__softwareKey \
  3177.                         $__2__softwarePwd \
  3178.                         $__2__softwareCrt \
  3179.                         $__2__softwareCrl \
  3180.                         $__2__softwareChainPem \
  3181.                         $__2__caConfig \
  3182.                         $__2__caPwd \
  3183.                         $__2__caChainPem
  3184.                    
  3185.                     publishCrt      $__2__softwareCrt       $__2__softwareCrtDer
  3186.                     publishCACrl    $__2__softwareCrl       $__2__softwareCrlDer
  3187.                     publishCAChain  $__2__softwareChainPem  $__2__softwareChainP7c
  3188.                 done
  3189.             fi
  3190.         done
  3191.     fi
  3192.    
  3193.     do_unlock
  3194. }
  3195.  
  3196.  
  3197. demo()
  3198. {
  3199.     local pass='UDUslpOy:lsp.amsCw,Z09o&ooYx:lko123---0'
  3200.     root_ca $DEFAULT_DOMAIN 'example.com;example2.com' 'mail;smtp'
  3201.     certificate $DEFAULT_DOMAIN example.com create code-signing fruffi -CN 'fruffi IRC BOT' -password $pass
  3202.     certificate $DEFAULT_DOMAIN example.com create email lucas -password $pass -CN 'lucas' -emailAddress 'lucas@example.com'
  3203.     certificate $DEFAULT_DOMAIN example.com create tls-client lucas -CN 'Luc' -password $pass
  3204.     certificate $DEFAULT_DOMAIN example.com create tls-client-external luc-external -CN 'Luc' -O 'frufflwochen' -C 'NL' -password $pass
  3205.     certificate $DEFAULT_DOMAIN example.com create tls-server 1337
  3206.     certificate $DEFAULT_DOMAIN example.com create tls-server-external example.com -CN 'external.com' -O 'frufflwochen' -C 'NL' -password $pass
  3207. }
Add Comment
Please, Sign In to add comment