From 67d6d4159fbeaeb5c1deebf0b7571e4e798169e7 Mon Sep 17 00:00:00 2001 From: JDierkse Date: Wed, 9 Feb 2022 14:07:39 +0100 Subject: [PATCH] Add LetsEncrypt support --- certificate.sh | 170 +++++++++++++++++++++++++++++++++++++++---------- expiryCheck.sh | 28 ++++++-- expiryShow.sh | 53 +++++++++++++++ 3 files changed, 213 insertions(+), 38 deletions(-) create mode 100755 expiryShow.sh diff --git a/certificate.sh b/certificate.sh index 9148d55..3c3acb4 100755 --- a/certificate.sh +++ b/certificate.sh @@ -17,6 +17,7 @@ VERIFY="${OPENSSL} verify" X509="${OPENSSL} x509" PKCS12="${OPENSSL} pkcs12" +CERTFOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P )" CAFOLDER="./CA" CAKEY="./cakey.pem" CAREQ="./careq.pem" @@ -26,6 +27,10 @@ PASSFILE="./${PASSEXTENSION}" TYPEFILE="./type" CHAINFILE="./cachain.pem" +CERTBOT="certbot" +#CERTBOT="certbot --staging" +CERTBOTACMEPATH="${CERTFOLDER}/../../certbot" + C="NL" ST="Noord-Brabant" L="Veldhoven" @@ -62,6 +67,7 @@ validateType() { "${TYPE}" == "INTERMEDIATECA" || "${TYPE}" == "VPNCA" || "${TYPE}" == "WEBSERVER" || + "${TYPE}" == "LETSENCRYPT" || "${TYPE}" == "WEBCLIENT" || "${TYPE}" == "APPLICATIONCLIENT" || "${TYPE}" == "EMAIL" || @@ -128,6 +134,17 @@ newCertificate() { IP=("${EXTRAIP[@]}") fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + EXTENSIONS="server_cert -nodes" + + SAN=() + if [ ! -z "${CN}" ]; then + SAN+=("${CN}") + SAN+=("remote.${CN}") + fi + SAN+=("${EXTRASAN[@]}") + fi + if [[ "${TYPE}" == "WEBCLIENT" ]]; then EXTENSIONS="client_cert -nodes" fi @@ -155,31 +172,33 @@ newCertificate() { EXTENSIONS="intermediate_extensions" fi - COMMAND="${REQ} -new -x509 -newkey rsa:${KEYBITS} -extensions server_cert -keyout \"${FILENAME}.key\" -out \"${FILENAME}.crt\" ${DAYS}" + COMMAND="${REQ} -new -x509 -newkey rsa:${KEYBITS} -extensions ${EXTENSIONS} -keyout \"${FILENAME}.key\" -out \"${FILENAME}.crt\" ${DAYS}" if [ ! -z "${CN}" ]; then SUBJECT="/C=${C}/ST=${ST}/L=${L}/O=${O}/OU=${OU}/CN=${CN}/emailAddress=${E}" COMMAND+=" -subj \"${SUBJECT}\"" fi - if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then - COMMAND+=" -addext \"subjectAltName=" - INDEX=0 - for S in "${SAN[@]}" - do - ((INDEX+=1)) - COMMAND+="DNS.${INDEX}: ${S}," - done + if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "LETSENCRYPT"|| "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then + if [[ ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then + COMMAND+=" -addext \"subjectAltName=" + INDEX=0 + for S in "${SAN[@]}" + do + ((INDEX+=1)) + COMMAND+="DNS.${INDEX}: ${S}," + done - INDEX=0 - for I in "${IP[@]}" - do - ((INDEX+=1)) - COMMAND+="IP.${INDEX}: ${I}," - done + INDEX=0 + for I in "${IP[@]}" + do + ((INDEX+=1)) + COMMAND+="IP.${INDEX}: ${I}," + done - COMMAND=${COMMAND%?} - COMMAND+="\"" + COMMAND=${COMMAND%?} + COMMAND+="\"" + fi fi execute ${COMMAND} @@ -206,6 +225,17 @@ newRequest() { IP=("${EXTRAIP[@]}") fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + EXTENSIONS="server_cert -nodes" + + SAN=() + if [ ! -z "${CN}" ]; then + SAN+=("${CN}") + SAN+=("remote.${CN}") + fi + SAN+=("${EXTRASAN[@]}") + fi + if [[ "${TYPE}" == "WEBCLIENT" ]]; then EXTENSIONS="client_cert -nodes" fi @@ -241,24 +271,26 @@ newRequest() { COMMAND+=" -subj \"${SUBJECT}\"" fi - if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then - COMMAND+=" -addext \"subjectAltName=" - INDEX=0 - for S in "${SAN[@]}" - do - ((INDEX+=1)) - COMMAND+="DNS.${INDEX}: ${S}," - done + if [[ "${TYPE}" == "WEBSERVER" || "${TYPE}" == "LETSENCRYPT" || "${TYPE}" == "VPN" || ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then + if [[ ${#SAN[@]} -ne "0" || ${#IP[@]} -ne "0" ]]; then + COMMAND+=" -addext \"subjectAltName=" + INDEX=0 + for S in "${SAN[@]}" + do + ((INDEX+=1)) + COMMAND+="DNS.${INDEX}: ${S}," + done - INDEX=0 - for I in "${IP[@]}" - do - ((INDEX+=1)) - COMMAND+="IP.${INDEX}: ${I}," - done + INDEX=0 + for I in "${IP[@]}" + do + ((INDEX+=1)) + COMMAND+="IP.${INDEX}: ${I}," + done - COMMAND=${COMMAND%?} - COMMAND+="\"" + COMMAND=${COMMAND%?} + COMMAND+="\"" + fi fi execute ${COMMAND} @@ -418,6 +450,7 @@ renewCertificateAuthorityCertificate() { fi echo "Not implemented" + exit -1 } signCertificate() { @@ -431,6 +464,11 @@ signCertificate() { exit -1 fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + echo "Not implemented" + exit -1 + fi + COMMAND="${X509} -x509toreq -signkey \"${FILENAME}.key\" -in \"${FILENAME}.csr\" -out temporary.pem" execute ${COMMAND} @@ -461,6 +499,28 @@ signRequest() { EXTENSIONS="server_cert" fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + if [ -f "${FILENAME}.crt" ]; then + echo "Certificate Exists (${FILENAME}.crt)" + exit -1 + fi + + if [ -f "${FILENAME}.ca.pem" ]; then + echo "Certificate Exists (${FILENAME}.ca.pem)" + exit -1 + fi + + if [ -f "${FILENAME}.pem" ]; then + echo "Certificate Exists (${FILENAME}.pem)" + exit -1 + fi + + COMMAND="${CERTBOT} certonly -n --webroot -w ${CERTBOTACMEPATH} --csr \"${FILENAME}.csr\" --cert-path \"${FILENAME}.crt\" --chain-path \"${FILENAME}.ca.pem\" --fullchain-path \"${FILENAME}.pem\" --agree-tos --email ${E}" + execute ${COMMAND} + + return + fi + if [[ "${TYPE}" == "WEBCLIENT" ]]; then EXTENSIONS="client_cert" fi @@ -506,6 +566,7 @@ signCertificateAuthorityCertificate() { # RET=$? echo "Not implemented" + exit -1 } signRequestAnything() { @@ -520,6 +581,7 @@ signRequestAnything() { # RET=$? echo "Not implemented" + exit -1 } createCertificatePackage() { @@ -538,6 +600,11 @@ createCertificatePackage() { exit -1 fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + echo "Not implemented" + exit -1 + fi + CACERTCN=$(${X509} -noout -subject -nameopt multiline -in ${CAFOLDER}/${CACERT} | sed -n 's/ *commonName *= //p') COMMAND="${PKCS12} -in \"${FILENAME}.crt\" -inkey \"${FILENAME}.key\" -certfile ${CAFOLDER}/${CHAINFILE} -caname \"${CACERTCN}\" -out \"${FILENAME}.p12\" -export -name \"${FILENAME}\"" @@ -550,6 +617,11 @@ generateCrl() { exit -1 fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + echo "Not implemented" + exit -1 + fi + COMMAND="${CA} -passin file:${CAFOLDER}/private/${PASSFILE} -gencrl -out ${CAFOLDER}/crl/crl.pem" execute ${COMMAND} @@ -568,12 +640,28 @@ revokeCertificate() { exit -1 fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + #COMMAND="${CERTBOT} revoke -n --cert-path \"${FILENAME}.crt\"" + #execute ${COMMAND} + + COMMAND="mv \"${FILENAME}.crt\" \"${FILENAME}.crt.revoked\"" + execute ${COMMAND} + + COMMAND="rm -f \"${FILENAME}.pem\" \"${FILENAME}.ca.pem\"" + execute ${COMMAND} + + return + fi + COMMAND="${CA} -passin file:${CAFOLDER}/private/${PASSFILE} -revoke \"${FILENAME}.crt\"" execute ${COMMAND} COMMAND="mv \"${FILENAME}.crt\" \"${FILENAME}.crt.revoked\"" execute ${COMMAND} + COMMAND="rm -f \"${FILENAME}.pem\"" + execute ${COMMAND} + generateCrl } @@ -588,6 +676,21 @@ verifyCertificate() { exit -1 fi + if [[ "${TYPE}" == "LETSENCRYPT" ]]; then + COMMAND="${VERIFY} \"${FILENAME}.ca.pem\"" + execute ${COMMAND} + + COMMAND="${VERIFY} -CAfile \"${FILENAME}.ca.pem\" \"${FILENAME}.crt\"" + execute ${COMMAND} + + #"openssl ocsp -issuer \"${FILENAME}.ca.pem\" -cert \"${FILENAME}.crt\" -text -url http://stg-r3.o.lencr.org" + + return + fi + + COMMAND="${VERIFY} ${CAFOLDER}/${CHAINFILE}" + execute ${COMMAND} + COMMAND="${VERIFY} -CAfile ${CAFOLDER}/${CHAINFILE} \"${FILENAME}.crt\"" execute ${COMMAND} @@ -604,6 +707,7 @@ printHelp() { echo " INTERMEDIATECA " >&2 echo " VPNCA " >&2 echo " WEBSERVER " >&2 + echo " LETSENCRYPT " >&2 echo " WEBCLIENT " >&2 echo " APPLICATIONCLIENT " >&2 echo " EMAIL " >&2 diff --git a/expiryCheck.sh b/expiryCheck.sh index a8743bd..3bcef79 100755 --- a/expiryCheck.sh +++ b/expiryCheck.sh @@ -1,14 +1,19 @@ #!/bin/bash -EXPIRATIONDAYS=90 +EXPIRATIONDAYS=14 + +OUTPUTBUFFER="" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P )" +cd ${DIR} checkCertificate () { + OUTPUT="" CERTIFICATE=$@ STARTNOTIFICATIONDATE=$(date +%s) EXPIRYNOTIFICATIONDATE=$(($(date +%s) + (86400*${EXPIRATIONDAYS}))) - SUBJECT=$(openssl x509 -in "${CERTIFICATE}" -noout -text | grep "Subject:" | sed 's/^.*CN[ ]*=[ ]*\(.*\),.*$/\1/') + SUBJECT=$(openssl x509 -in "${CERTIFICATE}" -noout -text | grep "Subject:" | sed 's/^.*CN[ ]*=[ ]*\([^,]*\).*$/\1/') STARTDATE=$(openssl x509 -in "${CERTIFICATE}" -noout -text | grep 'Not Before' | awk '{printf "%s %.2d %s %s\n",$3,$4,$6,$5}') STARTDATENUMERIC=$(date -d "${STARTDATE}" '+%s'); @@ -18,12 +23,14 @@ checkCertificate () { if [ ${STARTNOTIFICATIONDATE} -lt ${STARTDATENUMERIC} ] then - echo -e "\tOn ${STARTDATE}, the Certificate for \"${SUBJECT}\" will become valid" + WARNING=true + OUTPUT="\tOn ${STARTDATE}, the Certificate for \"${SUBJECT}\" will become valid\n" fi if [ ${EXPIRYNOTIFICATIONDATE} -gt ${EXPIRATIONDATENUMERIC} ] then - echo -e "\tOn ${EXPIRATIONDATE}, the Certificate for \"${SUBJECT}\" will expire" + WARNING=true + OUTPUT="\tOn ${EXPIRATIONDATE}, the Certificate for \"${SUBJECT}\" will expire\n" fi } @@ -33,18 +40,29 @@ do DIRECTORY=${DIRECTORY:2} if [ "${DIRECTORY}" != "openssl" ]; then - echo "${DIRECTORY}:" + TEMPORARYBUFFER="" cd "${DIRECTORY}" for CERTIFICATE in ./*.crt do + WARNING=false if [[ -f "${CERTIFICATE}" ]] then checkCertificate ${CERTIFICATE} + if [ "${WARNING}" = true ]; then + TEMPORARYBUFFER+=${OUTPUT} + fi fi done + if [ ! -z "${TEMPORARYBUFFER}" ]; then + OUTPUTBUFFER+="${DIRECTORY}:\n" + OUTPUTBUFFER+=${TEMPORARYBUFFER} + fi + cd - > /dev/null fi done +echo -e ${OUTPUTBUFFER} + diff --git a/expiryShow.sh b/expiryShow.sh new file mode 100755 index 0000000..bccac17 --- /dev/null +++ b/expiryShow.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +EXPIRATIONDAYS=0 + +OUTPUTBUFFER="" +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd -P )" +cd ${DIR} + +checkCertificate () { + OUTPUT="" + CERTIFICATE=$@ + + STARTNOTIFICATIONDATE=$(date +%s) + EXPIRYNOTIFICATIONDATE=$(($(date +%s) + (86400*${EXPIRATIONDAYS}))) + + SUBJECT=$(openssl x509 -in "${CERTIFICATE}" -noout -text | grep "Subject:" | sed 's/^.*CN[ ]*=[ ]*\([^,]*\).*$/\1/') + + STARTDATE=$(openssl x509 -in "${CERTIFICATE}" -noout -text | grep 'Not Before' | awk '{printf "%s %.2d %s %s\n",$3,$4,$6,$5}') + STARTDATENUMERIC=$(date -d "${STARTDATE}" '+%s'); + + EXPIRATIONDATE=$(openssl x509 -in "${CERTIFICATE}" -noout -text | grep 'Not After' | awk '{printf "%s %.2d %s %s\n",$4,$5,$7,$6}') + EXPIRATIONDATENUMERIC=$(date -d "${EXPIRATIONDATE}" '+%s'); + + if [ ${STARTNOTIFICATIONDATE} -lt ${STARTDATENUMERIC} ] + then + OUTPUT="\tOn ${STARTDATE}, the Certificate for \"${SUBJECT}\" will become valid" + fi + + OUTPUT="\tOn ${EXPIRATIONDATE}, the Certificate for \"${SUBJECT}\" will expire" +} + +for DIRECTORY in ./*/ +do + DIRECTORY=${DIRECTORY%*/} + DIRECTORY=${DIRECTORY:2} + + if [ "${DIRECTORY}" != "openssl" ]; then + echo -e "\n${DIRECTORY}:" + cd "${DIRECTORY}" + + for CERTIFICATE in ./*.crt + do + if [[ -f "${CERTIFICATE}" ]] + then + checkCertificate ${CERTIFICATE} + echo -e "${OUTPUT}" + fi + done + + cd - > /dev/null + fi +done +