CertMng 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469
  1. #!/bin/bash
  2. #
  3. # Steps to create certs:
  4. # #######################
  5. # Generate private key
  6. # openssl genrsa -aes128 -out dsm01-key.pem 4096
  7. # Removing password from key
  8. # openssl rsa -in dsm01-key.pem -out dsm01-key-nopasswd.pem
  9. # Creating sign request for CA
  10. # openssl req -new -out dsm01-req.pem -key dsm01-key-nopasswd.pem -config "$gencert"
  11. # Sign CA request
  12. # openssl ca -in dsm01-req.pem -days "$exp_days" -cert ca-cert.pem -keyfile ca-key.pem -out dsm01-cert.pem -config "$gencert"
  13. #
  14. # TODO:
  15. # CertMng --CASetup /tmp/cert --Ext v3_req --Opt "MsgDigestAlg="md5",SSLKeySize=1024,ExpDays=365,DNS=casipgw01.networklab.ca,IP=192.168.10.69"
  16. # Default value: SSLKeySize=4096; ExpDays="$exp_days", MsgDigestAlg="md5"
  17. #
  18. #DEF_DIR
  19. def_dir="/etc/pki/pg_bdr"
  20. date=$(date +"%m-%d-%Y-%T")
  21. #CONF_FILE
  22. conf_file="networklab.cnf"
  23. ca_ext="-extensions v3_ca"
  24. req_ext="-extensions v3_req"
  25. usr_ext="-extensions usr_cert"
  26. version='1.0.1'
  27. declare -A opt_array
  28. usage() {
  29. echo -ne "Valid options for: $0\n[ --CASetup | Setup new CA | Value: Installation directory full path ]\n[ --GenCert | Generate Cert | Value: CNF file name | File format 'myorg.cnf' ] \n[ --GenReq | Generate Cert Request | Value: CNF file name | File format 'myorg.cnf' ]\n[ --RevokeCert | Cancel Certificate | Value: CNF file name | File format 'myorg.cnf' ]\n[ --SignRequest | Self Sign CA Certificate | Value: full path to request file | File format 'shortname-req.pem' ]\n[ --Ext | Openssl Extensions | Value: v3_ca,v3_req,usr_cert ]\n[ --Export | Export to PKSC12 or JKS | Value: P12, JKS ]\n[ --Opt | If Opt specified it will override default value | Default Value: SSLKeySize=4096; ExpDays=1095; MsgDigestAlg=sha1 | Supported Option: SSLKeySize; ExpDays; MsgDigestAlg; DNS; IP; ]\nExample: CA Authority setup with alternative dns names:\nCertMng --CASetup /tmp/cert --Ext v3_ca --Opt \"MsgDigestAlg=md5,SSLKeySize=1024,ExpDays=365,DNS1=myhostname.mydomainname.org,IP1=10.10.10.10\"\nNote: DNS IP can be specified how match you need.\n"
  30. }
  31. GenCert=""
  32. GenReq=""
  33. RevokeCert=""
  34. SignReq=""
  35. CASetup=""
  36. Opt=""
  37. Ext=""
  38. Export=""
  39. val=$(getopt -o :h::v::o:: --long GenCert:,GenReq:,RevokeCert:,SignRequest:,CASetup:,Opt:,Ext:,Export:,version:: -n 'CertMng' -- "$@")
  40. eval set -- "$val"
  41. if (( $# == 1 )); then
  42. usage
  43. exit
  44. fi
  45. while :; do
  46. case "$1" in
  47. -h|--help) usage $0 && exit 0;;
  48. -v|--version) echo "${0##*/} $version" && exit 0;;
  49. -c|--CASetup) setup=$2; shift 2;;
  50. -o|--Opt) list=$2; IFS=, read -r -a opt_list <<< "$list"; shift 2;;
  51. -g|--GenCert) gencert=$2; shift 2;;
  52. -r|--GenReq) genreq=$2; shift 2;;
  53. -R|--RevokeCert) certrevoke=$2; shift 2;;
  54. -S|--SignRequest) req_file=$2; shift 2;;
  55. -e|--Ext) ext=$2; shift 2;;
  56. -E|--Export) con=$2; shift 2;;
  57. --) shift 1; break;;
  58. *) break; usage ;;
  59. esac
  60. done
  61. for c in "${opt_list[@]}"; do
  62. opt_array+=([${c%%=*}]=${c#*=})
  63. done
  64. key_size=${opt_array['SSLKeySize']:=4096}
  65. exp_days=${opt_array['ExpDays']:=1095}
  66. msg_alg=${opt_array['MsgDigestAlg']:=sha1}
  67. if [[ "$ext" == v3_req ]]; then
  68. for r in "${!opt_array[@]}"; do
  69. if [[ $r = DNS* ]]; then
  70. sum=$((n++))
  71. new_dns=$(sed -r 's/[0-9]{1,10}$//' <<< "$r")
  72. str_dns+=("$new_dns.$sum = ${opt_array[$r]}")
  73. fi
  74. if [[ $r = IP* ]]; then
  75. num=$((m++))
  76. new_ip=$(sed -r 's/[0-9]{1,10}$//' <<< "$r")
  77. str_ip+=("$new_ip.$num = ${opt_array[$r]}")
  78. fi
  79. done
  80. fi
  81. con() {
  82. echo -n "Please enter user last name: "
  83. read name
  84. if [[ -d "$def_dir"/"$name" ]]; then
  85. passwd
  86. case "$con" in
  87. P12)
  88. openssl pkcs12 -export -name "$name"-cert -in "$def_dir"/"$name"/"$name"-cert.pem -inkey "$def_dir"/"$name"/"$name"-key-nopasswd.pem -out "$def_dir"/"$name"/"$name".p12 -passout pass:"${password[*]}"
  89. ;;
  90. JKS)
  91. if [[ -f "$def_dir"/"$name"/"$name".p12 ]]; then
  92. keytool -importkeystore -srckeystore "$def_dir"/"$name"/"$name".p12 -srcstoretype pkcs12 -destkeystore "$def_dir"/"$name"/"$name".jks -srckeypass "${password[*]}" -destkeypass "${password[*]}" -deststorepass "${password[*]}" -srcstorepass "${password[*]}" -noprompt -alias "$name"-cert
  93. keytool -list -v -keystore "$def_dir"/"$name"/"$name".jks -storepass "${password[*]}"
  94. else
  95. openssl pkcs12 -export -name "$name"-cert -in "$def_dir"/"$name"/"$name"-cert.pem -inkey "$def_dir"/"$name"/"$name"-key-nopasswd.pem -out "$def_dir"/"$name"/"$name".p12 -passout pass:"${password[*]}"
  96. keytool -importkeystore -srckeystore "$def_dir"/"$name"/"$name".p12 -srcstoretype pkcs12 -destkeystore "$def_dir"/"$name"/"$name".jks -srckeypass "${password[*]}" -destkeypass "${password[*]}" -deststorepass "${password[*]}" -srcstorepass "${password[*]}" -noprompt -alias "$name"-cert
  97. keytool -list -v -keystore "$def_dir"/"$name"/"$name".jks -storepass "${password[*]}"
  98. fi
  99. ;;
  100. *)
  101. echo "Invalid Option $1 ..."
  102. exit 1
  103. ;;
  104. esac
  105. fi
  106. }
  107. passwd() {
  108. echo -n "Enter Global Password [private key/keystore]: "
  109. unset password
  110. while IFS= read -r -s -n1 pass; do
  111. if [[ -z $pass ]]; then
  112. echo
  113. break
  114. else
  115. echo -n '*'
  116. password+="$pass"
  117. fi
  118. done
  119. }
  120. name_print() {
  121. printf '%s\n' '/^#NAMES/a' "${str_ip[@]}" . w a | ex -s $1
  122. printf '%s\n' '/^#NAMES/a' "${str_dns[@]}" . w a | ex -s $1
  123. }
  124. add_req_v3() {
  125. sed -i '/#EXT_V3/a \
  126. [ v3_req ] \
  127. basicConstraints = CA:FALSE \
  128. subjectKeyIdentifier = hash \
  129. keyUsage = nonRepudiation, digitalSignature, keyEncipherment, dataEncipherment \
  130. subjectAltName = @alt_names \
  131. \
  132. [alt_names] \
  133. #NAMES' "$1"
  134. sed -i '/#EXT_REQ/a \
  135. req_extensions = v3_req' "$1"
  136. }
  137. add_ca_ext() {
  138. sed -i '/#EXT_CA/a \
  139. x509_extensions = v3_ca' "$1"
  140. }
  141. add_default_ext() {
  142. sed -i '/#EXT_USR/a \
  143. x509_extensions = usr_cert' "$1"
  144. }
  145. remove_ext() {
  146. sed -i '/#EXT_V3/,/#END/{//!d}' "$1"
  147. sed -i '/#EXT_REQ/,/#END/{//!d}' "$1"
  148. sed -i '/#EXT_CA/,/#END/{//!d}' "$1"
  149. sed -i '/#EXT_USR/,/#END/{//!d}' "$1"
  150. }
  151. sign_req() {
  152. echo -n "Please enter short name: "
  153. read name
  154. passwd
  155. echo "Signing request for $name ..."
  156. if [[ ! -d "$def_dir"/"$name" ]]; then
  157. mkdir -p "$def_dir"/"$name"
  158. fi
  159. /bin/mv "$req_file" "$def_dir"/"$name"
  160. openssl ca -in "$def_dir"/"$name"/"${req_file##*/}" -days "$exp_days" -cert "$def_dir"/ca-cert.pem -keyfile "$def_dir"/ca-key.pem -out "$def_dir"/"$name"/"$name"-cert.pem -passin pass:"${password[*]}" -config "$def_dir"/"$conf_file"
  161. if [[ "$?" -ne 0 ]]; then
  162. echo "Error is happened, check certificate request file. Exiting ..."
  163. exit 1
  164. fi
  165. echo "Done ..."
  166. echo -n "Verifing created cert for $name"
  167. openssl verify -CAfile "$def_dir"/ca-cert.pem "$def_dir"/"$name"/"$name"-cert.pem
  168. echo "Done ..."
  169. exit 0
  170. }
  171. gen_req() {
  172. echo -n "Please enter user last name: "
  173. read name
  174. passwd
  175. echo "Generating certificates request for $name ..."
  176. if [[ ! -d "$def_dir"/"$name" ]]; then
  177. mkdir -p "$def_dir"/"$name"
  178. fi
  179. openssl genrsa -aes128 -passout pass:"${password[*]}" -out "$def_dir"/"$name"/"$name"-key.pem "$key_size"
  180. openssl rsa -passin pass:"${password[*]}" -in "$def_dir"/"$name"/"$name"-key.pem -out "$def_dir"/"$name"/"$name"-key-nopasswd.pem
  181. if [[ "$ext" == v3_req ]]; then
  182. add_req_v3 "$def_dir"/"$genreq"
  183. name_print "$def_dir"/"$genreq"
  184. openssl req -new -passin pass:"${password[*]}" -out "$def_dir"/"$name"/"$name"-req.pem -key "$def_dir"/"$name"/"$name"-key-nopasswd.pem -extensions v3_req -config "$def_dir"/"$genreq"
  185. else
  186. openssl req -new -passin pass:"${password[*]}" -out "$def_dir"/"$name"/"$name"-req.pem -key "$def_dir"/"$name"/"$name"-key-nopasswd.pem -config "$def_dir"/"$genreq"
  187. fi
  188. cat "$def_dir"/"$name"/"$name"-req.pem
  189. echo "Done ..."
  190. exit 0
  191. }
  192. gen_user() {
  193. echo -n "Please enter user last name: "
  194. read name
  195. passwd
  196. echo "Generating certificates for $name ..."
  197. if [[ -d "$def_dir"/"$name" ]]; then
  198. echo -n "User with name $name already exist. Do you want revoke cert first? [Y/n]: "
  199. read answer
  200. if [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]; then
  201. openssl ca -cert "$def_dir"/ca-cert.pem -keyfile "$def_dir"/ca-key.pem -revoke "$def_dir"/"$name"/"$name"-cert.pem -passin pass:"${password[*]}" -config "$def_dir"/"$gencert"
  202. openssl ca -cert "$def_dir"/ca-cert.pem -keyfile "$def_dir"/ca-key.pem -gencrl -out "$def_dir"/ca_rev-list.pem -passin pass:"${password[*]}" -config "$def_dir"/"$gencert"
  203. /bin/mv -f "$def_dir"/"$name" "$def_dir"/"$name"_rev-"$date"
  204. else
  205. echo "Done. Exiting ..."
  206. exit 1
  207. fi
  208. fi
  209. if [[ ! -d "$def_dir"/"$name" ]]; then
  210. mkdir -p "$def_dir"/"$name"
  211. fi
  212. openssl genrsa -aes128 -passout pass:"${password[*]}" -out "$def_dir"/"$name"/"$name"-key.pem "$key_size"
  213. openssl rsa -passin pass:"${password[*]}" -in "$def_dir"/"$name"/"$name"-key.pem -out "$def_dir"/"$name"/"$name"-key-nopasswd.pem
  214. if [[ "$ext" == v3_req ]]; then
  215. add_req_v3 "$def_dir"/"$gencert"
  216. name_print "$def_dir"/"$gencert"
  217. openssl req -new -passin pass:"${password[*]}" -out "$def_dir"/"$name"/"$name"-req.pem -key "$def_dir"/"$name"/"$name"-key-nopasswd.pem -extensions v3_req -config "$def_dir"/"$gencert"
  218. openssl ca -in "$def_dir"/"$name"/"$name"-req.pem -days "$exp_days" -cert "$def_dir"/ca-cert.pem -keyfile "$def_dir"/ca-key.pem -out "$def_dir"/"$name"/"$name"-cert.pem -extensions v3_req -config "$def_dir"/"$gencert" -passin pass:"${password[*]}"
  219. else
  220. openssl req -new -passin pass:"${password[*]}" -out "$def_dir"/"$name"/"$name"-req.pem -key "$def_dir"/"$name"/"$name"-key-nopasswd.pem -config "$def_dir"/"$gencert"
  221. openssl ca -in "$def_dir"/"$name"/"$name"-req.pem -days "$exp_days" -cert "$def_dir"/ca-cert.pem -keyfile "$def_dir"/ca-key.pem -out "$def_dir"/"$name"/"$name"-cert.pem -config "$def_dir"/"$gencert" -passin pass:"${password[*]}"
  222. fi
  223. cat "$def_dir"/"$name"/"$name"-cert.pem "$def_dir"/"$name"/"$name"-key-nopasswd.pem > "$def_dir"/"$name"/"$name"-bundle.pem
  224. echo "Done ..."
  225. echo -n "Verifing created cert for $name"
  226. openssl verify -CAfile "$def_dir"/ca-cert.pem "$def_dir"/"$name"/"$name"-cert.pem
  227. remove_ext "$def_dir"/"$gencert"
  228. echo "Done ..."
  229. exit 0
  230. }
  231. certrev_user() {
  232. echo -n "Please enter user last name: "
  233. read name
  234. passwd
  235. openssl ca -cert "$def_dir"/ca-cert.pem -keyfile "$def_dir"/ca-key.pem -revoke "$def_dir"/"$name"/"$name"-cert.pem -passin pass:"${password[*]}" -config "$def_dir"/"$certrevoke"
  236. openssl ca -cert "$def_dir"/ca-cert.pem -keyfile "$def_dir"/ca-key.pem -gencrl -out "$def_dir"/ca_rev-list.pem -passin pass:"${password[*]}" -config "$def_dir"/"$certrevoke"
  237. /bin/mv -f "$def_dir"/"$name" "$def_dir"/"$name"_rev-"$date"
  238. }
  239. ca_cnf() {
  240. d='$dir'
  241. printf "%sdefault_ca = CA_default
  242. [ CA_default ]
  243. dir = ca_dir
  244. serial = $d/serial
  245. database = $d/index.txt
  246. new_certs_dir = $d/certs
  247. certificate = $d/ca-cert.pem
  248. crl = $d/ca_rev-list.pem
  249. private_key = $d/ca-key.pem
  250. default_days = "$exp_days"
  251. default_crl_days = 15
  252. default_md = "$msg_alg"
  253. crl_extensions = crl_ext
  254. #EXT_USR
  255. #END
  256. preserve = no
  257. email_in_dn = no
  258. unique_subject = no
  259. nameopt = default_ca
  260. certopt = default_ca
  261. policy = policy_match
  262. [ policy_match ]
  263. countryName = match
  264. stateOrProvinceName = match
  265. organizationName = match
  266. organizationalUnitName = optional
  267. commonName = supplied
  268. emailAddress = optional
  269. [ req ]
  270. default_bits = "$key_size" # Size of keys
  271. default_keyfile = ca_key.pem # name of generated keys
  272. default_md = "$msg_alg" # message digest algorithm
  273. string_mask = nombstr # permitted characters
  274. distinguished_name = req_distinguished_name
  275. #EXT_REQ
  276. #END
  277. #EXT_CA
  278. #END
  279. [ req_distinguished_name ]
  280. # Variable name Prompt string
  281. #------------------------- ----------------------------------
  282. 0.organizationName = Organization Name (company)
  283. organizationalUnitName = Organizational Unit Name (department, division)
  284. emailAddress = Email Address
  285. emailAddress_max = 40
  286. localityName = Locality Name (city, district)
  287. stateOrProvinceName = State or Province Name (full name)
  288. countryName = Country Name (2 letter code)
  289. countryName_min = 2
  290. countryName_max = 2
  291. commonName = Common Name (hostname, IP, or your name)
  292. commonName_max = 64
  293. # Default values for the above, for consistency and less typing.
  294. # Variable name Value
  295. #------------------------ ------------------------------
  296. 0.organizationName_default = org_name
  297. organizationalUnitName_default = org_unit
  298. localityName_default = org_locality
  299. stateOrProvinceName_default = org_state
  300. countryName_default = org_country
  301. emailAddress_default = org_email
  302. [ usr_cert ]
  303. # These extensions are added when 'ca' signs a request.
  304. basicConstraints = CA:FALSE
  305. keyUsage = nonRepudiation, digitalSignature, keyEncipherment
  306. nsComment = \"OpenSSL Generated Certificate\"
  307. subjectKeyIdentifier = hash
  308. authorityKeyIdentifier = keyid,issuer
  309. [ v3_ca ]
  310. # Extensions for a typical CA
  311. subjectKeyIdentifier = hash
  312. authorityKeyIdentifier = keyid:always,issuer
  313. basicConstraints = CA:true
  314. keyUsage = cRLSign, keyCertSign
  315. #EXT_V3
  316. #END
  317. [ crl_ext ]
  318. # issuerAltName=issuer:copy
  319. authorityKeyIdentifier = keyid:always,issuer:always
  320. "
  321. }
  322. ca_setup() {
  323. echo -n "Specify Organization Name: "
  324. read org_name
  325. echo -n "Specify Organization Unit: "
  326. read org_unit
  327. echo -n "Specify Organization Locality: "
  328. read org_locality
  329. echo -n "Specify Organization State: "
  330. read org_state
  331. echo -n "Specify Organization Country: "
  332. read org_country
  333. echo -n "Specify Organization Email: "
  334. read org_email
  335. passwd
  336. echo "Generating CNF file for Openssl .."
  337. mkdir -p "$setup"
  338. mkdir -p "$setup"/certs
  339. ca_cnf > "$setup"/${org_name,,}.cnf
  340. ca_dir="$(echo $setup | sed 's:/:\\\/:g')"
  341. sed -i -e "s/org_name/$org_name/g" \
  342. -e "s/org_unit/$org_unit/g" \
  343. -e "s/org_locality/$org_locality/g" \
  344. -e "s/org_state/$org_state/g" \
  345. -e "s/org_country/$org_country/g" \
  346. -e "s/ca_dir/$ca_dir/g" \
  347. -e "s/org_email/$org_email/g" "$setup"/"${org_name,,}".cnf
  348. echo "Done ..."
  349. #fi
  350. echo "01" > "$setup"/serial
  351. echo "01" > "$setup"/crlnumber
  352. touch "$setup"/index.txt
  353. openssl genrsa -aes128 -passout pass:"${password[*]}" -out "$setup"/ca-key.pem "$key_size"
  354. if [[ "$ext" == v3_req ]]; then
  355. add_req_v3 "$setup"/"${org_name,,}".cnf
  356. add_ca_ext "$setup"/"${org_name,,}".cnf
  357. name_print "$setup"/"${org_name,,}".cnf
  358. openssl req -new -x509 -extensions v3_ca -key "$setup"/ca-key.pem -out "$setup"/ca-cert.pem -days "$exp_days" -passin pass:"${password[*]}" -config "$setup"/"${org_name,,}".cnf
  359. else
  360. add_ca_ext "$setup"/"${org_name,,}".cnf
  361. openssl req -new -x509 -key "$setup"/ca-key.pem -out "$setup"/ca-cert.pem -days "$exp_days" -passin pass:"${password[*]}" -config "$setup"/"${org_name,,}".cnf
  362. fi
  363. openssl ca -passin pass:"${password[*]}" -config "$setup"/"${org_name,,}".cnf -gencrl -out "$setup"/ca_rev-list.pem
  364. cert_mng=$(which CertMng)
  365. sed -i "/^conf_file/d" $cert_mng
  366. sed -i "/^#CONF_FILE/a \conf_file="\"$"${org_name,,}".cnf"\"" $cert_mng
  367. sed -i "/^def_dir/d" $cert_mng
  368. sed -i "/^#DEF_DIR/a \def_dir="\"$ca_dir"\"" $cert_mng
  369. echo "Done ..."
  370. }
  371. if [[ -n $gencert ]]; then
  372. gen_user
  373. fi
  374. if [[ -n $genreq ]]; then
  375. gen_req
  376. fi
  377. if [[ -n $certrevoke ]]; then
  378. certrev_user
  379. fi
  380. if [[ -d $setup ]] && [[ -n $setup ]]; then
  381. ca_dir=$(sed -r 's:/:\\\/:g' <<< "$setup")
  382. echo -ne "CA is aleady setup under this dir $setup ...\n"
  383. echo -ne "Do you want delete existing CA Authority in $def_dir [Y/n]: "
  384. read answer
  385. [[ "$answer" =~ ^([yY][eE][sS]|[yY])$ ]]
  386. rm -rf "$setup"
  387. ca_setup
  388. exit 0
  389. else
  390. ca_setup
  391. exit 0
  392. fi
  393. if [[ -f $req_file ]] && [[ -n $req_file ]]; then
  394. sign_req
  395. else
  396. echo "Request file not found. Exiting ..."
  397. exit 1
  398. fi
  399. if [[ -n "$con" ]]; then
  400. con
  401. exit 0
  402. fi
  403. remove_ext "$setup"/"${org_name,,}".cnf