diff --git a/getssl b/getssl index a5e72cf..2737f1a 100755 --- a/getssl +++ b/getssl @@ -234,6 +234,7 @@ # 2020-06-06 Fix missing URL_revoke definition when no CA directory suffix (#566) # 2020-06-18 Fix CHECK_REMOTE for DUAL_RSA_ECDSA (#570) # 2020-07-14 Support space separated SANS (#574) (2.29) +# 2020-08-06 Use -sigalgs instead of -cipher when checking remote for tls1.3 (#570) # ---------------------------------------------------------------------------------------- PROGNAME=${0##*/} @@ -2564,11 +2565,17 @@ fi # if check_remote is true then connect and obtain the current certificate (if not forcing renewal) if [[ "${CHECK_REMOTE}" == "true" ]] && [[ $_FORCE_RENEW -eq 0 ]]; then debug "getting certificate for $DOMAIN from remote server" -if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then - CIPHER="-cipher RSA" -else + if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then + # shellcheck disable=SC2086 + # check if openssl supports RSA-PSS + if [[ $(echo | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} -sigalgs RSA-PSS+SHA256 2>/dev/null) ]]; then + CIPHER="-sigalgs RSA+SHA256:RSA+SHA384:RSA+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA512" + else + CIPHER="-sigalgs RSA+SHA256:RSA+SHA384:RSA+SHA512" + fi + else CIPHER="" -fi + fi # shellcheck disable=SC2086 EX_CERT=$(echo \ | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} ${CIPHER} 2>/dev/null \ @@ -2826,7 +2833,14 @@ fi if [[ ${CHECK_REMOTE} == "true" ]]; then sleep "$CHECK_REMOTE_WAIT" if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then - PARAMS=("-cipher RSA" "-cipher ECDSA") + # shellcheck disable=SC2086 + # check if openssl supports RSA-PSS + if [[ $(echo | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} -sigalgs RSA-PSS+SHA256 2>/dev/null) ]]; then + PARAMS=("-sigalgs RSA-PSS+SHA256:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512" "-sigalgs ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512") + else + PARAMS=("-sigalgs RSA+SHA256:RSA+SHA384:RSA+SHA512" "-sigalgs ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512") + fi + CERTS=("$CERT_FILE" "${CERT_FILE%.*}.ec.crt") TYPES=("rsa" "$PRIVATE_KEY_ALG") else @@ -2842,8 +2856,13 @@ if [[ ${CHECK_REMOTE} == "true" ]]; then | openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} ${PARAMS[i]} 2>/dev/null \ | openssl x509 -noout -fingerprint 2>/dev/null) CERT_LOCAL=$(openssl x509 -noout -fingerprint < "${CERTS[i]}" 2>/dev/null) + debug CERT_LOCAL="${CERT_LOCAL}" + debug CERT_REMOTE="${CERT_REMOTE}" if [[ "$CERT_LOCAL" == "$CERT_REMOTE" ]]; then info "${DOMAIN} - ${TYPES[i]} certificate installed OK on server" + elif [[ "$CERT_REMOTE" == "" ]]; then + info "${CERTS[i]} not returned by server" + error_exit "${DOMAIN} - ${TYPES[i]} certificate obtained but not installed on server" else info "${CERTS[i]} didn't match server" error_exit "${DOMAIN} - ${TYPES[i]} certificate obtained but certificate on server is different from the new certificate" diff --git a/test/14-test-revoke.bats b/test/14-test-revoke.bats index 2e95e0d..e624552 100644 --- a/test/14-test-revoke.bats +++ b/test/14-test-revoke.bats @@ -38,5 +38,5 @@ setup() { run ${CODE_DIR}/getssl -d --revoke $CERT $KEY $CA assert_success - check_output_for_errors + check_output_for_errors "debug" } diff --git a/test/15-test-revoke-no-suffix.bats b/test/15-test-revoke-no-suffix.bats index 7b19c5a..26f5f3f 100644 --- a/test/15-test-revoke-no-suffix.bats +++ b/test/15-test-revoke-no-suffix.bats @@ -38,5 +38,5 @@ setup() { run ${CODE_DIR}/getssl -d --revoke $CERT $KEY $CA assert_success - check_output_for_errors + check_output_for_errors "debug" } diff --git a/test/6-dual-rsa-ecdsa-copy-2-locations.bats b/test/6-dual-rsa-ecdsa-copy-2-locations.bats index a8e7653..6f75f25 100644 --- a/test/6-dual-rsa-ecdsa-copy-2-locations.bats +++ b/test/6-dual-rsa-ecdsa-copy-2-locations.bats @@ -40,6 +40,10 @@ teardown() { create_certificate assert_success check_output_for_errors + if [ "$OLD_NGINX" = "false" ]; then + assert_line --partial "rsa certificate installed OK on server" + assert_line --partial "prime256v1 certificate installed OK on server" + fi # Check that the RSA chain and key have been copied to both locations assert [ -e "/etc/nginx/pki/domain-chain.crt" ] @@ -53,3 +57,25 @@ teardown() { assert [ -e "/etc/nginx/pki/private/server.ec.key" ] assert [ -e "/root/a.${GETSSL_HOST}/server.ec.key" ] } + + +@test "Create dual certificates and copy to two locations but not returned by server" { + if [ -n "$STAGING" ]; then + skip "Using staging server, skipping internal test" + fi + + check_nginx + if [ "$OLD_NGINX" = "false" ]; then + CONFIG_FILE="getssl-http01-dual-rsa-ecdsa-2-locations-wrong-nginx.cfg" + else + skip "Skipping as old nginx servers cannot return both certificates" + fi + + setup_environment + mkdir -p /root/a.${GETSSL_HOST} + + init_getssl + create_certificate + assert_failure + assert_line --partial "prime256v1 certificate obtained but not installed on server" +} diff --git a/test/test-config/getssl-http01-dual-rsa-ecdsa-2-locations-wrong-nginx.cfg b/test/test-config/getssl-http01-dual-rsa-ecdsa-2-locations-wrong-nginx.cfg new file mode 100644 index 0000000..80533ce --- /dev/null +++ b/test/test-config/getssl-http01-dual-rsa-ecdsa-2-locations-wrong-nginx.cfg @@ -0,0 +1,32 @@ +# Test that more than one location can be specified for CERT and KEY locations and that the +# files are copied to both locations when both RSA and ECDSA certificates are created +# +CA="https://pebble:14000/dir" + +DUAL_RSA_ECDSA="true" +ACCOUNT_KEY_TYPE="prime256v1" +PRIVATE_KEY_ALG="prime256v1" + +# Additional domains - this could be multiple domains / subdomains in a comma separated list +SANS="a.${GETSSL_HOST}" + +# Acme Challenge Location. +ACL=('/var/www/html/.well-known/acme-challenge') + +#Set USE_SINGLE_ACL="true" to use a single ACL for all checks +USE_SINGLE_ACL="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/nginx/pki/server.crt" +DOMAIN_KEY_LOCATION="/etc/nginx/pki/private/server.key;/root/a.${GETSSL_HOST}/server.key" +CA_CERT_LOCATION="/etc/nginx/pki/chain.crt" +DOMAIN_CHAIN_LOCATION="/etc/nginx/pki/domain-chain.crt;/root/a.${GETSSL_HOST}/domain-chain.crt" # this is the domain cert and CA cert +DOMAIN_PEM_LOCATION="" # this is the domain_key, domain cert and CA cert + +# The command needed to reload apache / nginx or whatever you use +RELOAD_CMD="cp /getssl/test/test-config/nginx-ubuntu-ssl ${NGINX_CONFIG} && /getssl/test/restart-nginx" + +# Define the server type and confirm correct certificate is installed +SERVER_TYPE="https" +CHECK_REMOTE="true" diff --git a/test/test-config/getssl-http01-dual-rsa-ecdsa-old-nginx.cfg b/test/test-config/getssl-http01-dual-rsa-ecdsa-old-nginx.cfg index 41581ae..9cf155f 100644 --- a/test/test-config/getssl-http01-dual-rsa-ecdsa-old-nginx.cfg +++ b/test/test-config/getssl-http01-dual-rsa-ecdsa-old-nginx.cfg @@ -19,8 +19,8 @@ USE_SINGLE_ACL="false" # 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/nginx/pki/server.ec.crt" -DOMAIN_KEY_LOCATION="/etc/nginx/pki/private/server.ec.key" +DOMAIN_CERT_LOCATION="/etc/nginx/pki/server.crt" +DOMAIN_KEY_LOCATION="/etc/nginx/pki/private/server.key" CA_CERT_LOCATION="/etc/nginx/pki/chain.crt" DOMAIN_CHAIN_LOCATION="" # this is the domain cert and CA cert DOMAIN_PEM_LOCATION="" # this is the domain_key, domain cert and CA cert diff --git a/test/test-config/nginx-ubuntu-dual-certs b/test/test-config/nginx-ubuntu-dual-certs index ce1fbbf..1eceecd 100644 --- a/test/test-config/nginx-ubuntu-dual-certs +++ b/test/test-config/nginx-ubuntu-dual-certs @@ -42,7 +42,7 @@ server { # Add index.php to the list if you are using PHP index index.html index.htm index.nginx-debian.html; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; server_name _; ssl_certificate /etc/nginx/pki/server.crt; diff --git a/test/test_helper.bash b/test/test_helper.bash index 9358619..db79ea4 100644 --- a/test/test_helper.bash +++ b/test/test_helper.bash @@ -12,7 +12,7 @@ check_certificates() # https://unix.stackexchange.com/questions/285924/how-to-compare-a-programs-version-in-a-shell-script check_nginx() { requiredver="1.11.0" - currentver="$(nginx -v)" + currentver=$(nginx -v 2>&1 | awk -F"/" '{print $2}') if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then export OLD_NGINX="false" else