Browse Source

Merge pull request #599 from srvrco/timkimber/issue347

Wildcard support in ACMEv2 - fixes #347 and #400
pull/601/head
Tim Kimber 5 years ago
committed by GitHub
parent
commit
8ec8deac3d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 822 additions and 230 deletions
  1. +131
    -145
      getssl
  2. +3
    -1
      test/10-mixed-case.bats
  3. +3
    -1
      test/14-test-revoke.bats
  4. +3
    -1
      test/15-test-revoke-no-suffix.bats
  5. +3
    -1
      test/17-test-spaces-in-sans-dns01.bats
  6. +3
    -1
      test/17-test-spaces-in-sans-http01.bats
  7. +9
    -6
      test/19-test-add-to-sans.bats
  8. +3
    -1
      test/2-simple-dns01-dig.bats
  9. +3
    -1
      test/2-simple-dns01-nslookup.bats
  10. +68
    -0
      test/20-wildcard-simple.bats
  11. +82
    -0
      test/21-wildcard-dual-rsa.bats
  12. +65
    -0
      test/22-wildcard-dual-rsa-ecdsa-copy-2-locations.bats
  13. +46
    -0
      test/23-wildcard-check-globbing.bats
  14. +72
    -0
      test/24-wildcard-sans.bats
  15. +42
    -0
      test/25-wildcard-all.bats
  16. +49
    -0
      test/26-wildcard-revoke.bats
  17. +45
    -0
      test/27-wildcard-existing-cert.bats
  18. +31
    -0
      test/28-wildcard-error-http01-validation.bats
  19. +1
    -1
      test/Dockerfile-alpine
  20. +1
    -1
      test/Dockerfile-centos6
  21. +1
    -1
      test/Dockerfile-centos7
  22. +1
    -1
      test/Dockerfile-centos7-staging
  23. +1
    -1
      test/Dockerfile-centos8
  24. +1
    -1
      test/Dockerfile-debian
  25. +1
    -2
      test/Dockerfile-ubuntu
  26. +1
    -1
      test/Dockerfile-ubuntu-staging
  27. +1
    -1
      test/Dockerfile-ubuntu16
  28. +1
    -1
      test/Dockerfile-ubuntu18
  29. +1
    -1
      test/README-Testing.md
  30. +1
    -0
      test/run-test.cmd
  31. +1
    -0
      test/run-test.sh
  32. +37
    -0
      test/test-config/getssl-dns01-dual-rsa-ecdsa-2-locations.cfg
  33. +36
    -0
      test/test-config/getssl-dns01-secp384.cfg
  34. +7
    -0
      test/test-config/getssl-dns01.cfg
  35. +5
    -1
      test/test-config/getssl-staging-dns01.cfg
  36. +63
    -59
      test/test_helper.bash

+ 131
- 145
getssl View File

