diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index e6f6646..27fe83f 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -57,15 +57,14 @@ Here is the list of commands available with a short syntax reminder. Use the export-p8 [ cmd-opts ] export-p12 [ cmd-opts ] set-pass [ cmd-opts ] - upgrade -" + upgrade " # collect/show dir status: text_only=1 err_source="Not defined: vars autodetect failed and no value provided" work_dir="${EASYRSA:-$err_source}" pki_dir="${EASYRSA_PKI:-$err_source}" - print "\ + print " DIRECTORY STATUS (commands would take effect on these locations) EASYRSA: $work_dir PKI: $pki_dir @@ -74,7 +73,8 @@ DIRECTORY STATUS (commands would take effect on these locations) } # => usage() # Detailed command help -# When called with no args, calls usage(), otherwise shows help for a command +# When called with no args, calls usage(), +# otherwise shows help for a command # Please maintain strict indentation rules. # Commands are TAB indented, while text is SPACE indented. # 'case' indentation is minimalistic. @@ -111,7 +111,7 @@ cmd_help() { text=" * gen-dh - Generates DH (Diffie-Hellman) parameters" + Generates DH (Diffie-Hellman) parameters file" ;; gen-req) text=" @@ -130,8 +130,10 @@ cmd_help() { text=" * sign-req [ cmd-opts ] - Sign a certificate request of the defined type. must be a known type, - such as: 'client', 'server', 'serverClient', or 'ca' (or a user-added type). + Sign a certificate request of the defined type. + + must be a known type. + eg: 'client', 'server', 'serverClient', 'ca' or a user-added type. All supported types are listed in the x509-types directory. This request file must exist in the reqs/ dir and have a .req file @@ -145,14 +147,13 @@ cmd_help() { * build-server-full [ cmd-opts ] * build-serverClient-full [ cmd-opts ] - Generate a keypair and sign locally for a client and/or server + Generate a keypair and sign locally. - This mode uses the as the X509 CN." + This mode uses the as the X509 commonName." opts=" * nopass - Do not encrypt the private key (default is encrypted) - (Equivalent to global option '--nopass|--no-pass') - * inline - Create an inline credentials file for this node" + (Equivalent to global option '--nopass|--no-pass')" ;; revoke) text=" @@ -252,7 +253,7 @@ cmd_help() { Human-readable output is shown." opts=" - * full - show full cert info, including pubkey/sig data" + * full - show full CA info, including pubkey/sig data" ;; show-crl) text=" @@ -469,7 +470,7 @@ General options: --batch : Set automatic (no-prompts when possible) mode --silent|-s : Disable all warnings, notices and information --sbatch : Combined --silent and --batch operating mode ---silent-ssl|-S : Silence SSL output (Requires bach mode) +--silent-ssl|-S : Silence SSL output (Requires batch mode) --no-pass : Do not use passwords Can not be used with --passin or --passout @@ -505,7 +506,8 @@ Certificate & Request options: (these impact cert/req field values) --digest=ALG : Digest to use in the requests & certificates --keysize=# : Size in bits of keypair to generate (RSA Only) --use-algo=ALG : Crypto alg to use: choose rsa (default), ec or ed ---curve=NAME : For elliptic curve, sets the named curve (Default: secp384r1) +--curve=NAME : For elliptic curve, sets the named curve + (Default: algo ec: secp384r1, algo ed: ed25519) --subca-len=# : Path length of signed intermediate CA certificates --copy-ext : Copy included request X509 extensions (namely subjAltName) @@ -537,7 +539,9 @@ Deprecated features: # Wrapper around printf - clobber print since it's not POSIX anyway # print() is used internally, so MUST NOT be silenced. # shellcheck disable=SC1117 -print() { printf "%s\n" "$*" || exit 1; } +print() { + printf '%s\n' "$*" +} # => print() # Exit fatally with a message to stderr # present even with EASYRSA_BATCH as these are fatal problems @@ -547,16 +551,30 @@ Easy-RSA error: $1 " + # error_info is currently unused if [ "$error_info" ]; then print "${error_info}${NL}" fi + # show host info show_host + + # exit to cleanup() exit "${2:-1}" } # => die() -# Necessary verbose warnings -# This is a debug function for status-reports and date +# User errors, less noise than die() +user_error() { + print " +EasyRSA version $EASYRSA_version + +Error +----- +$1" + exit 1 +} # => user_error() + +# verbose information verbose() { [ "$EASYRSA_VERBOSE" ] || return 0 printf '%s\n' " > $*" @@ -568,8 +586,7 @@ warn() { print " WARNING ======= -$1 -" 1>&2 +$1" } # => warn() # informational notices to stdout @@ -584,8 +601,7 @@ $1" # Helpful information information() { [ "$EASYRSA_SILENT" ] && return - print " -* $1" + print "$1" } # => information() # intent confirmation helper func @@ -656,6 +672,7 @@ secure_session() { unset -v mktemp_counter \ OPENSSL_CONF easyrsa_safe_ssl_conf \ working_safe_ssl_conf + easyrsa_err_log="$secured_session/error.log" verbose "\ secure_session: CREATED: $secured_session" return @@ -679,7 +696,6 @@ remove_secure_session: DELETED: $secured_session" return fi fi - die "remove_secure_session: $secured_session" } # => remove_secure_session() @@ -715,9 +731,14 @@ easyrsa_mktemp: create shotfile failed (1) $1" # Create temp-file or die # subshells do not update mktemp_counter, # which is why this extension is required. - # Current max required is 7 deep - for i in 1 2 3 4 5 6 7 8 9 10; do + # Current max required is 3 attempts + for i in 1 2 3 4 5 6 7 8 9; do want_tmp_file="${t}.${i}" + + # Warn to error log file for max reached + [ "$EASYRSA_MAX_TEMP" -gt "$i" ] || print "\ +Max temp-file limit $i, hit for: $1" >> "$easyrsa_err_log" + if [ -e "$want_tmp_file" ]; then verbose "\ easyrsa_mktemp: temp-file EXISTS: $want_tmp_file" @@ -749,13 +770,24 @@ easyrsa_mktemp - force_set_var $1 failed" fi done - die "\ -easyrsa_mktemp - failed for: $1 @ depth=$i + # In case of subshell abuse, report to error log + err_msg="\ +easyrsa_mktemp - failed for: $1 @ attempt=$i want_tmp_file: $want_tmp_file" + print "$err_msg" >> "$easyrsa_err_log" + die "$err_msg" + } # => easyrsa_mktemp() # remove temp files and do terminal cleanups cleanup() { + # In case of subshell abuse, display error log file + if [ -f "$easyrsa_err_log" ]; then + print + cat "$easyrsa_err_log" + print + fi + if [ "${secured_session%/*}" ] && \ [ -d "$secured_session" ] then @@ -779,14 +811,15 @@ Temporary session not preserved." else # remove temp-session remove_secure_session || \ - die "cleanup - remove_secure_session" + warn "cleanup - remove_secure_session failed" fi fi + # These cleanup routines must be called after die() + # because the relate commands can die in subshells. # Remove files when build_full()->sign_req() is interrupted [ "$error_build_full_cleanup" ] && \ rm -f "$crt_out" "$req_out" "$key_out" - # Restore files when renew is interrupted [ "$error_undo_renew_move" ] && renew_restore_move # Restore files when rebuild is interrupted @@ -834,7 +867,6 @@ Temporary session not preserved." # Make a copy safe SSL config file make_safe_ssl() { - verify_pki_init EASYRSA_FORCE_SAFE_SSL=1 easyrsa_openssl makesafeconf notice "\ @@ -935,7 +967,9 @@ easyrsa_openssl() { # Do not allow 'rand' here, see easyrsa_random() case "$openssl_command" in - rand) die "easyrsa_openssl: Illegal SSL command: rand" ;; + rand) + die "easyrsa_openssl: Illegal SSL command: rand" + ;; makesafeconf) require_safe_ssl_conf=1 ;; ca|req|srp|ts) has_config=1 ;; *) unset -v has_config @@ -1058,7 +1092,8 @@ easyrsa_openssl - Command has failed: ${has_config:+-config $easyrsa_safe_ssl_conf }$*" } # => easyrsa_openssl() -# Verify the SSL library is functional and establish version dependencies +# Verify the SSL library is functional +# and establish version dependencies verify_ssl_lib() { # Run once only [ "$EASYRSA_SSL_OK" ] && die "verify_ssl_lib - Overloaded" @@ -1080,12 +1115,13 @@ verify_ssl_lib() { ssl_lib=libressl require_safe_ssl_conf=1 if [ "$EASYRSA_NO_SAFE_SSL" ]; then - die "Cannot use '--no-safe-ssl' with LibreSSL" + user_error \ + "Cannot use '--no-safe-ssl' with LibreSSL" fi ;; *) error_msg="$("$EASYRSA_OPENSSL" version 2>&1)" - die "\ + user_error "\ * OpenSSL must either exist in your PATH or be defined in your vars file. @@ -1104,32 +1140,40 @@ $error_msg" case "$ssl_lib" in openssl) no_password='-noenc' ;; libressl) no_password='-nodes' ;; - *) die "Unsupported SSL library: $ssl_lib" + *) user_error \ + "Unsupported SSL library: $ssl_lib" esac ;; - *) die "Unsupported SSL library: $osslv_major" + *) user_error "Unsupported SSL library: $osslv_major" esac ssl_version="$val" + } # => verify_ssl_lib() # Basic sanity-check of PKI init and complain if missing verify_pki_init() { - help_note="Run easyrsa without commands for usage and command help." + help_note="\ +Run easyrsa without commands for usage and command help." # Check for defined EASYRSA_PKI [ "$EASYRSA_PKI" ] || die "\ EASYRSA_PKI env-var undefined" # check that the pki dir exists - [ -d "$EASYRSA_PKI" ] || die "\ + [ -d "$EASYRSA_PKI" ] || user_error "\ EASYRSA_PKI does not exist (perhaps you need to run init-pki)? -Expected to find the EASYRSA_PKI at: $EASYRSA_PKI +Expected to find the EASYRSA_PKI at: +* $EASYRSA_PKI + $help_note" # verify expected dirs present: for i in private reqs; do - [ -d "$EASYRSA_PKI/$i" ] || die "\ -Missing expected directory: $i (perhaps you need to run init-pki?) + [ -d "$EASYRSA_PKI/$i" ] || user_error "\ +Missing expected directory: $i + +(perhaps you need to run init-pki?) + $help_note" done unset -v help_note @@ -1137,18 +1181,24 @@ $help_note" # Verify core CA files present verify_ca_init() { - # First check the PKI has been initialized - verify_pki_init + help_note="\ +Run easyrsa without commands for usage and command help." - help_note="Run without commands for usage and command help." - - # Verify expected files are present. Allow files to be regular files - # (or symlinks), but also pipes, for flexibility with ca.key - for i in ca.crt private/ca.key index.txt index.txt.attr serial; do - if [ ! -f "$EASYRSA_PKI/$i" ] && [ ! -p "$EASYRSA_PKI/$i" ]; then + # Verify expected files are present. + # Allow files to be regular files (or symlinks), + # but also pipes, for flexibility with ca.key + for i in ca.crt private/ca.key \ + index.txt index.txt.attr serial + do + if [ ! -f "$EASYRSA_PKI/$i" ] && \ + [ ! -p "$EASYRSA_PKI/$i" ] + then [ "$1" = "test" ] && return 1 - die "\ -Missing expected CA file: $i (perhaps you need to run build-ca?) + user_error "\ +Missing expected CA file: $i + +(perhaps you need to run build-ca?) + $help_note" fi done @@ -1160,8 +1210,11 @@ $help_note" # verify expected CA-specific dirs: for i in issued certs_by_serial do - [ -d "$EASYRSA_PKI/$i" ] || die "\ -Missing expected CA dir: $i (perhaps you need to run build-ca?) + [ -d "$EASYRSA_PKI/$i" ] || user_error "\ +Missing expected CA dir: $i + +(perhaps you need to run build-ca?) + $help_note" done @@ -1185,7 +1238,7 @@ init_pki() { # If EASYRSA_PKI exists, confirm before deletion if [ -e "$EASYRSA_PKI" ]; then - confirm "Confirm removal: " "yes" "\ + confirm "Confirm removal: " "yes" " WARNING!!! You are about to remove the EASYRSA_PKI at: @@ -1228,7 +1281,7 @@ and initialize a fresh PKI here." done ;; *) - die "Unknown reset type: $reset" + user_error "Unknown reset type: $reset" esac fi @@ -1254,18 +1307,17 @@ Your newly created PKI dir is: # if $no_new_vars then there are one or more known vars # which are not in the PKI. All further commands will fail # until vars is manually corrected - [ "$no_new_vars" ] || information "\ -Using Easy-RSA configuration: ${vars:-Not found}" + [ "$no_new_vars" ] || information " +Using Easy-RSA configuration: +* ${vars:-Not found}" # For new PKIs , pki/vars was auto-created, show message if [ "$new_vars_true" ]; then - information "\ -IMPORTANT: \ -Easy-RSA 'vars' template file has been created in your new PKI. - \ -Edit this 'vars' file to customise the settings for your PKI. - \ -To use a global vars file, use global option --vars=" + information " +IMPORTANT: + Easy-RSA 'vars' template file has been created in your new PKI. + Edit this 'vars' file to customise the settings for your PKI. + To use a global vars file, use global option --vars=" elif [ "$user_vars_true" ] || [ "$old_vars_true" ] || \ [ "$no_new_vars" ] @@ -1275,14 +1327,15 @@ To use a global vars file, use global option --vars=" # Not in PKI and not user defined prefer_vars_in_pki_msg fi - information "\ -Using x509-types directory: ${EASYRSA_EXT_DIR:-Not found}" + information " +Using x509-types directory: +* ${EASYRSA_EXT_DIR:-Not found}" } # => init_pki() # Must be used in two places, so made it a function prefer_vars_in_pki_msg() { information "\ -The preferred location for 'vars' is within the PKI folder. + The preferred location for 'vars' is within the PKI folder. To silence this message move your 'vars' file to your PKI or declare your 'vars' file with option: --vars=" } # => prefer_vars_in_pki_msg() @@ -1434,7 +1487,8 @@ create_x509_type_COMMON() { COMMONFILECOMPLETE } # => create_x509_type_COMMON() -# Create x509-type/COMMON +# Create x509-type/unlisted: easyrsa +# This could be COMMON but not for a CA create_x509_type_easyrsa() { cat << "EASYRSAFILECOMPLETE" basicConstraints = CA:FALSE @@ -1468,17 +1522,15 @@ extendedKeyUsage = clientAuth CLIFILECOMPLETE } # => create_x509_type_client() -# Create vars.example +# Create vars.example - Not used create_vars_example() { - # Default settings ONLY - return cat << "VARSEXFILECOMPLETE" VARSEXFILECOMPLETE } # => create_vars_example() # Create openssl-easyrsa.cnf create_openssl_easyrsa_cnf() { - cat << "FILECOMPLETE" + cat << "SSLCONFCOMPLETE" # For use with Easy-RSA 3.0+ and OpenSSL or LibreSSL #################################################################### @@ -1625,7 +1677,7 @@ keyUsage = cRLSign, keyCertSign # issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always,issuer:always' -FILECOMPLETE +SSLCONFCOMPLETE } # => create_openssl_easyrsa_cnf() # Disable terminal echo, if possible, otherwise warn @@ -1690,9 +1742,6 @@ build_ca() { shift done - # Verify PKI has been initialised - verify_pki_init - out_key="$EASYRSA_PKI/private/ca.key" # setup for an intermediate CA if [ "$sub_ca" ]; then @@ -1720,7 +1769,7 @@ build_ca() { # Test for existing CA, and complain if already present if verify_ca_init test; then - die "\ + user_error "\ Unable to create a CA as you already seem to have one set up. If you intended to start a new CA, run init-pki first." fi @@ -1729,7 +1778,7 @@ If you intended to start a new CA, run init-pki first." # but not signed. # Notify user and require a signed ca.crt or a init-pki: if [ -f "$out_key" ]; then - die "\ + user_error "\ A CA private key exists but no ca.crt is found in your PKI: $EASYRSA_PKI Refusing to create a new CA as this would overwrite your @@ -1857,7 +1906,7 @@ Raw CA mode unset -v p q else unset -v p q - die "Passphrases do not match!" + user_error "Passphrases do not match!" fi fi @@ -1880,18 +1929,14 @@ Raw CA mode if [ -f "$EASYRSA_EXT_DIR/ca" ]; then cat "$EASYRSA_EXT_DIR/ca" else - print "\ -basicConstraints = CA:TRUE -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer:always -keyUsage = cRLSign, keyCertSign" + create_x509_type_ca fi # COMMON file if [ -f "$EASYRSA_EXT_DIR/COMMON" ]; then cat "$EASYRSA_EXT_DIR/COMMON" else - : # ok + create_x509_type_COMMON fi # User extentions @@ -2029,7 +2074,7 @@ build_ca: CA certificate password created via temp-files" } mv "$out_file_tmp" "$out_file" || { rm -f "$out_key" # Also remove the key - die "Failed to move cert temp-file" + die "Failed to move cert temp-file" } # Success messages @@ -2053,16 +2098,13 @@ CA creation complete. Your new CA certificate is at: # gen-dh backend: gen_dh() { - # Verify PKI has been initialised - verify_pki_init - out_file="$EASYRSA_PKI/dh.pem" # check to see if we already have a dh parameters file if [ -e "$out_file" ]; then if [ "$EASYRSA_BATCH" ]; then # if batch is enabled, die - die "\ + user_error "\ DH parameters file already exists at: $out_file" else @@ -2101,14 +2143,14 @@ DH parameters of size $EASYRSA_KEY_SIZE created at: # gen-req and key backend: gen_req() { - # Verify PKI has been initialised - verify_pki_init - # pull filename, use as default interactive CommonName - [ "$1" ] || die "\ -Error: gen-req must have a file base as the first argument. + [ "$1" ] || user_error "\ +Error: gen-req must have a file-name-base as the first argument. Run easyrsa without commands for usage and commands." + file_name_base="$1" + shift # scrape off file-name-base + # Initialisation unset -v text ssl_batch @@ -2116,20 +2158,19 @@ Run easyrsa without commands for usage and commands." if [ "$EASYRSA_BATCH" ]; then ssl_batch=1 # If EASYRSA_REQ_CN is set to something other than - # ChangeMe then keep user defined value - [ "$EASYRSA_REQ_CN" = ChangeMe ] && \ - export EASYRSA_REQ_CN="$1" + # 'ChangeMe' then keep user defined value + if [ "$EASYRSA_REQ_CN" = ChangeMe ]; then + export EASYRSA_REQ_CN="$file_name_base" + fi else # --req-cn must be used with --batch # otherwise use file-name - export EASYRSA_REQ_CN="$1" + export EASYRSA_REQ_CN="$file_name_base" fi # Output files - key_out="$EASYRSA_PKI/private/$1.key" - req_out="$EASYRSA_PKI/reqs/$1.req" - - shift # scrape off file-name + key_out="$EASYRSA_PKI/private/${file_name_base}.key" + req_out="$EASYRSA_PKI/reqs/${file_name_base}.req" # function opts support while [ "$1" ]; do @@ -2146,12 +2187,14 @@ Run easyrsa without commands for usage and commands." done # don't wipe out an existing private key without confirmation - [ -f "$key_out" ] && confirm "Confirm key overwrite: " "yes" "\ + if [ -f "$key_out" ]; then + confirm "Confirm key overwrite: " "yes" "\ WARNING!!! An existing private key was found at $key_out Continuing with key generation will replace this key." + fi # When EASYRSA_EXTRA_EXTS is defined, # append it to openssl's [req] section: @@ -2185,10 +2228,12 @@ $EASYRSA_EXTRA_EXTS" easyrsa_mktemp conf_tmp || \ die "gen_req - easyrsa_mktemp conf_tmp" + # Insert $extra_exts @ %EXTRA_EXTS% in SSL Config print "$extra_exts" | \ awk "$awkscript" "$EASYRSA_SSL_CONF" \ - > "$conf_tmp" \ - || die "Writing SSL config to temp file failed" + > "$conf_tmp" || \ + die "Writing SSL config to temp file failed" + # Use this SSL config for the rest of this function EASYRSA_SSL_CONF="$conf_tmp" fi @@ -2201,47 +2246,61 @@ $EASYRSA_EXTRA_EXTS" easyrsa_mktemp req_out_tmp || \ die "gen_req - easyrsa_mktemp req_out_tmp" - # Set Edwards curve name or elliptic curve parameters file + # Set algorithm options algo_opts="" - if [ "ed" = "$EASYRSA_ALGO" ]; then - algo_opts="$EASYRSA_CURVE" - else - algo_opts="$EASYRSA_ALGO:$EASYRSA_ALGO_PARAMS" - fi + case "$EASYRSA_ALGO" in + rsa|ec) + # Set elliptic curve parameters-file + # or RSA bit-length + algo_opts="$EASYRSA_ALGO:$EASYRSA_ALGO_PARAMS" + ;; + ed) + # Set Edwards curve name + algo_opts="$EASYRSA_CURVE" + ;; + *) die "gen_req - Unknown algorithm: $EASYRSA_ALGO" + esac # Generate request - easyrsa_openssl req -utf8 -new -newkey "$algo_opts" \ - -keyout "$key_out_tmp" -out "$req_out_tmp" \ + if easyrsa_openssl req -utf8 -new -newkey "$algo_opts" \ + -keyout "$key_out_tmp" \ + -out "$req_out_tmp" \ ${EASYRSA_NO_PASS:+ "$no_password"} \ ${text:+ -text} \ ${ssl_batch:+ -batch} \ - ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ - || die "Failed to generate request" + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} + then + : # ok + else + die "Failed to generate request" + fi # Move temp-files to target-files - mv "$key_out_tmp" "$key_out" - mv "$req_out_tmp" "$req_out" + mv "$key_out_tmp" "$key_out" || { + die "Failed to move key temp-file" + } + mv "$req_out_tmp" "$req_out" || { + rm -f "$key_out" # Also remove the key + die "Failed to move req temp-file" + } # Success messages notice "\ -Keypair and certificate request completed. Your files are: +Private-Key and Public-Certificate-Request files created. +Your files are: * req: $req_out -* key: $key_out${build_full:+ $NL}" +* key: $key_out${do_build_full:+ $NL}" - return 0 } # => gen_req() # common signing backend sign_req() { - # CA is required to sign - verify_ca_init - crt_type="$1" req_in="$EASYRSA_PKI/reqs/$2.req" crt_out="$EASYRSA_PKI/issued/$2.crt" # Check argument sanity: - [ "$2" ] || die "\ + [ "$2" ] || user_error "\ Incorrect number of arguments provided to sign-req: expected 2, got $# (see command help for usage)" @@ -2261,28 +2320,27 @@ Missing X509-type '$crt_type'" Missing X509-type 'COMMON'" # Cert type must NOT be COMMON - [ "$crt_type" != COMMON ] || die "\ + [ "$crt_type" != COMMON ] || user_error "\ Invalid certificate type: '$crt_type'" # Request file must exist - [ -e "$req_in" ] || die "\ + [ -e "$req_in" ] || user_error "\ No request found for the input: '$2' Expected to find the request at: $req_in" # Certificate file must NOT exist - [ ! -e "$crt_out" ] || die "\ + [ ! -e "$crt_out" ] || user_error "\ Cannot sign this request for '$2'. Conflicting certificate already exists at: * $crt_out" # Confirm input is a cert req - verify_file req "$req_in" || die "\ + verify_file req "$req_in" || user_error "\ The certificate request file is not in a valid X509 format: * $req_in" # Randomize Serial number if [ "$EASYRSA_RAND_SN" != "no" ]; then - i="" serial="" check_serial="" unset -v unique_serial @@ -2365,13 +2423,7 @@ to the latest Easy-RSA release." # Begin output redirect { - # Append COMMON and cert-type extensions - if [ -f "$EASYRSA_EXT_DIR/COMMON" ]; then - cat "$EASYRSA_EXT_DIR/COMMON" - else - : # ok - fi - + # Append $cert-type extensions if [ -f "$EASYRSA_EXT_DIR/$crt_type" ]; then cat "$EASYRSA_EXT_DIR/$crt_type" else @@ -2394,6 +2446,13 @@ to the latest Easy-RSA release." esac fi + # Append COMMON extensions + if [ -f "$EASYRSA_EXT_DIR/COMMON" ]; then + cat "$EASYRSA_EXT_DIR/COMMON" + else + create_x509_type_COMMON + fi + # Support a dynamic CA path length when present: if [ "$crt_type" = "ca" ] && [ "$EASYRSA_SUBCA_LEN" ] then @@ -2489,21 +2548,26 @@ for '$EASYRSA_CERT_EXPIRE' days" # Display the request subject in an easy-to-read format # Confirm the user wishes to sign this request - # Support batch by internal caller: - confirm "Confirm request details: " "yes" "\ -You are about to sign the following certificate. + # The foriegn_request confirmation is not required + # for build_full: + if [ "$do_build_full" ]; then + unset -v foriegn_request + else + foriegn_request="\ Please check over the details shown below for accuracy. \ Note that this request has not been cryptographically verified. Please be sure \ it came from a trusted source or that you have verified the request checksum \ -with the sender. +with the sender.$NL" + fi -Request subject, to be signed as a $crt_type certificate \ -${valid_period}: + confirm "Confirm request details: " "yes" "\ +You are about to sign the following certificate: +${foriegn_request}Request subject, to be signed as a \ +$crt_type certificate ${valid_period}: -$(display_dn req "$req_in") -" # => confirm end +$(display_dn req "$req_in")" # => confirm end # Confirm deprecated use of NS extensions case "$EASYRSA_NS_SUPPORT" in @@ -2547,7 +2611,7 @@ Certificate created at: # used to generate+sign in 1 step build_full() { # pull filename base: - [ "$2" ] || die "\ + [ "$2" ] || user_error "\ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and commands." @@ -2574,10 +2638,14 @@ Run easyrsa without commands for usage and commands." err_exists="\ file already exists. Aborting build to avoid overwriting this file. If you wish to continue, please use a different name. -Matching file found at: " - [ -e "$req_out" ] && die "Request $err_exists $req_out" - [ -e "$key_out" ] && die "Key $err_exists $key_out" - [ -e "$crt_out" ] && die "Certificate $err_exists $crt_out" +Conflicting file found at: +*" + [ -e "$req_out" ] && \ + user_error "Request $err_exists $req_out" + [ -e "$key_out" ] && \ + user_error "Key $err_exists $key_out" + [ -e "$crt_out" ] && \ + user_error "Certificate $err_exists $crt_out" unset -v err_exists # Make inline directory @@ -2595,19 +2663,19 @@ An inline file for name '$name' already exists: * $inline_out" # Set commonName - [ "$EASYRSA_REQ_CN" = ChangeMe ] || die "\ + [ "$EASYRSA_REQ_CN" = ChangeMe ] || user_error "\ Option conflict: * '$cmd' does not support setting an external commonName" EASYRSA_REQ_CN="$name" # create request - build_full=1 + do_build_full=1 gen_req "$name" batch # Sign it error_build_full_cleanup=1 if sign_req "$crt_type" "$name"; then - unset -v error_build_full_cleanup + unset -v error_build_full_cleanup do_build_full else die "\ Failed to sign '$name' - \ @@ -2647,22 +2715,20 @@ inline_creds () # revoke backend revoke() { # pull filename base: - [ "$1" ] || die "\ + [ "$1" ] || user_error "\ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and command help." - verify_ca_init - # Assign file_name_base and dust off! file_name_base="$1" shift in_dir="$EASYRSA_PKI" - crt_in="$in_dir/issued/$file_name_base.crt" - key_in="$in_dir/private/$file_name_base.key" - req_in="$in_dir/reqs/$file_name_base.req" - creds_in="$in_dir/$file_name_base.creds" - inline_in="$in_dir/inline/$file_name_base.inline" + crt_in="$in_dir/issued/${file_name_base}.crt" + key_in="$in_dir/private/${file_name_base}.key" + req_in="$in_dir/reqs/${file_name_base}.req" + creds_in="$in_dir/${file_name_base}.creds" + inline_in="$in_dir/inline/${file_name_base}.inline" # Assign possible "crl_reason" if [ "$1" ]; then @@ -2677,7 +2743,7 @@ Run easyrsa without commands for usage and command help." superseded) : ;; cessationOfOperation) : ;; certificateHold) : ;; - *) die "Illegal reason: $crl_reason" + *) user_error "Illegal reason: $crl_reason" esac else unset -v crl_reason @@ -2685,22 +2751,22 @@ Run easyrsa without commands for usage and command help." # Enforce syntax if [ "$1" ]; then - die "Syntax error: $1" + user_error "Syntax error: $1" fi # referenced cert must exist: - [ -e "$crt_in" ] || die "\ + [ -e "$crt_in" ] || user_error "\ Unable to revoke as no certificate was found. Certificate was expected at: $crt_in" # Verify certificate - verify_file x509 "$crt_in" || die "\ + verify_file x509 "$crt_in" || user_error "\ Unable to revoke as the input file is not a valid certificate. Unexpected input in file: $crt_in" # Verify request if [ -e "$req_in" ]; then - verify_file req "$req_in" || die "\ + verify_file req "$req_in" || user_error "\ Unable to verify request. The file is not a valid request. Unexpected input in file: $req_in" fi @@ -2708,21 +2774,26 @@ Unexpected input in file: $req_in" # get the serial number of the certificate ssl_cert_serial "$crt_in" cert_serial - duplicate_crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + # Duplicate cert by serial file + dup_dir="$EASYRSA_PKI/certs_by_serial" + dup_crt_by_serial="$dup_dir/${cert_serial}.pem" # Set out_dir out_dir="$EASYRSA_PKI/revoked" - crt_out="$out_dir/certs_by_serial/$cert_serial.crt" - key_out="$out_dir/private_by_serial/$cert_serial.key" - req_out="$out_dir/reqs_by_serial/$cert_serial.req" + crt_out="$out_dir/certs_by_serial/${cert_serial}.crt" + key_out="$out_dir/private_by_serial/${cert_serial}.key" + req_out="$out_dir/reqs_by_serial/${cert_serial}.req" # NEVER over-write a revoked cert, serial number must be unique deny_msg="\ Cannot revoke this certificate because a conflicting file exists. *" - [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" - [ -e "$key_out" ] && die "$deny_msg private key: $key_out" - [ -e "$req_out" ] && die "$deny_msg request : $req_out" + [ -e "$crt_out" ] && \ + user_error "$deny_msg certificate: $crt_out" + [ -e "$key_out" ] && \ + user_error "$deny_msg private key: $key_out" + [ -e "$req_out" ] && \ + user_error "$deny_msg request : $req_out" unset -v deny_msg # Check for key and request files @@ -2747,7 +2818,7 @@ The inline credentials files: * $inline_in The duplicate certificate: -* $duplicate_crt_by_serial" +* $dup_crt_by_serial" confirm " Continue with revocation: " "yes" "\ Please confirm you wish to revoke the certificate @@ -2823,10 +2894,10 @@ revoke_move() { done # remove the duplicate certificate - if [ -e "$duplicate_crt_by_serial" ]; then - rm "$duplicate_crt_by_serial" || warn "\ + if [ -e "$dup_crt_by_serial" ]; then + rm "$dup_crt_by_serial" || warn "\ Failed to remove the duplicate certificate: -* $duplicate_crt_by_serial" +* $dup_crt_by_serial" fi # remove credentials file @@ -2849,25 +2920,23 @@ Failed to remove inline file: # renew backend renew() { # pull filename base: - [ "$1" ] || die "\ + [ "$1" ] || user_error "\ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and command help." - verify_ca_init - # Assign file_name_base and dust off! file_name_base="$1" shift # Assign input files in_dir="$EASYRSA_PKI" - crt_in="$in_dir/issued/$file_name_base.crt" - key_in="$in_dir/private/$file_name_base.key" + crt_in="$in_dir/issued/${file_name_base}.crt" + key_in="$in_dir/private/${file_name_base}.key" # key_out is used by inline_creds() - key_out="$in_dir/private/$file_name_base.key" - req_in="$in_dir/reqs/$file_name_base.req" - creds_in="$in_dir/$file_name_base.creds" - inline_in="$in_dir/inline/$file_name_base.inline" + key_out="$in_dir/private/${file_name_base}.key" + req_in="$in_dir/reqs/${file_name_base}.req" + creds_in="$in_dir/${file_name_base}.creds" + inline_in="$in_dir/inline/${file_name_base}.inline" # Upgrade CA index.txt.attr - unique_subject = no up23_upgrade_ca || \ @@ -2880,29 +2949,29 @@ Run easyrsa without commands for usage and command help." warn "\ Option 'nopass' is not supported by command 'renew'." ;; - *) die "Unknown option: $1" + *) user_error "Unknown option: $1" esac shift done # Verify certificate if [ -f "$crt_in" ]; then - verify_file x509 "$crt_in" || die "\ + verify_file x509 "$crt_in" || user_error "\ Input file is not a valid certificate: * $crt_in" else - die "\ + user_error "\ Missing certificate file: * $crt_in" fi # Verify request if [ -e "$req_in" ]; then - verify_file req "$req_in" || die "\ + verify_file req "$req_in" || user_error "\ Input file is not a valid request: * $req_in" else - die "\ + user_error "\ Missing request file: * $req_in" fi @@ -2910,18 +2979,20 @@ Missing request file: # get the serial number of the certificate ssl_cert_serial "$crt_in" cert_serial - duplicate_crt_by_serial="\ -$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + # Duplicate cert by serial file + dup_dir="$EASYRSA_PKI/certs_by_serial" + dup_crt_by_serial="$dup_dir/${cert_serial}.pem" # Set out_dir out_dir="$EASYRSA_PKI/renewed" - crt_out="$out_dir/issued/$file_name_base.crt" + crt_out="$out_dir/issued/${file_name_base}.crt" # NEVER over-write a renewed cert, revoke it first deny_msg="\ Cannot renew this certificate, a conflicting file exists: *" - [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" + [ -e "$crt_out" ] && \ + user_error "$deny_msg certificate: $crt_out" unset -v deny_msg # Make inline directory @@ -2978,7 +3049,7 @@ The inline credentials files: * $inline_in The duplicate certificate: -* $duplicate_crt_by_serial" +* $dup_crt_by_serial" confirm " Continue with renewal: " "yes" "\ Please confirm you wish to renew the certificate @@ -3085,10 +3156,10 @@ renew_move() { done # remove the duplicate certificate - if [ -e "$duplicate_crt_by_serial" ]; then - rm "$duplicate_crt_by_serial" || warn "\ + if [ -e "$dup_crt_by_serial" ]; then + rm "$dup_crt_by_serial" || warn "\ Failed to remove the duplicate certificate: -* $duplicate_crt_by_serial" +* $dup_crt_by_serial" fi # remove credentials file @@ -3111,12 +3182,10 @@ Failed to remove inline file: # revoke-renewed backend revoke_renewed() { # pull filename base: - [ "$1" ] || die "\ + [ "$1" ] || user_error "\ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and command help." - verify_ca_init - # Assign file_name_base and dust off! file_name_base="$1" shift @@ -3140,7 +3209,7 @@ Run easyrsa without commands for usage and command help." superseded) : ;; cessationOfOperation) : ;; certificateHold) : ;; - *) die "Illegal reason: $crl_reason" + *) user_error "Illegal reason: $crl_reason" esac else unset -v crl_reason @@ -3148,22 +3217,22 @@ Run easyrsa without commands for usage and command help." # Enforce syntax if [ "$1" ]; then - die "Syntax error: $1" + user_error "Syntax error: $1" fi # referenced cert must exist: - [ -f "$crt_in" ] || die "\ + [ -f "$crt_in" ] || user_error "\ Unable to revoke as no renewed certificate was found. Certificate was expected at: $crt_in" # Verify certificate - verify_file x509 "$crt_in" || die "\ + verify_file x509 "$crt_in" || user_error "\ Unable to revoke as the input file is not a valid certificate. Unexpected input in file: $crt_in" # Verify request if [ -e "$req_in" ]; then - verify_file req "$req_in" || die "\ + verify_file req "$req_in" || user_error "\ Unable to verify request. The file is not a valid request. Unexpected input in file: $req_in" fi @@ -3171,7 +3240,9 @@ Unexpected input in file: $req_in" # get the serial number of the certificate ssl_cert_serial "$crt_in" cert_serial - duplicate_crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + # Duplicate cert by serial file + dup_dir="$EASYRSA_PKI/certs_by_serial" + dup_crt_by_serial="$dup_dir/${cert_serial}.pem" # output out_dir="$EASYRSA_PKI/revoked" @@ -3183,9 +3254,12 @@ Unexpected input in file: $req_in" deny_msg="\ Cannot revoke this certificate because a conflicting file exists. *" - [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" - [ -e "$key_out" ] && die "$deny_msg private key: $key_out" - [ -e "$req_out" ] && die "$deny_msg request : $req_out" + [ -e "$crt_out" ] && \ + user_error "$deny_msg certificate: $crt_out" + [ -e "$key_out" ] && \ + user_error "$deny_msg private key: $key_out" + [ -e "$req_out" ] && \ + user_error "$deny_msg request : $req_out" unset -v deny_msg # confirm operation by displaying DN: @@ -3260,35 +3334,33 @@ revoke_renewed_move() { # Move renewed certs_by_serial to the new renew layout rewind_renew() { # pull filename base: serial number - [ "$1" ] || die "\ + [ "$1" ] || user_error "\ Error: didn't find a serial number as the first argument. Run easyrsa without commands for usage and command help." - verify_ca_init - # Assign file_name_base and dust off! file_name_base="$1" shift "$#" # No options supported cert_serial="$file_name_base" in_dir="$EASYRSA_PKI/renewed" - crt_in="$in_dir/certs_by_serial/$file_name_base.crt" - key_in="$in_dir/private_by_serial/$file_name_base.key" - req_in="$in_dir/reqs_by_serial/$file_name_base.req" + crt_in="$in_dir/certs_by_serial/${file_name_base}.crt" + key_in="$in_dir/private_by_serial/${file_name_base}.key" + req_in="$in_dir/reqs_by_serial/${file_name_base}.req" # referenced cert must exist: - [ -f "$crt_in" ] || die "\ + [ -f "$crt_in" ] || user_error "\ Unable to rewind as no certificate was found. Certificate was expected at: $crt_in" # Verify certificate - verify_file x509 "$crt_in" || die "\ + verify_file x509 "$crt_in" || user_error "\ Unable to rewind as the input file is not a valid certificate. Unexpected input in file: $crt_in" # Verify request if [ -e "$req_in" ]; then - verify_file req "$req_in" || die "\ + verify_file req "$req_in" || user_error "\ Unable to verify request. The file is not a valid request. Unexpected input in file: $req_in" fi @@ -3302,22 +3374,26 @@ Unexpected input in file: $req_in" # Set out_dir out_dir="$EASYRSA_PKI/renewed" - crt_out="$out_dir/issued/$crt_cn.crt" - key_out="$out_dir/private/$crt_cn.key" - req_out="$out_dir/reqs/$crt_cn.req" + crt_out="$out_dir/issued/${crt_cn}.crt" + key_out="$out_dir/private/${crt_cn}.key" + req_out="$out_dir/reqs/${crt_cn}.req" # Create out_dir for newdir in issued private reqs; do - mkdir -p "$out_dir/$newdir" || die "Failed to create: $out_dir/$newdir" + mkdir -p "$out_dir/$newdir" || \ + die "Failed to create: $out_dir/$newdir" done # NEVER over-write a renewed cert, revoke it first deny_msg="\ Cannot rewind this certificate because a conflicting file exists. *" - [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" - [ -e "$key_out" ] && die "$deny_msg private key: $key_out" - [ -e "$req_out" ] && die "$deny_msg request : $req_out" + [ -e "$crt_out" ] && \ + user_error "$deny_msg certificate: $crt_out" + [ -e "$key_out" ] && \ + user_error "$deny_msg private key: $key_out" + [ -e "$req_out" ] && \ + user_error "$deny_msg request : $req_out" unset -v deny_msg warn "\ @@ -3376,25 +3452,24 @@ To revoke use: 'revoke-renewed $crt_cn'" # rebuild backend rebuild() { # pull filename base: - [ "$1" ] || die "\ + [ "$1" ] || user_error "\ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and command help." - verify_ca_init - # Assign file_name_base and dust off! file_name_base="$1" shift in_dir="$EASYRSA_PKI" - crt_in="$in_dir/issued/$file_name_base.crt" - key_in="$in_dir/private/$file_name_base.key" - req_in="$in_dir/reqs/$file_name_base.req" - creds_in="$in_dir/$file_name_base.creds" - inline_in="$in_dir/inline/$file_name_base.inline" + crt_in="$in_dir/issued/${file_name_base}.crt" + key_in="$in_dir/private/${file_name_base}.key" + req_in="$in_dir/reqs/${file_name_base}.req" + creds_in="$in_dir/${file_name_base}.creds" + inline_in="$in_dir/inline/${file_name_base}.inline" # Upgrade CA index.txt.attr - unique_subject = no - up23_upgrade_ca || die "Failed to upgrade CA to support renewal." + up23_upgrade_ca || \ + die "Failed to upgrade CA to support renewal." # Set 'nopass' while [ "$1" ]; do @@ -3402,24 +3477,24 @@ Run easyrsa without commands for usage and command help." nopass) [ "$prohibit_no_pass" ] || EASYRSA_NO_PASS=1 ;; - *) die "Unknown option: $1" + *) user_error "Unknown option: $1" esac shift done # referenced cert must exist: - [ -f "$crt_in" ] || die "\ + [ -f "$crt_in" ] || user_error "\ Unable to rebuild as no certificate was found. Certificate was expected at: $crt_in" # Verify certificate - verify_file x509 "$crt_in" || die "\ + verify_file x509 "$crt_in" || user_error "\ Unable to rebuild as the input file is not a valid certificate. Unexpected input in file: $crt_in" # Verify request if [ -e "$req_in" ]; then - verify_file req "$req_in" || die "\ + verify_file req "$req_in" || user_error "\ Unable to verify request. The file is not a valid request. Unexpected input in file: $req_in" fi @@ -3427,30 +3502,28 @@ Unexpected input in file: $req_in" # get the serial number of the certificate ssl_cert_serial "$crt_in" cert_serial - duplicate_crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem" + # Duplicate cert by serial file + dup_dir="$EASYRSA_PKI/certs_by_serial" + dup_crt_by_serial="$dup_dir/${cert_serial}.pem" # Set out_dir out_dir="$EASYRSA_PKI/renewed" - crt_out="$out_dir/issued/$file_name_base.crt" - key_out="$out_dir/private/$file_name_base.key" - req_out="$out_dir/reqs/$file_name_base.req" + crt_out="$out_dir/issued/${file_name_base}.crt" + key_out="$out_dir/private/${file_name_base}.key" + req_out="$out_dir/reqs/${file_name_base}.req" # NEVER over-write a renewed cert, revoke it first deny_msg="\ Cannot rebuild this certificate because a conflicting file exists. *" - [ -e "$crt_out" ] && die "$deny_msg certificate: $crt_out" - [ -e "$key_out" ] && die "$deny_msg private key: $key_out" - [ -e "$req_out" ] && die "$deny_msg request : $req_out" + [ -e "$crt_out" ] && \ + user_error "$deny_msg certificate: $crt_out" + [ -e "$key_out" ] && \ + user_error "$deny_msg private key: $key_out" + [ -e "$req_out" ] && \ + user_error "$deny_msg request : $req_out" unset -v deny_msg - # # Check if old cert is expired or expires within 30 - # cert_dates "$crt_in" - # - # [ "$expire_date_s" -lt "$allow_renew_date_s" ] || die "\ - #Certificate expires in more than $EASYRSA_PRE_EXPIRY_WINDOW days. - #Renewal not allowed." - # Extract certificate usage from old cert cert_ext_key_usage="$( easyrsa_openssl x509 -in "$crt_in" -noout -text | @@ -3504,7 +3577,7 @@ The inline credentials files: * $inline_in The duplicate certificate: -* $duplicate_crt_by_serial +* $dup_crt_by_serial IMPORTANT: The new key will${EASYRSA_NO_PASS:+ NOT} be password protected." @@ -3637,10 +3710,10 @@ rebuild_move() { done # remove the duplicate certificate - if [ -e "$duplicate_crt_by_serial" ]; then - rm "$duplicate_crt_by_serial" || warn "\ + if [ -e "$dup_crt_by_serial" ]; then + rm "$dup_crt_by_serial" || warn "\ Failed to remove the duplicate certificate: -* $duplicate_crt_by_serial" +* $dup_crt_by_serial" fi # remove credentials file @@ -3662,8 +3735,6 @@ Failed to remove inline file: # gen-crl backend gen_crl() { - verify_ca_init - out_file="$EASYRSA_PKI/crl.pem" out_file_tmp="" @@ -3686,29 +3757,26 @@ An updated CRL has been created: # import-req backend import_req() { - # Verify PKI has been initialised - verify_pki_init - # pull passed paths in_req="$1" short_name="$2" out_req="$EASYRSA_PKI/reqs/$2.req" - [ "$short_name" ] || die "\ + [ "$short_name" ] || user_error "\ Unable to import: incorrect command syntax. Run easyrsa without commands for usage and command help." # Request file must exist - [ -e "$in_req" ] || die "\ + [ -e "$in_req" ] || user_error "\ No request found for the input: '$2' Expected to find the request at: $in_req" - verify_file req "$in_req" || die "\ + verify_file req "$in_req" || user_error "\ The input file does not appear to be a certificate request. Aborting import. File Path: $in_req" # destination must not exist - [ -e "$out_req" ] && die "\ + [ -e "$out_req" ] && user_error "\ Unable to import the request as the destination file already exists. Please choose a different name for your imported request file. Existing file at: $out_req" @@ -3728,7 +3796,7 @@ export_pkcs() { pkcs_type="$1" shift - [ "$1" ] || die "\ + [ "$1" ] || user_error "\ Unable to export p12: incorrect command syntax. Run easyrsa without commands for usage and command help." @@ -3739,9 +3807,6 @@ Run easyrsa without commands for usage and command help." key_in="$EASYRSA_PKI/private/$short_name.key" crt_ca="$EASYRSA_PKI/ca.crt" - # Verify PKI has been initialised - verify_pki_init - # opts support cipher=-aes256 want_ca=1 @@ -3762,16 +3827,20 @@ Run easyrsa without commands for usage and command help." pkcs_certfile_path= if [ "$want_ca" ]; then - verify_file x509 "$crt_ca" || die "\ -Unable to include CA cert in the $pkcs_type output (missing file, or use noca option.) -Missing file expected at: $crt_ca" + verify_file x509 "$crt_ca" || user_error "\ +Unable to include CA cert in the $pkcs_type output. +Missing CA file expected at: +* $crt_ca + +Try 'noca' option.)" pkcs_certfile_path="$crt_ca" fi # input files must exist - verify_file x509 "$crt_in" || die "\ -Unable to export $pkcs_type for short name '$short_name' without the certificate. -Missing cert expected at: $crt_in" + verify_file x509 "$crt_in" || user_error "\ +Unable to export $pkcs_type for short name '$short_name'. +Missing cert expected at: +* $crt_in" # For 'nopass' PKCS requires an explicit empty password 'pass:' if [ "$EASYRSA_NO_PASS" ]; then @@ -3785,10 +3854,12 @@ Missing cert expected at: $crt_in" pkcs_out="$EASYRSA_PKI/private/$short_name.p12" if [ "$want_key" ]; then - [ -e "$key_in" ] || die "\ -Unable to export p12 for short name '$short_name' without the key -(if you want a p12 without the private key, use nokey option.) -Missing key expected at: $key_in" + [ -e "$key_in" ] || user_error "\ +Unable to export p12 for short name '$short_name'. +Missing key expected at: +* $key_in + +if you want a p12 without the private key, use 'nokey' option." else nokeys=1 fi @@ -3845,9 +3916,6 @@ location: $pkcs_out" # set-pass backend legacy set_pass_legacy() { - # Verify PKI has been initialised - verify_pki_init - # key type, supplied internally from frontend command call (rsa/ec) key_type="$1" shift @@ -3856,9 +3924,9 @@ set_pass_legacy() { raw_file="$1" shift - file="$EASYRSA_PKI/private/$raw_file.key" + file="$EASYRSA_PKI/private/${raw_file}.key" - [ "$raw_file" ] || die "\ + [ "$raw_file" ] || user_error "\ Missing argument to 'set-$key_type-pass' command: no name/file supplied. See help output for usage details." @@ -3881,7 +3949,7 @@ See help output for usage details." unset -v cipher fi - [ -e "$file" ] || die "\ + [ -e "$file" ] || user_error "\ Missing private key: expected to find the private key component at: $file" @@ -3911,9 +3979,6 @@ Failed to change the private key passphrase. See above for error messages." # set-pass backend set_pass() { - # Verify PKI has been initialised - verify_pki_init - # values supplied by the user: raw_file="$1" file="$EASYRSA_PKI/private/$raw_file.key" @@ -3921,7 +3986,7 @@ set_pass() { if [ "$raw_file" ]; then shift else - die "\ + user_error "\ Missing argument: no name/file supplied." fi @@ -3943,7 +4008,7 @@ Missing argument: no name/file supplied." unset -v cipher fi - [ -e "$file" ] || die "\ + [ -e "$file" ] || user_error "\ Missing private key: expected to find the private key component at: $file" @@ -3959,11 +4024,12 @@ ${cipher:+You will then enter and verify a new PEM pass phrase for this key.}" easyrsa_openssl pkey -in "$file" -out "$out_key_tmp" \ ${cipher:+ "$cipher"} \ ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ - ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ -Failed to change the private key passphrase." + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || \ + die "Failed to change the private key passphrase." - mv "$out_key_tmp" "$file" || die "\ -Failed to update the private key file." + mv "$out_key_tmp" "$file" || { + die "Failed to update the private key file." + } key_update=changed [ "$EASYRSA_NO_PASS" ] && key_update=removed @@ -3972,13 +4038,9 @@ Failed to update the private key file." # update-db backend update_db() { - verify_ca_init - easyrsa_openssl ca -utf8 -updatedb \ - ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} || die "\ -Failed to perform update-db: see above for related openssl errors." - - return 0 + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} || \ + die "Failed to perform update-db." } # => update_db() # Display subjectAltName @@ -4000,7 +4062,7 @@ display_san - input error" else # Generate a SAN san="$( - x509v3san="X509v3 Subject Alternative Name:" + x509v3san='X509v3 Subject Alternative Name:' easyrsa_openssl "$format" -in "$path" -noout -text | sed -n \ "/${x509v3san}/{n;s/ //g;s/IPAddress:/IP:/g;s/RegisteredID/RID/;p;}" )" @@ -4064,12 +4126,10 @@ default_server_san - input error" # Verify certificate against CA verify_cert() { # pull filename base: - [ "$1" ] || die "\ + [ "$1" ] || user_error "\ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and command help." - verify_ca_init - # Assign file_name_base and dust off! file_name_base="$1" shift @@ -4100,11 +4160,11 @@ Run easyrsa without commands for usage and command help." crt_in="$in_dir/issued/$file_name_base.crt" # Cert file must exist - [ -e "$crt_in" ] || die "\ + [ -e "$crt_in" ] || user_error "\ No certificate found for the input: '$crt_in'" # Verify file is a valid cert - verify_file x509 "$crt_in" || die "\ + verify_file x509 "$crt_in" || user_error "\ Input is not a valid certificate: $crt_in" # Test SSL out @@ -4144,7 +4204,7 @@ show() { name="$2" in_file="" format="" - [ "$name" ] || die "\ + [ "$name" ] || user_error "\ Missing expected argument. Run easyrsa without commands for usage help." shift 2 @@ -4164,17 +4224,14 @@ Run easyrsa without commands for usage help." # Determine cert/req type (v2) case "$type" in cert) - verify_ca_init in_file="$EASYRSA_PKI/issued/$name.crt" format="x509" ;; req) - verify_pki_init in_file="$EASYRSA_PKI/reqs/$name.req" format="req" ;; crl) - verify_ca_init in_file="$EASYRSA_PKI/$name.pem" format="crl" unset -v type_opts out_opts name_opts @@ -4183,12 +4240,12 @@ Run easyrsa without commands for usage help." esac # Verify file exists and is of the correct type - [ -e "$in_file" ] || die "\ + [ -e "$in_file" ] || user_error "\ No such '$type' type file with a of '$name' is present. Expected to find this file at: $in_file" - verify_file "$format" "$in_file" || die "\ + verify_file "$format" "$in_file" || user_error "\ This file is not a valid $type file: $in_file" @@ -4200,9 +4257,8 @@ This file is stored at: easyrsa_openssl "$format" -in "$in_file" -noout -text \ ${type_opts:+ "$type_opts" "$out_opts"} \ - ${name_opts:+ -nameopt "$name_opts"} \ - || die "\ -OpenSSL failure to process the input" + ${name_opts:+ -nameopt "$name_opts"} || \ + die "OpenSSL failure to process the input" } # => show() @@ -4220,17 +4276,16 @@ show_ca() { shift done - verify_ca_init in_file="$EASYRSA_PKI/ca.crt" format="x509" # Verify file exists and is of the correct type - [ -e "$in_file" ] || die "\ + [ -e "$in_file" ] || user_error "\ No such $type file with a basename of '$name' is present. Expected to find this file at: $in_file" - verify_file "$format" "$in_file" || die "\ + verify_file "$format" "$in_file" || user_error "\ This file is not a valid $type file: $in_file" @@ -4240,8 +4295,8 @@ Showing details for CA certificate, at: " easyrsa_openssl "$format" -in "$in_file" -noout -text \ - -nameopt "$name_opts" -certopt "$out_opts" || die "\ -OpenSSL failure to process the input" + -nameopt "$name_opts" -certopt "$out_opts" || \ + die "OpenSSL failure to process the input" } # => show_ca() @@ -4867,7 +4922,7 @@ expire_status() { # an issued cert if [ "$db_serial" != "$cert_serial" ]; then information "\ -expire_status: SERIAL MISMATCH + expire_status: SERIAL MISMATCH db_serial: $db_serial cert_serial: $cert_serial commonName: $db_cn @@ -5133,8 +5188,6 @@ status() { report="$1" target="$2" - verify_ca_init - # test fix: https://github.com/OpenVPN/easy-rsa/issues/819 export LC_TIME=C.UTF-8 @@ -5285,8 +5338,9 @@ verify_algo_params() { ec) # Verify Elliptic curve EASYRSA_ALGO_PARAMS="" - easyrsa_mktemp EASYRSA_ALGO_PARAMS || die \ - "verify_algo_params - easyrsa_mktemp EASYRSA_ALGO_PARAMS" + easyrsa_mktemp EASYRSA_ALGO_PARAMS || \ + die "\ +verify_algo_params - easyrsa_mktemp EASYRSA_ALGO_PARAMS" # Create the required ecparams file # call openssl directly because error is expected @@ -5304,8 +5358,8 @@ Failed to generate ecparam file (permissions?) at: 1>/dev/null || die "\ Edwards Curve $EASYRSA_CURVE not found." ;; - *) die "\ -Alg '$EASYRSA_ALGO' is invalid: Must be 'rsa', 'ec' or 'ed'" + *) user_error "\ +Algorithm '$EASYRSA_ALGO' is invalid: Must be 'rsa', 'ec' or 'ed'" esac verbose "\ verify_algo_params: Params verified for algo '$EASYRSA_ALGO'" @@ -5331,7 +5385,7 @@ Option --silent-ssl requires batch mode --batch." # --startdate requires --enddate # otherwise, --days counts from now if [ "$EASYRSA_START_DATE" ]; then - [ "$EASYRSA_END_DATE" ] || die "\ + [ "$EASYRSA_END_DATE" ] || user_error "\ Use of --startdate requires use of --enddate." fi @@ -5370,7 +5424,8 @@ To correct this problem, it is recommended that you either: # Use of --silent and --verbose if [ "$EASYRSA_SILENT" ] && [ "$EASYRSA_VERBOSE" ]; then - die "Use of --silent and --verbose is unresolvable." + user_error "\ +Use of --silent and --verbose is unresolvable." fi } # => mutual_exclusions() @@ -5389,13 +5444,16 @@ vars_setup() { # Find vars # Explicit user defined vars file: - if [ "$EASYRSA_VARS_FILE" ]; then + if [ "$EASYRSA_NO_VARS" ]; then + : # ok + + elif [ "$EASYRSA_VARS_FILE" ]; then if [ -e "$EASYRSA_VARS_FILE" ]; then vars="$EASYRSA_VARS_FILE" user_vars_true=1 else # If the --vars option does not point to a file - die "\ + user_error "\ The 'vars' file was not found: * $EASYRSA_VARS_FILE" fi @@ -5474,12 +5532,12 @@ The 'vars' file was not found: ;; *) # For init-pki, skip this check - if [ "$pki_is_required" ]; then + if [ "$require_pki" ]; then [ "$e_pki_vars" ] && print "Found: $pki_vars" [ "$e_easy_vars" ] && print "Found: $easy_vars" [ "$e_pwd_vars" ] && print "Found: $pwd_vars" [ "$e_prog_vars" ] && print "Found: $prog_vars" - die "\ + user_error "\ Conflicting 'vars' files found. Priority should be given to your PKI vars file: @@ -5499,9 +5557,11 @@ Priority should be given to your PKI vars file: fi # If EASYRSA_NO_VARS is defined then do not use vars - # If no_pki_required then located vars files are not - # required - if [ "$EASYRSA_NO_VARS" ] || [ "$no_pki_required" ]; then + # If PKI is not required then located vars files are + # not required + if [ "$EASYRSA_NO_VARS" ]; then + : # ok + elif [ ! "$require_pki" ]; then : # ok # If a vars file was located then source it @@ -5523,7 +5583,7 @@ Missing vars file: # Installation information information "\ Using Easy-RSA configuration: - $vars" +* $vars" # Sanitize vars if grep -q \ @@ -5531,7 +5591,7 @@ Using Easy-RSA configuration: -e '[^(]`[^)]' \ "$vars" then - die "\ + user_error "\ One or more of these problems has been found in your 'vars' file: * Use of 'EASYRSA_PASSIN' or 'EASYRSA_PASSOUT': @@ -5602,7 +5662,8 @@ One or more of these problems has been found in your 'vars' file: ed) set_var EASYRSA_CURVE ed25519 ;; - *) die "Unknown algorithm '$EASYRSA_ALGO'" + *) user_error "\ +Algorithm '$EASYRSA_ALGO' is invalid: Must be 'rsa', 'ec' or 'ed'" esac set_var EASYRSA_CA_EXPIRE 3650 @@ -5613,14 +5674,20 @@ One or more of these problems has been found in your 'vars' file: set_var EASYRSA_NS_SUPPORT no set_var EASYRSA_NS_COMMENT \ "Easy-RSA (~VER~) Generated Certificate" + set_var EASYRSA_TEMP_DIR "$EASYRSA_PKI" set_var EASYRSA_REQ_CN ChangeMe set_var EASYRSA_DIGEST sha256 - set_var EASYRSA_SSL_CONF "$EASYRSA_PKI/openssl-easyrsa.cnf" - set_var EASYRSA_SAFE_CONF "$EASYRSA_PKI/safessl-easyrsa.cnf" + set_var EASYRSA_SSL_CONF \ + "$EASYRSA_PKI/openssl-easyrsa.cnf" + set_var EASYRSA_SAFE_CONF \ + "$EASYRSA_PKI/safessl-easyrsa.cnf" set_var EASYRSA_KDC_REALM "CHANGEME.EXAMPLE.COM" + + set_var EASYRSA_MAX_TEMP 4 + } # => vars_setup() # Verify working environment @@ -5633,8 +5700,9 @@ verify_working_env() { install_data_to_pki x509-types-only # For commands which 'require a PKI' and PKI exists - if [ "$pki_is_required" ] && [ -d "$EASYRSA_PKI" ] - then + if [ "$require_pki" ]; then + # Verify PKI is initialised + verify_pki_init # Temp dir MUST exist if [ -d "$EASYRSA_TEMP_DIR" ]; then @@ -5672,13 +5740,19 @@ verify_working_env - install_data_to_pki vars-setup failed" die "working_safe_ssl_conf must not be set!" } + # Verify CA is initialised + if [ "$require_ca" ]; then + verify_ca_init + fi + # Last setup msg - information "\ -Using SSL: $EASYRSA_OPENSSL $ssl_version -" + information " +Using SSL: +* $EASYRSA_OPENSSL $ssl_version" + else # The directory does not exist - die "\ + user_error "\ Temporary directory does not exist: * $EASYRSA_TEMP_DIR" fi @@ -6206,7 +6280,7 @@ up23_manage_upgrade_23 () return 0 fi else - die "upgrade type must be 'pki' or 'ca'." + user_error "upgrade type must be 'pki' or 'ca'." fi # PKI is potentially suitable for upgrade @@ -6351,7 +6425,9 @@ unset -v \ working_safe_ssl_conf \ user_vars_true \ user_san_true \ - alias_days + alias_days \ + do_build_full \ + error_info # Used by build-ca->cleanup to restore prompt # after user interrupt when using manual password @@ -6534,9 +6610,14 @@ subjectAltName = $val" ;; # Unsupported options --fix-offset) - die "Option $opt is not supported. + user_error "Option $opt is not supported. Use options --startdate and --enddate for fixed dates." ;; + -*) + user_error "\ +Unknown option '$opt'. +Run 'easyrsa help options' for option help." + ;; *) break esac @@ -6544,7 +6625,7 @@ Use options --startdate and --enddate for fixed dates." # fatal error when no value was provided if [ "$is_empty" ]; then [ "$empty_ok" ] || \ - die "Missing value to option: $opt" + user_error "Missing value to option: $opt" fi # fatal error when a number is expected but not provided @@ -6553,10 +6634,10 @@ Use options --startdate and --enddate for fixed dates." (0) # Allow zero only [ "$zero_allowed" ] || \ - die "$opt - Number expected: '$val'" + user_error "$opt - Number expected: '$val'" ;; (*[!1234567890]*|0*) - die "$opt - Number expected: '$val'" + user_error "$opt - Number expected: '$val'" esac fi @@ -6568,15 +6649,23 @@ done cmd="$1" [ "$1" ] && shift # scrape off command +# Establish PKI and CA initialisation requirements # This avoids unnecessary warnings and notices case "$cmd" in - init-pki|clean-all|""|help|-h|--help|--usage|version) - no_pki_required=1 - unset -v pki_is_required + init-pki|clean-all|\ + help|-h|--help|--usage|\ + version|upgrade|'') + unset -v require_pki require_ca ;; *) - pki_is_required=1 - unset -v no_pki_required + require_pki=1 + case "$cmd" in + gen-req|gen-dh|build-ca) + unset -v require_ca + ;; + *) + require_ca=1 + esac esac # Intelligent env-var detection and auto-loading: @@ -6717,7 +6806,7 @@ case "$cmd" in print_version ;; *) - die "\ + user_error "\ Unknown command '$cmd'. Run without commands for usage help." esac