cert-staple.sh 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. #!/bin/sh
  2. CERT_PEM="$1" # input (cert.pem)
  3. CHAIN_PEM="$2" # input (chain.pem)
  4. OCSP_DER="$3" # output symlink (staple.der)
  5. OCSP_TMP="" # temporary file
  6. if [ -z "$CERT_PEM" ] || [ -z "$CHAIN_PEM" ] || [ -z "$OCSP_DER" ] \
  7. || [ ! -f "$CERT_PEM" ] || [ ! -f "$CHAIN_PEM" ]; then
  8. echo 1>&2 "usage: cert-staple.sh cert.pem chain.pem staple.der"
  9. exit 1
  10. fi
  11. errexit() {
  12. [ -n "$OCSP_TMP" ] && rm -f "$OCSP_TMP"
  13. exit 1
  14. }
  15. # get URI of OCSP responder from certificate
  16. OCSP_URI=$(openssl x509 -in "$CERT_PEM" -ocsp_uri -noout)
  17. [ $? = 0 ] && [ -n "$OCSP_URI" ] || exit 1
  18. # exception for (unsupported, end-of-life) older versions of OpenSSL
  19. OCSP_HOST=
  20. OPENSSL_VERSION=$(openssl version)
  21. if [ "${OPENSSL_VERSION}" != "${OPENSSL_VERSION#OpenSSL 1.0.}" ]; then
  22. # get authority from URI
  23. OCSP_HOST=$(echo "$OCSP_URI" | cut -d/ -f3)
  24. fi
  25. # get OCSP response from OCSP responder
  26. OCSP_TMP="$OCSP_DER.$$"
  27. OCSP_RESP=$(openssl ocsp -issuer "$CHAIN_PEM" -cert "$CERT_PEM" -respout "$OCSP_TMP" -noverify -no_nonce -url "$OCSP_URI" ${OCSP_HOST:+-header Host "$OCSP_HOST"})
  28. [ $? = 0 ] || errexit
  29. # parse OCSP response from OCSP responder
  30. #
  31. #$CERT_PEM: good
  32. # This Update: Jun 5 21:00:00 2020 GMT
  33. # Next Update: Jun 12 21:00:00 2020 GMT
  34. ocsp_status="$(printf %s "$OCSP_RESP" | head -1)"
  35. [ "$ocsp_status" = "$CERT_PEM: good" ] || errexit
  36. next_update="$(printf %s "$OCSP_RESP" | grep 'Next Update:')"
  37. next_date="$(printf %s "$next_update" | sed 's/.*Next Update: //')"
  38. [ -n "$next_date" ] || errexit
  39. ocsp_expire=$(date -d "$next_date" +%s)
  40. # validate OCSP response
  41. ocsp_verify=$(openssl ocsp -issuer "$CHAIN_PEM" -verify_other "$CHAIN_PEM" -cert "$CERT_PEM" -respin "$OCSP_TMP" -no_nonce -out /dev/null 2>&1)
  42. [ "$ocsp_verify" = "Response verify OK" ] || errexit
  43. # rename and update symlink to install OCSP response to be used in OCSP stapling
  44. OCSP_OUT="$OCSP_DER.$ocsp_expire"
  45. mv "$OCSP_TMP" "$OCSP_OUT" || errexit
  46. OCSP_TMP=""
  47. ln -sf "${OCSP_OUT##*/}" "$OCSP_DER" || errexit
  48. # debug: display text output of OCSP .der file
  49. #openssl ocsp -respin "$OCSP_DER" -resp_text -noverify
  50. # remove old OCSP responses which have expired
  51. now=$(date +%s)
  52. for i in "$OCSP_DER".*; do
  53. ts="${i#${OCSP_DER}.}"
  54. if [ -n "$ts" ] && [ "$ts" -lt "$now" ]; then
  55. rm -f "$i"
  56. fi
  57. done