Browse Source

Fix bug #505 with DUAL_RSA_ECDSA and multiple locations

pull/507/head
Tim Kimber 6 years ago
parent
commit
74f4bbeac9
No known key found for this signature in database GPG Key ID: 3E1804964E76BD18
7 changed files with 119 additions and 19 deletions
  1. +25
    -12
      getssl
  2. +2
    -2
      test/4-more-than-10-hosts.bats
  3. +40
    -0
      test/6-dual-rsa-ecdsa-copy-2-locations.bats
  4. +12
    -2
      test/debug-test.sh
  5. +5
    -0
      test/run-all-tests.cmd
  6. +32
    -0
      test/test-config/getssl-http01-dual-rsa-ecdsa-2-locations.cfg
  7. +3
    -3
      test/test_helper.bash

+ 25
- 12
getssl View File

@ -211,10 +211,11 @@
# 2020-02-12 Fix for DUAL_RSA_ECDSA not working with ACMEv2 (#334, #474, #502)
# 2020-02-12 Fix #424 - Sporadic "error in EC signing couldn't get R from ..." (2.18)
# 2020-02-12 Fix "Registration key already in use" (2.19)
# 2020-02-13 Fix bug with copying to all locations when creating RSA and ECDSA certs (2.20)
# ----------------------------------------------------------------------------------------
PROGNAME=${0##*/}
VERSION="2.19"
VERSION="2.20"
# defaults
ACCOUNT_KEY_LENGTH=4096
@ -549,8 +550,12 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
cert=$1 # descriptive name, just used for display
from=$2 # current file location
to=$3 # location to move file to.
suffix=$4 # (optional) optional suffix for DUAL_RSA_ECDSA, i.e. save to private.key becomes save to private.ec.key
IFS=\; read -r -a copy_locations <<<"$3"
for to in "${copy_locations[@]}"; do
if [[ -n "$suffix" ]]; then
to="${to%.*}.${suffix}.${to##*.}"
fi
info "copying $cert to $to"
if [[ "${to:0:4}" == "ssh:" ]] ; then
debug "using scp -q $SCP_OPTS $from ${to:4}"
@ -1823,6 +1828,9 @@ sign_string() { # sign a string with a given key and algorithm and return urlbas
elif [[ "${signed:4:4}" == "0231" ]]; then #sha384 which needs trimming
R=$(echo "$signed" | cut -c 11-106)
part2=$(echo "$signed" | cut -c 107-)
elif [[ "${signed:6:4}" == "0240" ]]; then #sha512 which needs padding
R=$(echo -n 00;echo "$signed" | cut -c 9-138)
part2=$(echo "$signed" | cut -c 141-)
elif [[ "${signed:6:4}" == "0241" ]]; then #sha512 which needs padding
R=$(echo -n 00;echo "$signed" | cut -c 11-140)
part2=$(echo "$signed" | cut -c 141-)
@ -1846,6 +1854,8 @@ sign_string() { # sign a string with a given key and algorithm and return urlbas
S=$(echo "$part2" | cut -c 5-100)
elif [[ "${part2:0:4}" == "0231" ]]; then #sha384
S=$(echo "$part2" | cut -c 7-102)
elif [[ "${part2:0:4}" == "0240" ]]; then #sha512 with padding
S=$(echo -n 00;echo "$part2" | cut -c 5-)
elif [[ "${part2:0:4}" == "0241" ]]; then #sha512 with padding
S=$(echo -n 00;echo "$part2" | cut -c 5-)
elif [[ "${part2:0:4}" == "0242" ]]; then #sha512
@ -2545,17 +2555,20 @@ if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
if [[ -n "$DOMAIN_CERT_LOCATION" ]]; then
copy_file_to_location "ec domain certificate" \
"${CERT_FILE%.*}.ec.crt" \
"${DOMAIN_CERT_LOCATION%.*}.ec.crt"
"${DOMAIN_CERT_LOCATION}" \
"ec"
fi
if [[ -n "$DOMAIN_KEY_LOCATION" ]]; then
copy_file_to_location "ec private key" \
"$DOMAIN_DIR/${DOMAIN}.ec.key" \
"${DOMAIN_KEY_LOCATION%.*}.ec.key"
copy_file_to_location "ec private key" \
"$DOMAIN_DIR/${DOMAIN}.ec.key" \
"${DOMAIN_KEY_LOCATION}" \
"ec"
fi
if [[ -n "$CA_CERT_LOCATION" ]]; then
copy_file_to_location "ec CA certificate" \
"${CA_CERT%.*}.ec.crt" \
"${CA_CERT_LOCATION%.*}.ec.crt"
copy_file_to_location "ec CA certificate" \
"${CA_CERT%.*}.ec.crt" \
"${CA_CERT_LOCATION%.*}.crt" \
"ec"
fi
fi
@ -2570,7 +2583,7 @@ if [[ -n "$DOMAIN_CHAIN_LOCATION" ]]; then
copy_file_to_location "full chain" "$TEMP_DIR/${DOMAIN}_chain.pem" "$to_location"
if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
cat "${CERT_FILE%.*}.ec.crt" "${CA_CERT%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}_chain.pem.ec"
copy_file_to_location "full chain" "$TEMP_DIR/${DOMAIN}_chain.pem.ec" "${to_location%.*}.ec.${to_location##*.}"
copy_file_to_location "full chain" "$TEMP_DIR/${DOMAIN}_chain.pem.ec" "${to_location}" "ec"
fi
fi
# if DOMAIN_KEY_CERT_LOCATION is not blank, then create and copy file.
@ -2583,8 +2596,8 @@ if [[ -n "$DOMAIN_KEY_CERT_LOCATION" ]]; then
cat "$DOMAIN_DIR/${DOMAIN}.key" "$CERT_FILE" > "$TEMP_DIR/${DOMAIN}_K_C.pem"
copy_file_to_location "private key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem" "$to_location"
if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}_K_C.pem.ec"
copy_file_to_location "private ec key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem.ec" "${to_location%.*}.ec.${to_location##*.}"
cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}_K_C.pem.ec"
copy_file_to_location "private ec key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem.ec" "${to_location}" "ec"
fi
fi
# if DOMAIN_PEM_LOCATION is not blank, then create and copy file.
@ -2598,7 +2611,7 @@ if [[ -n "$DOMAIN_PEM_LOCATION" ]]; then
copy_file_to_location "full key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem" "$to_location"
if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE%.*}.ec.crt" "${CA_CERT%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}.pem.ec"
copy_file_to_location "full ec key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem.ec" "${to_location%.*}.ec.${to_location##*.}"
copy_file_to_location "full ec key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem.ec" "${to_location}" "ec"
fi
fi
# end of copying certs.


