aboutsummaryrefslogtreecommitdiffstats
path: root/letsencrypt
diff options
context:
space:
mode:
Diffstat (limited to 'letsencrypt')
-rwxr-xr-xletsencrypt49
1 files changed, 40 insertions, 9 deletions
diff --git a/letsencrypt b/letsencrypt
index 50406f7..7465378 100755
--- a/letsencrypt
+++ b/letsencrypt
@@ -11,12 +11,14 @@ WWW_USER=www-data
WWW_GROUP=www-data
ACME_WEBSERVER=acme-webserver
ACME_CLIENT=acme-slave
+CAfile=/usr/share/lets-encrypt/letsencryptauthorityx1.pem
declare COMMAND ACCOUNTKEY
declare -l GENKEY
declare RUNAS QUIET= DEBUG=
-declare SRVCERT= CHAIN= CSR SRVKEY
+declare SRVCRT= CHAIN= CSR SRVKEY
+declare -i MIN_AGE=0
declare -l HASH=
declare SUBJECT=/
declare SAN=
@@ -62,6 +64,8 @@ usage() {
(default: "digitalSignature,keyEncipherment,keyCertSign")
--chain Store not only the server certificate in the file specified with --output, but
also the CA's
+ --min-age=SECONDS Don't do anything if the certificate specified by --output exists and its expiration
+ is more than SECONDS ahead.
--output=FILE Where to store the issued (signed) X.509 certificate
--notify=COMMAND Command to run upon success. (This option can be repeated.)
@@ -96,7 +100,8 @@ while [ $# -gt 0 ]; do
--quiet|-q) QUIET=1;;
--debug) DEBUG=1;;
- --output=*) SRVCERT="${1#*=}";;
+ --output=*) SRVCRT="${1#*=}";;
+ --min-age=*) MIN_AGE="${1#*=}";;
--chain) CHAIN=1;;
--csr=*) CSR="${1#*=}";;
--key=*) SRVKEY="${1#*=}";;
@@ -160,10 +165,16 @@ if [ "$COMMAND" = 'revoke-cert' ]; then
exit 1
fi
elif [ "$COMMAND" = 'new-cert' ]; then
- if [ ! "${SRVCERT:-}" ]; then
+ if [ ! "${SRVCRT:-}" ]; then
echo "Error: Missing --output" >&2
exit 1
fi
+ if [ -s "$SRVCRT" ] && [ $MIN_AGE -gt 0 ] && \
+ exp=$(openssl x509 -noout -enddate <"$SRVCRT" 2>/dev/null) && \
+ [ $(( $(date -d "${exp#*=}" +%s) - $(date +%s))) -gt $MIN_AGE ]; then
+ [ ! "$DEBUG" ] || echo "Expiration date ($(date -d"${exp#*=}")) is too far away, come back later." >&2
+ exit 0
+ fi
# Generate a Certificate Signing Request if need be
if [ ${CSR+x} ]; then
@@ -267,15 +278,35 @@ while read data; do
done >"$pipe"
if [ "$COMMAND" = 'new-cert' ]; then
- # TODO
- # Verify: dump and compare public keys
- # Valid cert, signed by the right CA
+ # https://crt.sh/?q=mail.fripost.org&iCAID=7395
+ # https://crt.sh/?spkisha1=$sha1
+
+ # Ensure the cert's pubkey matches that of the CSR, and that it's signed by the intended CA
+ if [ ! -s "$x509" ] ||
+ ! diff <(openssl req -in "$CSR" -pubkey -noout) \
+ <(openssl x509 -in "$x509" -pubkey -noout) >/dev/null ||
+ ! openssl verify -CAfile "$CAfile" -purpose sslserver -x509_strict <"$x509" >/dev/null; then
+ echo "Error: Got an invalid X.509 certificate from the ACME server!" >&2
+ exit 1
+ fi
- # Copy "$x509" to "$SRVCERT", possibly chained
- # https://crt.sh/?q=cse-fresti.cse.chalmers.se&iCAID=7395
- cp "$x509" "$SRVCERT"
+ # if it doesn't exist, create the file with mode 0644 minus the process's umask(2)
+ [ -e "$SRVCRT" ] || touch "$SRVCRT"
+ cat "$x509" >"$SRVCRT"
+ [ ! "$DEBUG" ] || openssl x509 -noout -text <"$SRVCRT"
+
+ if [ ! "$QUIET" ]; then
+ echo "X.509 certificate $SRVCRT has been updated or renewed"
+ echo
+ openssl x509 -noout \
+ -text -certopt no_header,no_version,no_pubkey,no_sigdump \
+ -fingerprint -sha256 <"$SRVCRT"
+ fi
for (( i=0; i<${#NOTIFY[@]}; i++ )); do
${NOTIFY[$i]}
done
+
+else
+ [ "$QUIET" ] || echo OK
fi