Skip to content

Commit 304ef0a

Browse files
authored
Merge pull request #507 from srvrco/dual-rsa-ecdsa-2-locations
Fix bug #505 with DUAL_RSA_ECDSA and multiple locations
2 parents 7bf1475 + 74f4bbe commit 304ef0a

7 files changed

+119
-19
lines changed

getssl

+25-12
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,11 @@
211211
# 2020-02-12 Fix for DUAL_RSA_ECDSA not working with ACMEv2 (#334, #474, #502)
212212
# 2020-02-12 Fix #424 - Sporadic "error in EC signing couldn't get R from ..." (2.18)
213213
# 2020-02-12 Fix "Registration key already in use" (2.19)
214+
# 2020-02-13 Fix bug with copying to all locations when creating RSA and ECDSA certs (2.20)
214215
# ----------------------------------------------------------------------------------------
215216

216217
PROGNAME=${0##*/}
217-
VERSION="2.19"
218+
VERSION="2.20"
218219

219220
# defaults
220221
ACCOUNT_KEY_LENGTH=4096
@@ -549,8 +550,12 @@ copy_file_to_location() { # copies a file, using scp, sftp or ftp if required.
549550
cert=$1 # descriptive name, just used for display
550551
from=$2 # current file location
551552
to=$3 # location to move file to.
553+
suffix=$4 # (optional) optional suffix for DUAL_RSA_ECDSA, i.e. save to private.key becomes save to private.ec.key
552554
IFS=\; read -r -a copy_locations <<<"$3"
553555
for to in "${copy_locations[@]}"; do
556+
if [[ -n "$suffix" ]]; then
557+
to="${to%.*}.${suffix}.${to##*.}"
558+
fi
554559
info "copying $cert to $to"
555560
if [[ "${to:0:4}" == "ssh:" ]] ; then
556561
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
18231828
elif [[ "${signed:4:4}" == "0231" ]]; then #sha384 which needs trimming
18241829
R=$(echo "$signed" | cut -c 11-106)
18251830
part2=$(echo "$signed" | cut -c 107-)
1831+
elif [[ "${signed:6:4}" == "0240" ]]; then #sha512 which needs padding
1832+
R=$(echo -n 00;echo "$signed" | cut -c 9-138)
1833+
part2=$(echo "$signed" | cut -c 141-)
18261834
elif [[ "${signed:6:4}" == "0241" ]]; then #sha512 which needs padding
18271835
R=$(echo -n 00;echo "$signed" | cut -c 11-140)
18281836
part2=$(echo "$signed" | cut -c 141-)
@@ -1846,6 +1854,8 @@ sign_string() { # sign a string with a given key and algorithm and return urlbas
18461854
S=$(echo "$part2" | cut -c 5-100)
18471855
elif [[ "${part2:0:4}" == "0231" ]]; then #sha384
18481856
S=$(echo "$part2" | cut -c 7-102)
1857+
elif [[ "${part2:0:4}" == "0240" ]]; then #sha512 with padding
1858+
S=$(echo -n 00;echo "$part2" | cut -c 5-)
18491859
elif [[ "${part2:0:4}" == "0241" ]]; then #sha512 with padding
18501860
S=$(echo -n 00;echo "$part2" | cut -c 5-)
18511861
elif [[ "${part2:0:4}" == "0242" ]]; then #sha512
@@ -2545,17 +2555,20 @@ if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
25452555
if [[ -n "$DOMAIN_CERT_LOCATION" ]]; then
25462556
copy_file_to_location "ec domain certificate" \
25472557
"${CERT_FILE%.*}.ec.crt" \
2548-
"${DOMAIN_CERT_LOCATION%.*}.ec.crt"
2558+
"${DOMAIN_CERT_LOCATION}" \
2559+
"ec"
25492560
fi
25502561
if [[ -n "$DOMAIN_KEY_LOCATION" ]]; then
2551-
copy_file_to_location "ec private key" \
2552-
"$DOMAIN_DIR/${DOMAIN}.ec.key" \
2553-
"${DOMAIN_KEY_LOCATION%.*}.ec.key"
2562+
copy_file_to_location "ec private key" \
2563+
"$DOMAIN_DIR/${DOMAIN}.ec.key" \
2564+
"${DOMAIN_KEY_LOCATION}" \
2565+
"ec"
25542566
fi
25552567
if [[ -n "$CA_CERT_LOCATION" ]]; then
2556-
copy_file_to_location "ec CA certificate" \
2557-
"${CA_CERT%.*}.ec.crt" \
2558-
"${CA_CERT_LOCATION%.*}.ec.crt"
2568+
copy_file_to_location "ec CA certificate" \
2569+
"${CA_CERT%.*}.ec.crt" \
2570+
"${CA_CERT_LOCATION%.*}.crt" \
2571+
"ec"
25592572
fi
25602573
fi
25612574

@@ -2570,7 +2583,7 @@ if [[ -n "$DOMAIN_CHAIN_LOCATION" ]]; then
25702583
copy_file_to_location "full chain" "$TEMP_DIR/${DOMAIN}_chain.pem" "$to_location"
25712584
if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
25722585
cat "${CERT_FILE%.*}.ec.crt" "${CA_CERT%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}_chain.pem.ec"
2573-
copy_file_to_location "full chain" "$TEMP_DIR/${DOMAIN}_chain.pem.ec" "${to_location%.*}.ec.${to_location##*.}"
2586+
copy_file_to_location "full chain" "$TEMP_DIR/${DOMAIN}_chain.pem.ec" "${to_location}" "ec"
25742587
fi
25752588
fi
25762589
# if DOMAIN_KEY_CERT_LOCATION is not blank, then create and copy file.
@@ -2583,8 +2596,8 @@ if [[ -n "$DOMAIN_KEY_CERT_LOCATION" ]]; then
25832596
cat "$DOMAIN_DIR/${DOMAIN}.key" "$CERT_FILE" > "$TEMP_DIR/${DOMAIN}_K_C.pem"
25842597
copy_file_to_location "private key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem" "$to_location"
25852598
if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
2586-
cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}_K_C.pem.ec"
2587-
copy_file_to_location "private ec key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem.ec" "${to_location%.*}.ec.${to_location##*.}"
2599+
cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}_K_C.pem.ec"
2600+
copy_file_to_location "private ec key and domain cert pem" "$TEMP_DIR/${DOMAIN}_K_C.pem.ec" "${to_location}" "ec"
25882601
fi
25892602
fi
25902603
# if DOMAIN_PEM_LOCATION is not blank, then create and copy file.
@@ -2598,7 +2611,7 @@ if [[ -n "$DOMAIN_PEM_LOCATION" ]]; then
25982611
copy_file_to_location "full key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem" "$to_location"
25992612
if [[ "$DUAL_RSA_ECDSA" == "true" ]]; then
26002613
cat "$DOMAIN_DIR/${DOMAIN}.ec.key" "${CERT_FILE%.*}.ec.crt" "${CA_CERT%.*}.ec.crt" > "$TEMP_DIR/${DOMAIN}.pem.ec"
2601-
copy_file_to_location "full ec key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem.ec" "${to_location%.*}.ec.${to_location##*.}"
2614+
copy_file_to_location "full ec key, cert and chain pem" "$TEMP_DIR/${DOMAIN}.pem.ec" "${to_location}" "ec"
26022615
fi
26032616
fi
26042617
# end of copying certs.

test/4-more-than-10-hosts.bats

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ setup() {
1717

1818
# Add 11 hosts to DNS (also need to be added as aliases in docker-compose.yml)
1919
for prefix in a b c d e f g h i j k; do
20-
curl -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
20+
curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
2121
done
2222

2323
init_getssl
@@ -39,6 +39,6 @@ setup() {
3939
# Remove all the dns aliases
4040
cleanup_environment
4141
for prefix in a b c d e f g h i j k; do
42-
curl -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/del-a
42+
curl --silent -X POST -d '{"host":"'$prefix.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/del-a
4343
done
4444
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#! /usr/bin/env bats
2+
3+
load '/bats-support/load.bash'
4+
load '/bats-assert/load.bash'
5+
load '/getssl/test/test_helper.bash'
6+
7+
8+
# These are run for every test, not once per file
9+
setup() {
10+
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
11+
curl --silent -X POST -d '{"host":"'a.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/add-a
12+
}
13+
14+
15+
teardown() {
16+
curl --silent -X POST -d '{"host":"'a.$GETSSL_HOST'", "addresses":["'$GETSSL_IP'"]}' http://10.30.50.3:8055/del-a
17+
}
18+
19+
20+
@test "Create dual certificates and copy RSA and ECDSA chain and key to two locations" {
21+
CONFIG_FILE="getssl-http01-dual-rsa-ecdsa-2-locations.cfg"
22+
setup_environment
23+
mkdir -p /root/a.${GETSSL_HOST}
24+
25+
init_getssl
26+
create_certificate
27+
assert_success
28+
29+
# Check that the RSA chain and key have been copied to both locations
30+
assert [ -e "/etc/nginx/pki/domain-chain.crt" ]
31+
assert [ -e "/root/a.${GETSSL_HOST}/domain-chain.crt" ]
32+
assert [ -e "/etc/nginx/pki/private/server.key" ]
33+
assert [ -e "/root/a.${GETSSL_HOST}/server.key" ]
34+
35+
# Check that the ECDSA chain and key have been copied to both locations
36+
assert [ -e "/etc/nginx/pki/domain-chain.ec.crt" ]
37+
assert [ -e "/root/a.${GETSSL_HOST}/domain-chain.ec.crt" ]
38+
assert [ -e "/etc/nginx/pki/private/server.ec.key" ]
39+
assert [ -e "/root/a.${GETSSL_HOST}/server.ec.key" ]
40+
}

test/debug-test.sh

+12-2
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,22 @@
33
# This runs getssl outside of the BATS framework for debugging, etc, against pebble
44
# Usage: /getssl/test/debug-test.sh getssl-http01.cfg
55

6+
DEBUG=""
7+
if [ $# -eq 2 ]; then
8+
DEBUG=$1
9+
shift
10+
fi
11+
612
CONFIG_FILE=$1
13+
if [ ! -e "$CONFIG_FILE" ]; then
14+
CONFIG_FILE=${CODE_DIR}/test/test-config/${CONFIG_FILE}
15+
fi
716
source /getssl/test/test_helper.bash
817

918
setup_environment 3>&1
1019
export CURL_CA_BUNDLE=/root/pebble-ca-bundle.crt
1120

1221
"${CODE_DIR}/getssl" -c "$GETSSL_HOST" 3>&1
13-
cp "${CODE_DIR}/test/test-config/${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg"
14-
"${CODE_DIR}/getssl" -f "$GETSSL_HOST" 3>&1
22+
cp "${CONFIG_FILE}" "${INSTALL_DIR}/.getssl/${GETSSL_HOST}/getssl.cfg"
23+
# shellcheck disable=SC2086
24+
"${CODE_DIR}/getssl" ${DEBUG} -f "$GETSSL_HOST" 3>&1

test/run-all-tests.cmd

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
docker exec -it getssl-alpine bats /getssl/test
2+
docker exec -it getssl-centos6 bats /getssl/test
3+
docker exec -it getssl-debian bats /getssl/test
4+
docker exec -it getssl-ubuntu bats /getssl/test
5+
docker exec -it getssl-ubuntu18 bats /getssl/test
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Test that more than one location can be specified for CERT and KEY locations and that the
2+
# files are copied to both locations when both RSA and ECDSA certificates are created
3+
#
4+
CA="https://pebble:14000/dir"
5+
6+
DUAL_RSA_ECDSA="true"
7+
ACCOUNT_KEY_TYPE="prime256v1"
8+
PRIVATE_KEY_ALG="prime256v1"
9+
10+
# Additional domains - this could be multiple domains / subdomains in a comma separated list
11+
SANS="a.${GETSSL_HOST}"
12+
13+
# Acme Challenge Location.
14+
ACL=('/var/www/html/.well-known/acme-challenge')
15+
16+
#Set USE_SINGLE_ACL="true" to use a single ACL for all checks
17+
USE_SINGLE_ACL="true"
18+
19+
# Location for all your certs, these can either be on the server (full path name)
20+
# or using ssh /sftp as for the ACL
21+
DOMAIN_CERT_LOCATION="/etc/nginx/pki/server.crt"
22+
DOMAIN_KEY_LOCATION="/etc/nginx/pki/private/server.key;/root/a.${GETSSL_HOST}/server.key"
23+
CA_CERT_LOCATION="/etc/nginx/pki/chain.crt"
24+
DOMAIN_CHAIN_LOCATION="/etc/nginx/pki/domain-chain.crt;/root/a.${GETSSL_HOST}/domain-chain.crt" # this is the domain cert and CA cert
25+
DOMAIN_PEM_LOCATION="" # this is the domain_key, domain cert and CA cert
26+
27+
# The command needed to reload apache / nginx or whatever you use
28+
RELOAD_CMD="cp /getssl/test/test-config/nginx-ubuntu-ssl ${NGINX_CONFIG} && /getssl/test/restart-nginx"
29+
30+
# Define the server type and confirm correct certificate is installed
31+
SERVER_TYPE="https"
32+
CHECK_REMOTE="true"

test/test_helper.bash

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@ setup_environment() {
99
fi
1010

1111
if [ ! -f ${INSTALL_DIR}/pebble.minica.pem ]; then
12-
wget --no-clobber https://raw.githubusercontent.com/letsencrypt/pebble/master/test/certs/pebble.minica.pem 2>&1
12+
wget --quiet --no-clobber https://raw.githubusercontent.com/letsencrypt/pebble/master/test/certs/pebble.minica.pem 2>&1
1313
CERT_FILE=/etc/ssl/certs/ca-certificates.crt
1414
if [ ! -f $CERT_FILE ]; then
1515
CERT_FILE=/etc/pki/tls/certs/ca-bundle.crt
1616
fi
1717
cat $CERT_FILE ${INSTALL_DIR}/pebble.minica.pem > ${INSTALL_DIR}/pebble-ca-bundle.crt
1818
fi
1919

20-
curl -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/add-a
20+
curl --silent -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/add-a
2121
cp ${CODE_DIR}/test/test-config/nginx-ubuntu-no-ssl "${NGINX_CONFIG}"
2222
/getssl/test/restart-nginx
2323
}
2424

2525

2626
cleanup_environment() {
27-
curl -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/del-a
27+
curl --silent -X POST -d '{"host":"'"$GETSSL_HOST"'", "addresses":["'"$GETSSL_IP"'"]}' http://10.30.50.3:8055/del-a
2828
}
2929

3030

0 commit comments

Comments
 (0)