Implement --compatibility-chain

https://github.com/Neilpang/acme.sh/issues/2221
This commit is contained in:
Alex Zorin 2019-05-15 16:23:30 +10:00
parent ade9d662db
commit 88846aafc1

82
acme.sh
View File

@ -1224,6 +1224,37 @@ _readKeyLengthFromCSR() {
fi fi
} }
# _substitute_compatibility_chain _leaf _issuer
_substitute_compatibility_chain() {
_leaf="$1"
_issuer="$2"
# We only want to replace the issuer if it's the Let's Encrypt Authority X3 key
_aki="$(printf "%s" "$_leaf" | ${ACME_OPENSSL_BIN:-openssl} x509 -noout -ext authorityKeyIdentifier | grep 'keyid:' | cut -d ':' -f 2-)"
if [ "$_aki" != "A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1" ]; then
_debug "Issuer is not X3, using default chain"
printf "%s" "$_issuer"
return
fi
# We only want to replace the issuer if the leaf is expiring after the cross-signed issuer
_expiry="$(printf "%s" "$_leaf" | ${ACME_OPENSSL_BIN:-openssl} x509 -noout -enddate | grep "notAfter" | cut -d '=' -f 2 | date +"%s" -f - )"
if [ "$_expiry" -gt "1615999246" ]; then
_debug "Leaf is expiring after cross-signed X3, using default chain"
printf "%s" "$_issuer"
return
fi
_debug "Using legacy cross-signed X3 issuer"
_newissuer="$(_get "https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt")"
if [ "$?" != "0" ]; then
_debug "Failed to download legacy chain, using default chain"
printf "%s" "$_issuer"
else
printf "%s" "$_newissuer"
fi
}
_ss() { _ss() {
_port="$1" _port="$1"
@ -3783,6 +3814,12 @@ issue() {
_cleardomainconf "Le_ChallengeAlias" _cleardomainconf "Le_ChallengeAlias"
fi fi
if [ "$Le_UseCompatibilityChain" = "1" ]; then
_savedomainconf "Le_UseCompatibilityChain" "$Le_UseCompatibilityChain"
else
_cleardomainconf "Le_UseCompatibilityChain"
fi
if [ "$ACME_DIRECTORY" != "$DEFAULT_CA" ]; then if [ "$ACME_DIRECTORY" != "$DEFAULT_CA" ]; then
Le_API="$ACME_DIRECTORY" Le_API="$ACME_DIRECTORY"
_savedomainconf "Le_API" "$Le_API" _savedomainconf "Le_API" "$Le_API"
@ -4432,11 +4469,18 @@ $_authorizations_map"
cat "$CERT_PATH" >"$CERT_FULLCHAIN_PATH" cat "$CERT_PATH" >"$CERT_FULLCHAIN_PATH"
_end_n="$(grep -n -- "$END_CERT" "$CERT_FULLCHAIN_PATH" | _head_n 1 | cut -d : -f 1)" _end_n="$(grep -n -- "$END_CERT" "$CERT_FULLCHAIN_PATH" | _head_n 1 | cut -d : -f 1)"
_debug _end_n "$_end_n" _debug _end_n "$_end_n"
sed -n "1,${_end_n}p" "$CERT_FULLCHAIN_PATH" >"$CERT_PATH" _leaf="$(sed -n "1,${_end_n}p" "$CERT_FULLCHAIN_PATH")"
_end_n="$(_math $_end_n + 1)" _end_n="$(_math $_end_n + 1)"
sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH" >"$CA_CERT_PATH" _issuer="$(sed -n "${_end_n},9999p" "$CERT_FULLCHAIN_PATH")"
if [ "$Le_UseCompatibilityChain" = "1" ]; then
_issuer="$(_substitute_compatibility_chain "$_leaf" "$_issuer")"
fi
echo "$_leaf" > "$CERT_PATH"
echo "$_issuer" > "$CA_CERT_PATH"
printf "%s\n%s" "$_leaf" "$_issuer" > "$CERT_FULLCHAIN_PATH"
fi fi
# ACME_VERSION != "2"
else else
if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then if ! _send_signed_request "${ACME_NEW_ORDER}" "{\"resource\": \"$ACME_NEW_ORDER_RES\", \"csr\": \"$der\"}" "needbase64"; then
_err "Sign failed. $response" _err "Sign failed. $response"
@ -4506,24 +4550,24 @@ $_authorizations_map"
_MAX_ISSUER_RETRY=5 _MAX_ISSUER_RETRY=5
while [ "$_link_issuer_retry" -lt "$_MAX_ISSUER_RETRY" ]; do while [ "$_link_issuer_retry" -lt "$_MAX_ISSUER_RETRY" ]; do
_debug _link_issuer_retry "$_link_issuer_retry" _debug _link_issuer_retry "$_link_issuer_retry"
if [ "$ACME_VERSION" = "2" ]; then if _get "$Le_LinkIssuer" >"$CA_CERT_PATH.der"; then
if _send_signed_request "$Le_LinkIssuer"; then echo "$BEGIN_CERT" >"$CA_CERT_PATH"
echo "$response" >"$CA_CERT_PATH" _base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH"
echo "$END_CERT" >>"$CA_CERT_PATH"
if ! _checkcert "$CA_CERT_PATH"; then
_err "Can not get the ca cert."
break break
fi fi
else cat "$CA_CERT_PATH" >>"$CERT_FULLCHAIN_PATH"
if _get "$Le_LinkIssuer" >"$CA_CERT_PATH.der"; then rm -f "$CA_CERT_PATH.der"
echo "$BEGIN_CERT" >"$CA_CERT_PATH"
_base64 "multiline" <"$CA_CERT_PATH.der" >>"$CA_CERT_PATH" if [ "$Le_UseCompatibilityChain" = "1" ]; then
echo "$END_CERT" >>"$CA_CERT_PATH" _leaf="$(cat "$CERT_PATH")"
if ! _checkcert "$CA_CERT_PATH"; then _issuer="$(_substitute_compatibility_chain "$_leaf" "$(cat "$CA_CERT_PATH")")"
_err "Can not get the ca cert." echo "$_issuer" > "$CA_CERT_PATH"
break printf "%s\n%s" "$_leaf" "$_issuer" > "$CERT_FULLCHAIN_PATH"
fi
cat "$CA_CERT_PATH" >>"$CERT_FULLCHAIN_PATH"
rm -f "$CA_CERT_PATH.der"
break
fi fi
break
fi fi
_link_issuer_retry=$(_math $_link_issuer_retry + 1) _link_issuer_retry=$(_math $_link_issuer_retry + 1)
_sleep "$_link_issuer_retry" _sleep "$_link_issuer_retry"
@ -6078,6 +6122,7 @@ Parameters:
--openssl-bin Specifies a custom openssl bin location. --openssl-bin Specifies a custom openssl bin location.
--use-wget Force to use wget, if you have both curl and wget installed. --use-wget Force to use wget, if you have both curl and wget installed.
--yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode: $_DNS_MANUAL_WIKI --yes-I-know-dns-manual-mode-enough-go-ahead-please Force to use dns manual mode: $_DNS_MANUAL_WIKI
--compatibility-chain If possible, use the older and more compatible cross-signed issuer certificate (Let's Encrypt only).
--branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to. --branch, -b Only valid for '--upgrade' command, specifies the branch name to upgrade to.
--notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT. --notify-level 0|1|2|3 Set the notification level: Default value is $NOTIFY_LEVEL_DEFAULT.
@ -6607,6 +6652,9 @@ _process() {
--yes-I-know-dns-manual-mode-enough-go-ahead-please) --yes-I-know-dns-manual-mode-enough-go-ahead-please)
export FORCE_DNS_MANUAL=1 export FORCE_DNS_MANUAL=1
;; ;;
--compatibility-chain)
Le_UseCompatibilityChain="1"
;;
--log | --logfile) --log | --logfile)
_log="1" _log="1"
_logfile="$2" _logfile="$2"