@ -240,6 +240,8 @@
# 2020-09-02 Fix issue when SANS is space and comma separated (#579) (2.30)
# 2020-10-02 Various fixes to get_auth_dns and changes to support unit tests (#308)
# 2020-10-04 Add CHECK_PUBLIC_DNS_SERVER to check the DNS challenge has been updated there
# 2020-10-13 Bugfix: strip comments in drill/dig output (mhameed)
# 2020-11-18 Wildcard support (#347)(#400)
# ----------------------------------------------------------------------------------------
PROGNAME=${0##*/}
@ -469,7 +471,7 @@ check_challenge_completion() { # checks with the ACME server if our challenge is
# if ACME response is that their check gave an invalid response, error exit
if [[ "$status" == "invalid" ]] ; then
err_detail=$(echo "$response" | grep "detail")
#! FIXME need to check for "DNS problem: SERVFAIL looking up CAA ..." and retry
# TODO need to check for "DNS problem: SERVFAIL looking up CAA ..." and retry
error_exit "$domain:Verify error:$err_detail"
fi
@ -491,6 +493,84 @@ check_challenge_completion() { # checks with the ACME server if our challenge is
fi
}
check_challenge_completion_dns() { # perform validation via DNS challenge
token=$1
uri=$2
keyauthorization=$3
d=$4
primary_ns=$5
auth_key=$6
# Always use lowercase domain name when querying DNS servers
# shellcheck disable=SC2018,SC2019
lower_d=$(echo "${d##\*.}" | tr A-Z a-z)
# check for token at public dns server, waiting for a valid response.
for ns in $primary_ns; do
debug "checking dns at $ns"
ntries=0
check_dns="fail"
while [[ "$check_dns" == "fail" ]]; do
if [[ "$os" == "cygwin" ]]; then
check_result=$(nslookup -type=txt "_acme-challenge.${lower_d}" "${ns}" \
| grep ^_acme -A2\
| grep '"'|awk -F'"' '{ print $2}')
elif [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
debug "$DNS_CHECK_FUNC" TXT "_acme-challenge.${lower_d}" "@${ns}"
check_result=$($DNS_CHECK_FUNC TXT "_acme-challenge.${lower_d}" "@${ns}" \
| grep -i "^_acme-challenge.${lower_d}" \
| grep 'IN\WTXT'|awk -F'"' '{ print $2}')
elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then
check_result=$($DNS_CHECK_FUNC -t TXT "_acme-challenge.${lower_d}" "${ns}" \
| grep 'descriptive text'|awk -F'"' '{ print $2}')
else
check_result=$(nslookup -type=txt "_acme-challenge.${lower_d}" "${ns}" \
| grep 'text ='|awk -F'"' '{ print $2}')
fi
debug "expecting $auth_key"
debug "${ns} gave ... $check_result"
if [[ "$check_result" == *"$auth_key"* ]]; then
check_dns="success"
else
if [[ $ntries -lt $DNS_WAIT_COUNT ]]; then
ntries=$(( ntries + 1 ))
if [[ $DNS_WAIT_RETRY_ADD == "true" && $(( ntries % 10 )) == 0 ]]; then
debug "Retrying adding dns via command: $DNS_ADD_COMMAND $lower_d $auth_key"
eval "$DNS_DEL_COMMAND" "$lower_d" "$auth_key"
if ! eval "$DNS_ADD_COMMAND" "$lower_d" "$auth_key" ; then
error_exit "DNS_ADD_COMMAND failed for domain $d"
fi
fi
info "checking DNS at ${ns} for ${lower_d}. Attempt $ntries/${DNS_WAIT_COUNT} gave wrong result, "\
"waiting $DNS_WAIT secs before checking again"
sleep $DNS_WAIT
else
debug "dns check failed - removing existing value"
eval "$DNS_DEL_COMMAND" "$lower_d" "$auth_key"
error_exit "checking _acme-challenge.${lower_d} gave $check_result not $auth_key"
fi
fi
done
done
if [[ "$DNS_EXTRA_WAIT" -gt 0 && "$PREVIOUSLY_VALIDATED" != "true" ]]; then
info "sleeping $DNS_EXTRA_WAIT seconds before asking the ACME server to check the dns"
sleep "$DNS_EXTRA_WAIT"
fi
check_challenge_completion "$uri" "$d" "$keyauthorization"
debug "remove DNS entry"
# shellcheck disable=SC2018,SC2019
lower_d=$(echo "${d##\*.}" | tr A-Z a-z)
eval "$DNS_DEL_COMMAND" "$lower_d" "$auth_key"
}
# end of ... perform validation if via DNS challenge
check_config() { # check the config files for all obvious errors
debug "checking config"
@ -518,13 +598,13 @@ check_config() { # check the config files for all obvious errors
config_errors=true
fi
# get all domains
# get all domains into an array
if [[ "$IGNORE_DIRECTORY_DOMAIN" == "true" ]]; then
alldomains=${SANS//[, ]/ }
read -r -a alldomains <<< "${SANS//[, ]/ }"
else
alldomains=$(echo "$DOMAIN,$SANS" | sed "s/,/ /g")
read -r -a alldomains <<< "$(echo "$DOMAIN,$SANS" | sed "s/,/ /g")"
fi
if [[ -z "$alldomains" ]]; then
if [[ -z "${alldomains[*]}" ]]; then
info "${DOMAIN}: no domains specified"
config_errors=true
fi
@ -542,11 +622,14 @@ check_config() { # check the config files for all obvious errors
dn=0
tmplist=$(mktemp 2>/dev/null || mktemp -t getssl)
for d in $alldomains; do # loop over domains (dn is domain number)
for d in "${alldomains[@]}"; do # loop over domains (dn is domain number)
debug "checking domain $d"
if [[ "$(grep "^${d}$" "$tmplist")" = "$d" ]]; then
info "${DOMAIN}: $d appears to be duplicated in domain, SAN list"
config_errors=true
elif [[ "$d" != "${d##\*.}" ]] && [[ "$VALIDATE_VIA_DNS" != "true" ]]; then
info "${DOMAIN}: cannot use http-01 validation for wildcard domains"
config_errors=true
else
echo "$d" >> "$tmplist"
fi
@ -682,7 +765,7 @@ clean_up() { # Perform pre-exit housekeeping
# shellcheck source=/dev/null
. "$dnsfile"
debug "attempting to clean up DNS entry for $d"
eval "$DNS_DEL_COMMAND" "$d" "$auth_key"
eval "$DNS_DEL_COMMAND" "${d##\*.}" "$auth_key"
done
shopt -u nullglob
fi
@ -809,14 +892,14 @@ create_csr() { # create a csr using a given key (if it doesn't already exist)
debug "domain csr exists at - $csr_file"
# check all domains in config are in csr
if [[ "$IGNORE_DIRECTORY_DOMAIN" == "true" ]]; then
alldomains=$(echo "$SANS" | sed -e 's/ //g; s/,$//; y/,/\n/' | sort -u)
read -r -a alldomains <<< "$(echo "$SANS" | sed -e 's/ //g; s/,$//; y/,/\n/' | sort -u)"
else
alldomains=$(echo "$DOMAIN,$SANS" | sed -e 's/,/ /g; s/ $//; y/ /\n/' | sort -u)
read -r -a alldomains <<< "$(echo "$DOMAIN,$SANS" | sed -e 's/,/ /g; s/ $//; y/ /\n/' | sort -u)"
fi
domains_in_csr=$(openssl req -text -noout -in "$csr_file" \
| sed -n -e 's/^ *Subject: .* CN=\([A-Za-z0-9.-]*\).*$/\1/p; /^ *DNS:.../ { s/ *DNS://g; y/,/\n/; p; }' \
| sort -u)
for d in $alldomains; do
for d in "${alldomains[@]}"; do
if [[ "$(echo "${domains_in_csr}"| grep "^${d}$")" != "${d}" ]]; then
info "existing csr at $csr_file does not contain ${d} - re-create-csr"\
".... $(echo "${domains_in_csr}"| grep "^${d}$")"
@ -824,7 +907,7 @@ create_csr() { # create a csr using a given key (if it doesn't already exist)
fi
done
# check all domains in csr are in config
if [[ "$alldomains" != "$domains_in_csr" ]]; then
if [[ "${alldomains[*]}" != "$domains_in_csr" ]]; then
info "existing csr at $csr_file does not have the same domains as the config - re-create-csr"
_RECREATE_CSR=1
fi
@ -877,7 +960,7 @@ create_key() { # create a domain key (if it doesn't already exist)
create_order() {
dstring="["
for d in $alldomains; do
for d in "${alldomains[@]}"; do
dstring="${dstring}{\"type\":\"dns\",\"value\":\"$d\"},"
done
dstring="${dstring::${#dstring}-1}]"
@ -893,9 +976,9 @@ create_order() {
if [[ $API -eq 1 ]]; then
dn=0
for d in $alldomains; do
for d in "${alldomains[@]}"; do
# get authorizations link
AuthLink[$dn]=$(json_get "$response" "identifiers" "value" "$d" "authorizations" "x")
AuthLink[$dn]=$(json_get "$response" "identifiers" "value" "${d##\*.}" "authorizations" "x")
debug "authorizations link for $d - ${AuthLink[$dn]}"
((dn++))
done
@ -909,12 +992,14 @@ create_order() {
send_signed_request "$l" ""
# Get domain from response
authdomain=$(json_get "$response" "identifier" "value")
# find array position (This is O(n2) but that doubt we'll see performance issues)
wildcard=$(json_get "$response" "wildcard")
debug wildcard="$wildcard"
# find array position (This is O(n2) but doubt that we'll see performance issues)
dn=0
for d in $alldomains; do
for d in "${alldomains[@]}"; do
# Convert domain to lowercase as response from server will be in lowercase
d=$(echo "$d" | tr "[:upper:]" "[:lower:]")
if [ "$d" == "$authdomain" ]; then
lower_d=$(echo "$d" | tr "[:upper:]" "[:lower:]")
if [[ ( "$lower_d" == "$authdomain" && -z "$wildcard" ) || ( "$lower_d" == "*.${authdomain}" && -n "$wildcard" ) ]]; then
debug "Saving authorization response for $authdomain for domain alldomains[$dn]"
debug "Response = ${response//[$'\t\r\n']}"
AuthLinkResponse[$dn]=$response
@ -1004,7 +1089,7 @@ find_dns_utils() {
fulfill_challenges() {
dn=0
for d in $alldomains; do
for d in "${alldomains[@]}"; do
# $d is domain in current loop, which is number $dn for ACL
info "Verifying $d"
if [[ "$USE_SINGLE_ACL" == "true" ]]; then
@ -1015,7 +1100,7 @@ for d in $alldomains; do
# request a challenge token from ACME server
if [[ $API -eq 1 ]]; then
request="{\"resource\":\"new-authz\",\"identifier\":{\"type\":\"dns\",\"value\":\"$d\"}}"
request="{\"resource\":\"new-authz\",\"identifier\":{\"type\":\"dns\",\"value\":\"${d##\*.}\"}}"
send_signed_request "$URL_new_authz" "$request"
debug "completed send_signed_request"
@ -1068,7 +1153,7 @@ for d in $alldomains; do
debug auth_key "$auth_key"
# shellcheck disable=SC2018,SC2019
lower_d=$(echo "$d" | tr A-Z a-z)
lower_d=$(echo "${d##\*.}" | tr A-Z a-z)
debug "adding dns via command: $DNS_ADD_COMMAND $lower_d $auth_key"
if ! eval "$DNS_ADD_COMMAND" "$lower_d" "$auth_key" ; then
error_exit "DNS_ADD_COMMAND failed for domain $d"
@ -1082,21 +1167,7 @@ for d in $alldomains; do
fi
debug primary_ns "$primary_ns"
# make a directory to hold pending dns-challenges
if [[ ! -d "$TEMP_DIR/dns_verify" ]]; then
mkdir "$TEMP_DIR/dns_verify"
fi
# generate a file with the current variables for the dns-challenge
cat > "$TEMP_DIR/dns_verify/$d" <<- _EOF_
token="${token}"
uri="${uri}"
keyauthorization="${keyauthorization}"
d="${d}"
primary_ns="${primary_ns}"
auth_key="${auth_key}"
_EOF_
check_challenge_completion_dns "${token}" "${uri}" "${keyauthorization}" "${d}" "${primary_ns}" "${auth_key}"
else # set up the correct http token for verification
if [[ $API -eq 1 ]]; then
# get the token from the http component
@ -1179,101 +1250,7 @@ for d in $alldomains; do
((dn++))
fi
done # end of ... loop through domains for cert ( from SANS list)
# perform validation if via DNS challenge
if [[ $VALIDATE_VIA_DNS == "true" ]]; then
# loop through dns-variable files to check if dns has been changed
for dnsfile in "$TEMP_DIR"/dns_verify/*; do
if [[ -e "$dnsfile" ]]; then
debug "loading DNSfile: $dnsfile"
# shellcheck source=/dev/null
. "$dnsfile"
# Always use lowercase domain name when querying DNS servers
# shellcheck disable=SC2018,SC2019
lower_d=$(echo "$d" | tr A-Z a-z)
# check for token at public dns server, waiting for a valid response.
for ns in $primary_ns; do
debug "checking dns at $ns"
ntries=0
check_dns="fail"
while [[ "$check_dns" == "fail" ]]; do
if [[ "$os" == "cygwin" ]]; then
check_result=$(nslookup -type=txt "_acme-challenge.${lower_d}" "${ns}" \
| grep ^_acme -A2\
| grep '"'|awk -F'"' '{ print $2}')
elif [[ "$DNS_CHECK_FUNC" == "drill" ]] || [[ "$DNS_CHECK_FUNC" == "dig" ]]; then
debug "$DNS_CHECK_FUNC" TXT "_acme-challenge.${lower_d}" "@${ns}"
check_result=$($DNS_CHECK_FUNC TXT "_acme-challenge.${lower_d}" "@${ns}" \
| grep -i "^_acme-challenge.${lower_d}" \
| grep 'IN\WTXT'|awk -F'"' '{ print $2}')
elif [[ "$DNS_CHECK_FUNC" == "host" ]]; then
check_result=$($DNS_CHECK_FUNC -t TXT "_acme-challenge.${lower_d}" "${ns}" \
| grep 'descriptive text'|awk -F'"' '{ print $2}')
else
check_result=$(nslookup -type=txt "_acme-challenge.${lower_d}" "${ns}" \
| grep 'text ='|awk -F'"' '{ print $2}')
fi
debug "expecting $auth_key"
debug "${ns} gave ... $check_result"
if [[ "$check_result" == *"$auth_key"* ]]; then
check_dns="success"
else
if [[ $ntries -lt $DNS_WAIT_COUNT ]]; then
ntries=$(( ntries + 1 ))
if [[ $DNS_WAIT_RETRY_ADD == "true" && $(( ntries % 10 )) == 0 ]]; then
debug "Retrying adding dns via command: $DNS_ADD_COMMAND $lower_d $auth_key"
eval "$DNS_DEL_COMMAND" "$lower_d" "$auth_key"
if ! eval "$DNS_ADD_COMMAND" "$lower_d" "$auth_key" ; then
error_exit "DNS_ADD_COMMAND failed for domain $d"
fi
fi
info "checking DNS at ${ns} for ${lower_d}. Attempt $ntries/${DNS_WAIT_COUNT} gave wrong result, "\
"waiting $DNS_WAIT secs before checking again"
sleep $DNS_WAIT
else
debug "dns check failed - removing existing value"
eval "$DNS_DEL_COMMAND" "$lower_d" "$auth_key"
# remove $dnsfile after each loop.
rm -f "$dnsfile"
error_exit "checking _acme-challenge.${lower_d} gave $check_result not $auth_key"
fi
fi
done
done
fi
done
if [[ "$DNS_EXTRA_WAIT" -gt 0 && "$PREVIOUSLY_VALIDATED" != "true" ]]; then
info "sleeping $DNS_EXTRA_WAIT seconds before asking the ACME server to check the dns"
sleep "$DNS_EXTRA_WAIT"
fi
# loop through dns-variable files to let the ACME server check the challenges
for dnsfile in "$TEMP_DIR"/dns_verify/*; do
if [[ -e "$dnsfile" ]]; then
debug "loading DNSfile: $dnsfile"
# shellcheck source=/dev/null
. "$dnsfile"
check_challenge_completion "$uri" "$d" "$keyauthorization"
debug "remove DNS entry"
# shellcheck disable=SC2018,SC2019
lower_d=$(echo "$d" | tr A-Z a-z)
eval "$DNS_DEL_COMMAND" "$lower_d" "$auth_key"
# remove $dnsfile after each loop.
rm -f "$dnsfile"
fi
done
fi
# end of ... perform validation if via DNS challenge
#end of varify each domain.
#end of verify each domain.
}
get_auth_dns() { # get the authoritative dns server for a domain (sets primary_ns )
@ -2557,7 +2534,7 @@ if [[ ${_CHECK_ALL} -eq 1 ]]; then
fi
# check if $dir is a directory with a getssl.cfg in it
if [[ -f "$dir/getssl.cfg" ]]; then
cmd="$cmd -w $WORKING_DIR $(basename "$dir")"
cmd="$cmd -w $WORKING_DIR \"$(basename "$dir")\""
debug "CMD: $cmd"
eval "$cmd"
fi
@ -2590,15 +2567,20 @@ if [[ ${_CREATE_CONFIG} -eq 1 ]]; then
info "creating domain config file in $DOMAIN_DIR/getssl.cfg"
# if domain has an existing cert, copy from domain and use to create defaults.
EX_CERT=$(echo \
| openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:443" 2>/dev/null \
| openssl s_client -servername "${DOMAIN##\*.}" -connect "${DOMAIN##\*.}:443" 2>/dev/null \
| openssl x509 2>/dev/null)
EX_SANS="www.${DOMAIN}"
EX_SANS="www.${DOMAIN##\*.}"
if [[ -n "${EX_CERT}" ]]; then
# Putting this inside the EX_SANS line below doesn't work on Centos7
escaped_d=${DOMAIN/\*/\\\*}
EX_SANS=$(echo "$EX_CERT" \
| openssl x509 -noout -text 2>/dev/null| grep "Subject Alternative Name" -A2 \
| grep -Eo "DNS:[a-zA-Z 0-9.-]*" | sed "s@DNS:$DOMAIN@@g" | grep -v '^$' | cut -c 5-)
| grep -Eo "DNS:[a-zA-Z 0-9.-\*]*" | sed "s@DNS:${escaped_d}@@g" | grep -v '^$' | cut -c 5-)
EX_SANS=${EX_SANS//$'\n'/','}
fi
if [[ -n "${EX_SANS}" ]]; then
info "Adding SANS=$EX_SANS from certificate installed on ${DOMAIN##\*.} to new configuration file"
fi
write_domain_template "$DOMAIN_DIR/getssl.cfg"
fi
TEMP_DIR="$DOMAIN_DIR/tmp"
@ -2674,11 +2656,12 @@ 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"
real_d=${DOMAIN##\*.}
debug "getting certificate for $DOMAIN from remote server ($real_d)"
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
if [[ $(echo | openssl s_client -servername "${real_d}" -connect "${real_d}:${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"
@ -2688,7 +2671,7 @@ if [[ "${CHECK_REMOTE}" == "true" ]] && [[ $_FORCE_RENEW -eq 0 ]]; then
fi
# shellcheck disable=SC2086
EX_CERT=$(echo \
| openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} ${CIPHER} 2>/dev/null \
| openssl s_client -servername "${real_d}" -connect "${real_d}:${REMOTE_PORT}" ${REMOTE_EXTRA} ${CIPHER} 2>/dev/null \
| openssl x509 2>/dev/null)
if [[ -n "$EX_CERT" ]]; then # if obtained a cert
if [[ -s "$CERT_FILE" ]]; then # if local exists
@ -2877,9 +2860,9 @@ info "Verify each domain"
# loop through domains for cert ( from SANS list)
if [[ "$IGNORE_DIRECTORY_DOMAIN" == "true" ]]; then
alldomains=${SANS//[, ]/ }
read -r -a alldomains <<< "${SANS//[, ]/ }"
else
alldomains=$(echo "$DOMAIN,$SANS" | sed "s/,/ /g")
read -r -a alldomains <<< "$(echo "$DOMAIN,$SANS" | sed "s/,/ /g")"
fi
if [[ $API -eq 2 ]]; then
@ -2941,11 +2924,12 @@ fi
# Check if the certificate is installed correctly
if [[ ${CHECK_REMOTE} == "true" ]]; then
real_d=${DOMAIN##\*.}
sleep "$CHECK_REMOTE_WAIT"
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
if [[ $(echo | openssl s_client -servername "${real_d}" -connect "${real_d}:${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")
@ -2962,20 +2946,22 @@ if [[ ${CHECK_REMOTE} == "true" ]]; then
for ((i=0; i<${#PARAMS[@]};++i)); do
debug "Checking ${CERTS[i]}"
# shellcheck disable=SC2086
debug openssl s_client -servername "${real_d}" -connect "${real_d}:${REMOTE_PORT}" ${REMOTE_EXTRA} ${PARAMS[i]}
# shellcheck disable=SC2086
CERT_REMOTE=$(echo \
| openssl s_client -servername "${DOMAIN}" -connect "${DOMAIN}:${REMOTE_PORT}" ${REMOTE_EXTRA} ${PARAMS[i]} 2>/dev/null \
| openssl s_client -servername "${real_d}" -connect "${real_d}:${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"
info "${real_d} - ${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"
error_exit "${real_d} - ${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"
error_exit "${real_d} - ${TYPES[i]} certificate obtained but certificate on server is different from the new certificate"
fi
done
fi


+ 3
- 1
test/10-mixed-case.bats View File

@ -7,7 +7,9 @@ load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
}
@test "Check that HTTP-01 verification works if the domain is not lowercase" {


+ 3
- 1
test/14-test-revoke.bats View File

@ -7,7 +7,9 @@ load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
}


+ 3
- 1
test/15-test-revoke-no-suffix.bats View File

@ -7,7 +7,9 @@ load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
}


+ 3
- 1
test/17-test-spaces-in-sans-dns01.bats View File

@ -7,7 +7,9 @@ load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
}


+ 3
- 1
test/17-test-spaces-in-sans-http01.bats View File

@ -7,7 +7,9 @@ load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
}


+ 9
- 6
test/19-test-add-to-sans.bats View File

@ -7,18 +7,21 @@ load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
curl --silent -X POST -d '{"host":"a.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
curl --silent -X POST -d '{"host":"b.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
curl --silent -X POST -d '{"host":"a.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
curl --silent -X POST -d '{"host":"b.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
fi
}
teardown() {
curl --silent -X POST -d '{"host":"a.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/clear-a
curl --silent -X POST -d '{"host":"b.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/clear-a
if [ -z "$STAGING" ]; then
curl --silent -X POST -d '{"host":"a.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/clear-a
curl --silent -X POST -d '{"host":"b.'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/clear-a
fi
}
@test "Create certificate to check can add to SANS" {
skip "FIXME: Certificate is not recreated when SANS is updated"
if [ -n "$STAGING" ]; then


+ 3
- 1
test/2-simple-dns01-dig.bats View File

@ -6,7 +6,9 @@ load '/getssl/test/test_helper.bash'
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
if [ -f /usr/bin/host ]; then
mv /usr/bin/host /usr/bin/host.getssl.bak
fi


+ 3
- 1
test/2-simple-dns01-nslookup.bats View File

@ -7,7 +7,9 @@ load '/getssl/test/test_helper.bash'
# This is run for every test
setup() {
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
if [ -f /usr/bin/dig ]; then
mv /usr/bin/dig /usr/bin/dig.getssl.bak
fi


+ 68
- 0
test/20-wildcard-simple.bats View File

@ -0,0 +1,68 @@
#! /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 "Create wildcard certificate" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
create_certificate
assert_success
check_output_for_errors
}
@test "Check CHECK_REMOTE works for wildcard certificates" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
run ${CODE_DIR}/getssl "*.$GETSSL_HOST"
assert_success
assert_line --partial "certificate is valid for more than"
check_output_for_errors
}
@test "Force renewal of wildcard certificate" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
run ${CODE_DIR}/getssl -f "*.$GETSSL_HOST"
assert_success
refute_line --partial "certificate is valid for more than"
check_output_for_errors
}
@test "Check renewal of near-expiration wildcard certificate" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
fi
echo "RENEW_ALLOW=2000" >> "${INSTALL_DIR}/.getssl/*.${GETSSL_HOST}/getssl.cfg"
run ${CODE_DIR}/getssl "*.$GETSSL_HOST"
assert_success
refute_line --partial "certificate is valid for more than"
check_output_for_errors
cleanup_environment
}

+ 82
- 0
test/21-wildcard-dual-rsa.bats View File

@ -0,0 +1,82 @@
#! /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 "Create secp384r1 wildcard certificate" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
ACCOUNT_KEY_TYPE="secp384r1"
PRIVATE_KEY_ALG="secp384r1"
EOF
create_certificate
assert_success
check_output_for_errors
run openssl x509 -noout -text -in "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt"
assert_line --partial "Public Key Algorithm: id-ecPublicKey"
cleanup_environment
}
@test "Create dual certificates using DNS-01 verification" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
cat <<- EOF > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
DUAL_RSA_ECDSA="true"
ACCOUNT_KEY_TYPE="prime256v1"
PRIVATE_KEY_ALG="prime256v1"
EOF
check_nginx
if [ "$OLD_NGINX" = "false" ]; then
echo 'RELOAD_CMD="cp /getssl/test/test-config/nginx-ubuntu-dual-certs ${NGINX_CONFIG} && /getssl/test/restart-nginx"' >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
else
echo 'CHECK_REMOTE="false"' >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
fi
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" ]
run openssl x509 -noout -text -in "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt"
assert_line --partial "Public Key Algorithm: rsaEncryption"
run openssl x509 -noout -text -in "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.ec.crt"
assert_line --partial "Public Key Algorithm: id-ecPublicKey"
cleanup_environment
}

+ 65
- 0
test/22-wildcard-dual-rsa-ecdsa-copy-2-locations.bats View File

@ -0,0 +1,65 @@
#! /usr/bin/env bats
load '/bats-support/load.bash'
load '/bats-assert/load.bash'
load '/getssl/test/test_helper.bash'
# These are run for every test, not once per file
setup() {
if [ -z "$STAGING" ]; then
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
fi
}
@test "Create dual certificates (one wildcard) and copy RSA and ECDSA chain and key to two locations" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
cat <<- 'EOF' > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
DUAL_RSA_ECDSA="true"
ACCOUNT_KEY_TYPE="prime256v1"
PRIVATE_KEY_ALG="prime256v1"
DOMAIN_KEY_LOCATION="/etc/nginx/pki/private/server.key;/root/a.${GETSSL_HOST}/server.key"
DOMAIN_CHAIN_LOCATION="/etc/nginx/pki/domain-chain.crt;/root/a.${GETSSL_HOST}/domain-chain.crt" # this is the domain cert and CA cert
EOF
check_nginx
if [ "$OLD_NGINX" = "false" ]; then
echo 'RELOAD_CMD="cp /getssl/test/test-config/nginx-ubuntu-dual-certs ${NGINX_CONFIG} && /getssl/test/restart-nginx"' >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
else
echo 'CHECK_REMOTE="false"' >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
fi
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" ]
assert [ -e "/root/a.${GETSSL_HOST}/domain-chain.crt" ]
assert [ -e "/etc/nginx/pki/private/server.key" ]
assert [ -e "/root/a.${GETSSL_HOST}/server.key" ]
# Check that the ECDSA chain and key have been copied to both locations
assert [ -e "/etc/nginx/pki/domain-chain.ec.crt" ]
assert [ -e "/root/a.${GETSSL_HOST}/domain-chain.ec.crt" ]
assert [ -e "/etc/nginx/pki/private/server.ec.key" ]
assert [ -e "/root/a.${GETSSL_HOST}/server.ec.key" ]
cleanup_environment
}

+ 46
- 0
test/23-wildcard-check-globbing.bats View File

@ -0,0 +1,46 @@
#! /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 "Check for globbing for wildcard domains" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
# Create a directory in /root which looks like a domain so that if glob expansion is performed a certificate for the wrong domain will be created
mkdir -p "${INSTALL_DIR}/a.${GETSSL_HOST}"
create_certificate
assert_success
check_output_for_errors
}
@test "Force renewal of wildcard certificate" {
if [ -n "$STAGING" ]; then
skip "Not trying on staging server yet"
fi
run ${CODE_DIR}/getssl -f "*.$GETSSL_HOST"
assert_success
refute_line --partial "certificate is valid for more than"
check_output_for_errors
}

+ 72
- 0
test/24-wildcard-sans.bats View File

@ -0,0 +1,72 @@
#! /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
curl --silent -X POST -d '{"host":"wild-'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
fi
}
teardown() {
if [ -z "$STAGING" ]; then
curl --silent -X POST -d '{"host":"wild-'$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/clear-a
fi
}
@test "Check can create certificate for wildcard domain as arg and non-wildcard in SANS" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
# Staging server generates an error if try to create a certificate for *.domain and a.domain
# so create for *.wild-domain and a.domain instead
GETSSL_CMD_HOST="*.wild-${GETSSL_HOST}"
setup_environment
init_getssl
echo 'SANS="${GETSSL_HOST}"' > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
if [ -n "$STAGING" ]; then
echo 'CHECK_REMOTE="false"' >> ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
fi
create_certificate
assert_success
check_output_for_errors
run openssl x509 -noout -text -in "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt"
# verify certificate is for wildcard domain with non-wildcard domain in the Subject Alternative Name list
assert_output --regexp "Subject: CN[ ]?=[ ]?\*.wild-${GETSSL_HOST}"
assert_output --partial "DNS:${GETSSL_HOST}"
}
@test "Check can create certificate for non-wildcard domain as arg and wildcard in SANS" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="${GETSSL_HOST}"
setup_environment
init_getssl
echo 'SANS="*.wild-${GETSSL_HOST}"' > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
create_certificate
assert_success
check_output_for_errors
run openssl x509 -noout -text -in "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt"
# verify certificate is for non-wildcard domain with wildcard domain in the Subject Alternative Name list
assert_output --regexp "Subject: CN[ ]?=[ ]?${GETSSL_HOST}"
assert_output --partial "DNS:*.wild-${GETSSL_HOST}"
}

+ 42
- 0
test/25-wildcard-all.bats View File

@ -0,0 +1,42 @@
#! /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 "Check can create certificate for wildcard domain using --all" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
# Create .getssl directory and .getssl/*.{host} directory
init_getssl
cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/*.${GETSSL_HOST}/getssl.cfg"
# create another domain in the .getssl directory
run ${CODE_DIR}/getssl -c "a.${GETSSL_HOST}"
cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/a.${GETSSL_HOST}/getssl.cfg"
# Create a directory in /root which looks like a domain so that if glob expansion is performed the wildcard certificate won't be created
mkdir -p "${INSTALL_DIR}/a.${GETSSL_HOST}"
run ${CODE_DIR}/getssl --all
assert_success
assert_line --partial "Certificate saved in /root/.getssl/*.${GETSSL_HOST}/*.${GETSSL_HOST}"
assert_line --partial "Certificate saved in /root/.getssl/a.${GETSSL_HOST}/a.${GETSSL_HOST}"
check_output_for_errors
}

+ 49
- 0
test/26-wildcard-revoke.bats View File

@ -0,0 +1,49 @@
#! /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 "Create certificate to check wildcard revoke" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
create_certificate
assert_success
check_output_for_errors
}
@test "Check we can revoke a wildcard certificate" {
if [ -n "$STAGING" ]; then
CONFIG_FILE="getssl-staging-dns01.cfg"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
. "${CODE_DIR}/test/test-config/${CONFIG_FILE}"
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
CERT=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt
KEY=${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.key
run ${CODE_DIR}/getssl -d --revoke $CERT $KEY $CA
assert_line "certificate revoked"
assert_success
check_output_for_errors "debug"
}

+ 45
- 0
test/27-wildcard-existing-cert.bats View File

@ -0,0 +1,45 @@
#! /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 "Check that new creating a new configuration files uses details from existing certificate" {
if [ -n "$STAGING" ]; then
skip "Using staging server, skipping internal test"
else
CONFIG_FILE="getssl-dns01.cfg"
fi
# Create and install certificate for wildcard + another domain
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
echo 'SANS="a.${GETSSL_HOST}"' > ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl_test_specific.cfg
create_certificate
assert_success
check_output_for_errors
# Delete configuration
rm -r ${INSTALL_DIR}/.getssl
# Create configuration
run ${CODE_DIR}/getssl -c "${GETSSL_CMD_HOST}"
# Assert that the newly created configuration contains the additional domain in SANS
# if this fails then error in tests will be "grep failed" - this means SANS did not hold the expected value
# eg SANS="a.centos7.getssl.test"
grep -q "SANS=\"a.${GETSSL_HOST}\"" ${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl.cfg
assert_success
}

+ 31
- 0
test/28-wildcard-error-http01-validation.bats View File

@ -0,0 +1,31 @@
#! /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 "Check that trying to create a wildcard certificate using http-01 validation shows an error message" {
if [ -n "$STAGING" ]; then
skip "Internal test, no need to test on staging server"
else
CONFIG_FILE="getssl-http01.cfg"
fi
# Try and create a wildcard certificate using http-01 validation
GETSSL_CMD_HOST="*.${GETSSL_HOST}"
setup_environment
init_getssl
create_certificate
assert_failure
assert_line --partial "cannot use http-01 validation for wildcard domains"
}

+ 1
- 1
test/Dockerfile-alpine View File

@ -12,7 +12,7 @@ RUN mkdir /etc/nginx/pki
RUN mkdir /etc/nginx/pki/private
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-centos6 View File

@ -16,7 +16,7 @@ RUN mkdir /etc/nginx/pki/private
COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/conf.d/default.conf
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-centos7 View File

@ -12,7 +12,7 @@ COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/conf.d/default.conf
COPY ./test/test-config/nginx-centos7.conf /etc/nginx/nginx.conf
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local

+ 1
- 1
test/Dockerfile-centos7-staging View File

@ -17,7 +17,7 @@ COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/conf.d/default.conf
COPY ./test/test-config/nginx-centos7.conf /etc/nginx/nginx.conf
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-centos8 View File

@ -14,7 +14,7 @@ COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/conf.d/default.conf
COPY ./test/test-config/nginx-centos7.conf /etc/nginx/nginx.conf
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local

+ 1
- 1
test/Dockerfile-debian View File

@ -11,7 +11,7 @@ RUN mkdir /etc/nginx/pki
RUN mkdir /etc/nginx/pki/private
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 2
test/Dockerfile-ubuntu View File

@ -9,7 +9,6 @@ ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update --fix-missing
RUN apt-get install -y git curl dnsutils ldnsutils wget nginx-light
RUN apt-get install -y vim dos2unix # for debugging
# TODO test with drill, dig, host
WORKDIR /root
@ -17,7 +16,7 @@ WORKDIR /root
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-ubuntu-staging View File

@ -20,7 +20,7 @@ WORKDIR /root
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-ubuntu16 View File

@ -13,7 +13,7 @@ RUN mkdir /etc/nginx/pki/private
COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/sites-enabled/default
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/Dockerfile-ubuntu18 View File

@ -16,7 +16,7 @@ COPY ./test/test-config/nginx-ubuntu-no-ssl /etc/nginx/sites-enabled/default
RUN touch /root/.rnd
# BATS (Bash Automated Testings)
RUN git clone https://github.com/bats-core/bats-core.git /bats-core
RUN git clone https://github.com/bats-core/bats-core.git /bats-core --branch v1.2.1
RUN git clone https://github.com/bats-core/bats-support /bats-support
RUN git clone https://github.com/bats-core/bats-assert /bats-assert
RUN /bats-core/install.sh /usr/local


+ 1
- 1
test/README-Testing.md View File

@ -8,7 +8,7 @@ For continuous integration testing we have the following:
1. Uses `docker-compose` to start `pebble` (letsencrypt test server) and `challtestsrv` (minimal dns client for pebble)
2. Then runs the `bats` test scripts (all the files with a ".bats" extension) for each OS (alpine, centos6, debian, ubuntu)
3. Runs the `bats` test script against the staging server (using nn ubuntu docker image and duckdns.org)
3. Runs the `bats` test script against the staging server (using ubuntu docker image and duckdns.org)
## To run all the tests on a single OS


+ 1
- 0
test/run-test.cmd View File

@ -49,6 +49,7 @@ docker run -it ^
--network-alias i.%OS%.getssl.test ^
--network-alias j.%OS%.getssl.test ^
--network-alias k.%OS%.getssl.test ^
--network-alias wild-%ALIAS% ^
--name getssl-%OS% ^
getssl-%OS% ^
%COMMAND%

+ 1
- 0
test/run-test.sh View File

@ -42,6 +42,7 @@ docker run \
--network-alias "i.$OS.getssl.test" \
--network-alias "j.$OS.getssl.test" \
--network-alias "k.$OS.getssl.test" \
--network-alias "wild-$OS.getssl.test" \
--name "getssl-$OS" \
"getssl-$OS" \
$COMMAND

+ 37
- 0
test/test-config/getssl-dns01-dual-rsa-ecdsa-2-locations.cfg View File

@ -0,0 +1,37 @@
# 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"
VALIDATE_VIA_DNS=true
DNS_ADD_COMMAND="/getssl/dns_scripts/dns_add_challtestsrv"
DNS_DEL_COMMAND="/getssl/dns_scripts/dns_del_challtestsrv"
AUTH_DNS_SERVER=10.30.50.3
# Speed up the test by reducing the number or retries and the wait between retries.
DNS_WAIT=2
DNS_WAIT_COUNT=11
DNS_EXTRA_WAIT=0
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=""
# SANS="a.${GETSSL_HOST}"
# 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-dual-certs ${NGINX_CONFIG} && /getssl/test/restart-nginx"
# Define the server type and confirm correct certificate is installed
SERVER_TYPE="https"
CHECK_REMOTE="true"

+ 36
- 0
test/test-config/getssl-dns01-secp384.cfg View File

@ -0,0 +1,36 @@
# Uncomment and modify any variables you need
# see https://github.com/srvrco/getssl/wiki/Config-variables for details
# see https://github.com/srvrco/getssl/wiki/Example-config-files for example configs
#
CA="https://pebble:14000/dir"
VALIDATE_VIA_DNS=true
DNS_ADD_COMMAND="/getssl/dns_scripts/dns_add_challtestsrv"
DNS_DEL_COMMAND="/getssl/dns_scripts/dns_del_challtestsrv"
AUTH_DNS_SERVER=10.30.50.3
# Speed up the test by reducing the number or retries and the wait between retries.
DNS_WAIT=2
DNS_WAIT_COUNT=11
DNS_EXTRA_WAIT=0
ACCOUNT_KEY_TYPE="secp384r1"
PRIVATE_KEY_ALG="secp384r1"
# Additional domains - this could be multiple domains / subdomains in a comma separated list
SANS=""
# 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"
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
# 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"

+ 7
- 0
test/test-config/getssl-dns01.cfg View File

@ -31,3 +31,10 @@ RELOAD_CMD="cp /getssl/test/test-config/nginx-ubuntu-ssl ${NGINX_CONFIG} && /get
# Define the server type and confirm correct certificate is installed
SERVER_TYPE="https"
CHECK_REMOTE="true"
#_USE_DEBUG=1
#_RUNNING_TEST=1
if [[ -s "$DOMAIN_DIR/getssl_test_specific.cfg" ]]; then
. $DOMAIN_DIR/getssl_test_specific.cfg
fi

+ 5
- 1
test/test-config/getssl-staging-dns01.cfg View File

@ -31,6 +31,10 @@ 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 (using a custom port)
# Define the server type and confirm correct certificate is installed
SERVER_TYPE="https"
CHECK_REMOTE="true"
if [[ -s "$DOMAIN_DIR/getssl_test_specific.cfg" ]]; then
. $DOMAIN_DIR/getssl_test_specific.cfg
fi

+ 63
- 59
test/test_helper.bash View File

@ -3,99 +3,103 @@ CODE_DIR=/getssl
check_certificates()
{
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/chain.crt" ]
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" ]
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" ]
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/chain.crt" ]
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/fullchain.crt" ]
assert [ -e "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/${GETSSL_CMD_HOST}.crt" ]
}
# Only nginx > 1.11.0 support dual certificates in a single configuration file
# 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 2>&1 | awk -F"/" '{print $2}')
if [ "$(printf '%s\n' "$requiredver" "$currentver" | sort -V | head -n1)" = "$requiredver" ]; then
export OLD_NGINX="false"
else
echo "INFO: Running nginx version $currentver which doesn't support dual certificates" >&3
echo "INFO: not checking that certificate is installed correctly" >&3
export OLD_NGINX="true"
fi
requiredver="1.11.0"
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
echo "INFO: Running nginx version $currentver which doesn't support dual certificates" >&3
echo "INFO: not checking that certificate is installed correctly" >&3
export OLD_NGINX="true"
fi
}
check_output_for_errors() {
refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]'
# less strict tests if running with debug output
if [ -n "$1" ]; then
# don't fail for :error:badNonce
refute_output --regexp '[^:][Ee][Rr][Rr][Oo][Rr][^:]'
# don't check for "Warnings:" as there might be a warning message if nslookup doesn't support -debug (alpine/ubuntu)
refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg][^:]'
else
refute_output --regexp '[Ee][Rr][Rr][Oo][Rr]'
refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]'
fi
refute_line --partial 'command not found'
refute_output --regexp '[Ff][Aa][Ii][Ll][Ee][Dd]'
# less strict tests if running with debug output
if [ -n "$1" ]; then
# don't fail for :error:badNonce
refute_output --regexp '[^:][Ee][Rr][Rr][Oo][Rr][^:]'
# don't check for "Warnings:" as there might be a warning message if nslookup doesn't support -debug (alpine/ubuntu)
refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg][^:]'
else
refute_output --regexp '[Ee][Rr][Rr][Oo][Rr]'
refute_output --regexp '[Ww][Aa][Rr][Nn][Ii][Nn][Gg]'
fi
refute_line --partial 'command not found'
}
cleanup_environment() {
if [ -z "$STAGING" ]; then
curl --silent -X POST -d '{"host":"'"$GETSSL_HOST"'"}' http://10.30.50.3:8055/clear-a
fi
}
create_certificate() {
# Create certificate
cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl.cfg"
# shellcheck disable=SC2086
run ${CODE_DIR}/getssl $1 "$GETSSL_CMD_HOST"
# Create certificate
cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_CMD_HOST}/getssl.cfg"
# shellcheck disable=SC2086
run ${CODE_DIR}/getssl $1 "$GETSSL_CMD_HOST"
}
init_getssl() {
# Run initialisation (create account key, etc)
run ${CODE_DIR}/getssl -c "$GETSSL_CMD_HOST"
assert_success
[ -d "$INSTALL_DIR/.getssl" ]
# Run initialisation (create account key, etc)
run ${CODE_DIR}/getssl -c "$GETSSL_CMD_HOST"
assert_success
[ -d "$INSTALL_DIR/.getssl" ]
}
setup_environment() {
# One-off test setup
if [[ -d ${INSTALL_DIR}/.getssl ]]; then
rm -r ${INSTALL_DIR}/.getssl
fi
# One-off test setup
if [[ -d ${INSTALL_DIR}/.getssl ]]; then
rm -r ${INSTALL_DIR}/.getssl
fi
if [ -z "$STAGING" ]; then
curl --silent -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/add-a
cp ${CODE_DIR}/test/test-config/nginx-ubuntu-no-ssl "${NGINX_CONFIG}"
/getssl/test/restart-nginx
fi
cp ${CODE_DIR}/test/test-config/nginx-ubuntu-no-ssl "${NGINX_CONFIG}"
/getssl/test/restart-nginx
}
# start nginx in background on alpine via supervisord
# shellcheck disable=SC2153 # Ignore GETSSL_OS looks like typo of GETSSL_IP
if [[ -f /usr/bin/supervisord && -f /etc/supervisord.conf ]]; then
if [[ ! $(pgrep supervisord) ]]; then
/usr/bin/supervisord -c /etc/supervisord.conf >&3-
fi
if [[ ! $(pgrep supervisord) ]]; then
/usr/bin/supervisord -c /etc/supervisord.conf >&3-
fi
elif [[ "$GETSSL_OS" == "centos"[78] ]]; then
if [ -z "$(pgrep nginx)" ]; then
nginx >&3-
fi
if [ -z "$(pgrep nginx)" ]; then
nginx >&3-
fi
fi
# Find NGINX configuration directory for HTTP-01 testing (need to add SSL to config)
if [[ -f /etc/nginx/conf.d/default.conf ]]; then
export NGINX_CONFIG=/etc/nginx/conf.d/default.conf
export NGINX_CONFIG=/etc/nginx/conf.d/default.conf
elif [[ -f /etc/nginx/sites-enabled/default ]]; then
export NGINX_CONFIG=/etc/nginx/sites-enabled/default
export NGINX_CONFIG=/etc/nginx/sites-enabled/default
else
echo "Can't find NGINX directory"
exit 1
echo "Can't find NGINX directory"
exit 1
fi
# Find IP address
if [[ -n "$(command -v ip)" ]]; then
GETSSL_IP=$(ip address | awk '/10.30.50/ { print $2 }' | awk -F/ '{ print $1 }')
GETSSL_IP=$(ip address | awk '/10.30.50/ { print $2 }' | awk -F/ '{ print $1 }')
elif [[ -n "$(command -v hostname)" ]]; then
GETSSL_IP=$(hostname -I | sed -e 's/[[:space:]]*$//')
GETSSL_IP=$(hostname -I | sed -e 's/[[:space:]]*$//')
else
echo "Cannot find IP address"
exit 1
echo "Cannot find IP address"
exit 1
fi
export GETSSL_IP
@ -103,11 +107,11 @@ export GETSSL_IP
GETSSL_CMD_HOST=$GETSSL_HOST
export GETSSL_CMD_HOST
if [ ! -f ${INSTALL_DIR}/pebble.minica.pem ]; then
wget --quiet --no-clobber https://raw.githubusercontent.com/letsencrypt/pebble/master/test/certs/pebble.minica.pem 2>&1
CERT_FILE=/etc/ssl/certs/ca-certificates.crt
if [ ! -f $CERT_FILE ]; then
CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
fi
cat $CERT_FILE ${INSTALL_DIR}/pebble.minica.pem > ${INSTALL_DIR}/pebble-ca-bundle.crt
if [ -z "$STAGING" ] && [ ! -f ${INSTALL_DIR}/pebble.minica.pem ]; then
wget --quiet --no-clobber https://raw.githubusercontent.com/letsencrypt/pebble/master/test/certs/pebble.minica.pem 2>&1
CERT_FILE=/etc/ssl/certs/ca-certificates.crt
if [ ! -f $CERT_FILE ]; then
CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
fi
cat $CERT_FILE ${INSTALL_DIR}/pebble.minica.pem > ${INSTALL_DIR}/pebble-ca-bundle.crt
fi

Loading…
Cancel
Save