+ 2
- 2
test/4-more-than-10-hosts.bats View File

@ -17,7 +17,7 @@ setup() {
# Add 11 hosts to DNS (also need to be added as aliases in docker-compose.yml)
for prefix in a b c d e f g h i j k; do
curl -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
done
init_getssl
@ -39,6 +39,6 @@ setup() {
# Remove all the dns aliases
cleanup_environment
for prefix in a b c d e f g h i j k; do
curl -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/del-a
curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/del-a
done
}

+ 40
- 0
test/6-dual-rsa-ecdsa-copy-2-locations.bats View File

@ -0,0 +1,40 @@
#! /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() {
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
}
teardown() {
curl --silent -X POST -d '{"host":"'a.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/del-a
}
@test "Create dual certificates and copy RSA and ECDSA chain and key to two locations" {
CONFIG_FILE="getssl-http01-dual-rsa-ecdsa-2-locations.cfg"
setup_environment
mkdir -p /root/a.${GETSSL_HOST}
init_getssl
create_certificate
assert_success
# 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" ]
}

+ 12
- 2
test/debug-test.sh View File

@ -3,12 +3,22 @@
# This runs getssl outside of the BATS framework for debugging, etc, against pebble
# Usage: /getssl/test/debug-test.sh getssl-http01.cfg
DEBUG=""
if [ $# -eq 2 ]; then
DEBUG=$1
shift
fi
CONFIG_FILE=$1
if [ ! -e "$CONFIG_FILE" ]; then
CONFIG_FILE=${CODE_DIR}/test/test-config/${CONFIG_FILE}
fi
source /getssl/test/test_helper.bash
setup_environment 3>&1
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
"${CODE_DIR}/getssl" -c "$GETSSL_HOST" 3>&1
cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg"
"${CODE_DIR}/getssl" -f "$GETSSL_HOST" 3>&1
cp "${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg"
# shellcheck disable=SC2086
"${CODE_DIR}/getssl" ${DEBUG} -f "$GETSSL_HOST" 3>&1

+ 5
- 0
test/run-all-tests.cmd View File

@ -0,0 +1,5 @@
docker exec -it getssl-alpine bats /getssl/test
docker exec -it getssl-centos6 bats /getssl/test
docker exec -it getssl-debian bats /getssl/test
docker exec -it getssl-ubuntu bats /getssl/test
docker exec -it getssl-ubuntu18 bats /getssl/test

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

@ -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"

+ 3
- 3
test/test_helper.bash View File

@ -9,7 +9,7 @@ setup_environment() {
fi
if [ ! -f ${INSTALL_DIR}/pebble.minica.pem ]; then
wget --no-clobber https://raw.githubusercontent.com/letsencrypt/pebble/master/test/certs/pebble.minica.pem 2>&1
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
@ -17,14 +17,14 @@ setup_environment() {
cat $CERT_FILE ${INSTALL_DIR}/pebble.minica.pem > ${INSTALL_DIR}/pebble-ca-bundle.crt
fi
curl -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/add-a
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
}
cleanup_environment() {
curl -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/del-a
curl --silent -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/del-a
}


Loading…
Cancel
Save