certificate.sh 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. #!/bin/bash
  2. #------ Settings ------
  3. OPENSSL="openssl"
  4. CONFIG="./openssl.cnf"
  5. ROOTCADAYS="-days 3650" # 10 years
  6. CADAYS="-days 1825" # 5 years
  7. #CADAYS="-days 825" # 2 years
  8. DAYS="-days 397" # 1 year
  9. CONFIGOPTION="-config ${CONFIG}"
  10. REQ="${OPENSSL} req ${CONFIGOPTION}"
  11. CA="${OPENSSL} ca ${CONFIGOPTION}"
  12. VERIFY="${OPENSSL} verify"
  13. X509="${OPENSSL} x509"
  14. PKCS12="${OPENSSL} pkcs12"
  15. CAFOLDER="./CA"
  16. CAKEY="./cakey.pem"
  17. CAREQ="./careq.pem"
  18. CACERT="./cacert.pem"
  19. PASSEXTENSION="keyfile"
  20. PASSFILE="./${PASSEXTENSION}"
  21. TYPEFILE="./type"
  22. CHAINFILE="./cachain.pem"
  23. C="NL"
  24. ST="Noord-Brabant"
  25. L="Veldhoven"
  26. O="Dierkse DataManagement"
  27. OU="Secure Digital Certificate Signing"
  28. #CN="CommonName"
  29. E="certification@dierkse.nl"
  30. #------ Functions ------
  31. execute() {
  32. COMMAND=$@
  33. eval ${COMMAND}
  34. RETURNVALUE=$?
  35. if [ "${RETURNVALUE}" -ne "0" ]; then
  36. exit ${RETURNVALUE}
  37. fi
  38. }
  39. writeRandomString() {
  40. SIZE=$1
  41. FILE=$2
  42. tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' < /dev/urandom | head -c ${SIZE} > "${FILE}"
  43. }
  44. validateType() {
  45. TYPE=$1
  46. VALIDTYPE=""
  47. if [[ "${TYPE}" == "ROOTCA" ||
  48. "${TYPE}" == "INTERMEDIATECA" ||
  49. "${TYPE}" == "VPNCA" ||
  50. "${TYPE}" == "WEBSERVER" ||
  51. "${TYPE}" == "WEBCLIENT" ||
  52. "${TYPE}" == "APPLICATIONCLIENT" ||
  53. "${TYPE}" == "EMAIL" ||
  54. "${TYPE}" == "VPN" ]]; then
  55. VALIDTYPE=${TYPE}
  56. fi
  57. }
  58. copyPem() {
  59. INFILE=$1
  60. OUTFILE=$2
  61. BOUND=$3
  62. FLAG=0
  63. if [ ! -f "${INFILE}" ]; then
  64. echo "Missing File ${INFILE}"
  65. exit -1
  66. fi
  67. if [[ -z "$BOUND" ]]; then
  68. echo "Missing Boundary"
  69. exit -1
  70. fi
  71. exec < "${INFILE}";
  72. while read LINE; do
  73. if [ ${FLAG} -eq 1 ]; then
  74. echo ${LINE}|grep "^-----END.*${BOUND}" 2>/dev/null 1>/dev/null
  75. if [ $? -eq 0 ] ; then
  76. echo ${LINE} >> "${OUTFILE}"
  77. break
  78. else
  79. echo ${LINE} >> "${OUTFILE}"
  80. fi
  81. fi
  82. echo ${LINE} | grep "^-----BEGIN.*${BOUND}" 2>/dev/null 1>/dev/null
  83. if [ $? -eq 0 ]; then
  84. echo ${LINE} > "${OUTFILE}"
  85. FLAG=1
  86. fi
  87. done
  88. }
  89. newCertificate() {
  90. KEYBITS=2048
  91. if [ ! -d ${CAFOLDER} ]; then
  92. echo "Missing CA Folder"
  93. exit -1
  94. fi
  95. if [[ "${TYPE}" == "WEBSERVER" ]]; then
  96. EXTENSIONS="server_cert -nodes"
  97. SAN=()
  98. if [ ! -z "${CN}" ]; then
  99. SAN+=("${CN}")
  100. SAN+=("*.${CN}")
  101. fi
  102. SAN+=("${EXTRASAN[@]}")
  103. IP=("${EXTRAIP[@]}")
  104. fi
  105. if [[ "${TYPE}" == "WEBCLIENT" ]]; then
  106. EXTENSIONS="client_cert -nodes"
  107. fi
  108. if [[ "${TYPE}" == "APPLICATIONCLIENT" ]]; then
  109. EXTENSIONS="application_cert -nodes"
  110. fi
  111. if [[ "${TYPE}" == "EMAIL" ]]; then
  112. EXTENSIONS="email_cert -nodes"
  113. fi
  114. if [[ "${TYPE}" == "VPN" ]]; then
  115. EXTENSIONS="vpn_cert -nodes"
  116. SAN=()
  117. if [ ! -z "${CN}" ]; then
  118. SAN+=("${CN}")
  119. fi
  120. fi
  121. if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
  122. KEYBITS=4096
  123. DAYS=${CADAYS}
  124. EXTENSIONS="intermediate_extensions"
  125. fi
  126. COMMAND="${REQ} -new -x509 -newkey rsa:${KEYBITS} -extensions server_cert -keyout \"${FILENAME}.key\" -out \"${FILENAME}.crt\" ${DAYS}"
  127. if [ ! -z "${CN}" ]; then
  128. SUBJECT="/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${E}"
  129. COMMAND+=" -subj \"${SUBJECT}\""
  130. fi
  131. if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then
  132. COMMAND+=" -addext \"subjectAltName="
  133. INDEX=0
  134. for S in "${SAN[@]}"
  135. do
  136. ((INDEX+=1))
  137. COMMAND+="DNS.${INDEX}: ${S},"
  138. done
  139. INDEX=0
  140. for I in "${IP[@]}"
  141. do
  142. ((INDEX+=1))
  143. COMMAND+="IP.${INDEX}: ${I},"
  144. done
  145. COMMAND=${COMMAND%?}
  146. COMMAND+="\""
  147. fi
  148. execute ${COMMAND}
  149. }
  150. newRequest() {
  151. KEYBITS=2048
  152. if [ ! -d ${CAFOLDER} ]; then
  153. echo "Missing CA Folder"
  154. exit -1
  155. fi
  156. if [[ "${TYPE}" == "WEBSERVER" ]]; then
  157. EXTENSIONS="server_cert -nodes"
  158. SAN=()
  159. if [ ! -z "${CN}" ]; then
  160. SAN+=("${CN}")
  161. SAN+=("*.${CN}")
  162. fi
  163. SAN+=("${EXTRASAN[@]}")
  164. IP=("${EXTRAIP[@]}")
  165. fi
  166. if [[ "${TYPE}" == "WEBCLIENT" ]]; then
  167. EXTENSIONS="client_cert -nodes"
  168. fi
  169. if [[ "${TYPE}" == "APPLICATIONCLIENT" ]]; then
  170. EXTENSIONS="application_cert -nodes"
  171. fi
  172. if [[ "${TYPE}" == "EMAIL" ]]; then
  173. EXTENSIONS="email_cert -nodes"
  174. fi
  175. if [[ "${TYPE}" == "VPN" ]]; then
  176. EXTENSIONS="vpn_cert -nodes"
  177. SAN=()
  178. if [ ! -z "${CN}" ]; then
  179. SAN+=("${CN}")
  180. fi
  181. fi
  182. if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
  183. KEYBITS=4096
  184. writeRandomString 128 "${FILENAME}.${PASSEXTENSION}"
  185. chmod 000 "${FILENAME}.${PASSEXTENSION}"
  186. EXTENSIONS="intermediate_extensions -passout file:\"${FILENAME}.${PASSEXTENSION}\""
  187. fi
  188. COMMAND="${REQ} -new -newkey rsa:${KEYBITS} -extensions ${EXTENSIONS} -keyout \"${FILENAME}.key\" -out \"${FILENAME}.csr\""
  189. if [ ! -z "${CN}" ]; then
  190. SUBJECT="/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${E}"
  191. COMMAND+=" -subj \"${SUBJECT}\""
  192. fi
  193. if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then
  194. COMMAND+=" -addext \"subjectAltName="
  195. INDEX=0
  196. for S in "${SAN[@]}"
  197. do
  198. ((INDEX+=1))
  199. COMMAND+="DNS.${INDEX}: ${S},"
  200. done
  201. INDEX=0
  202. for I in "${IP[@]}"
  203. do
  204. ((INDEX+=1))
  205. COMMAND+="IP.${INDEX}: ${I},"
  206. done
  207. COMMAND=${COMMAND%?}
  208. COMMAND+="\""
  209. fi
  210. execute ${COMMAND}
  211. }
  212. newCertificateAuthority() {
  213. if [[ "${TYPE}" == "ROOTCA" ]]; then
  214. KEYBITS=8192
  215. EXTENSIONS="CA_root"
  216. DAYS=${ROOTCADAYS}
  217. SUBTYPE="INTERMEDIATECA"
  218. fi
  219. if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
  220. KEYBITS=4096
  221. EXTENSIONS="CA_intermediate"
  222. DAYS=${CADAYS}
  223. fi
  224. if [[ "${TYPE}" == "VPNCA" ]]; then
  225. KEYBITS=4096
  226. EXTENSIONS="CA_root"
  227. DAYS=${ROOTCADAYS}
  228. SUBTYPE="VPN"
  229. fi
  230. if [ -z "${KEYBITS}" ]; then
  231. echo "Error: invalid certificate authority type" >&2
  232. exit -1
  233. fi
  234. if [ ! -f ${CAFOLDER}/serial ]; then
  235. mkdir -p ${CAFOLDER}
  236. mkdir -p ${CAFOLDER}/certs
  237. mkdir -p ${CAFOLDER}/crl
  238. mkdir -p ${CAFOLDER}/newcerts
  239. mkdir -p ${CAFOLDER}/private
  240. touch ${CAFOLDER}/index.txt
  241. echo 1000 > ${CAFOLDER}/crl/crlnumber
  242. openssl rand -writerand ${CAFOLDER}/private/.rand
  243. writeRandomString 128 ${CAFOLDER}/private/${PASSFILE}
  244. chmod 000 ${CAFOLDER}/private/${PASSFILE}
  245. if [ ! -z "${SUBTYPE}" ]; then
  246. echo "${SUBTYPE}" > ${CAFOLDER}/${TYPEFILE}
  247. fi
  248. fi
  249. if [ ! -f ${CAFOLDER}/private/${CAKEY} ]; then
  250. if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
  251. echo "CA certificate filename (or enter to create)"
  252. read NAME
  253. fi
  254. if [ "${NAME}" ]; then
  255. if [ -f "./${NAME}" ]; then
  256. NAME="./${NAME%.*}"
  257. else
  258. if [ -f "../${NAME}" ]; then
  259. NAME="../${NAME%.*}"
  260. else
  261. if [ -f "./${NAME}.crt" ]; then
  262. NAME="./${NAME}"
  263. else
  264. if [ -f "../${NAME}.crt" ]; then
  265. NAME="../${NAME}"
  266. else
  267. echo "Certificate not found"
  268. echo " ("./${NAME}")"
  269. echo " ("../${NAME}")"
  270. echo " ("./${NAME}.crt")"
  271. echo " ("../${NAME}.crt")"
  272. echo ""
  273. exit -1
  274. fi
  275. fi
  276. fi
  277. fi
  278. if [ -f "${NAME}.csr" ]; then
  279. copyPem "${NAME}.csr" ${CAFOLDER}/${CAREQ} CERTIFICATE
  280. else
  281. echo "CA Request missing (${NAME}.csr)"
  282. exit -1
  283. fi
  284. if [ -f "${NAME}.key" ]; then
  285. copyPem "${NAME}.key" ${CAFOLDER}/private/${CAKEY} PRIVATE
  286. else
  287. echo "CA Private Key missing (${NAME}.key)"
  288. exit -1
  289. fi
  290. if [ -f "${NAME}.${PASSEXTENSION}" ]; then
  291. cp "${NAME}.${PASSEXTENSION}" ${CAFOLDER}/private/${PASSFILE}
  292. chmod 000 ${CAFOLDER}/private/${PASSFILE}
  293. else
  294. echo "CA Private Key Keyfile missing (${NAME}.${PASSEXTENSION})"
  295. fi
  296. if [ -f "${NAME}.crt" ]; then
  297. copyPem "${NAME}.crt" ${CAFOLDER}/${CACERT} CERTIFICATE
  298. else
  299. echo "CA Certificate missing (${NAME}.crt)"
  300. exit -1
  301. fi
  302. if [ -f "${NAME}.pem" ]; then
  303. COMMAND="cp \"${NAME}.pem\" ${CAFOLDER}/${CHAINFILE}"
  304. execute ${COMMAND}
  305. else
  306. echo "CA Chain missing (${NAME}.pem)"
  307. exit -1
  308. fi
  309. if [ ! -f "${CAFOLDER}/serial" ]; then
  310. COMMAND="$X509 -in ${CAFOLDER}/${CACERT} -noout -next_serial -out ${CAFOLDER}/serial"
  311. execute ${COMMAND}
  312. fi
  313. else
  314. COMMAND="$REQ -new -newkey rsa:${KEYBITS} -passout file:${CAFOLDER}/private/${PASSFILE} -keyout ${CAFOLDER}/private/${CAKEY} -out ${CAFOLDER}/${CAREQ}"
  315. if [ ! -z "${CN}" ]; then
  316. SUBJECT="/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${E}"
  317. COMMAND+=" -subj \"${SUBJECT}\""
  318. fi
  319. execute ${COMMAND}
  320. COMMAND="$CA -create_serial -out ${CAFOLDER}/${CACERT} ${DAYS} -batch -keyfile ${CAFOLDER}/private/${CAKEY} -passin file:${CAFOLDER}/private/${PASSFILE} -selfsign -name ${EXTENSIONS} -infiles ${CAFOLDER}/${CAREQ}"
  321. execute ${COMMAND}
  322. copyPem ${CAFOLDER}/${CACERT} ${CAFOLDER}/${CACERT}.tmp CERTIFICATE
  323. COMMAND="mv ${CAFOLDER}/${CACERT}.tmp ${CAFOLDER}/${CACERT}"
  324. execute ${COMMAND}
  325. COMMAND="cp ${CAFOLDER}/${CACERT} ${CAFOLDER}/${CHAINFILE}"
  326. execute ${COMMAND}
  327. fi
  328. fi
  329. generateCrl
  330. }
  331. renewCertificate() {
  332. revokeCertificate
  333. signRequest
  334. }
  335. renewCertificateAuthorityCertificate() {
  336. # TODO
  337. if [ ! -d ${CAFOLDER} ]; then
  338. echo "Missing CA Folder"
  339. exit -1
  340. fi
  341. echo "Not implemented"
  342. }
  343. signCertificate() {
  344. if [ ! -d ${CAFOLDER} ]; then
  345. echo "Missing CA Folder"
  346. exit -1
  347. fi
  348. if [ ! -f "${FILENAME}.csr" ]; then
  349. echo "Missing Certificate Request"
  350. exit -1
  351. fi
  352. COMMAND="${X509} -x509toreq -signkey \"${FILENAME}.key\" -in \"${FILENAME}.csr\" -out temporary.pem"
  353. execute ${COMMAND}
  354. COMMAND="${CA} -policy policy_anything -passin file:${CAFOLDER}/private/${PASSFILE} ${DAYS} -out \"${FILENAME}.crt\" -infiles temporary.pem"
  355. execute ${COMMAND}
  356. copyPem "${FILENAME}.crt" "${FILENAME}.crt.tmp" CERTIFICATE
  357. COMMAND="mv \"${FILENAME}.crt.tmp\" \"${FILENAME}.crt\""
  358. execute ${COMMAND}
  359. COMMAND="cat \"${FILENAME}.crt\" ${CAFOLDER}/${CHAINFILE} > \"${FILENAME}.pem\""
  360. execute ${COMMAND}
  361. }
  362. signRequest() {
  363. if [ ! -d ${CAFOLDER} ]; then
  364. echo "Missing CA Folder"
  365. exit -1
  366. fi
  367. if [ ! -f "${FILENAME}.csr" ]; then
  368. echo "Missing Certificate Request"
  369. exit -1
  370. fi
  371. if [[ "${TYPE}" == "WEBSERVER" ]]; then
  372. EXTENSIONS="server_cert"
  373. fi
  374. if [[ "${TYPE}" == "WEBCLIENT" ]]; then
  375. EXTENSIONS="client_cert"
  376. fi
  377. if [[ "${TYPE}" == "APPLICATIONCLIENT" ]]; then
  378. EXTENSIONS="application_cert"
  379. fi
  380. if [[ "${TYPE}" == "EMAIL" ]]; then
  381. EXTENSIONS="email_cert"
  382. fi
  383. if [[ "${TYPE}" == "VPN" ]]; then
  384. EXTENSIONS="vpn_cert"
  385. fi
  386. if [[ "${TYPE}" == "INTERMEDIATECA" ]]; then
  387. DAYS=${CADAYS}
  388. EXTENSIONS="intermediate_extensions"
  389. fi
  390. COMMAND="${CA} -policy policy_match -passin file:${CAFOLDER}/private/${PASSFILE} -name CA_intermediate -extensions ${EXTENSIONS} ${DAYS} -out \"${FILENAME}.crt\" -infiles \"${FILENAME}.csr\""
  391. execute ${COMMAND}
  392. copyPem "${FILENAME}.crt" "${FILENAME}.crt.tmp" CERTIFICATE
  393. COMMAND="mv \"${FILENAME}.crt.tmp\" \"${FILENAME}.crt\""
  394. execute ${COMMAND}
  395. COMMAND="cat \"${FILENAME}.crt\" ${CAFOLDER}/${CHAINFILE} > \"${FILENAME}.pem\""
  396. execute ${COMMAND}
  397. }
  398. signCertificateAuthorityCertificate() {
  399. # TODO
  400. if [ ! -d ${CAFOLDER} ]; then
  401. echo "Missing CA Folder"
  402. exit -1
  403. fi
  404. # $CA -policy policy_anything -out newcert.pem -extensions v3_ca -infiles newreq.pem
  405. # RET=$?
  406. echo "Not implemented"
  407. }
  408. signRequestAnything() {
  409. # TODO
  410. if [ ! -d ${CAFOLDER} ]; then
  411. echo "Missing CA Folder"
  412. exit -1
  413. fi
  414. # $CA -policy policy_anything -infiles newreq.pem
  415. # RET=$?
  416. echo "Not implemented"
  417. }
  418. createCertificatePackage() {
  419. if [ ! -d ${CAFOLDER} ]; then
  420. echo "Missing CA Folder"
  421. exit -1
  422. fi
  423. if [ ! -f "${FILENAME}.crt" ]; then
  424. echo "Missing Certificate"
  425. exit -1
  426. fi
  427. if [ ! -f "${FILENAME}.key" ]; then
  428. echo "Missing Private Key"
  429. exit -1
  430. fi
  431. CACERTCN=$(${X509} -noout -subject -nameopt multiline -in ${CAFOLDER}/${CACERT} | sed -n 's/ *commonName *= //p')
  432. COMMAND="${PKCS12} -in \"${FILENAME}.crt\" -inkey \"${FILENAME}.key\" -certfile ${CAFOLDER}/${CHAINFILE} -caname \"${CACERTCN}\" -out \"${FILENAME}.p12\" -export -name \"${FILENAME}\""
  433. execute ${COMMAND}
  434. }
  435. generateCrl() {
  436. if [ ! -d ${CAFOLDER} ]; then
  437. echo "Missing CA Folder"
  438. exit -1
  439. fi
  440. COMMAND="${CA} -passin file:${CAFOLDER}/private/${PASSFILE} -gencrl -out ${CAFOLDER}/crl/crl.pem"
  441. execute ${COMMAND}
  442. COMMAND="cat ${CAFOLDER}/${CHAINFILE} ${CAFOLDER}/crl/crl.pem > ${CAFOLDER}/crl/crl_chain.pem"
  443. execute ${COMMAND}
  444. }
  445. revokeCertificate() {
  446. if [ ! -d ${CAFOLDER} ]; then
  447. echo "Missing CA Folder"
  448. exit -1
  449. fi
  450. if [ ! -f "${FILENAME}.crt" ]; then
  451. echo "Missing Certificate"
  452. exit -1
  453. fi
  454. COMMAND="${CA} -passin file:${CAFOLDER}/private/${PASSFILE} -revoke \"${FILENAME}.crt\""
  455. execute ${COMMAND}
  456. COMMAND="mv \"${FILENAME}.crt\" \"${FILENAME}.crt.revoked\""
  457. execute ${COMMAND}
  458. generateCrl
  459. }
  460. verifyCertificate() {
  461. if [ ! -d ${CAFOLDER} ]; then
  462. echo "Missing CA Folder"
  463. exit -1
  464. fi
  465. if [ ! -f "${FILENAME}.crt" ]; then
  466. echo "Missing Certificate"
  467. exit -1
  468. fi
  469. COMMAND="${VERIFY} -CAfile ${CAFOLDER}/${CHAINFILE} \"${FILENAME}.crt\""
  470. execute ${COMMAND}
  471. COMMAND="${VERIFY} -crl_check -CAfile ${CAFOLDER}/crl/crl_chain.pem \"${FILENAME}.crt\""
  472. execute ${COMMAND}
  473. }
  474. printHelp() {
  475. echo "" >&2
  476. echo "usage: $0 <OPERATION> -t <TYPE> [--san <SAN>] [--ip <IP>] [COMMON NAME]" >&2
  477. echo "" >&2
  478. echo " Certificate Types:" >&2
  479. echo " ROOTCA " >&2
  480. echo " INTERMEDIATECA " >&2
  481. echo " VPNCA " >&2
  482. echo " WEBSERVER " >&2
  483. echo " WEBCLIENT " >&2
  484. echo " APPLICATIONCLIENT " >&2
  485. echo " EMAIL " >&2
  486. echo " VPN " >&2
  487. echo "" >&2
  488. echo " Operations:" >&2
  489. echo " -c|--newcert Create a new certificate and private key" >&2
  490. echo " -n|--newreq Create a new certificate request and private key" >&2
  491. echo " --newca Create a new certificate authority" >&2
  492. echo " -r|--renewcert Renew an existing certificate (requires a certificate request)" >&2
  493. #echo " --renewca Renew the certificate authority certificate" >&2
  494. echo " --signcert Sign a certificate with the certificate authority" >&2
  495. echo " -s|--signreq Create and sign a new certificate with the certificate autority" >&2
  496. #echo " --signca Sign the certificate authority certificate" >&2
  497. #echo " --xsign Sign the certificate request with the certificate authority using the 'policy_anything' option" >&2
  498. echo " -p|--pkcs12 Create pkcs12 package containing the certificate and its private key" >&2
  499. echo " --revoke Revoke a certificate" >&2
  500. echo " --crl Generate CRL file" >&2
  501. echo " -v|--verify Verify a certificate" >&2
  502. echo " -h|--help Display this help message" >&2
  503. echo "" >&2
  504. }
  505. #------ Commandline parsing ------
  506. shopt -s nocasematch
  507. EXTRASAN=()
  508. EXTRAIP=()
  509. POSITIONAL=()
  510. while [[ $# -gt 0 ]]; do
  511. key="$1"
  512. case $key in
  513. -t|--type)
  514. validateType ${2}
  515. shift # past argument
  516. shift # past value
  517. ;;
  518. -c|--newcert)
  519. OPERATION="newCertificate"
  520. shift # past argument
  521. ;;
  522. -n|--newreq)
  523. OPERATION="newRequest"
  524. shift # past argument
  525. ;;
  526. --newca)
  527. OPERATION="newCertificateAuthority"
  528. shift # past argument
  529. ;;
  530. -r|--renewcert)
  531. OPERATION="renewCertificate"
  532. shift # past argument
  533. ;;
  534. #--renewca)
  535. # OPERATION="renewCertificateAuthorityCertificate"
  536. #
  537. # shift # past argument
  538. # ;;
  539. --signcert)
  540. OPERATION="signCertificate"
  541. shift # past argument
  542. ;;
  543. -s|--signreq)
  544. OPERATION="signRequest"
  545. shift # past argument
  546. ;;
  547. #--signca)
  548. # OPERATION="signCertificateAuthorityCertificate"
  549. #
  550. # shift # past argument
  551. # ;;
  552. #--xsign)
  553. # OPERATION="signRequestAnything"
  554. #
  555. # shift # past argument
  556. # ;;
  557. -p|--pkcs12)
  558. OPERATION="createCertificatePackage"
  559. shift # past argument
  560. ;;
  561. --revoke)
  562. OPERATION="revokeCertificate"
  563. shift # past argument
  564. ;;
  565. --crl)
  566. OPERATION="generateCrl"
  567. shift # past argument
  568. ;;
  569. -v|--verify)
  570. OPERATION="verifyCertificate"
  571. shift # past argument
  572. ;;
  573. --san)
  574. EXTRASAN+=("$2")
  575. shift # past argument
  576. shift # past value
  577. ;;
  578. --ip)
  579. EXTRAIP+=("$2")
  580. shift # past argument
  581. shift # past value
  582. ;;
  583. -h|--help)
  584. OPERATION="printHelp"
  585. shift # past argument
  586. ;;
  587. *)
  588. POSITIONAL+=("$1")
  589. shift # past argument
  590. ;;
  591. esac
  592. done
  593. FILENAME="newCertificate"
  594. if (( ${#POSITIONAL[@]} )); then
  595. CN=${POSITIONAL[0]}
  596. FILENAME=${CN}
  597. fi
  598. if [[ -z "${TYPE}" &&
  599. -f "${CAFOLDER}/${TYPEFILE}" ]]; then
  600. TYPE=$(<${CAFOLDER}/${TYPEFILE})
  601. validateType ${TYPE}
  602. fi
  603. if [[ -z "${TYPE}" &&
  604. "${OPERATION}" != "revokeCertificate" &&
  605. "${OPERATION}" != "generateCrl" &&
  606. "${OPERATION}" != "verifyCertificate" &&
  607. "${OPERATION}" != "createCertificatePackage" &&
  608. "${OPERATION}" != "printHelp" ]]; then
  609. echo "Error: missing certificate type" >&2
  610. printHelp
  611. exit -1
  612. fi
  613. if [[ ! -z "${TYPE}" &&
  614. -z "${VALIDTYPE}" &&
  615. "${OPERATION}" != "revokeCertificate" &&
  616. "${OPERATION}" != "generateCrl" &&
  617. "${OPERATION}" != "verifyCertificate" &&
  618. "${OPERATION}" != "createCertificatePackage" &&
  619. "${OPERATION}" != "printHelp" ]]; then
  620. echo "Error: invalid certificate type" >&2
  621. printHelp
  622. exit -1
  623. fi
  624. if [ -z "${OPERATION}" ]; then
  625. echo "Error: missing operation" >&2
  626. printHelp
  627. exit -1
  628. fi
  629. TYPE=${VALIDTYPE}
  630. eval ${OPERATION}
  631. exit 0