From: Mark Wooding Date: Sat, 2 Oct 2021 10:39:05 +0000 (+0100) Subject: bin/make-cert, bin/fix-cert-chain: Hack certificate chains for compatiblity. X-Git-Url: https://git.distorted.org.uk/~mdw/distorted-letsencrypt/commitdiff_plain bin/make-cert, bin/fix-cert-chain: Hack certificate chains for compatiblity. Oh, this is a mess. https://community.letsencrypt.org/t/openssl-client-compatibility-changes-for-let-s-encrypt-certificates/143816 Old versions of Android don't recognize the new Let's Encrypt issuer. So LE deployed a kludge: their certificate chains include a reference to their old issuer, which /is/ recognized by old Android versions. But there's a problem: this issuer /expired/ yesterday, and old versions of OpenSSL and GnuTLS reject certificate bundles involving expired issuers, even if (a) the expired certificate is in the cert store, not provided by the server, and (b) there's a perfectly fine trust path which doesn't involve the duff certificate. Introduce a new script `fix-cert-chain' to generally tidy up certificate chains by (a) deleting duplicate certificates and (b) removing certificates from `bad' issuers. --- diff --git a/bin/fix-cert-chain b/bin/fix-cert-chain new file mode 100755 index 0000000..dc9a313 --- /dev/null +++ b/bin/fix-cert-chain @@ -0,0 +1,41 @@ +#! /bin/sh -e + +bad_issuers=" +O = Digital Signature Trust Co., CN = DST Root CA X3 +" + +case $# in + 1) certs=$1 ;; + *) echo >&2 "usage: $0 CERTLIST-FILE"; exit 2 ;; +esac + +nl=" +" +mode=skip all= +while IFS= read -r line; do + case $line,$mode in + "-----BEGIN CERTIFICATE-----",skip) + mode=keep + buf="$line$nl" + ;; + "-----END CERTIFICATE-----",keep) + mode=skip + buf="$buf$line" + keep=t + case "$nl$nl$all$nl$nl" in + *"$nl$nl$buf$nl$nl"*) keep=nil ;; + esac + case $keep in + t) + issuer=$(echo "$buf" | openssl x509 -noout -issuer) + case $bad_issuers in $"$nl$issuer$nl"*) keep=nil ;; esac + ;; + esac + case $keep in t) all="${all:+$all$nl$nl}$buf" ;; esac + ;; + *,keep) buf="$buf$line$nl" ;; + esac +done <"$certs" + +case $all in "") echo >&2 "$0: no certificates found"; exit 127 ;; esac +echo "$all" diff --git a/bin/make-cert b/bin/make-cert index 9dcf15b..a094a53 100755 --- a/bin/make-cert +++ b/bin/make-cert @@ -22,4 +22,6 @@ unset http_proxy cert=$home/cert/$tag cd $cert dehydrated -f $HOME/dehydrated-config.sh -fc -s req >full-chain.new -mv full-chain.new full-chain +fix-cert-chain full-chain.new >full-chain.fixed +mv full-chain.fixed full-chain +rm full-chain.new