make-ca 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850
  1. #!/bin/bash
  2. # Begin /usr/milis/bin/make-ca
  3. # Not: url deki cerdata.txt i indir make-ca -f -g komutla
  4. # Script to create p11-kit anchors, OpenSSL certs directory, GnuTLS certificate
  5. # bundle, NSS shared DB, and Java cacerts from upstream certdata.txt and local
  6. # sources
  7. #
  8. # Authors: DJ Lucas
  9. # Bruce Dubbs
  10. # Graham Weldon
  11. VERSION="1.4"
  12. MAKE_CA_CONF="/etc/make-ca.conf"
  13. # Get/set defaults
  14. if test -f "${MAKE_CA_CONF}"; then
  15. . "${MAKE_CA_CONF}"
  16. else
  17. CERTDATA="certdata.txt"
  18. PKIDIR="/etc/pki"
  19. SSLDIR="/etc/ssl"
  20. CERTUTIL="/usr/bin/certutil"
  21. KEYTOOL="${JAVA_HOME}/bin/keytool"
  22. MD5SUM="/usr/bin/md5sum"
  23. OPENSSL="/usr/bin/openssl"
  24. TRUST="/usr/bin/trust"
  25. ANCHORDIR="${PKIDIR}/anchors"
  26. ANCHORLIST="${PKIDIR}/anchors.md5sums"
  27. BUNDLEDIR="${PKIDIR}/tls/certs"
  28. CABUNDLE="${BUNDLEDIR}/ca-bundle.crt"
  29. SMBUNDLE="${BUNDLEDIR}/email-ca-bundle.crt"
  30. CSBUNDLE="${BUNDLEDIR}/objsign-ca-bundle.crt"
  31. CERTDIR="${SSLDIR}/certs"
  32. KEYSTORE="${CERTDIR}/java"
  33. NSSDB="${PKIDIR}/nssdb"
  34. LOCALDIR="${SSLDIR}/local"
  35. DESTDIR=""
  36. URL="https://hg.mozilla.org/releases/mozilla-release/raw-file/default/security/nss/lib/ckfw/builtins/certdata.txt"
  37. fi
  38. # Some data in the certs have UTF-8 characters
  39. # It doesn't really matter which locale, change if you like
  40. export LANG=en_US.utf8
  41. TEMPDIR=$(mktemp -d)
  42. WORKDIR="${TEMPDIR}/work"
  43. CERTDATAY=0
  44. FORCE=0
  45. GET=0
  46. REBUILD=0
  47. WITH_P12=0
  48. WITH_NSS=0
  49. function get_args(){
  50. while test -n "${1}" ; do
  51. case "${1}" in
  52. -C | --certdata)
  53. if test "${REBUILD}" == "0" -a "${GET}" == "0"; then
  54. check_arg $1 $2
  55. CERTDATA="${2}"
  56. CERTDATAY="1"
  57. shift 2
  58. else
  59. echo "Error: ${1} cannot be used with the -r/--rebuild or -g/--get switches."
  60. exit 3
  61. fi
  62. if test ! -f "${CERTDATA}" -a "${GET}" == "0"; then
  63. echo "Error: ${CERTDATA} not found!"
  64. exit 3
  65. fi
  66. ;;
  67. -D | --destdir)
  68. check_arg $1 $2
  69. DESTDIR="${2}"
  70. shift 2
  71. ;;
  72. -P | --pkidir)
  73. check_arg $1 $2
  74. PKIDIR="${2}"
  75. ANCHORDIR="${PKIDIR}/anchors"
  76. NSSDB="${PKIDIR}/nssdb"
  77. echo "${@}" | grep -e "-a " -e "--anchordir" \
  78. -e "-n " -e "--nssdb" > /dev/null
  79. if test "${?}" == "0"; then
  80. echo "Error! ${1} cannot be used with the -a/--anchordir or -n/--nssdb switches."
  81. echo ""
  82. exit 3
  83. fi
  84. shift 2
  85. ;;
  86. -S | --ssldir)
  87. check_arg $1 $2
  88. SSLDIR="${2}"
  89. CERTDIR="${SSLDIR}/certs"
  90. LOCALDIR="${SSLDIR}/local"
  91. echo "${@}" | grep -e "-d " -e "--cadir" > /dev/null 2>&1
  92. if test "${?}" == "0"; then
  93. echo "Error! ${1} cannot be used with the -d/--cadir switch."
  94. echo ""
  95. exit 3
  96. fi
  97. shift 2
  98. ;;
  99. -a | --anchordir)
  100. check_arg $1 $2
  101. ANCHORDIR="${2}"
  102. echo "${@}" | grep -e "-P " -e "--pkidir" > /dev/null 2>&1
  103. if test "${?}" == "0"; then
  104. echo "Error! ${1} cannot be used with the -P/--pkidir switch."
  105. echo ""
  106. exit 3
  107. fi
  108. shift 2
  109. ;;
  110. -b | --bundledir)
  111. check_arg $1 $2
  112. BUNDLEDIR="${2}"
  113. shift 2
  114. ;;
  115. -d | --cadir)
  116. check_arg $1 $2
  117. CERTDIR="${2}"
  118. echo "$@" | grep -e "-S" -e "--ssldir" > /dev/null 2>&1
  119. if test "${?}" == "0"; then
  120. echo "Error! ${1} cannot be used with the -S/--ssldir switch."
  121. echo ""
  122. exit 3
  123. fi
  124. shift 2
  125. ;;
  126. -g | --get)
  127. if test "${REBUILD}" == "0" -a "${CERTDATAY}" == "0"; then
  128. GET="1"
  129. CERTDATA="${TEMPDIR}/certdatanew.txt"
  130. shift 1
  131. else
  132. echo "Error: ${1} cannot be used with the -r/--rebuild or -C/--certdata switches."
  133. exit 3
  134. fi
  135. ;;
  136. -j | --javacerts)
  137. check_arg $1 $2
  138. KEYSTORE="${2}"
  139. shift 2
  140. ;;
  141. -k | --keytool)
  142. check_arg $1 $2
  143. KEYTOOL="${2}"
  144. shift 2
  145. ;;
  146. -l | --localdir)
  147. check_arg $1 $2
  148. LOCALDIR="${2}"
  149. shift 2
  150. ;;
  151. -m | --java-p12)
  152. WITH_P12="1"
  153. shift 1
  154. ;;
  155. -n | --nssdb)
  156. echo "${2}" | grep -v "^-" > /dev/null
  157. if [ "$?" -ne "0" -o ! -n "$2" ]; then
  158. WITH_NSS="1"
  159. shift 1
  160. else
  161. NSSDB="${2}"
  162. WITH_NSS="1"
  163. echo "${@}" | grep -e "-P " -e "--pkidir" > /dev/null
  164. if test "${?}" == "0"; then
  165. echo "Error! ${1} cannot be used with both an argument and the -P/--pkidir switch."
  166. echo ""
  167. exit 3
  168. fi
  169. shift 2
  170. fi
  171. ;;
  172. -p | --proxy)
  173. check_arg $1 $2
  174. PROXY="${2}"
  175. shift 2
  176. ;;
  177. -r | --rebuild)
  178. if test "${CERTDATAY}" == "0" -a "${GET}" == "0"; then
  179. REBUILD="1"
  180. FORCE="1"
  181. shift 1
  182. else
  183. echo "Error: ${1} cannot be used with the -C/--certdata or -g/--get switches."
  184. exit 3
  185. fi
  186. ;;
  187. -s | --openssl)
  188. check_arg $1 $2
  189. OPENSSL="${2}"
  190. shift 2
  191. ;;
  192. -t | --certutil)
  193. check_arg $1 $2
  194. CERTUTIL="${2}"
  195. WITH_NSS="1"
  196. shift 2
  197. ;;
  198. -u | --trust)
  199. check_arg $1 $2
  200. TRUST="${2}"
  201. shift 2
  202. ;;
  203. -f | --force)
  204. FORCE="1"
  205. shift 1
  206. ;;
  207. -h | --help)
  208. showhelp
  209. exit 0
  210. ;;
  211. -v | --version)
  212. echo -e "$(basename ${0}) ${VERSION}\n"
  213. exit 0
  214. ;;
  215. *)
  216. showhelp
  217. exit 1
  218. ;;
  219. esac
  220. done
  221. }
  222. function check_arg(){
  223. echo "${2}" | grep "^-" > /dev/null
  224. if [ "$?" == "0" -o ! -n "$2" ]; then
  225. echo "Error: $1 requires a valid argument."
  226. exit 1
  227. fi
  228. }
  229. function showhelp(){
  230. echo ""
  231. echo "`basename ${0}` is a utility to deliver and manage a complete PKI configuration"
  232. echo "for workstaitons and servers using only standard Unix utilities and OpenSSL. It"
  233. echo "will optionally generate keystores for OpenJDK and NSS if already installed,"
  234. echo "using a Mozilla cacerts.txt or like formatted file. It was originally developed"
  235. echo "for use with Linux From Scratch to minimize dependencies for early system"
  236. echo "build, but has been written to be generic enough for any Linux distribution."
  237. echo ""
  238. echo " -C, --certdata [certdata.txt]"
  239. echo " The location of the certificates source"
  240. echo ""
  241. echo " -D, --destdir [/]"
  242. echo " Change the output directory and use relative"
  243. echo " paths for all other values"
  244. echo ""
  245. echo " -P, --pkidir [/etc/pki]"
  246. echo " The output PKI directory - Cannot be used with"
  247. echo " the -a / --anchordir or -n / --nssdb switches"
  248. echo ""
  249. echo " -S, --ssldir [/etc/ssl]"
  250. echo " The output SSL root direcotry - Cannot be used"
  251. echo " with the -d / --cadir switch"
  252. echo ""
  253. echo " -a, --anchordir [\$PKIDIR/anchors]"
  254. echo " The output directory for OpenSSL trusted"
  255. echo " CA certificates used as trust anchors"
  256. echo ""
  257. echo " -b, --bundledir [\$PKIDIR/certs]"
  258. echo " The output direcotry for the PEM formated bundles"
  259. echo ""
  260. echo " -d, --cadir [\$SSLDIR/certs]"
  261. echo " The output directory for the OpenSSL trusted"
  262. echo " CA certificates"
  263. echo ""
  264. echo " -j, --javacerts [\$PKIDIR/java/cacerts]"
  265. echo " The output directory for the Java cacerts file(s)"
  266. echo ""
  267. echo " -l, --localdir [\$SSLDIR/local]"
  268. echo " The path to a local set of OpenSSL trusted"
  269. echo " certificates, used to both override trust bits"
  270. echo " from upstream sources and provide system local"
  271. echo " certifiates"
  272. echo ""
  273. echo " -m, --java-p12"
  274. echo " Export Java PKCS#12 store - will default to"
  275. echo " \$PKIDIR/java/cacerts.p12 unless modified by"
  276. echo " the '-j/--javacerts' switch"
  277. echo ""
  278. echo " -n, --nssdb {\$PKIDIR/nssdb}"
  279. echo " The output path for the shared NSS DB"
  280. echo ""
  281. echo " -p, --proxy [URI:PORT]"
  282. echo " Use proxy server for download"
  283. echo ""
  284. echo " -k, --keytool [\$JAVA_HOME/bin/keytool]"
  285. echo " The path of the Java keytool utility"
  286. echo ""
  287. echo " -s, --openssl [/usr/bin/openssl]"
  288. echo " The path of the openssl utility"
  289. echo ""
  290. echo " -t, --certutil [/usr/bin/certutil]"
  291. echo " The path of the NSS certutil utility"
  292. echo ""
  293. echo " -u, --trust [/usr/bin/trust]"
  294. echo " The path of the p11-kit trust utility"
  295. echo ""
  296. echo " -f, --force Force run, even if source is not newer"
  297. echo ""
  298. echo " -g, --get Download certdata.txt directly from Mozilla's"
  299. echo " Mecurial server"
  300. echo ""
  301. echo " -h, --help Show this help message and exit"
  302. echo ""
  303. echo " -r, --rebuild Rebuild the enitre PKI tree using the previous"
  304. echo " certdata.txt file"
  305. echo ""
  306. echo " -v. --version Show version information and exit"
  307. echo ""
  308. echo "Example: `basename ${0}` -f -C ~/certdata.txt"
  309. echo ""
  310. }
  311. # Convert CKA_TRUST values to trust flags for certutil
  312. function convert_trust(){
  313. case $1 in
  314. CKT_NSS_TRUSTED_DELEGATOR)
  315. echo "C"
  316. ;;
  317. CKT_NSS_NOT_TRUSTED)
  318. echo "p"
  319. ;;
  320. CKT_NSS_MUST_VERIFY_TRUST)
  321. echo ""
  322. ;;
  323. esac
  324. }
  325. function convert_trust_arg(){
  326. case $1 in
  327. C)
  328. case $2 in
  329. sa)
  330. echo "-addtrust serverAuth"
  331. ;;
  332. sm)
  333. echo "-addtrust emailProtection"
  334. ;;
  335. cs)
  336. echo "-addtrust codeSigning"
  337. ;;
  338. ca)
  339. echo "-addtrust clientAuth"
  340. ;;
  341. esac
  342. ;;
  343. p)
  344. case $2 in
  345. sa)
  346. echo "-addreject serverAuth"
  347. ;;
  348. sm)
  349. echo "-addreject emailProtection"
  350. ;;
  351. cs)
  352. echo "-addreject codeSigning"
  353. ;;
  354. ca)
  355. echo "-addreject clientAuth"
  356. ;;
  357. esac
  358. ;;
  359. *)
  360. echo ""
  361. ;;
  362. esac
  363. }
  364. # Define p11-kit ext value constants (see p11-kit API documentation)
  365. function get-p11-val() {
  366. case $1 in
  367. p11sasmcs)
  368. p11value="0%2a%06%03U%1d%25%01%01%ff%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
  369. ;;
  370. p11sasm)
  371. p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01"
  372. ;;
  373. p11sacs)
  374. p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
  375. ;;
  376. p11sa)
  377. p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%01"
  378. ;;
  379. p11smcs)
  380. p11value="0 %06%03U%1d%25%01%01%ff%04%160%14%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%03"
  381. ;;
  382. p11sm)
  383. p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%04"
  384. ;;
  385. p11cs)
  386. p11value="0%16%06%03U%1d%25%01%01%ff%04%0c0%0a%06%08%2b%06%01%05%05%07%03%03"
  387. ;;
  388. p11)
  389. p11value="0%18%06%03U%1d%25%01%01%ff%04%0e0%0c%06%0a%2b%06%01%04%01%99w%06%0a%10"
  390. ;;
  391. esac
  392. }
  393. function get_p11_label() {
  394. # $1 == individual nss certificate extracted from certdata.txt
  395. # or x509 certificate with OpenSSL text values
  396. p11label="$(grep -m1 "Issuer" ${1} | grep -o CN=.*$ | \
  397. cut -d ',' -f 1 | sed 's@CN=@@')"
  398. # Fallback to the OU value if CN does not exeist in Issuer string
  399. if [ "${p11label}" == "" ]; then
  400. p11label="$(grep -m1 "Issuer" ${1} | grep -o "OU=.*$" | \
  401. cut -d ',' -f 1 | sed 's@OU=@@')"
  402. # If still empty, fall back to Object value as a last resort
  403. if [ "${p11label}" == "" ]; then
  404. p11label="$(grep -m1 "Issuer" ${1} | grep -o "O=.*$" | \
  405. cut -d ',' -f 1 | sed 's@O=@@')"
  406. fi
  407. fi
  408. }
  409. function get_trust_values() {
  410. # $1 == indiviual certificate extracted from NSS certdata.txt
  411. # Determine certificate trust values for SSL/TLS, S/MIME, and Code Signing
  412. satrust="$(convert_trust `grep '^CKA_TRUST_SERVER_AUTH' ${1} | \
  413. cut -d " " -f 3`)"
  414. smtrust="$(convert_trust `grep '^CKA_TRUST_EMAIL_PROTECTION' ${1} | \
  415. cut -d " " -f 3`)"
  416. cstrust="$(convert_trust `grep '^CKA_TRUST_CODE_SIGNING' ${1} | \
  417. cut -d " " -f 3`)"
  418. # Not currently included in NSS certdata.txt
  419. #catrust="$(convert_trust `grep '^CKA_TRUST_CLIENT_AUTH' ${1} | \
  420. # cut -d " " -f 3`)"
  421. }
  422. function get_p11_trust() {
  423. # if distrusted at all, x-distrusted
  424. if test "${satrust}" == "p" -o "${smtrust}" == "p" -o "${cstrust}" == "p"
  425. then
  426. # if any distrusted, x-distrusted
  427. p11trust="x-distrusted: true"
  428. p11oid="1.3.6.1.4.1.3319.6.10.1"
  429. p11value="0.%06%0a%2b%06%01%04%01%99w%06%0a%01%04 0%1e%06%08%2b%06%01%05%05%07%03%04%06%08%2b%06%01%05%05%07%03%01%06%08%2b%06%01%05%05%07%03%03"
  430. else
  431. p11trust="trusted: true"
  432. p11oid="2.5.29.37"
  433. trustp11="p11"
  434. if test "${satrust}" == "C"; then
  435. trustp11="${trustp11}sa"
  436. fi
  437. if test "${smtrust}" == "C"; then
  438. trustp11="${trustp11}sm"
  439. fi
  440. if test "${cstrust}" == "C"; then
  441. trustp11="${trustp11}cs"
  442. fi
  443. get-p11-val "${trustp11}"
  444. fi
  445. }
  446. function write_anchor() {
  447. echo "[p11-kit-object-v1]" >> "${anchorfile}"
  448. echo "label: \"${p11label}\"" >> "${anchorfile}"
  449. echo "class: x-certificate-extension" >> "${anchorfile}"
  450. echo "object-id: ${p11oid}" >> "${anchorfile}"
  451. echo "value: \"${p11value}\"" >> "${anchorfile}"
  452. echo "modifiable: false" >> "${anchorfile}"
  453. echo "${certkey}" >> "${anchorfile}"
  454. echo "" >> "${anchorfile}"
  455. echo "[p11-kit-object-v1]" >> "${anchorfile}"
  456. echo "label: \"${p11label}\"" >> "${anchorfile}"
  457. echo "${p11trust}" >> "${anchorfile}"
  458. echo "nss-mozilla-ca-policy: ${moz_trust}" >> "${anchorfile}"
  459. echo "modifiable: false" >> "${anchorfile}"
  460. echo "${certcer}" >> "${anchorfile}"
  461. echo "${certtxt}" | sed 's@^@#@' >> "${anchorfile}"
  462. echo "Added to p11-kit anchor directory with trust '${satrust},${smtrust},${cstrust}'."
  463. }
  464. function write_nss_db() {
  465. # $1 == NSS database
  466. # $2 == x509 certificate in PEM format
  467. "${CERTUTIL}" -d "sql:${1}" -A \
  468. -t "${satrust},${smtrust},${cstrust}" \
  469. -n "${certname}" -i "${2}"
  470. echo "Added to NSS shared DB with trust '${satrust},${smtrust},${cstrust}'."
  471. }
  472. function write_java_p12() {
  473. # $1 == cacerts.p12 file
  474. # $2 == x509 certificate in PEM format
  475. # Remove existing certificate
  476. "${KEYTOOL}" -delete -noprompt -alias "${certname}" \
  477. -keystore "${1}" \
  478. -storepass 'changeit' > /dev/null 2>&1
  479. # Determine ExtendedKeyUsage
  480. EKU=""
  481. EKUVAL=""
  482. if test "${satrust}" == "C"; then EKU="serverAuth"; fi
  483. if test "${smtrust}" == "C"; then
  484. if test "${EKU}" == ""; then
  485. EKU="clientAuth"
  486. else
  487. EKU="${EKU},clientAuth"
  488. fi
  489. fi
  490. if test "${cstrust}" == "C"; then
  491. if test "${EKU}" == ""; then
  492. EKU="codeSigning"
  493. else
  494. EKU="${EKU},codeSigning"
  495. fi
  496. fi
  497. if test "${EKU}" != ""; then
  498. EKUVAL="-ext EKU=${EKU}"
  499. "${KEYTOOL}" -importcert -file "${2}" -storetype PKCS12 \
  500. -noprompt -alias "${certname}" -storepass 'changeit' \
  501. -keystore "${1}" $EKUVAL \
  502. > /dev/null 2>&1 | \
  503. sed -e "s@Certificate was a@A@" \
  504. -e 's@keystore@Java cacerts (PKCS#12) with trust '${satrust},${smtrust},${cstrust}'.@' \
  505. | sed 's@p@@'
  506. unset EKU
  507. unset EKUVAL
  508. fi
  509. }
  510. # Process command line arguments
  511. get_args $@
  512. test ! -x "${OPENSSL}" && \
  513. echo "OpenSSL not found at ${OPENSSL}. Exiting..." && exit 1
  514. mkdir -p "${TEMPDIR}"/{certs,pki/anchors,work}
  515. if test "${WITH_P12}" -eq "1"; then
  516. test ! -x "${KEYTOOL}" && \
  517. echo "Java keytool not found at ${KEYTOOL}. Exiting..." && exit 1
  518. else
  519. mkdir -p "${TEMPDIR}/ssl/java"
  520. fi
  521. if test "${WITH_NSS}" -eq "1"; then
  522. test ! -x "${CERTUTIL}" && \
  523. echo "NSS certutil not found at ${CERTUTIL}. Exiting..." && exit 1
  524. # Create a blank NSS DB
  525. mkdir -p "${TEMPDIR}/pki/nssdb"
  526. "${CERTUTIL}" -N --empty-password -d "sql:${TEMPDIR}/pki/nssdb"
  527. fi
  528. # Download certdata.txt if selected
  529. if test "${GET}" == "1"; then
  530. HOST=$(echo "${URL}" | /usr/bin/cut -d / -f 3)
  531. _url=$(echo "${URL}" | sed 's@raw-file@log@')
  532. SARGS="-ign_eof -connect ${HOST}:443"
  533. if test "${PROXY}x" != "x"; then
  534. SARGS="${SARGS} -proxy ${PROXY}"
  535. fi
  536. echo GET ${_url} | \
  537. ${OPENSSL} s_client ${SARGS} 2> /dev/null > "${TEMPDIR}/certdata.txt.log"
  538. unset _url
  539. # Error out here if we couldn't get the file
  540. grep -m1 "<i>" "${TEMPDIR}/certdata.txt.log" > /dev/null 2>&1
  541. if test "$?" -gt 0; then
  542. echo "Unable to get revision from server! Exiting."
  543. exit 1
  544. fi
  545. # See if we need to update before downloading the file
  546. REVISION=$(grep -m1 "<i>" "${TEMPDIR}/certdata.txt.log" | cut -d "<" -f 1)
  547. if test -e "${DESTDIR}${SSLDIR}/certdata.txt"; then
  548. OLDVERSION=$(grep "^# Revision:" "${DESTDIR}${SSLDIR}/certdata.txt" | \
  549. cut -d ":" -f 2)
  550. if test "${OLDVERSION}x" == "${REVISION}x" -a "${FORCE}" == "0"; then
  551. echo "No update required! Use --force to update anyway."
  552. exit 0
  553. fi
  554. fi
  555. # Download the new file
  556. echo GET ${URL} | \
  557. ${OPENSSL} s_client ${SARGS} 2> /dev/null >> "${CERTDATA}"
  558. _line=$(( $(grep -n "certdata.txt" "${CERTDATA}" | cut -d ":" -f 1) - 1))
  559. sed -e "1,${_line}d" -i "${CERTDATA}"
  560. sed "1i # Revision:${REVISION}" -i "${CERTDATA}"
  561. fi
  562. if test "${REBUILD}" == "1"; then
  563. CERTDATA="${DESTDIR}${SSLDIR}/certdata.txt"
  564. fi
  565. if test ! -r "${CERTDATA}"; then
  566. echo "${CERTDATA} was not found. The certdata.txt file must be in the local"
  567. echo "directory, speficied with the -C/--certdata switch, or downloaded with"
  568. echo "the -g/--get switch."
  569. exit 1
  570. fi
  571. REVISION=$(grep "^# Revision" "${CERTDATA}" | cut -d ":" -f 2)
  572. if test "${REVISION}x" == "x"; then
  573. echo "WARNING! ${CERTDATA} has no 'Revision' value."
  574. echo "Will run conversion unconditionally."
  575. sleep 2
  576. REVISION="$(date -u +%Y%m%d-%H%M)"
  577. echo "# Revision:${REVISION}" > "${WORKDIR}/certdata.txt"
  578. else
  579. if test "${FORCE}" == "1"; then
  580. echo "Output forced. Will run conversion unconditionally."
  581. sleep 2
  582. elif test "${DESTDIR}x" == "x"; then
  583. test -f "${CABUNDLE}" &&
  584. OLDVERSION=$(grep "^# Revision:" "${CABUNDLE}" | cut -d ":" -f 2)
  585. if test "${OLDVERSION}x" == "${REVISION}x"; then
  586. echo "No update required! Use --force to update anyway."
  587. exit 0
  588. fi
  589. fi
  590. fi
  591. cat "${CERTDATA}" >> "${WORKDIR}/certdata.txt"
  592. pushd "${WORKDIR}" > /dev/null
  593. # Get a list of starting lines for each cert
  594. CERTBEGINLIST=`grep -n "^# Certificate" "${WORKDIR}/certdata.txt" | \
  595. cut -d ":" -f1`
  596. # Dump individual certs to temp file
  597. for certbegin in ${CERTBEGINLIST}; do
  598. awk "NR==$certbegin,/^CKA_TRUST_STEP_UP_APPROVED/" "${WORKDIR}/certdata.txt" \
  599. > "${TEMPDIR}/certs/${certbegin}.tmp"
  600. done
  601. unset CERTBEGINLIST certbegin
  602. for tempfile in ${TEMPDIR}/certs/*.tmp; do
  603. # Get a name for the cert
  604. certname="$(grep "^# Certificate" "${tempfile}" | cut -d '"' -f 2)"
  605. get_trust_values "${tempfile}"
  606. # Convert to a PEM formated certificate
  607. printf $(awk '/^CKA_VALUE/{flag=1;next}/^END/{flag=0}flag{printf $0}' \
  608. "${tempfile}") | "${OPENSSL}" x509 -text -inform DER -fingerprint \
  609. > tempfile.crt
  610. # Get individual values for certificates
  611. certkey="$(${OPENSSL} x509 -in tempfile.crt -noout -pubkey)"
  612. certcer="$(${OPENSSL} x509 -in tempfile.crt)"
  613. certtxt="$(${OPENSSL} x509 -in tempfile.crt -noout -text)"
  614. # Get p11-kit label, oid, and values
  615. get_p11_label "${tempfile}"
  616. # Get p11 trust and OID values
  617. get_p11_trust
  618. # Get a hash for the cert
  619. keyhash=$("${OPENSSL}" x509 -noout -in tempfile.crt -hash)
  620. # Print information about cert
  621. echo "Certificate: ${certname}"
  622. echo "Keyhash: ${keyhash}"
  623. # Place certificate into trust anchors dir
  624. anchorfile="${TEMPDIR}/pki/anchors/${keyhash}.pem"
  625. moz_trust="true"
  626. write_anchor
  627. # Import all certificates with trust args to the temporary NSS DB
  628. if test "${WITH_NSS}" == "1"; then
  629. write_nss_db ${TEMPDIR}/pki/nssdb tempfile.crt
  630. fi
  631. # Import all certificates with trust args to the java cacerts.p12 file
  632. if test "${WITH_P12}" == "1"; then
  633. write_java_p12 "${TEMPDIR}/ssl/java/cacerts.p12" tempfile.crt
  634. fi
  635. # Clean up the directory and environment as we go
  636. rm -f tempfile.crt
  637. unset keyhash subject count certname
  638. unset trustlist rejectlist satrust smtrust cstrust catrust
  639. unset p11trust p11oid p11value trustp11 p11label anchrorfile moz_trust
  640. echo -e "\n"
  641. done
  642. unset tempfile
  643. # Install anchors in $ANCHORDIR
  644. test -d "${DESTDIR}${ANCHORDIR}" && rm -rf "${DESTDIR}${ANCHORDIR}"
  645. install -dm755 "${DESTDIR}${ANCHORDIR}" > /dev/null 2>&1
  646. install -m644 "${TEMPDIR}"/pki/anchors/*.pem "${DESTDIR}${ANCHORDIR}"
  647. # Install NSS Shared DB
  648. if test "${WITH_NSS}" == "1"; then
  649. sed -e "s@${TEMPDIR}/pki/nssdb@${NSSDB}@" \
  650. -e 's/library=/library=libnsssysinit.so/' \
  651. -e 's/Flags=internal/Flags=internal,moduleDBOnly/' \
  652. -i "${TEMPDIR}/pki/nssdb/pkcs11.txt"
  653. test -d "${DESTDIR}${NSSDB}" && rm -rf "${DESTDIR}${NSSDB}"
  654. install -dm755 "${DESTDIR}${NSSDB}" > /dev/null 2>&1
  655. install -m644 "${TEMPDIR}"/pki/nssdb/{cert9.db,key4.db,pkcs11.txt} \
  656. "${DESTDIR}${NSSDB}"
  657. fi
  658. # Install Java cacerts.p12 in ${KEYSTORE}
  659. if test "${WITH_P12}" == "1"; then
  660. test -f "${DESTDIR}${KEYSTORE}/cacerts.p12" &&
  661. rm -f "${DESTDIR}${KEYSTORE}/cacerts.p12"
  662. install -dm644 "${TEMPDIR}/ssl/java/cacerts.p12" \
  663. "${DESTDIR}${KEYSTORE}/cacerts.p12"
  664. fi
  665. # Import any certs in $LOCALDIR
  666. # Don't do any checking, just trust the admin
  667. if test -d "${LOCALDIR}"; then
  668. echo "Processing local certificates..."
  669. for cert in `find "${LOCALDIR}" -name "*.pem"`; do
  670. # Get some information about the certificate
  671. keyhash=$("${OPENSSL}" x509 -noout -in "${cert}" -hash)
  672. subject=$("${OPENSSL}" x509 -noout -in "${cert}" -subject)
  673. # This will always be OpenSSL, values will be separated by spaces
  674. certname=$( echo "${subject}" | grep -o "CN = .*" | sed 's@CN = @@' | cut -d "," -f 1)
  675. echo "Certificate: ${certname}"
  676. echo "Keyhash: ${keyhash}"
  677. # Get trust information
  678. trustlist=$("${OPENSSL}" x509 -in "${cert}" -text -trustout | \
  679. grep -A1 "Trusted Uses")
  680. satrust=""
  681. smtrust=""
  682. cstrust=""
  683. catrust=""
  684. satrust=$(echo "${trustlist}" | \
  685. grep "TLS Web Server" > /dev/null 2>&1 && echo "C")
  686. smtrust=$(echo "${trustlist}" | \
  687. grep "E-mail Protection" > /dev/null 2>&1 && echo "C")
  688. cstrust=$(echo "${trustlist}" | \
  689. grep "Code Signing" > /dev/null 2>&1 && echo "C")
  690. catrust=$(echo "${trustlist}" | \
  691. grep "Client Auth" > /dev/null 2>&1 && echo "C")
  692. # Get reject information
  693. rejectlist=$("${OPENSSL}" x509 -in "${cert}" -text -trustout | \
  694. grep -A1 "Rejected Uses")
  695. if test "${satrust}" == ""; then satrust=$(echo "${rejectlist}" | \
  696. grep "TLS Web Server" > /dev/null 2>&1 && echo "p"); fi
  697. if test "${smtrust}" == ""; then smtrust=$(echo "${rejectlist}" | \
  698. grep "E-mail Protection" > /dev/null 2>&1 && echo "p"); fi
  699. if test "${cstrust}" == ""; then cstrust=$(echo "${rejectlist}" | \
  700. grep "Code Signing" > /dev/null 2>&1 && echo "p"); fi
  701. if test "${catrust}" == ""; then catrust=$(echo "${rejectlist}" | \
  702. grep "Client Auth" > /dev/null 2>&1 && echo "p"); fi
  703. # Get individual values for certificates
  704. certkey="$(${OPENSSL} x509 -in ${cert} -noout -pubkey)"
  705. certcer="$(${OPENSSL} x509 -in ${cert})"
  706. certtxt="$(${OPENSSL} x509 -in ${cert} -noout -text)"
  707. # Place certificate into trust anchors dir
  708. get_p11_label "${cert}"
  709. # Get p11 trust and OID values
  710. get_p11_trust
  711. # Place certificate into trust anchors dir
  712. anchorfile="${DESTDIR}${ANCHORDIR}/${keyhash}.pem"
  713. moz_trust="false"
  714. write_anchor
  715. # Generate working copy
  716. "${OPENSSL}" x509 -in "${cert}" -text -fingerprint > tempfile.crt
  717. # Add to Shared NSS DB
  718. if test "${WITH_NSS}" == "1"; then
  719. write_nss_db "${DESTDIR}${NSSDB}" tempfile.crt
  720. fi
  721. # Import certificate (with trust args) into the java cacerts.p12 file
  722. if test "${WITH_P12}" == "1"; then
  723. write_java_p12 "${DESTDIR}${KEYSTORE}/cacerts.p12" tempfile.crt
  724. fi
  725. unset keyhash subject count certname
  726. unset trustlist rejectlist satrust smtrust cstrust catrust
  727. unset p11trust p11oid p11value trustp11 p11label anchorfile moz_trust
  728. echo ""
  729. done
  730. unset cert
  731. fi
  732. # Install certdata.txt
  733. if test "${REBUILD}" == "0"; then
  734. install -vdm755 "${DESTDIR}${SSLDIR}"
  735. install -m644 "${WORKDIR}/certdata.txt" "${DESTDIR}${SSLDIR}/certdata.txt"
  736. fi
  737. # Clean up the mess
  738. popd
  739. rm -rf "${TEMPDIR}"
  740. # Build ANCHORLIST
  741. "${MD5SUM}" "${ANCHORDIR}"/*.pem > "${ANCHORLIST}"
  742. # Build alternate formats using p11-kit trust (if not using DESTDIR)
  743. if test "x${DESTDIR}" == "x"; then
  744. mkdir -p "${BUNDLEDIR}" "${KEYSTORE}"
  745. echo -n "Extracting OpenSSL certificates to ${CERTDIR}..."
  746. "${TRUST}" extract --filter=certificates --format=openssl-directory \
  747. --overwrite --comment "${CERTDIR}" \
  748. && echo "Done!" || echo "Failed!!!"
  749. echo -n "Extracting GNUTLS server auth certificates to ${CABUNDLE}..."
  750. "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \
  751. --purpose server-auth --overwrite --comment "${CABUNDLE}" \
  752. && echo "Done!" || echo "Failed!!!"
  753. echo -n "Extracting GNUTLS S-Mime certificates to ${SMBUNDLE}..."
  754. "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \
  755. --purpose email --overwrite --comment "${SMBUNDLE}" \
  756. && echo "Done!" || echo "Failed!!!"
  757. echo -n "Extracting GNUTLS code signing certificates to ${CSBUNDLE}..."
  758. "${TRUST}" extract --filter=ca-anchors --format=pem-bundle \
  759. --purpose code-signing --overwrite --comment \
  760. "${CSBUNDLE}" && echo "Done!" || echo "Failed!!!"
  761. echo -n "Extracting Java cacerts (JKS) to ${KEYSTORE}/cacerts..."
  762. "${TRUST}" extract --filter=ca-anchors --format=java-cacerts \
  763. --purpose server-auth --overwrite \
  764. --comment "${KEYSTORE}/cacerts" \
  765. && echo "Done!" || echo "Failed!!!"
  766. fi
  767. # End /usr/sbin/make-ca