From 84b7e13a2a708f0c7b1ed5767fccea09b488e657 Mon Sep 17 00:00:00 2001 From: Dan Schaper Date: Sun, 24 Dec 2017 14:15:49 -0800 Subject: [PATCH] Move logic for key creation to argparser. Refactor code and remove account specific key creation function. Signed-off-by: Dan Schaper --- getsslD | 152 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 91 insertions(+), 61 deletions(-) diff --git a/getsslD b/getsslD index 831fa0a..002e661 100755 --- a/getsslD +++ b/getsslD @@ -17,77 +17,71 @@ # more details. PROGNAME=getsslD -VERSION="1.0" +VERSION="0.2" # Default values, accepts environment variables if set, otherwise default are used WORKING_DIR=${WORKING_DIR:="/ssl}" +ACCOUNT_KEY_LOCATION=${ACCOUNT_KEY_LOCATION:="$WORKING_DIR/account.key"} ACCOUNT_KEY_LENGTH=${ACCOUNT_KEY_LENGTH:="4096"} ACCOUNT_KEY_TYPE=${ACCOUNT_KEY_TYPE:="rsa"} -ACCOUNT_KEY=${ACCOUNT_KEY:="$WORKING_DIR/account.key"} + ##### # Functions ##### -create_account_key() { - # Create account key - - # Set values to args otherwise use environment variables - # https://stackoverflow.com/a/13864829 - if [[ ! -z ${1+x} ]]; then - ACCOUNT_KEY_LENGTH="${1}" - fi - if [[ ! -z ${2+x} ]]; then - ACCOUNT_KEY="${2}" - fi - if [[ -s ${ACCOUNT_KEY} ]]; then - printf '%s\n' "Account key exists at ${ACCOUNT_KEY} skipping generation." - return 0 - elif [[ ! -d $(dirname "${2}") ]]; then - print_error "Directory for storing ${2} does not exist." - return 1 - else - printf '%s\n' "Creating account key ${ACCOUNT_KEY}:" - create_key "${ACCOUNT_KEY}" "${ACCOUNT_KEY_LENGTH}" - fi - return 0 -} create_key() { # Create an openSSL key local key_loc=${1} local key_len=${2} - local key_type + local key_type=${3} + local valid_key_type - # Determine key type by length - # Valid Let's Encrypt RSA key lengths 2048-4096 - # Valid Let's Encrypt ECC key lengths 256, 384, 521*(Not implemented) - - if [[ "${key_len}" -ge 2048 ]] && [[ "${key_len}" -le 4096 ]]; then - key_type="RSA" - elif [[ "${key_len}" -eq 256 ]]; then - key_type="prime256v1" - elif [[ "${key_len}" -eq 384 ]]; then - key_type="secp384r1" - elif [[ "${key_len}" -eq 521 ]]; then - key_type="secp521r1" + # Check for existing key + if [[ -s "${key_loc}" ]]; then + printf 'Key exists at %s skipping generation.\n' "${key_loc}" + return 0 + elif [[ ! -d $(dirname "${key_loc}") ]]; then + print_error "Directory for storing ${key_loc} does not exist." + return 1 else + printf 'Creating %s bit %s account key in %s...' "${key_len}" "${key_type}" "${key_loc}" + fi + + # Determine key type by length + # Valid Let's Encrypt RSA key lengths 2048-8192 + # Valid Let's Encrypt ECC key lengths 256, 384, 521 + + if [[ "${key_len}" -ge 2048 ]] && [[ "${key_len}" -le 8192 ]] && [[ "${key_type}" == "rsa" ]]; then + valid_key_type="RSA" + fi + + if [[ "${key_type}" == "ecc" ]]; then + if [[ "${key_len}" -eq 256 ]] ; then + valid_key_type="prime256v1" + elif [[ "${key_len}" -eq 384 ]]; then + valid_key_type="secp384r1" + elif [[ "${key_len}" -eq 521 ]]; then + valid_key_type="secp521r1" + fi + fi + + if [[ -z ${valid_key_type+x} ]]; then print_error "Invalid key length. Please check your configuration." return 1 fi - case "$key_type" in + case "$valid_key_type" in RSA) - printf '\t%s' "Creating ${key_len} bit RSA key..." openssl genrsa -out "${key_loc}" "${key_len}" >& /dev/null printf '%s\n' "Done." return 0 ;; prime256v1|secp384r1|secp521r1) - printf '\t%s' "Creating ${key_len} bit ECC key..." - openssl ecparam -genkey -out "${key_loc}" -name "${key_type}" >& /dev/null + openssl ecparam -genkey -out "${key_loc}" -name "${valid_key_type}" >& /dev/null printf '%s\n' "Done." return 0 ;; @@ -105,18 +99,21 @@ get_date() { echo $(date -u +"%Y-%m-%dT%H:%M:%SZ") } -help_message() { +help_message_top() { # Print help message cat <<- _EOF_ - Usage: "${PROGNAME}" [OPTION]... [ARGS]... + Usage: "${PROGNAME}" [option] [COMMAND] [ARGS...] Obtain SSL certificates from the letsencrypt.org ACME server. + Commands: + account Create or modify Lets Encrypt account. + Options to long options apply to short options also. Options: - -a, --account [LENGTH] [FILE] Create an account key of LENGTH with FILE name. - LENGTH is 2048-4096 for RSA keys, 256|384|521 for ECC keys. - Defaults to 4096 bit RSA key in account.key. + -r, --rsa Use RSA algorith for key generation + -e, --ecc Use elliptic curve algorithm for key or cert generation + _EOF_ return 0 } @@ -146,28 +143,62 @@ print_error() { arg_parser() { # Check CLI arguments and process + local key_type + local key_length while [[ -n ${1} ]]; do - case $1 in - -a | --account) + case ${1} in + -r | --rsa) shift - create_account_key $* - exit 0 + key_type="rsa" + ;; + -e | --ecc) + shift + key_type="ecc" ;; -h | --help) - help_message; + help_message_top exit 0 ;; + -v | --version) + printf '%s version %s\n' ${PROGNAME} ${VERSION} + exit 0 + ;; + account) + # Remove account command + shift + case $1 in + key) + # Remove key subcommand + shift + # If no key type specified on the command line + # https://stackoverflow.com/a/13864829 + if [[ -z "${key_type+x}" ]]; then + # No key types specified use default of RSA or environment variable + key_type="${ACCOUNT_KEY_TYPE:=rsa}" + printf 'No key type specified, using default of %s\n' "${key_type}" + fi + # We have a key type need length + # If no key length specified on the command line + if [[ -z "${1}" ]]; then + # No length specified, use default of 4096 or environment variable + key_length="${ACCOUNT_KEY_LENGTH:=4096}" + printf 'No key length specified, using default of %s\n' "${key_length}" + else + key_length="${1}" + fi + + create_key "${ACCOUNT_KEY_LOCATION}" "${key_length}" "${key_type}" + exit 0 + ;; + esac # End account subcommands + ;; *) - printf '%s\n\n' "Invalid option." - help_message + printf 'Invalid command\n\n' + help_message_top exit 1 ;; - esac - shift - if [[ -z ${1} ]]; then - break - fi + esac # End options done } @@ -179,8 +210,7 @@ main() { # read any variables from config in working directory if [[ -s "$WORKING_DIR/getsslD.cfg" ]]; then - debug "reading config from $WORKING_DIR/getsslD.cfg" - # shellcheck source=/dev/null + printf '%s\n'"Reading config from from $WORKING_DIR/getsslD.cfg" . "$WORKING_DIR/getsslD.cfg" fi