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