From 522918f023d2be3093583c834efc48db74627ffb Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Thu, 18 Feb 2021 17:06:13 +0000 Subject: [PATCH 1/7] Add FULL_CHAIN_INCLUDE_ROOT Fixes #594 #272 #564 --- getssl | 30 +++++++++++- test/36-full-chain-inc-root.bats | 81 ++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 test/36-full-chain-inc-root.bats diff --git a/getssl b/getssl index 066a83c..80a3fae 100755 --- a/getssl +++ b/getssl @@ -256,7 +256,8 @@ # 2021-02-07 Allow -u --upgrade without any domain, so that one can only update the script (Benno-K)(2.34) # 2021-02-09 Prevent listing the complete file if version tag missing (#637)(softins) # 2021-02-12 Add PREFERRED_CHAIN -# 2021-02-15 ADD ftp explicit SSL with curl for upload the challenge +# 2021-02-15 ADD ftp explicit SSL with curl for upload the challenge (CoolMischa) +# 2021-02-18 Add FULL_CHAIN_INCLUDE_ROOT # ---------------------------------------------------------------------------------------- case :$SHELLOPTS: in @@ -283,6 +284,7 @@ DEFAULT_REVOKE_CA="https://acme-v02.api.letsencrypt.org" DOMAIN_KEY_LENGTH=4096 DUAL_RSA_ECDSA="false" FTP_OPTIONS="" +FULL_CHAIN_INCLUDE_ROOT="false" GETSSL_IGNORE_CP_PRESERVE="false" HTTP_TOKEN_CHECK_WAIT=0 IGNORE_DIRECTORY_DOMAIN="false" @@ -1598,7 +1600,27 @@ get_certificate() { # get certificate for csr, if all domains validated. # tidy up rm -f "$cert_to_check" fi + awk -v CERT_FILE="$gc_certfile" -v CA_CERT="$gc_cafile" 'BEGIN {outfile=CERT_FILE} split_after==1 {outfile=CA_CERT;split_after=0} /-----END CERTIFICATE-----/ {split_after=1} {print > outfile}' "$gc_fullchain" + if [[ "$FULL_CHAIN_INCLUDE_ROOT" = "true" ]]; then + # Some of the code below was copied from zakjan/cert-chain-resolver + + # Download the certificate for the issuer using the "CA Issuers" attribute from the AIA x509 extension + issuer_url=$(openssl x509 -inform pem -noout -text -in "$gc_certfile" | awk 'BEGIN {FS="CA Issuers - URI:"} NF==2 {print $2; exit}') + debug Issuer for "$gc_certfile" is "$issuer_url" + + # Keep downloading issuer certficates until we find the root certificate (which doesn't have a "CA Issuers" attribure) + cp "$gc_certfile" "$gc_fullchain" + while [[ -n "$issuer_url" ]]; do + debug Fetching certificate issuer from "$issuer_url" + issuer_cert=$(curl --user-agent "$CURL_USERAGENT" --silent "$issuer_url" | openssl x509 -inform der -outform pem) + debug Fetched issuer certificate "$(echo "$issuer_cert" | openssl x509 -inform pem -noout -text | awk 'BEGIN {FS="Subject: "} NF==2 {print $2; exit}')" + echo "$issuer_cert" >> "$gc_fullchain" + + # get issuer for the certificate that's just been downloaded + issuer_url=$(echo "$issuer_cert" | openssl x509 -inform pem -noout -text | awk 'BEGIN {FS="CA Issuers - URI:"} NF==2 {print $2; exit}') + done + fi info "Certificate saved in $gc_certfile" fi } @@ -2382,6 +2404,9 @@ write_domain_template() { # write out a template file for a domain. # Production options are: "ISRG Root X1" and "ISRG Root X2" #PREFERRED_CHAIN="" + # Uncomment this if you need the full chain file to include the root certificate (Java keystores, Nutanix Prism) + #FULL_CHAIN_INCLUDE_ROOT="true" + # Location for all your certs, these can either be on the server (full path name) # or using ssh /sftp as for the ACL #DOMAIN_CERT_LOCATION="/etc/ssl/${DOMAIN}.crt" # this is domain cert @@ -2441,6 +2466,9 @@ write_getssl_template() { # write out the main template file # Production options are: "ISRG Root X1" and "ISRG Root X2" #PREFERRED_CHAIN="" + # Uncomment this if you need the full chain file to include the root certificate (Java keystores, Nutanix Prism) + #FULL_CHAIN_INCLUDE_ROOT="true" + # The command needed to reload apache / nginx or whatever you use. # Several (ssh) commands may be given using a bash array: # RELOAD_CMD=('ssh:sshuserid@server5:systemctl reload httpd' 'logger getssl for server5 efficient.') diff --git a/test/36-full-chain-inc-root.bats b/test/36-full-chain-inc-root.bats new file mode 100644 index 0000000..5932ea7 --- /dev/null +++ b/test/36-full-chain-inc-root.bats @@ -0,0 +1,81 @@ +#! /usr/bin/env bats + +load '/bats-support/load.bash' +load '/bats-assert/load.bash' +load '/getssl/test/test_helper.bash' + + +# This is run for every test +setup() { + if [ -z "$STAGING" ]; then + export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt + fi +} + + +@test "Use FULL_CHAIN_INCLUDE_ROOT to include the root certificate in the fullchain" { + CONFIG_FILE="getssl-dns01.cfg" + setup_environment + init_getssl + + cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg +FULL_CHAIN_INCLUDE_ROOT="true" +EOF + + create_certificate + assert_success + check_output_for_errors + + if [ -n "$STAGING" ]; then + PREFERRED_CHAIN="Fake LE Root X1" + else + # pebble doesn't support CA Issuers so the fullchain.crt will just contain the certificate (code path means it won't contain the intermediate cert in this case) + # This is testing that requesting FULL_CHAIN_INCLUDE_ROOT doesn't fail if there is no CA Issuers in the certificate + PREFERRED_CHAIN=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + fi + + final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + # verify certificate includes the chain root + [ "$PREFERRED_CHAIN" = "$final_issuer" ] +} + + +@test "Use FULL_CHAIN_INCLUDE_ROOT with dual certificates" { + if [ -n "$STAGING" ]; then + PREFERRED_CHAIN="Fake LE Root X1" + fi + + CONFIG_FILE="getssl-dns01.cfg" + setup_environment + init_getssl + + cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg +FULL_CHAIN_INCLUDE_ROOT="true" +DUAL_RSA_ECDSA="true" +ACCOUNT_KEY_TYPE="prime256v1" +PRIVATE_KEY_ALG="prime256v1" +CHECK_REMOTE="false" +EOF + + create_certificate + assert_success + check_output_for_errors + check_certificates + assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/chain.ec.crt" ] + assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.ec.crt" ] + assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.ec.crt" ] + + if [ -n "$STAGING" ]; then + PREFERRED_CHAIN="Fake LE Root X1" + else + # pebble doesn't support CA Issuers so the fullchain.crt will just contain the certificate (code path means it won't contain the intermediate cert in this case) + # This is testing that requesting FULL_CHAIN_INCLUDE_ROOT doesn't fail if there is no CA Issuers in the certificate + PREFERRED_CHAIN=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + fi + + # verify both rsa and ecdsa certificates include the chain root + final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + [ "$PREFERRED_CHAIN" = "$final_issuer" ] + ecdsa_final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.ec.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + [ "$PREFERRED_CHAIN" = "$ecdsa_final_issuer" ] +} From e19afe87af0863c95f570997c537e8bbad3d006a Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Thu, 18 Feb 2021 17:14:44 +0000 Subject: [PATCH 2/7] Fixes double slash reported in #585 --- getssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getssl b/getssl index 80a3fae..88b4d9f 100755 --- a/getssl +++ b/getssl @@ -302,7 +302,7 @@ OCSP_MUST_STAPLE="false" TEMP_UPGRADE_FILE="" TOKEN_USER_ID="" USE_SINGLE_ACL="false" -WORKING_DIR_CANDIDATES=("/etc/getssl/" "${PROGDIR}/conf" "${PROGDIR}/.getssl" "${HOME}/.getssl") +WORKING_DIR_CANDIDATES=("/etc/getssl" "${PROGDIR}/conf" "${PROGDIR}/.getssl" "${HOME}/.getssl") # Variables used when validating using a DNS entry VALIDATE_VIA_DNS="" # Set this to "true" to enable DNS validation From 27af6d9f2f8043e4df47e1df2a23c2bf0c9de7ee Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Fri, 19 Feb 2021 15:51:56 +0000 Subject: [PATCH 3/7] Fix test scripts to add to dns once and remove once --- test/17-test-spaces-in-sans-dns01.bats | 19 +++++-------------- test/17-test-spaces-in-sans-http01.bats | 19 +++++-------------- 2 files changed, 10 insertions(+), 28 deletions(-) diff --git a/test/17-test-spaces-in-sans-dns01.bats b/test/17-test-spaces-in-sans-dns01.bats index 9f3b3dc..9d425af 100644 --- a/test/17-test-spaces-in-sans-dns01.bats +++ b/test/17-test-spaces-in-sans-dns01.bats @@ -50,11 +50,6 @@ setup() { CONFIG_FILE="getssl-dns01-spaces-sans-and-ignore-dir-domain.cfg" setup_environment - # Add hosts to DNS (also need to be added as aliases in docker-compose.yml) - for prefix in a b c; do - curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a - done - init_getssl create_certificate assert_success @@ -70,10 +65,6 @@ setup() { assert_success check_output_for_errors cleanup_environment - - for prefix in a b c; do - curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'"}' http://10.30.50.3:8055/clear-a - done } @@ -84,13 +75,13 @@ setup() { CONFIG_FILE="getssl-dns01-spaces-and-commas-sans.cfg" setup_environment - # Add hosts to DNS (also need to be added as aliases in docker-compose.yml) - for prefix in a b c; do - curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a - done - init_getssl create_certificate assert_success check_output_for_errors + cleanup_environment + + for prefix in a b c; do + curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'"}' http://10.30.50.3:8055/clear-a + done } diff --git a/test/17-test-spaces-in-sans-http01.bats b/test/17-test-spaces-in-sans-http01.bats index fab530f..1730e99 100644 --- a/test/17-test-spaces-in-sans-http01.bats +++ b/test/17-test-spaces-in-sans-http01.bats @@ -50,11 +50,6 @@ setup() { CONFIG_FILE="getssl-http01-spaces-sans-and-ignore-dir-domain.cfg" setup_environment - # Add hosts to DNS (also need to be added as aliases in docker-compose.yml) - for prefix in a b c; do - curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a - done - init_getssl create_certificate assert_success @@ -70,10 +65,6 @@ setup() { assert_success check_output_for_errors cleanup_environment - - for prefix in a b c; do - curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'"}' http://10.30.50.3:8055/clear-a - done } @@ -84,13 +75,13 @@ setup() { CONFIG_FILE="getssl-http01-spaces-and-commas-sans.cfg" setup_environment - # Add hosts to DNS (also need to be added as aliases in docker-compose.yml) - for prefix in a b c; do - curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a - done - init_getssl create_certificate assert_success check_output_for_errors + cleanup_environment + + for prefix in a b c; do + curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'"}' http://10.30.50.3:8055/clear-a + done } From 2863e9e52d0f2c65536a41891fe7be79ede80253 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Fri, 19 Feb 2021 15:52:24 +0000 Subject: [PATCH 4/7] Clear previous dns entries before adding a new entry --- test/test_helper.bash | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_helper.bash b/test/test_helper.bash index 11cdf44..48a8d4b 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -64,6 +64,8 @@ setup_environment() { fi if [ -z "$STAGING" ]; then + # Make sure that we have cleared any previous entries, otherwise get random dns failures + curl --silent -X POST -d '{"host":"'"$GETSSL_HOST"'"}' http://10.30.50.3:8055/clear-a curl --silent -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/add-a fi cp ${CODE_DIR}/test/test-config/nginx-ubuntu-no-ssl "${NGINX_CONFIG}" From 4f5b518038116405aef6ed554fab6bd54b392e8d Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Sat, 20 Feb 2021 11:55:20 +0000 Subject: [PATCH 5/7] Update staging certificate names --- getssl | 12 +++++---- test/35-preferred-chain.bats | 45 +++++++++++++++++++++----------- test/36-full-chain-inc-root.bats | 35 +++++++++++++++++-------- 3 files changed, 61 insertions(+), 31 deletions(-) diff --git a/getssl b/getssl index 88b4d9f..d73faea 100755 --- a/getssl +++ b/getssl @@ -1582,7 +1582,7 @@ get_certificate() { # get certificate for csr, if all domains validated. cp "$gc_fullchain" "$cert_to_check" i=0 while [[ $i -le ${#alternate_links[@]} ]]; do - cert_issuer=$(openssl crl2pkcs7 -nocrl -certfile "$cert_to_check" | openssl pkcs7 -print_certs -text -noout | grep 'Issuer:' | tail -1 | cut -d= -f2) + cert_issuer=$(openssl crl2pkcs7 -nocrl -certfile "$cert_to_check" | openssl pkcs7 -print_certs -text -noout | grep 'Issuer:' | tail -1 | awk -F"CN=" '{ print $2 }') debug Certificate issued by "$cert_issuer" if [[ $cert_issuer = *${PREFERRED_CHAIN}* ]]; then debug "Found required certificate" @@ -2400,9 +2400,10 @@ write_domain_template() { # write out a template file for a domain. #USE_SINGLE_ACL="false" # Preferred Chain - use an different certificate root from the default - # Staging options are: "Fake LE Root X1" and "Fake LE Root X2" + # This uses wildcard matching so requesting "X1" returns the correct certificate - may need to escape characters + # Staging options are: "(STAGING) Doctored Durian Root CA X3" and "(STAGING) Pretend Pear X1" # Production options are: "ISRG Root X1" and "ISRG Root X2" - #PREFERRED_CHAIN="" + #PREFERRED_CHAIN="\(STAGING\) Pretend Pear X1" # Uncomment this if you need the full chain file to include the root certificate (Java keystores, Nutanix Prism) #FULL_CHAIN_INCLUDE_ROOT="true" @@ -2462,9 +2463,10 @@ write_getssl_template() { # write out the main template file #REUSE_PRIVATE_KEY="true" # Preferred Chain - use an different certificate root from the default - # Staging options are: "Fake LE Root X1" and "Fake LE Root X2" + # This uses wildcard matching so requesting "X1" returns the correct certificate - may need to escape characters + # Staging options are: "(STAGING) Doctored Durian Root CA X3" and "(STAGING) Pretend Pear X1" # Production options are: "ISRG Root X1" and "ISRG Root X2" - #PREFERRED_CHAIN="" + #PREFERRED_CHAIN="\(STAGING\) Pretend Pear X1" # Uncomment this if you need the full chain file to include the root certificate (Java keystores, Nutanix Prism) #FULL_CHAIN_INCLUDE_ROOT="true" diff --git a/test/35-preferred-chain.bats b/test/35-preferred-chain.bats index 4389d3b..0a5821c 100644 --- a/test/35-preferred-chain.bats +++ b/test/35-preferred-chain.bats @@ -15,10 +15,12 @@ setup() { @test "Use PREFERRED_CHAIN to select an alternate root" { if [ -n "$STAGING" ]; then - PREFERRED_CHAIN="Fake LE Root X2" + PREFERRED_CHAIN="\(STAGING\) Pretend Pear X1" + CHECK_CHAIN="(STAGING) Pretend Pear X1" else - PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | cut -d= -f2) + PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | awk -F"CN=" '{ print $2 }') PREFERRED_CHAIN="${PREFERRED_CHAIN# }" # remove leading whitespace + CHECK_CHAIN=$PREFERRED_CHAIN fi CONFIG_FILE="getssl-dns01.cfg" @@ -29,21 +31,27 @@ setup() { PREFERRED_CHAIN="${PREFERRED_CHAIN}" EOF - create_certificate + create_certificate -d assert_success check_output_for_errors - issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Issuer: | tail -1 | cut -d= -f2) + issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Issuer: | tail -1 | awk -F"CN=" '{ print $2 }') # verify certificate is issued by preferred chain root - [ "$PREFERRED_CHAIN" = "$issuer" ] + if [[ "${CHECK_CHAIN}" != "$issuer" ]]; then + echo "# PREFERRED_CHAIN=$PREFERRED_CHAIN" + echo "# issuer=$issuer" + fi + + [ "${CHECK_CHAIN}" = "$issuer" ] } @test "Use PREFERRED_CHAIN to select the default root" { if [ -n "$STAGING" ]; then - PREFERRED_CHAIN="Fake LE Root X1" + PREFERRED_CHAIN="\(STAGING\) Doctored Durian Root CA X3" + CHECK_CHAIN="(STAGING) Doctored Durian Root CA X3" else - PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/0 | openssl x509 -text -noout | grep Issuer: | cut -d= -f2 ) + PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/0 | openssl x509 -text -noout | grep Issuer: | awk -F"CN=" '{ print $2 }') PREFERRED_CHAIN="${PREFERRED_CHAIN# }" # remove leading whitespace fi @@ -59,17 +67,21 @@ EOF assert_success check_output_for_errors - issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Issuer: | tail -1 | cut -d= -f2) + issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Issuer: | tail -1 | awk -F"CN=" '{ print $2 }') # verify certificate is issued by preferred chain root - [ "$PREFERRED_CHAIN" = "$issuer" ] + if [[ "${CHECK_CHAIN}" != "$issuer" ]]; then + echo "# PREFERRED_CHAIN=$PREFERRED_CHAIN" + echo "# issuer=$issuer" + fi + [ "${CHECK_CHAIN}" = "$issuer" ] } @test "Use PREFERRED_CHAIN to select an alternate root by suffix" { if [ -n "$STAGING" ]; then - FULL_PREFERRED_CHAIN="Fake LE Root X2" + FULL_PREFERRED_CHAIN="(STAGING) Pretend Pear X1" else - FULL_PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | cut -d= -f2) + FULL_PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | awk -F"CN=" '{ print $2 }') FULL_PREFERRED_CHAIN="${FULL_PREFERRED_CHAIN# }" # remove leading whitespace fi @@ -87,9 +99,12 @@ EOF assert_success check_output_for_errors - issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Issuer: | tail -1 | cut -d= -f2) + issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Issuer: | tail -1 | awk -F"CN=" '{ print $2 }') # verify certificate is issued by preferred chain root - echo "# ${issuer}" - echo "# ${FULL_PREFERRED_CHAIN}" - [ "$FULL_PREFERRED_CHAIN" = "$issuer" ] + if [[ "${FULL_PREFERRED_CHAIN}" != "$issuer" ]]; then + echo "# PREFERRED_CHAIN=$PREFERRED_CHAIN" + echo "# FULL_PREFERRED_CHAIN=$FULL_PREFERRED_CHAIN" + echo "# issuer=$issuer" + fi + [ "${FULL_PREFERRED_CHAIN}" = "$issuer" ] } diff --git a/test/36-full-chain-inc-root.bats b/test/36-full-chain-inc-root.bats index 5932ea7..5b29d0b 100644 --- a/test/36-full-chain-inc-root.bats +++ b/test/36-full-chain-inc-root.bats @@ -27,22 +27,27 @@ EOF check_output_for_errors if [ -n "$STAGING" ]; then - PREFERRED_CHAIN="Fake LE Root X1" + PREFERRED_CHAIN="(STAGING) Doctored Durian Root CA X3" else # pebble doesn't support CA Issuers so the fullchain.crt will just contain the certificate (code path means it won't contain the intermediate cert in this case) # This is testing that requesting FULL_CHAIN_INCLUDE_ROOT doesn't fail if there is no CA Issuers in the certificate - PREFERRED_CHAIN=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + PREFERRED_CHAIN=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | awk -F"CN=" '{ print $2 }') fi - final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | awk -F"CN=" '{ print $2 }') + # verify certificate includes the chain root - [ "$PREFERRED_CHAIN" = "$final_issuer" ] + if [[ "${PREFERRED_CHAIN}" != "$final_issuer" ]]; then + echo "# PREFERRED_CHAIN=$PREFERRED_CHAIN" + echo "# final_issuer=$final_issuer" + fi + [ "${PREFERRED_CHAIN}" = "$final_issuer" ] } @test "Use FULL_CHAIN_INCLUDE_ROOT with dual certificates" { if [ -n "$STAGING" ]; then - PREFERRED_CHAIN="Fake LE Root X1" + PREFERRED_CHAIN="(STAGING) Doctored Durian Root CA X3" fi CONFIG_FILE="getssl-dns01.cfg" @@ -66,16 +71,24 @@ EOF assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.ec.crt" ] if [ -n "$STAGING" ]; then - PREFERRED_CHAIN="Fake LE Root X1" + PREFERRED_CHAIN="(STAGING) Doctored Durian Root CA X3" else # pebble doesn't support CA Issuers so the fullchain.crt will just contain the certificate (code path means it won't contain the intermediate cert in this case) # This is testing that requesting FULL_CHAIN_INCLUDE_ROOT doesn't fail if there is no CA Issuers in the certificate - PREFERRED_CHAIN=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) + PREFERRED_CHAIN=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | awk -F"CN=" '{ print $2 }') fi # verify both rsa and ecdsa certificates include the chain root - final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) - [ "$PREFERRED_CHAIN" = "$final_issuer" ] - ecdsa_final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.ec.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | cut -d= -f2) - [ "$PREFERRED_CHAIN" = "$ecdsa_final_issuer" ] + final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | awk -F"CN=" '{ print $2 }') + if [[ "${PREFERRED_CHAIN}" != "$final_issuer" ]]; then + echo "# PREFERRED_CHAIN=$PREFERRED_CHAIN" + echo "# final_issuer=$final_issuer" + fi + [ "${PREFERRED_CHAIN}" = "$final_issuer" ] + ecdsa_final_issuer=$(openssl crl2pkcs7 -nocrl -certfile "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.ec.crt" | openssl pkcs7 -print_certs -text -noout | grep Subject: | tail -1 | awk -F"CN=" '{ print $2 }') + if [[ "$PREFERRED_CHAIN" != "$ecdsa_final_issuer" ]]; then + echo "# PREFERRED_CHAIN=$PREFERRED_CHAIN" + echo "# ecdsa_final_issuer=$ecdsa_final_issuer" + fi + [ "${PREFERRED_CHAIN}" = "$ecdsa_final_issuer" ] } From da63cf3ac42b43c18af8e42a982bdc236c80e668 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Sat, 20 Feb 2021 15:07:58 +0000 Subject: [PATCH 6/7] Fix awk command for pebble --- test/35-preferred-chain.bats | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/35-preferred-chain.bats b/test/35-preferred-chain.bats index 0a5821c..b16e77a 100644 --- a/test/35-preferred-chain.bats +++ b/test/35-preferred-chain.bats @@ -18,7 +18,7 @@ setup() { PREFERRED_CHAIN="\(STAGING\) Pretend Pear X1" CHECK_CHAIN="(STAGING) Pretend Pear X1" else - PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | awk -F"CN=" '{ print $2 }') + PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | awk -F"CN *= *" '{ print $2 }') PREFERRED_CHAIN="${PREFERRED_CHAIN# }" # remove leading whitespace CHECK_CHAIN=$PREFERRED_CHAIN fi @@ -51,8 +51,9 @@ EOF PREFERRED_CHAIN="\(STAGING\) Doctored Durian Root CA X3" CHECK_CHAIN="(STAGING) Doctored Durian Root CA X3" else - PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/0 | openssl x509 -text -noout | grep Issuer: | awk -F"CN=" '{ print $2 }') + PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/0 | openssl x509 -text -noout | grep Issuer: | awk -F"CN *= *" '{ print $2 }') PREFERRED_CHAIN="${PREFERRED_CHAIN# }" # remove leading whitespace + CHECK_CHAIN=$PREFERRED_CHAIN fi CONFIG_FILE="getssl-dns01.cfg" @@ -81,7 +82,7 @@ EOF if [ -n "$STAGING" ]; then FULL_PREFERRED_CHAIN="(STAGING) Pretend Pear X1" else - FULL_PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | awk -F"CN=" '{ print $2 }') + FULL_PREFERRED_CHAIN=$(curl --silent https://pebble:15000/roots/2 | openssl x509 -text -noout | grep "Issuer:" | awk -F"CN *= *" '{ print $2 }') FULL_PREFERRED_CHAIN="${FULL_PREFERRED_CHAIN# }" # remove leading whitespace fi From 8bb211417457bf20e0a964d703a86acb9bf83023 Mon Sep 17 00:00:00 2001 From: Tim Kimber Date: Sat, 20 Feb 2021 15:49:37 +0000 Subject: [PATCH 7/7] Remove debug --- test/35-preferred-chain.bats | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/35-preferred-chain.bats b/test/35-preferred-chain.bats index b16e77a..9c3fc6b 100644 --- a/test/35-preferred-chain.bats +++ b/test/35-preferred-chain.bats @@ -31,7 +31,7 @@ setup() { PREFERRED_CHAIN="${PREFERRED_CHAIN}" EOF - create_certificate -d + create_certificate assert_success check_output_for_errors