]> git.street.me.uk Git - andy/dehydrated.git/commitdiff
Basic implementation for private key rollover (#294)
authorcrza <crza@users.noreply.github.com>
Mon, 17 Oct 2016 20:40:03 +0000 (22:40 +0200)
committerLukas Schauer <lukas2511@users.noreply.github.com>
Mon, 17 Oct 2016 20:40:03 +0000 (22:40 +0200)
* initial commit for PRIVATE_KEY_ROLLOVER

* fix if syntax

* rolloverkey without  timestamps

* update example config: PRIVATE_KEY_ROLLOVER

* rolloverkey creation logic updated

* updated tests. untested.

* added cleanup for rolloverkeys: if disabled, delete privkey.roll.pem

dehydrated
docs/examples/config
test.sh

index 63e3fc3eb6d870caef555420ec603d05e54f0c9c..f7408908b538ac10744a0f1cdcb6b80d39b0293c 100755 (executable)
@@ -118,6 +118,7 @@ load_config() {
   KEYSIZE="4096"
   WELLKNOWN=
   PRIVATE_KEY_RENEW="yes"
+  PRIVATE_KEY_ROLLOVER="no"
   KEY_ALGO=rsa
   OPENSSL_CNF="$(openssl version -d | cut -d\" -f2)/openssl.cnf"
   CONTACT_EMAIL=
@@ -596,6 +597,26 @@ sign_domain() {
       prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${CERTDIR}/${domain}/privkey-${timestamp}.pem";;
     esac
   fi
+  # move rolloverkey into position (if any)
+  if [[ -r "${CERTDIR}/${domain}/privkey.pem" && -r "${CERTDIR}/${domain}/privkey.roll.pem" && "${PRIVATE_KEY_RENEW}" = "yes" && "${PRIVATE_KEY_ROLLOVER}" = "yes" ]]; then
+    echo " + Moving Rolloverkey into position....  "
+    mv "${CERTDIR}/${domain}/privkey.roll.pem" "${CERTDIR}/${domain}/privkey-tmp.pem"
+    mv "${CERTDIR}/${domain}/privkey-${timestamp}.pem" "${CERTDIR}/${domain}/privkey.roll.pem"
+    mv "${CERTDIR}/${domain}/privkey-tmp.pem" "${CERTDIR}/${domain}/privkey-${timestamp}.pem"
+  fi
+  # generate a new private rollover key if we need or want one
+  if [[ ! -r "${CERTDIR}/${domain}/privkey.roll.pem" && "${PRIVATE_KEY_ROLLOVER}" = "yes" && "${PRIVATE_KEY_RENEW}" = "yes" ]]; then
+    echo " + Generating private rollover key..."
+    case "${KEY_ALGO}" in
+      rsa) _openssl genrsa -out "${CERTDIR}/${domain}/privkey.roll.pem" "${KEYSIZE}";;
+      prime256v1|secp384r1) _openssl ecparam -genkey -name "${KEY_ALGO}" -out "${CERTDIR}/${domain}/privkey.roll.pem";;
+    esac
+  fi
+  # delete rolloverkeys if disabled
+  if [[ -r "${CERTDIR}/${domain}/privkey.roll.pem" && ! "${PRIVATE_KEY_ROLLOVER}" = "yes" ]]; then
+    echo " + Removing Rolloverkey (feature disabled)..."
+    rm -f "${CERTDIR}/${domain}/privkey.roll.pem"
+  fi
 
   # Generate signing request config and the actual signing request
   echo " + Generating signing request..."
@@ -709,7 +730,7 @@ command_sign_domains() {
         config_var="$(echo "${cfgline:1}" | cut -d'=' -f1)"
         config_value="$(echo "${cfgline:1}" | cut -d'=' -f2-)"
         case "${config_var}" in
-          KEY_ALGO|OCSP_MUST_STAPLE|PRIVATE_KEY_RENEW|KEYSIZE|CHALLENGETYPE|HOOK|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS)
+          KEY_ALGO|OCSP_MUST_STAPLE|PRIVATE_KEY_RENEW|PRIVATE_KEY_ROLLOVER|KEYSIZE|CHALLENGETYPE|HOOK|WELLKNOWN|HOOK_CHAIN|OPENSSL_CNF|RENEW_DAYS)
             echo "   + ${config_var} = ${config_value}"
             declare -- "${config_var}=${config_value}"
             ;;
index 17621d2aa1b2ce52e16c31d9b591e1e1bf46da7c..92b2b83be3d8d3757d4b1a981754d87ded3d277c 100644 (file)
@@ -72,6 +72,9 @@
 # Regenerate private keys instead of just signing new certificates on renewal (default: yes)
 #PRIVATE_KEY_RENEW="yes"
 
+# Create an extra private key for rollover (default: no)
+#PRIVATE_KEY_ROLLOVER="no"
+
 # Which public key algorithm should be used? Supported: rsa, prime256v1 and secp384r1
 #KEY_ALGO=rsa
 
diff --git a/test.sh b/test.sh
index 430dd1dccfe74c5006a0fbd985aa3283b31283dc..804404983116e2801037901e1f0c0c17b23a4419 100755 (executable)
--- a/test.sh
+++ b/test.sh
@@ -209,6 +209,26 @@ _CHECK_LOG "Done."
 _CHECK_FILE "certs/${TMP_URL}/${REAL_CERT}-revoked"
 _CHECK_ERRORLOG
 
+# Enable private key renew
+echo 'PRIVATE_KEY_RENEW="yes"' >> config
+echo 'PRIVATE_KEY_ROLLOVER="yes"' >> config
+
+# Check if Rolloverkey creation works
+_TEST "Testing Rolloverkeys..."
+_SUBTEST "First Run: Creating rolloverkey"
+./dehydrated --cron --domain "${TMP2_URL}" > tmplog 2> errorlog || _FAIL "Script execution failed"
+CERT_ROLL_HASH=$(openssl rsa -in certs/${TMP2_URL}/privkey.roll.pem -outform DER -pubout 2>/dev/null | openssl sha256)
+_CHECK_LOG "Generating private key"
+_CHECK_LOG "Generating private rollover key"
+_SUBTEST "Second Run: Force Renew, Use rolloverkey"
+./dehydrated --cron --force --domain "${TMP2_URL}" > tmplog 2> errorlog || _FAIL "Script execution failed"
+CERT_NEW_HASH=$(openssl rsa -in certs/${TMP2_URL}/privkey.pem -outform DER -pubout 2>/dev/null | openssl sha256)
+_CHECK_LOG "Generating private key"
+_CHECK_LOG "Moving Rolloverkey into position"
+_SUBTEST "Verifying Hash Rolloverkey and private key second run"
+[[ "${CERT_ROLL_HASH}" = "${CERT_NEW_HASH}" ]] && _PASS || _FAIL
+_CHECK_ERRORLOG
+
 # Test cleanup command
 _TEST "Cleaning up certificates"
 ./dehydrated --cleanup > tmplog 2> errorlog || _FAIL "Script execution failed"