From 48eee21d2ab54674d7bab267c33440781b80cd36 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Thu, 7 Apr 2022 17:18:41 +0100 Subject: [PATCH 01/73] Disallow use of single quote (') in vars file Using single quotes in the vars file does not work: * Either the vars file syntax is corrupted by an unescaped single quote. * Or the SSL library will drop the single quote from the signed certificate. Changes: * Sanitize vars.example - Remove all single quotes. * Search vars for single quote before sourcing it. Closes: #34 Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 23 ++++++++++++++++------- easyrsa3/vars.example | 34 +++++++++++++++++----------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 502f26d..03cacaf 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -249,7 +249,7 @@ Certificate & Request options: (these impact cert/req field values) ./easyrsa help altname --use-algo=ALG : crypto alg to use: choose rsa (default), ec or ed --curve=NAME : for elliptic curve, sets the named curve to use ---copy-ext : Copy included request X509 extensions (namely subjAltName +--copy-ext : Copy included request X509 extensions (namely subjAltName) Organizational DN options: (only used with the 'org' DN mode) (values may be blank for org DN options) @@ -2126,18 +2126,27 @@ Priority should be given to your PKI vars file: if [ -z "$EASYRSA_NO_VARS" ] && [ -z "$want_init_pki" ]; then # If a vars file was located then source it if [ "$vars" ]; then + # Sanitize vars if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then - die "\ -Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration \ -file. Storing sensitive information in the configuration file is not \ -recommended - please remove it from there before continuing." + die " +Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration +file. Storing sensitive information in the configuration file is not +recommended - please remove it from there before continuing. +" fi + if grep -Eq \' "$vars"; then + die " +Single quote (') has been found in the configuration file. +This character is not allowed in the configuration file. +Please remove it before continuing. +" + fi + # shellcheck disable=SC2034 # EASYRSA_CALLER appears unused. EASYRSA_CALLER=1 # shellcheck disable=1090 # can't follow non-constant source. vars . "$vars" - notice "\ -Note: using Easy-RSA configuration from: $vars" + notice "Note: using Easy-RSA configuration from: $vars" else # $vars remains undefined .. no vars found [ "$want_init_pki" ] || warn " No vars file defined! diff --git a/easyrsa3/vars.example b/easyrsa3/vars.example index 3fac814..61d79f5 100644 --- a/easyrsa3/vars.example +++ b/easyrsa3/vars.example @@ -1,22 +1,22 @@ # Easy-RSA 3 parameter settings -# NOTE: If you installed Easy-RSA from your distro's package manager, don't edit +# NOTE: If you installed Easy-RSA from your package manager, do not edit # this file in place -- instead, you should copy the entire easy-rsa directory -# to another location so future upgrades don't wipe out your changes. +# to another location so future upgrades do not wipe out your changes. # HOW TO USE THIS FILE # # vars.example contains built-in examples to Easy-RSA settings. You MUST name -# this file 'vars' if you want it to be used as a configuration file. If you do +# this file "vars" if you want it to be used as a configuration file. If you do # not, it WILL NOT be automatically read when you call easyrsa commands. # # It is not necessary to use this config file unless you wish to change # operational defaults. These defaults should be fine for many uses without the -# need to copy and edit the 'vars' file. +# need to copy and edit the "vars" file. # # All of the editable settings are shown commented and start with the command -# 'set_var' -- this means any set_var command that is uncommented has been -# modified by the user. If you're happy with a default, there is no need to +# "set_var" -- this means any set_var command that is uncommented has been +# modified by the user. If you are happy with a default, there is no need to # define the value to its default. # NOTES FOR WINDOWS USERS @@ -26,14 +26,14 @@ # the openssl binary might look like this: # "C:/Program Files/OpenSSL-Win32/bin/openssl.exe" -# A little housekeeping: DON'T EDIT THIS SECTION +# A little housekeeping: DO NOT EDIT THIS SECTION # -# Easy-RSA 3.x doesn't source into the environment directly. +# Easy-RSA 3.x does not source into the environment directly. # Complain if a user tries to do this: if [ -z "$EASYRSA_CALLER" ]; then - echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2 + echo "You appear to be sourcing an Easy-RSA *vars* file." >&2 echo "This is no longer necessary and is disallowed. See the section called" >&2 - echo "'How to use this file' near the top comments for more details." >&2 + echo "*How to use this file* near the top comments for more details." >&2 return 1 fi @@ -78,7 +78,7 @@ fi # Define X509 DN mode. # This is used to adjust what elements are included in the Subject field as the DN # (this is the "Distinguished Name.") -# Note that in cn_only mode the Organizational fields further below aren't used. +# Note that in cn_only mode the Organizational fields further below are not used. # # Choices are: # cn_only - use just a CN value @@ -86,9 +86,9 @@ fi #set_var EASYRSA_DN "cn_only" -# Organizational fields (used with 'org' mode and ignored in 'cn_only' mode.) +# Organizational fields (used with "org" mode and ignored in "cn_only" mode.) # These are the default values for fields which will be placed in the -# certificate. Don't leave any of these fields blank, although interactively +# certificate. Do not leave any of these fields blank, although interactively # you may omit any specific field by typing the "." symbol (not valid for # email.) @@ -171,9 +171,9 @@ fi # Broken shell command aliases: If you have a largely broken shell that is # missing any of these POSIX-required commands used by Easy-RSA, you will need # to define an alias to the proper path for the command. The symptom will be -# some form of a 'command not found' error from your shell. This means your +# some form of a "command not found" error from your shell. This means your # shell is BROKEN, but you can hack around it here if you really need. These -# shown values are not defaults: it is up to you to know what you're doing if +# shown values are not defaults: it is up to you to know what you are doing if # you touch these. # #alias awk="/alt/bin/awk" @@ -182,9 +182,9 @@ fi # X509 extensions directory: # If you want to customize the X509 extensions used, set the directory to look # for extensions here. Each cert type you sign must have a matching filename, -# and an optional file named 'COMMON' is included first when present. Note that +# and an optional file named "COMMON" is included first when present. Note that # when undefined here, default behaviour is to look in $EASYRSA_PKI first, then -# fallback to $EASYRSA for the 'x509-types' dir. You may override this +# fallback to $EASYRSA for the "x509-types" dir. You may override this # detection with an explicit dir here. # #set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types" From 75bc3d1ed5570a374d4730aefd52013a415cc5e7 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Thu, 7 Apr 2022 18:02:31 +0100 Subject: [PATCH 02/73] Do not require/use Extended Regular Expression Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 03cacaf..40b9ef8 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2134,7 +2134,7 @@ file. Storing sensitive information in the configuration file is not recommended - please remove it from there before continuing. " fi - if grep -Eq \' "$vars"; then + if grep -q "'" "$vars"; then die " Single quote (') has been found in the configuration file. This character is not allowed in the configuration file. From fe47eba2c0ec697ba09581b26bc49b891e346031 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Thu, 7 Apr 2022 22:09:50 +0100 Subject: [PATCH 03/73] Style improvements to vars_setup() Make detecting all vars files more simple and robust. Improve warning and error messages. Favour PKI/vars, wiith bias. * Minor changes to output format for warn() and notice() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 121 ++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 502f26d..b65cc8e 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -286,17 +286,17 @@ $1" 1>&2 # non-fatal warning output warn() { [ "$EASYRSA_SILENT" ] && return - print "* Warning: + print "* WARNING: -$1" 1>&2 + $1 +" 1>&2 } # => warn() # informational notices to stdout notice() { [ "$EASYRSA_SILENT" ] && return [ "$EASYRSA_BATCH" ] && return - print " -$1" + print "* Notice: $1" } # => notice() # yes/no case-insensitive match (operates on stdin pipe) @@ -475,9 +475,8 @@ verify_ssl_lib () { 3) no_password='-noenc' ;; *) die "Unsupported SSL library: $osslv_major" esac - print "\ -Using SSL: $EASYRSA_OPENSSL $("$EASYRSA_OPENSSL" version)" ;; - *) die "\ + notice "Using SSL: $EASYRSA_OPENSSL $("$EASYRSA_OPENSSL" version)" ;; + *) die " Missing or invalid OpenSSL Expected to find openssl command at: $EASYRSA_OPENSSL" ;; esac @@ -485,7 +484,7 @@ Expected to find openssl command at: $EASYRSA_OPENSSL" ;; EASYRSA_SSL_OK=1 # Verify EASYRSA_SSL_CONF file exists - [ -f "$EASYRSA_SSL_CONF" ] || die "\ + [ -f "$EASYRSA_SSL_CONF" ] || die " The OpenSSL config file cannot be found. Expected location: $EASYRSA_SSL_CONF" } # => verify_ssl_lib () @@ -2014,10 +2013,10 @@ $in_file" This file is not a valid $type file: $in_file" - notice "\ -Showing $type details for 'ca'. -This file is stored at: -$in_file + notice " + Showing $type details for 'ca'. + This file is stored at: + $in_file " # shellcheck disable=SC2086 # Ignore unquoted variables @@ -2046,15 +2045,18 @@ vars_setup() { # Program dir vars - This location is least wanted. prog_vars="${prog_dir}/vars" + # set up PKI path vars - Top preference pki_vars="${EASYRSA_PKI:-$PWD/pki}/vars" - keep_pki_vars="$pki_vars" + expected_pki_vars="$pki_vars" + # Some other place vars, out of scope. if [ "$EASYRSA" ]; then easy_vars="${EASYRSA}/vars" else unset -v easy_vars fi + # vars of last resort - Eventually this file must be removed from EasyRSA pwd_vars="$PWD/vars" @@ -2072,53 +2074,58 @@ vars_setup() { else # if NOT $want_init_pki if [ -z "$want_init_pki" ]; then + + # Clear flags - This is the preferred order to find: + unset -v e_pki_vars e_easy_vars e_pwd_vars e_prog_vars found_vars + # PKI location, if present: - [ -e "$pki_vars" ] || unset -v pki_vars - # program location: - [ -e "$prog_vars" ] || unset -v prog_vars + { [ -e "$pki_vars" ] && e_pki_vars=1; } || unset -v pki_vars + # EASYRSA, if defined: - [ -e "$easy_vars" ] || unset -v easy_vars - # vars of last resort - Eventually this file must be removed from EasyRSA - [ -e "$pwd_vars" ] || unset -v pwd_vars + { [ -e "$easy_vars" ] && e_easy_vars=1; } || unset -v easy_vars + + # Eventually the file below must be removed from EasyRSA + # vars of last resort + { [ -e "$pwd_vars" ] && e_pwd_vars=1; } || unset -v pwd_vars + + # program location: + { [ -e "$prog_vars" ] && e_prog_vars=1; } || unset -v prog_vars # Allow only one vars to be found, No exceptions! - too_many_vars= - if [ "$pki_vars" ]; then - if [ "$pwd_vars" ] || [ "$easy_vars" ] || [ "$prog_vars" ]; then - too_many_vars=1 - fi - elif [ "$prog_vars" ]; then - if [ "$pwd_vars" ] || [ "$easy_vars" ]; then - too_many_vars=1 - fi - elif [ "$easy_vars" ]; then - if [ "$pwd_vars" ]; then - too_many_vars=1 - fi - elif [ "$pwd_vars" ]; then - warn "Move your vars file to your PKI folder, where it is safe!" - else - warn "No vars file found! Please create one in your PKI folder." - fi + found_vars="$((e_pki_vars + e_easy_vars + e_pwd_vars + e_prog_vars))" - # If too_many_vars then output user info and exit - if [ "$too_many_vars" ]; then - [ "$pki_vars" ] && print "Found: $pki_vars" - [ "$prog_vars" ] && print "Found: $prog_vars" - [ "$easy_vars" ] && print "Found: $easy_vars" - [ "$pwd_vars" ] && print "Found: $pwd_vars" + # If found_vars greater than 1 then output user info and exit + case "$found_vars" in + 0) + unset -v found_vars + ;; + 1) : ;; #ok + *) + [ "$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 "Conflicting 'vars' files found. Priority should be given to your PKI vars file: -* $keep_pki_vars + +* $expected_pki_vars " - fi + esac # If a SINGLE vars file is found then assign $vars - [ "$pwd_vars" ] && vars="$pwd_vars" - [ "$easy_vars" ] && vars="$easy_vars" - [ "$prog_vars" ] && vars="$prog_vars" - [ "$pki_vars" ] && vars="$pki_vars" + if [ "$found_vars" ] && [ "$e_pki_vars" ]; then + vars="${pki_vars}" + # Final warnings + elif [ -z "$found_vars" ]; then + vars= + warn "No vars file found! Please create one in your PKI folder." + else + # This can only be one: + vars="${easy_vars}${pwd_vars}${prog_vars}" + [ -e "$vars" ] || die "undefined state, vars: $vars" + warn "Move your vars file to your PKI folder, where it is safe!" + fi fi # If $EASYRSA_NO_VARS is defined (not blank) then do not use vars @@ -2127,24 +2134,20 @@ Priority should be given to your PKI vars file: # If a vars file was located then source it if [ "$vars" ]; then if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then - die "\ -Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration \ -file. Storing sensitive information in the configuration file is not \ + die " +Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration +file. Storing sensitive information in the configuration file is not recommended - please remove it from there before continuing." fi # shellcheck disable=SC2034 # EASYRSA_CALLER appears unused. EASYRSA_CALLER=1 # shellcheck disable=1090 # can't follow non-constant source. vars . "$vars" - notice "\ -Note: using Easy-RSA configuration from: $vars" + notice "Note: using Easy-RSA configuration from: $vars" else # $vars remains undefined .. no vars found - [ "$want_init_pki" ] || warn " No vars file defined! - -Expected to find 'vars' file: -* $keep_pki_vars -" + # Warning already issued! + : # ok fi else # EASYRSA_NO_VARS is defined or want_init_pki, no vars is required. From b4ab1713c1218a878bad2e913af3bb0a6fdf43c1 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 8 Apr 2022 02:11:17 +0100 Subject: [PATCH 04/73] Remove all use of single quote (') from vars.example A step toward a solution to #364 Signed-off-by: Richard T Bonhomme --- easyrsa3/vars.example | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/easyrsa3/vars.example b/easyrsa3/vars.example index 3fac814..61d79f5 100644 --- a/easyrsa3/vars.example +++ b/easyrsa3/vars.example @@ -1,22 +1,22 @@ # Easy-RSA 3 parameter settings -# NOTE: If you installed Easy-RSA from your distro's package manager, don't edit +# NOTE: If you installed Easy-RSA from your package manager, do not edit # this file in place -- instead, you should copy the entire easy-rsa directory -# to another location so future upgrades don't wipe out your changes. +# to another location so future upgrades do not wipe out your changes. # HOW TO USE THIS FILE # # vars.example contains built-in examples to Easy-RSA settings. You MUST name -# this file 'vars' if you want it to be used as a configuration file. If you do +# this file "vars" if you want it to be used as a configuration file. If you do # not, it WILL NOT be automatically read when you call easyrsa commands. # # It is not necessary to use this config file unless you wish to change # operational defaults. These defaults should be fine for many uses without the -# need to copy and edit the 'vars' file. +# need to copy and edit the "vars" file. # # All of the editable settings are shown commented and start with the command -# 'set_var' -- this means any set_var command that is uncommented has been -# modified by the user. If you're happy with a default, there is no need to +# "set_var" -- this means any set_var command that is uncommented has been +# modified by the user. If you are happy with a default, there is no need to # define the value to its default. # NOTES FOR WINDOWS USERS @@ -26,14 +26,14 @@ # the openssl binary might look like this: # "C:/Program Files/OpenSSL-Win32/bin/openssl.exe" -# A little housekeeping: DON'T EDIT THIS SECTION +# A little housekeeping: DO NOT EDIT THIS SECTION # -# Easy-RSA 3.x doesn't source into the environment directly. +# Easy-RSA 3.x does not source into the environment directly. # Complain if a user tries to do this: if [ -z "$EASYRSA_CALLER" ]; then - echo "You appear to be sourcing an Easy-RSA 'vars' file." >&2 + echo "You appear to be sourcing an Easy-RSA *vars* file." >&2 echo "This is no longer necessary and is disallowed. See the section called" >&2 - echo "'How to use this file' near the top comments for more details." >&2 + echo "*How to use this file* near the top comments for more details." >&2 return 1 fi @@ -78,7 +78,7 @@ fi # Define X509 DN mode. # This is used to adjust what elements are included in the Subject field as the DN # (this is the "Distinguished Name.") -# Note that in cn_only mode the Organizational fields further below aren't used. +# Note that in cn_only mode the Organizational fields further below are not used. # # Choices are: # cn_only - use just a CN value @@ -86,9 +86,9 @@ fi #set_var EASYRSA_DN "cn_only" -# Organizational fields (used with 'org' mode and ignored in 'cn_only' mode.) +# Organizational fields (used with "org" mode and ignored in "cn_only" mode.) # These are the default values for fields which will be placed in the -# certificate. Don't leave any of these fields blank, although interactively +# certificate. Do not leave any of these fields blank, although interactively # you may omit any specific field by typing the "." symbol (not valid for # email.) @@ -171,9 +171,9 @@ fi # Broken shell command aliases: If you have a largely broken shell that is # missing any of these POSIX-required commands used by Easy-RSA, you will need # to define an alias to the proper path for the command. The symptom will be -# some form of a 'command not found' error from your shell. This means your +# some form of a "command not found" error from your shell. This means your # shell is BROKEN, but you can hack around it here if you really need. These -# shown values are not defaults: it is up to you to know what you're doing if +# shown values are not defaults: it is up to you to know what you are doing if # you touch these. # #alias awk="/alt/bin/awk" @@ -182,9 +182,9 @@ fi # X509 extensions directory: # If you want to customize the X509 extensions used, set the directory to look # for extensions here. Each cert type you sign must have a matching filename, -# and an optional file named 'COMMON' is included first when present. Note that +# and an optional file named "COMMON" is included first when present. Note that # when undefined here, default behaviour is to look in $EASYRSA_PKI first, then -# fallback to $EASYRSA for the 'x509-types' dir. You may override this +# fallback to $EASYRSA for the "x509-types" dir. You may override this # detection with an explicit dir here. # #set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types" From 0db21c3dd466a554b173e46ead4feb21417a373a Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 8 Apr 2022 19:47:27 +0100 Subject: [PATCH 05/73] Detect Windows and Git-for-Windows bash Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index b65cc8e..be0e4b6 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -280,6 +280,10 @@ die() { Easy-RSA error: $1" 1>&2 + + [ "$EASYRSA_WIN" ] && print "$EASYRSA_WIN" + [ "$EASYRSA_WIN_GIT_BASH" ] && print "$EASYRSA_WIN_GIT_BASH" + exit "${2:-1}" } # => die() @@ -2262,6 +2266,7 @@ set_var() { } #=> set_var() + ############################################################################ # Upgrade v2 PKI to v3 PKI @@ -2969,6 +2974,31 @@ init-pki|clean-all) want_init_pki=1 ;; *) unset -v want_init_pki esac +# Detect Windows +if [ "$OS" ]; then + case "$OS" in + Windows_NT) + EASYRSA_WIN=Windows_NT + ;; + *) EASYRSA_WIN="$OS" + esac +else + unset -v EASYRSA_WIN +fi + +# Detect Windows git/bash +if [ "$EXEPATH" ]; then + case "${EXEPATH##*\\}" in + Git) + EASYRSA_WIN_GIT_BASH=Git-bash + [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl + ;; + *) EASYRSA_WIN_GIT_BASH="$EXEPATH" + esac +else + unset -v EASYRSA_WIN_GIT_BASH +fi + # Intelligent env-var detection and auto-loading: vars_setup From 1844ec10afc357dbdf73fa89ca756e346612f7e3 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 8 Apr 2022 20:02:30 +0100 Subject: [PATCH 06/73] Remove old comment for upgrade function Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 4 ---- 1 file changed, 4 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index be0e4b6..87c7b5f 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -3012,10 +3012,6 @@ trap "exit 3" 3 trap "exit 6" 6 trap "exit 14" 15 -# Upgrade: EasyRSA v2.x to EasyRSA v3.x -# Upgrade: EasyRSA < v3.0.6 to v3.0.6+ -#up23_manage_upgrade_23 - # determine how we were called, then hand off to the function responsible case "$cmd" in init-pki|clean-all) From 29eaa061c2d730616e351de13ae409e7146eeb49 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 8 Apr 2022 20:14:46 +0100 Subject: [PATCH 07/73] Simplify detecting Windows Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 87c7b5f..dfffbac 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2975,29 +2975,20 @@ init-pki|clean-all) want_init_pki=1 ;; esac # Detect Windows -if [ "$OS" ]; then - case "$OS" in - Windows_NT) - EASYRSA_WIN=Windows_NT - ;; +case "$OS" in + '') unset -v EASYRSA_WIN ;; *) EASYRSA_WIN="$OS" - esac -else - unset -v EASYRSA_WIN -fi +esac # Detect Windows git/bash -if [ "$EXEPATH" ]; then - case "${EXEPATH##*\\}" in +case "${EXEPATH##*\\}" in Git) EASYRSA_WIN_GIT_BASH=Git-bash [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl ;; + '') unset -v EASYRSA_WIN_GIT_BASH ;; *) EASYRSA_WIN_GIT_BASH="$EXEPATH" - esac -else - unset -v EASYRSA_WIN_GIT_BASH -fi +esac # Intelligent env-var detection and auto-loading: vars_setup From 1e7fb8243a4f4ae0de3040d6a33844f3be7f0f83 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 8 Apr 2022 20:33:25 +0100 Subject: [PATCH 08/73] Silence cleanup() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index b65cc8e..b22288f 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -350,7 +350,7 @@ cleanup() { [ -z "$EASYRSA_TEMP_DIR_session" ] || rm -rf "$EASYRSA_TEMP_DIR_session" # shellcheck disable=SC3040 (stty echo 2>/dev/null) || { (set -o echo 2>/dev/null) && set -o echo; } - echo "" # just to get a clean line + [ "$EASYRSA_SILENT" ] || echo "" # just to get a clean line } # => cleanup() easyrsa_openssl() { From ccec36d3eaf8f2c0a3cbf5ce723fdb7acb54e363 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 8 Apr 2022 21:32:12 +0100 Subject: [PATCH 09/73] Fold vars_source_check() back into verify_pki_init() vars_source_check() is ONLY used by verify_pki_init(), remove the extra function. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index b22288f..9369cea 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -425,12 +425,6 @@ easyrsa_openssl() { return $err } # => easyrsa_openssl -vars_source_check() { - # Check for defined EASYRSA_PKI - [ -n "$EASYRSA_PKI" ] || die "\ -EASYRSA_PKI env-var undefined" -} # => vars_source_check() - # Verify supplied curve exists and generate curve file if needed verify_curve_ec() { if ! "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" > /dev/null; then @@ -493,8 +487,11 @@ Expected location: $EASYRSA_SSL_CONF" verify_pki_init() { help_note="Run easyrsa without commands for usage and command help." + # Check for defined EASYRSA_PKI + [ -n "$EASYRSA_PKI" ] || die "\ +EASYRSA_PKI env-var undefined" + # check that the pki dir exists - vars_source_check [ -d "$EASYRSA_PKI" ] || die "\ EASYRSA_PKI does not exist (perhaps you need to run init-pki)? Expected to find the EASYRSA_PKI at: $EASYRSA_PKI From 057be57825616199d125dfffbc5abfa9efaae792 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 9 Apr 2022 17:52:42 +0100 Subject: [PATCH 10/73] Remove EASYRSA_EXTRA_EXTS code injection inside 'sed' script. This code injection 'attempted' to insert a temp-file created with EASYRSA_EXTRA_EXTS data. The insertion would take place at the awk script marker "^#%EXTRA_EXTS%". However, this marker has already been replaced by gen_req(), thus the condition to insert the code was never met and the code injection has never taken place. Testing this, I created a new marker for this injection to key from and, due to the file-name variable not having been quoted, the test fails when the file name has a space in it. General tidy-up of easyrsa_openssl() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 117 +++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 65 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 9369cea..1c21363 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -353,76 +353,63 @@ cleanup() { [ "$EASYRSA_SILENT" ] || echo "" # just to get a clean line } # => cleanup() +# Easy-RSA meta-wrapper for SSL easyrsa_openssl() { - openssl_command=$1; shift + openssl_command="$1"; shift - case $openssl_command in - makesafeconf) has_config=true;; - ca|req|srp|ts) has_config=true;; - *) has_config=false;; + case "$openssl_command" in + makesafeconf) has_config=true ;; + ca|req|srp|ts) has_config=true ;; + *) has_config=false esac - case "$osslv_major" in - 3) - case $openssl_command in - genpkey) has_config=true;; - *) : ;; # ok - esac + # OpenSSL 1x genpkey does not support -config - Not as documented: + # https://www.openssl.org/docs/manmaster/man1/openssl-genpkey.html + if [ "$osslv_major" = 3 ] && [ "$openssl_command" = genpkey ]; then + has_config=true + fi + + case "$has_config" in + false) + "$EASYRSA_OPENSSL" "$openssl_command" "$@" || return ;; - 1|2) : ;; # ok - LibreSSL 2.x - '') : ;; # Unset then this is init-pki - *) die "Unsupported openssl version: $osslv_major" + true) + # Make LibreSSL safe config file from OpenSSL config file + easyrsa_openssl_conf="$(easyrsa_mktemp)" || \ + die "easyrsa_openssl - Failed to create temporary file" + + sed \ + -e "s\`ENV::EASYRSA\`EASYRSA\`g" \ + -e "s\`\$dir\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_PKI\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_CERT_EXPIRE\`$EASYRSA_CERT_EXPIRE\`g" \ + -e "s\`\$EASYRSA_CRL_DAYS\`$EASYRSA_CRL_DAYS\`g" \ + -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ + -e "s\`\$EASYRSA_KEY_SIZE\`$EASYRSA_KEY_SIZE\`g" \ + -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ + -e "s\`\$EASYRSA_DN\`$EASYRSA_DN\`g" \ + -e "s\`\$EASYRSA_REQ_COUNTRY\`$EASYRSA_REQ_COUNTRY\`g" \ + -e "s\`\$EASYRSA_REQ_PROVINCE\`$EASYRSA_REQ_PROVINCE\`g" \ + -e "s\`\$EASYRSA_REQ_CITY\`$EASYRSA_REQ_CITY\`g" \ + -e "s\`\$EASYRSA_REQ_ORG\`$EASYRSA_REQ_ORG\`g" \ + -e "s\`\$EASYRSA_REQ_OU\`$EASYRSA_REQ_OU\`g" \ + -e "s\`\$EASYRSA_REQ_CN\`$EASYRSA_REQ_CN\`g" \ + -e "s\`\$EASYRSA_REQ_EMAIL\`$EASYRSA_REQ_EMAIL\`g" \ + "$EASYRSA_SSL_CONF" > "$easyrsa_openssl_conf" || \ + die "easyrsa_openssl - Failed to make temporary config" + + if [ "$openssl_command" = "makesafeconf" ]; then + # move temp file to safessl-easyrsa.cnf + mv "$easyrsa_openssl_conf" "$EASYRSA_SAFE_CONF" || \ + die "easyrsa_openssl - makesafeconf failed" + else + # Exec SSL with -config temp-file + "$EASYRSA_OPENSSL" "$openssl_command" \ + -config "$easyrsa_openssl_conf" "$@" || return + fi + ;; + *) die "Undefined state: has_config is $has_config" esac - - if ! $has_config; then - "$EASYRSA_OPENSSL" "$openssl_command" "$@" - return - fi - - easyrsa_openssl_conf=$(easyrsa_mktemp) || die "Failed to create temporary file" - easyrsa_extra_exts= - if [ -n "$EASYRSA_EXTRA_EXTS" ]; then - easyrsa_extra_exts=$(easyrsa_mktemp) || die "Failed to create temporary file" - cat >"$easyrsa_extra_exts" <<-EOF - req_extensions = req_extra - [ req_extra ] - $EASYRSA_EXTRA_EXTS - EOF - fi - - # Make LibreSSL safe config file from OpenSSL config file - sed \ - -e "s\`ENV::EASYRSA\`EASYRSA\`g" \ - -e "s\`\$dir\`$EASYRSA_PKI\`g" \ - -e "s\`\$EASYRSA_PKI\`$EASYRSA_PKI\`g" \ - -e "s\`\$EASYRSA_CERT_EXPIRE\`$EASYRSA_CERT_EXPIRE\`g" \ - -e "s\`\$EASYRSA_CRL_DAYS\`$EASYRSA_CRL_DAYS\`g" \ - -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ - -e "s\`\$EASYRSA_KEY_SIZE\`$EASYRSA_KEY_SIZE\`g" \ - -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ - -e "s\`\$EASYRSA_DN\`$EASYRSA_DN\`g" \ - -e "s\`\$EASYRSA_REQ_COUNTRY\`$EASYRSA_REQ_COUNTRY\`g" \ - -e "s\`\$EASYRSA_REQ_PROVINCE\`$EASYRSA_REQ_PROVINCE\`g" \ - -e "s\`\$EASYRSA_REQ_CITY\`$EASYRSA_REQ_CITY\`g" \ - -e "s\`\$EASYRSA_REQ_ORG\`$EASYRSA_REQ_ORG\`g" \ - -e "s\`\$EASYRSA_REQ_OU\`$EASYRSA_REQ_OU\`g" \ - -e "s\`\$EASYRSA_REQ_CN\`$EASYRSA_REQ_CN\`g" \ - -e "s\`\$EASYRSA_REQ_EMAIL\`$EASYRSA_REQ_EMAIL\`g" \ - ${EASYRSA_EXTRA_EXTS:+-e "/^#%EXTRA_EXTS%/r $easyrsa_extra_exts"} \ - "$EASYRSA_SSL_CONF" > "$easyrsa_openssl_conf" || - die "Failed to update $easyrsa_openssl_conf" - - if [ "$openssl_command" = "makesafeconf" ]; then - cp "$easyrsa_openssl_conf" "$EASYRSA_SAFE_CONF" - err=$? - else - "$EASYRSA_OPENSSL" "$openssl_command" -config "$easyrsa_openssl_conf" "$@" - err=$? - fi - - rm -f "$easyrsa_openssl_conf" - rm -f "$easyrsa_extra_exts" - return $err } # => easyrsa_openssl # Verify supplied curve exists and generate curve file if needed @@ -469,7 +456,7 @@ verify_ssl_lib () { 3) no_password='-noenc' ;; *) die "Unsupported SSL library: $osslv_major" esac - notice "Using SSL: $EASYRSA_OPENSSL $("$EASYRSA_OPENSSL" version)" ;; + notice "Using SSL: $EASYRSA_OPENSSL $val" ;; *) die " Missing or invalid OpenSSL Expected to find openssl command at: $EASYRSA_OPENSSL" ;; From 484bc56acc19091b1373198ccfc1b5b6f96396ad Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 9 Apr 2022 19:28:18 +0100 Subject: [PATCH 11/73] Remove redundant Create $EASYRSA_SSL_CONF The config file is unambiguously and previously created by install_data_to_pki(). The config file location is exported in the previous command. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 9 --------- 1 file changed, 9 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 9369cea..2eac27d 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2225,15 +2225,6 @@ recommended - please remove it from there before continuing." die "Failed to find Safe-SSL config file." fi - # Upgrade to 306: Create $EASYRSA_SSL_CONF if it does not exist - # but only if $EASYRSA_PKI exists. - if [ -d "$EASYRSA_PKI" ] && [ -e "$EASYRSA/openssl-easyrsa.cnf" ] && \ - [ ! -e "$EASYRSA_SSL_CONF" ] - then - cp "$EASYRSA/openssl-easyrsa.cnf" "$EASYRSA_SSL_CONF" - easyrsa_openssl makesafeconf - fi - else # If the directory does not exist then we have not run init-pki if mkdir -p "$EASYRSA_TEMP_DIR"; then From 4b75783375a4e92e4a7f23dca053c6b6ba77b345 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 9 Apr 2022 21:40:44 +0100 Subject: [PATCH 12/73] Upgrade Linux based unit test to OpenSSL 3.0.2 - 15 Mar 2022 (Library: OpenSSL 3.0.2 15 Mar 2022) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 2 +- op-test.sh | 36 ++++++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 5 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 2eac27d..4cf89e9 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -339,7 +339,7 @@ easyrsa_mktemp() { die "Could not create temporary directory '$EASYRSA_TEMP_DIR_session'. Permission or concurrency problem?" [ -d "$EASYRSA_TEMP_DIR_session" ] || die "Temporary directory '$EASYRSA_TEMP_DIR_session' does not exist" - tempfile="$EASYRSA_TEMP_DIR_session/tmp.$($EASYRSA_OPENSSL rand -hex 3)" || return + tempfile="$EASYRSA_TEMP_DIR_session/tmp.$("$EASYRSA_OPENSSL" rand -hex 3)" || return printf "" > "$tempfile" || return echo "$tempfile" diff --git a/op-test.sh b/op-test.sh index 21c5cc0..6f15c70 100644 --- a/op-test.sh +++ b/op-test.sh @@ -32,8 +32,10 @@ if [ -e "shellcheck" ] && [ "$EASYRSA_NIX" ]; then fi elif [ "$EASYRSA_NIX" ]; then github_target='OpenVPN/easyrsa-unit-tests/master/shellcheck' - curl -O "${github_url}/${github_target}" - [ -e "shellcheck" ] || { echo "shellcheck download failed."; exit 9; } + curl -f -O "${github_url}/${github_target}" || { + echo "shellcheck download failed." + exit 9 + } chmod +x shellcheck ./shellcheck -V if [ -e easyrsa3/easyrsa ]; then @@ -54,9 +56,35 @@ fi estat=0 if [ -e "easyrsa-unit-tests.sh" ]; then - if sh easyrsa-unit-tests.sh "$verb"; then + + + if : ; then + + + +# sh easyrsa-unit-tests.sh "$verb"; then + + + if [ "$EASYRSA_NIX" ] && [ "$EASYRSA_BY_TINCANTECH" ]; then - sh easyrsa-unit-tests.sh "$verb" -x || estat=2 + + + # two tests in one: x509-alt and ossl-3 + # Not without --x509-alt, waiting for merge + + # openssl v3 + if [ ! -e ./openssl ]; then + github_target='OpenVPN/easyrsa-unit-tests/master/openssl' + curl -f -O "${github_url}/${github_target}" || { + echo "openssl download failed." + exit 9 + } + fi + chmod +x openssl + ./openssl version + export EASYRSA_OPENSSL="${PWD}/openssl" + sh easyrsa-unit-tests.sh "$verb" || estat=2 + #rm ./openssl fi else estat=1 From 538f3eada62d297d0ae7da0251b2bc3b4efd5a55 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 9 Apr 2022 21:44:51 +0100 Subject: [PATCH 13/73] Enable OpenSSL version 3 unit tests Signed-off-by: Richard T Bonhomme --- .github/workflows/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 0cc196e..158993d 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest env: - #EASYRSA_BY_TINCANTECH: 1 + EASYRSA_BY_TINCANTECH: 1 EASYRSA_REMOTE_CI: 1 EASYRSA_NIX: 1 TERM: xterm-256color From a482caa79b586809296a2746fdae2abf205e835d Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 9 Apr 2022 22:00:03 +0100 Subject: [PATCH 14/73] Unit test - Temporarily disable shellcheck Signed-off-by: Richard T Bonhomme --- op-test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/op-test.sh b/op-test.sh index 6f15c70..f012f00 100644 --- a/op-test.sh +++ b/op-test.sh @@ -19,6 +19,8 @@ done github_url='https://raw.githubusercontent.com' +# disable 'shellcheck' in favour of 'openssl3' +unset -v enable_shellcheck if [ "$enable_shellcheck" ]; then if [ -e "shellcheck" ] && [ "$EASYRSA_NIX" ]; then From adc03b5a5d4cc1bc242d50e6d88103380dab653d Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 9 Apr 2022 22:40:22 +0100 Subject: [PATCH 15/73] Enable unit test with OpenSSL version 3 on REMOTE-CI Signed-off-by: Richard T Bonhomme --- op-test.sh | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/op-test.sh b/op-test.sh index f012f00..c8a37db 100644 --- a/op-test.sh +++ b/op-test.sh @@ -77,14 +77,14 @@ if [ -e "easyrsa-unit-tests.sh" ]; then # openssl v3 if [ ! -e ./openssl ]; then github_target='OpenVPN/easyrsa-unit-tests/master/openssl' - curl -f -O "${github_url}/${github_target}" || { - echo "openssl download failed." - exit 9 - } + curl -SO "${github_url}/${github_target}" || + printf '%s\n' "openssl download failed." fi + chmod +x openssl ./openssl version export EASYRSA_OPENSSL="${PWD}/openssl" + printf '%s\n' "* exported EASYRSA_OPENSSL:" " ${PWD}/openssl" " $EASYRSA_OPENSSL" sh easyrsa-unit-tests.sh "$verb" || estat=2 #rm ./openssl fi @@ -95,6 +95,29 @@ else github_target='OpenVPN/easyrsa-unit-tests/master/easyrsa-unit-tests.sh' curl -O "${github_url}/${github_target}" [ -e "easyrsa-unit-tests.sh" ] || { echo "Unit-test download failed."; exit 9; } + + + if [ "$EASYRSA_NIX" ] && [ "$EASYRSA_BY_TINCANTECH" ]; then + + + # two tests in one: x509-alt and ossl-3 + # Not without --x509-alt, waiting for merge + + # openssl v3 + if [ ! -e ./openssl ]; then + github_target='OpenVPN/easyrsa-unit-tests/master/openssl' + curl -SO "${github_url}/${github_target}" || + printf '%s\n' "openssl download failed." + fi + + chmod +x openssl + ./openssl version + export EASYRSA_OPENSSL="${PWD}/openssl" + printf '%s\n' "* exported EASYRSA_OPENSSL:" " ${PWD}/openssl" " $EASYRSA_OPENSSL" + sh easyrsa-unit-tests.sh "$verb" || estat=2 + #rm ./openssl + fi + if sh easyrsa-unit-tests.sh "$verb"; then : # ok else From f79b66aba7d38a7edccb89043ff498f206edc483 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 15:36:30 +0100 Subject: [PATCH 16/73] op-test.sh - Total rewrite Signed-off-by: Richard T Bonhomme --- op-test.sh | 440 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 336 insertions(+), 104 deletions(-) diff --git a/op-test.sh b/op-test.sh index c8a37db..b4f6f24 100644 --- a/op-test.sh +++ b/op-test.sh @@ -4,127 +4,359 @@ # and executes that - allows for disconnected testing from the easy-rsa # repo with TravisCI. -verb='-v' -enable_shellcheck=1 +# log +log () { + [ "$disable_log" ] && return + if printf '%s\n' "* $*"; then + return + else + echo "printf failed" + exit 9 + fi +} # => log () + +# clean up +clean_up () { + if [ "$no_delete" ]; then + log "saved final state.." + else + if [ "$EASYRSA_NIX" ]; then + [ "$keep_eut" ] || rm -f "$utest_bin" + [ "$keep_sc" ] || rm -f "$sc_bin" + [ "$keep_ssl" ] || rm -f "$ssl_bin" + fi + fi +} # => clean_up () + +# curl download and openssl hash +# wing it .. +curl_it () { + #log "BEGIN: curl_it" + if [ "$#" -eq 2 ]; then + file="$1" + hash="$2" + else + log "> Usage: " + return 1 + fi + + if [ "$enable_curl" ]; then + : # ok + else + log "> curl disabled" + return 0 + fi + + # valid target + case "$file" in + easyrsa-unit-tests.sh) + unset -v require_hash + ;; + shellcheck|openssl) + require_hash=1 + ;; + *) + log "> invalid target: $file" + return 1 + esac + + # download + if [ "$enable_curl" ]; then + log "> download: ${gh_url}/${file}" + curl -SO "${gh_url}/${file}" || \ + log "> download failed: ${file}" + else + log "> curl disabled" + fi + + # hash download + if [ "${require_hash}" ]; then + if [ -e "${file}" ]; then + log "> hash ${file}" + temp_hash="$(openssl sha256 "${file}")" + log "temp_hash: $temp_hash" + log "hash : $hash" + if [ "$temp_hash" = "$hash" ]; then + : # OK - hash is good + else + log "> hash failed: ${file}" + return 1 + fi + else + log "> file missing: ${file}" + return 1 + fi + else + if [ -e "${file}" ]; then + : # ok - file is here + else + log "> file missing: ${file}" + return 1 + fi + fi +} # => curl_it () + +################################################################################ + +# RUN unit test +run_unit_test () +{ + if [ "${utest_bin_ok}" ] && [ "${ssl_bin_ok}" ]; then + + # Start unit tests + log ">>> BEGIN unit tests:" + + if [ "${dry_run}" ]; then + log "<> sh ${utest_bin} ${verb}" + estat=1 + else + log ">>>>>>: sh ${utest_bin} ${verb}" + sh "${utest_bin}" "${verb}" + + #if sh "${utest_bin}" "${verb}" -v; then + # estat=0 + #else + # estat=1 + #fi + + # TODO: dispose of 'estat' garbage + estat=1 # This is a bug and an error .. fix it. + fi + + log "<<< END unit tests:" + + else + log "unit-test abandoned" + estat=1 + fi +} # => run_unit_test () + +######################################## + +## DOWNLOAD unit-test +download_unit_test () { + # if not present then download unit-test + target_file="${utest_file}" + target_hash="${utest_hash}" + if [ "$enable_unit_test" ]; then + if [ -e "${ERSA_UT}/${target_file}" ]; then + keep_eut=1 + [ -x "${ERSA_UT}/${target_file}" ] || \ + chmod +x "${ERSA_UT}/${target_file}" + # version check + if "${ERSA_UT}/${target_file}" version; then + utest_bin="${ERSA_UT}/${target_file}" + utest_bin_ok=1 + else + log "version check failed: ${ERSA_UT}/${target_file}" + fi + else + # download and basic check + log "curl_it ${target_file}" + if curl_it "${target_file}" "${target_hash}"; then + [ -x "${ERSA_UT}/${target_file}" ] || \ + chmod +x "${ERSA_UT}/${target_file}" + # functional check - version check + if "${ERSA_UT}/${target_file}" version; then + utest_bin="${ERSA_UT}/${target_file}" + utest_bin_ok=1 + else + log "version check failed: ${target_file}" + fi + else + log "curl_it ${target_file} - failed" + fi + fi + [ "$utest_bin_ok" ] || log "undefined: utest_bin_ok" + log "setup unit-test - ok" + else + log "unit-test disabled" + fi # => shellcheck +} +## DOWNLOAD unit-test + +################################################################################ + +## USE shellcheck + +# Run shellcheck +run_shellcheck () { + if [ "$enable_shellcheck" ] && [ "$sc_bin_ok" ] && [ "$EASYRSA_NIX" ]; then + if [ -e easyrsa3/easyrsa ]; then + if "${sc_bin}" -s sh -S warning -x easyrsa3/easyrsa; then + log "shellcheck completed - ok" + else + log "shellcheck completed - *easyrsa* FAILED" + fi + else + log "easyrsa binary not present, not using shellcheck" + fi + else + log "shellcheck abandoned" + fi +} +## USE shellcheck + +######################################## + +## DOWNLOAD shellcheck +download_shellcheck () { + # if not present then download shellcheck + target_file="${sc_file}" + target_hash="${sc_hash}" + if [ "$enable_shellcheck" ] && [ "$EASYRSA_NIX" ]; then + log "setup shellcheck" + if [ -e "${ERSA_UT}/${target_file}" ]; then + keep_sc=1 + [ -x "${ERSA_UT}/${target_file}" ] || \ + chmod +x "${ERSA_UT}/${target_file}" + "${ERSA_UT}/${target_file}" -V || \ + log "version check failed: ${ERSA_UT}/${target_file}" + sc_bin="${ERSA_UT}/${target_file}" + sc_bin_ok=1 + else + # download and basic check + log "curl_it ${target_file}" + if curl_it "${target_file}" "${target_hash}"; then + log "curl_it ${target_file} - ok" + [ -x "${ERSA_UT}/${target_file}" ] || \ + chmod +x "${ERSA_UT}/${target_file}" + # functional check + if "${ERSA_UT}/${target_file}" -V; then + sc_bin="${ERSA_UT}/${target_file}" + sc_bin_ok=1 + else + log "version check failed: ${ERSA_UT}/${target_file}" + fi + + else + log "curl_it ${target_file} - failed" + fi + fi + fi + + ## DOWNLOAD shellcheck +} + +################################################################################ + +## DOWNLOAD openssl-3 +download_opensslv3 () { + # if not present then download and then use openssl3 + target_file="${ssl_file}" + target_hash="${ssl_hash}" + if [ "$enable_openssl3" ] && [ "$EASYRSA_NIX" ]; then + if [ -e "${ERSA_UT}/${target_file}" ]; then + keep_ssl=1 + [ -x "${ERSA_UT}/${target_file}" ] || \ + chmod +x "${ERSA_UT}/${target_file}" + # version check 'openssl version' + "${ERSA_UT}/${target_file}" version || \ + log "version check failed: ${ERSA_UT}/${target_file}" + ssl_bin="${ERSA_UT}/${target_file}" + ssl_bin_ok=1 + else + # download and basic check + log "curl_it ${target_file}" + if curl_it "${target_file}" "${target_hash}"; then + log "curl_it ${target_file} - ok" + [ -x "${ERSA_UT}/${target_file}" ] || \ + chmod +x "${ERSA_UT}/${target_file}" + # functional check - version check 'openssl version' + if "${ERSA_UT}/${target_file}" version; then + ssl_bin="${ERSA_UT}/${target_file}" + ssl_bin_ok=1 + # Set up Easy-RSA Unit-Test for OpenSSL-v3 + export EASYRSA_OPENSSL="${ssl_bin}" + else + log "version check failed: ${ERSA_UT}/${target_file}" + fi + else + log "curl_it ${target_file} - failed" + fi + fi + + log "setup openssl3 - hey hokey-dokey-lopey" + log "OpenSSL-v3 ENabled" + + else + if [ "$EASYRSA_NIX" ]; then + log "System SSL enabled" + ssl_bin="openssl" + ssl_bin_ok=1 + else + log "Windows, no OpenSSL-v3" + fi + fi +} # => ## DOWNLOAD openssl-3 + +################################################################################ + +unset -v disable_log verb enable_unit_test enable_shellcheck enable_openssl3 \ + keep_sc keep_ssl keep_eut no_delete + +# Set by default +enable_unit_test=1 +enable_curl=1 while [ -n "$1" ]; do case "$1" in - -v) verb='-v' ;; - -vv) verb='-vv' ;; - -scoff) unset -v enable_shellcheck ;; - *) verb='-v' + --no-log) disable_log=1 ;; + '') verb='-v' ;; + -v) verb='-v' ;; + -vv) verb='-vv' ;; + -sc) enable_shellcheck=1 ;; + -o3) enable_openssl3=1 ;; + -dr) dry_run=1 ;; + -nt|--no-test) unset -v enable_unit_test ;; + -nc|--no-curl) unset -v enable_curl ;; + -nd|--no-delete) no_delete=1 ;; + *) + log "Unknown option: $1" + exit 9 esac shift done -github_url='https://raw.githubusercontent.com' +log "Easy-RSA Unit Tests:" -# disable 'shellcheck' in favour of 'openssl3' -unset -v enable_shellcheck -if [ "$enable_shellcheck" ]; then +# Layout +ERSA_UT="${PWD}" -if [ -e "shellcheck" ] && [ "$EASYRSA_NIX" ]; then - chmod +x shellcheck - ./shellcheck -V - if [ -e easyrsa3/easyrsa ]; then - ./shellcheck -s sh -S warning -x easyrsa3/easyrsa - echo "* shellcheck completed *" - else - echo "* easyrsa binary not present, using path, no shellcheck" - fi -elif [ "$EASYRSA_NIX" ]; then - github_target='OpenVPN/easyrsa-unit-tests/master/shellcheck' - curl -f -O "${github_url}/${github_target}" || { - echo "shellcheck download failed." - exit 9 - } - chmod +x shellcheck - ./shellcheck -V - if [ -e easyrsa3/easyrsa ]; then - ./shellcheck -s sh -S warning -x easyrsa3/easyrsa - echo "* shellcheck completed *" - else - echo "* easyrsa binary not present, using path, no shellcheck" - fi - rm -f ./shellcheck -fi +# Sources +gh_url='https://raw.githubusercontent.com/OpenVPN/easyrsa-unit-tests/master' -else - # shellcheck is disabled - : -fi +utest_file='easyrsa-unit-tests.sh' +unset -v utest_bin utest_bin_ok +utest_hash='no-hash' +sc_file='shellcheck' +unset -v sc_bin sc_bin_ok +sc_hash='SHA256(shellcheck)= f4bce23c11c3919c1b20bcb0f206f6b44c44e26f2bc95f8aa708716095fa0651' -estat=0 +ssl_file='openssl' +unset -v ssl_bin ssl_bin_ok +ssl_hash='SHA256(openssl)= bc4a5882bad4f51e6d04c25877e1e85ad86f14c5f6e078dd9c02f9d38f8791be' -if [ -e "easyrsa-unit-tests.sh" ]; then +# Here we go .. +# allow shellcheck to fail +download_shellcheck +run_shellcheck - if : ; then +# if this fails then fly system ssl +download_opensslv3 +# The test which matters! +download_unit_test +run_unit_test +clean_up -# sh easyrsa-unit-tests.sh "$verb"; then +################################################################################ - - - if [ "$EASYRSA_NIX" ] && [ "$EASYRSA_BY_TINCANTECH" ]; then - - - # two tests in one: x509-alt and ossl-3 - # Not without --x509-alt, waiting for merge - - # openssl v3 - if [ ! -e ./openssl ]; then - github_target='OpenVPN/easyrsa-unit-tests/master/openssl' - curl -SO "${github_url}/${github_target}" || - printf '%s\n' "openssl download failed." - fi - - chmod +x openssl - ./openssl version - export EASYRSA_OPENSSL="${PWD}/openssl" - printf '%s\n' "* exported EASYRSA_OPENSSL:" " ${PWD}/openssl" " $EASYRSA_OPENSSL" - sh easyrsa-unit-tests.sh "$verb" || estat=2 - #rm ./openssl - fi - else - estat=1 - fi -else - github_target='OpenVPN/easyrsa-unit-tests/master/easyrsa-unit-tests.sh' - curl -O "${github_url}/${github_target}" - [ -e "easyrsa-unit-tests.sh" ] || { echo "Unit-test download failed."; exit 9; } - - - if [ "$EASYRSA_NIX" ] && [ "$EASYRSA_BY_TINCANTECH" ]; then - - - # two tests in one: x509-alt and ossl-3 - # Not without --x509-alt, waiting for merge - - # openssl v3 - if [ ! -e ./openssl ]; then - github_target='OpenVPN/easyrsa-unit-tests/master/openssl' - curl -SO "${github_url}/${github_target}" || - printf '%s\n' "openssl download failed." - fi - - chmod +x openssl - ./openssl version - export EASYRSA_OPENSSL="${PWD}/openssl" - printf '%s\n' "* exported EASYRSA_OPENSSL:" " ${PWD}/openssl" " $EASYRSA_OPENSSL" - sh easyrsa-unit-tests.sh "$verb" || estat=2 - #rm ./openssl - fi - - if sh easyrsa-unit-tests.sh "$verb"; then - : # ok - else - estat=1 - fi - rm -f easyrsa-unit-tests.sh -fi - -echo "estat: $estat" +log "estat: $estat ${dry_run:+<>}" exit $estat + +# vim: no + From ea666d5b97ba090f7beb70d128c12f332c51bf3b Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 16:00:45 +0100 Subject: [PATCH 17/73] op-test.sh - exit with correct status Signed-off-by: Richard T Bonhomme --- op-test.sh | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/op-test.sh b/op-test.sh index b4f6f24..a55ab21 100644 --- a/op-test.sh +++ b/op-test.sh @@ -105,26 +105,20 @@ run_unit_test () # Start unit tests log ">>> BEGIN unit tests:" - if [ "${dry_run}" ]; then log "<> sh ${utest_bin} ${verb}" estat=1 else log ">>>>>>: sh ${utest_bin} ${verb}" - sh "${utest_bin}" "${verb}" - - #if sh "${utest_bin}" "${verb}" -v; then - # estat=0 - #else - # estat=1 - #fi - - # TODO: dispose of 'estat' garbage - estat=1 # This is a bug and an error .. fix it. + if sh "${utest_bin}" "${verb}"; then + log "OK" + estat=0 + else + log "FAIL" + estat=1 + fi fi - log "<<< END unit tests:" - else log "unit-test abandoned" estat=1 From 50850f5ff3e1743e441f7df52cddd6dd752b6ca6 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 16:07:26 +0100 Subject: [PATCH 18/73] op-test.sh - Set System SSL for Windows Signed-off-by: Richard T Bonhomme --- op-test.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/op-test.sh b/op-test.sh index a55ab21..f36fdc9 100644 --- a/op-test.sh +++ b/op-test.sh @@ -280,6 +280,9 @@ download_opensslv3 () { ssl_bin_ok=1 else log "Windows, no OpenSSL-v3" + log "System SSL enabled" + ssl_bin="openssl" + ssl_bin_ok=1 fi fi } # => ## DOWNLOAD openssl-3 From 1aeddd9fcf134f5bc25ddcbb08ccdf0902c8a5f9 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 16:13:04 +0100 Subject: [PATCH 19/73] Unit tests: Enable shellcheck and OpenSSL v3 (*nix only) Signed-off-by: Richard T Bonhomme --- .github/workflows/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 158993d..b717133 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -33,7 +33,7 @@ jobs: # Runs a single command using the runners shell - name: operational test - run: sh op-test.sh -v + run: sh op-test.sh -v -sc -o3 # Runs a set of commands using the runners shell # - name: Run a multi-line script From 3e24a76d7e952f8c6a6f72dd8ff41b211f6fe994 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 19:38:44 +0100 Subject: [PATCH 20/73] Allow saving test data and improve log output Signed-off-by: Richard T Bonhomme --- op-test.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/op-test.sh b/op-test.sh index f36fdc9..94a007a 100644 --- a/op-test.sh +++ b/op-test.sh @@ -105,6 +105,8 @@ run_unit_test () # Start unit tests log ">>> BEGIN unit tests:" + [ "$no_delete" ] && export SAVE_PKI=1 + if [ "${dry_run}" ]; then log "<> sh ${utest_bin} ${verb}" estat=1 @@ -119,6 +121,7 @@ run_unit_test () fi fi log "<<< END unit tests:" + unset SAVE_PKI else log "unit-test abandoned" estat=1 @@ -249,6 +252,8 @@ download_opensslv3 () { log "version check failed: ${ERSA_UT}/${target_file}" ssl_bin="${ERSA_UT}/${target_file}" ssl_bin_ok=1 + # Set up Easy-RSA Unit-Test for OpenSSL-v3 + export EASYRSA_OPENSSL="${ssl_bin}" else # download and basic check log "curl_it ${target_file}" @@ -270,8 +275,7 @@ download_opensslv3 () { fi fi - log "setup openssl3 - hey hokey-dokey-lopey" - log "OpenSSL-v3 ENabled" + log "OpenSSL-v3 enabled" else if [ "$EASYRSA_NIX" ]; then From 540c6ff5afba5a647bd0a47e732b9ab155cf147b Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 21:16:25 +0100 Subject: [PATCH 21/73] Unit test: shellcheck easyrsa-unit-tests.sh Signed-off-by: Richard T Bonhomme --- op-test.sh | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/op-test.sh b/op-test.sh index 94a007a..0c290bb 100644 --- a/op-test.sh +++ b/op-test.sh @@ -144,6 +144,7 @@ download_unit_test () { if "${ERSA_UT}/${target_file}" version; then utest_bin="${ERSA_UT}/${target_file}" utest_bin_ok=1 + export ERSA_UTEST_CURL_TARGET=localhost else log "version check failed: ${ERSA_UT}/${target_file}" fi @@ -157,6 +158,7 @@ download_unit_test () { if "${ERSA_UT}/${target_file}" version; then utest_bin="${ERSA_UT}/${target_file}" utest_bin_ok=1 + export ERSA_UTEST_CURL_TARGET=online else log "version check failed: ${target_file}" fi @@ -179,15 +181,27 @@ download_unit_test () { # Run shellcheck run_shellcheck () { if [ "$enable_shellcheck" ] && [ "$sc_bin_ok" ] && [ "$EASYRSA_NIX" ]; then + # shellcheck easyrsa3/easyrsa if [ -e easyrsa3/easyrsa ]; then if "${sc_bin}" -s sh -S warning -x easyrsa3/easyrsa; then - log "shellcheck completed - ok" + log "shellcheck easyrsa3/easyrsa completed - ok" else - log "shellcheck completed - *easyrsa* FAILED" + log "shellcheck easyrsa3/easyrsa completed - FAILED" fi else log "easyrsa binary not present, not using shellcheck" fi + + # shellcheck easyrsa-unit-tests.sh + if [ -e easyrsa-unit-tests.sh ]; then + if "${sc_bin}" -s sh -S warning -x easyrsa-unit-tests.sh; then + log "shellcheck easyrsa-unit-tests.sh completed - ok" + else + log "shellcheck easyrsa-unit-tests.sh completed - FAILED" + fi + else + log "easyrsa-unit-tests.sh binary not present, not using shellcheck" + fi else log "shellcheck abandoned" fi @@ -341,15 +355,11 @@ ssl_hash='SHA256(openssl)= bc4a5882bad4f51e6d04c25877e1e85ad86f14c5f6e078dd9c02f # Here we go .. -# allow shellcheck to fail download_shellcheck -run_shellcheck - -# if this fails then fly system ssl download_opensslv3 - -# The test which matters! download_unit_test + +run_shellcheck run_unit_test clean_up @@ -360,4 +370,3 @@ log "estat: $estat ${dry_run:+<>}" exit $estat # vim: no - From e30bfd3773cf22681784c46cbab989990a8e028c Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 21:58:11 +0100 Subject: [PATCH 22/73] Unit test: Improve output Signed-off-by: Richard T Bonhomme --- op-test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/op-test.sh b/op-test.sh index 0c290bb..dba7245 100644 --- a/op-test.sh +++ b/op-test.sh @@ -74,8 +74,8 @@ curl_it () { if [ -e "${file}" ]; then log "> hash ${file}" temp_hash="$(openssl sha256 "${file}")" - log "temp_hash: $temp_hash" - log "hash : $hash" + #log "temp_hash: $temp_hash" + #log "hash : $hash" if [ "$temp_hash" = "$hash" ]; then : # OK - hash is good else From 4c4efbd6ae08783e043611cbeef372d92cffbdd1 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 23:08:36 +0100 Subject: [PATCH 23/73] Change Error to Warning: Make (') in vars-file non-fatal Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 40b9ef8..d42ea80 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2135,10 +2135,10 @@ recommended - please remove it from there before continuing. " fi if grep -q "'" "$vars"; then - die " + warn " Single quote (') has been found in the configuration file. -This character is not allowed in the configuration file. -Please remove it before continuing. +This character is not supported in the configuration file. +Sourcing the vars file will probably fail .. " fi From de7735115cac542539d5617a807b2d65965e5786 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 11 Apr 2022 23:32:17 +0100 Subject: [PATCH 24/73] Only warn if 'vars' is in PKI Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index d42ea80..2123aef 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2118,7 +2118,9 @@ Priority should be given to your PKI vars file: [ "$pwd_vars" ] && vars="$pwd_vars" [ "$easy_vars" ] && vars="$easy_vars" [ "$prog_vars" ] && vars="$prog_vars" - [ "$pki_vars" ] && vars="$pki_vars" + # Prioritise vars_in_pki + unset -v vars_in_pki && \ + [ "$pki_vars" ] && vars="$pki_vars" && vars_in_pki=1 fi # If $EASYRSA_NO_VARS is defined (not blank) then do not use vars @@ -2134,7 +2136,7 @@ file. Storing sensitive information in the configuration file is not recommended - please remove it from there before continuing. " fi - if grep -q "'" "$vars"; then + if [ "$vars_in_pki" ] && grep -q "'" "$vars"; then warn " Single quote (') has been found in the configuration file. This character is not supported in the configuration file. From 7d5185f52c3bafbd7b5a9ff1551993d2871899ab Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 12 Apr 2022 14:01:42 +0100 Subject: [PATCH 25/73] easyrsa_openssl() - Minor syle changes Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 154bd9b..4d0a4d7 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -362,22 +362,18 @@ easyrsa_openssl() { openssl_command="$1"; shift case "$openssl_command" in - makesafeconf) has_config=true ;; - ca|req|srp|ts) has_config=true ;; - *) has_config=false + makesafeconf) has_config=1 ;; + ca|req|srp|ts) has_config=1 ;; + *) unset -v has_config esac # OpenSSL 1x genpkey does not support -config - Not as documented: # https://www.openssl.org/docs/manmaster/man1/openssl-genpkey.html if [ "$osslv_major" = 3 ] && [ "$openssl_command" = genpkey ]; then - has_config=true + has_config=1 fi - case "$has_config" in - false) - "$EASYRSA_OPENSSL" "$openssl_command" "$@" || return - ;; - true) + if [ "$has_config" ]; then # Make LibreSSL safe config file from OpenSSL config file easyrsa_openssl_conf="$(easyrsa_mktemp)" || \ die "easyrsa_openssl - Failed to create temporary file" @@ -411,9 +407,10 @@ easyrsa_openssl() { "$EASYRSA_OPENSSL" "$openssl_command" \ -config "$easyrsa_openssl_conf" "$@" || return fi - ;; - *) die "Undefined state: has_config is $has_config" - esac + else + # Exec SSL without -config temp-file + "$EASYRSA_OPENSSL" "$openssl_command" "$@" || return + fi } # => easyrsa_openssl # Verify supplied curve exists and generate curve file if needed From 6e2d1391770f6847cba9d0ae44192135c0bba9a6 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 12 Apr 2022 18:35:47 +0100 Subject: [PATCH 26/73] Add helpful Warnings to promote preferred use of PKI/vars Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 14c3fa8..9bf2e82 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2136,10 +2136,11 @@ Sourcing the vars file will probably fail .. # shellcheck disable=1090 # can't follow non-constant source. vars . "$vars" notice "Note: using Easy-RSA configuration from: $vars" + [ "$vars_in_pki" ] || \ + warn "Move your vars file to your PKI folder, where it is safe!" else # $vars remains undefined .. no vars found - # Warning already issued! - : # ok + warn "No vars file found! Please create one in your PKI folder." fi else # EASYRSA_NO_VARS is defined or want_init_pki, no vars is required. From 3dfd57b7601685b437080f5d18e8c8bd449caf86 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 12 Apr 2022 19:09:48 +0100 Subject: [PATCH 27/73] Optimize 'vars_in_pki' - Allow further checks on PKI/vars Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 9bf2e82..875d537 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2064,7 +2064,8 @@ vars_setup() { if [ -z "$want_init_pki" ]; then # Clear flags - This is the preferred order to find: - unset -v e_pki_vars e_easy_vars e_pwd_vars e_prog_vars found_vars + unset -v e_pki_vars e_easy_vars e_pwd_vars e_prog_vars \ + found_vars vars_in_pki # PKI location, if present: { [ -e "$pki_vars" ] && e_pki_vars=1; } || unset -v pki_vars @@ -2106,8 +2107,7 @@ Priority should be given to your PKI vars file: [ "$easy_vars" ] && vars="$easy_vars" [ "$prog_vars" ] && vars="$prog_vars" # Prioritise vars_in_pki - unset -v vars_in_pki && \ - [ "$pki_vars" ] && vars="$pki_vars" && vars_in_pki=1 + [ "$pki_vars" ] && vars="$pki_vars" && vars_in_pki=1 fi # If $EASYRSA_NO_VARS is defined (not blank) then do not use vars @@ -2123,12 +2123,17 @@ file. Storing sensitive information in the configuration file is not recommended - please remove it from there before continuing. " fi - if [ "$vars_in_pki" ] && grep -q "'" "$vars"; then - warn " + + # Sanitize vars further but ONLY if it is in PKI folder + if [ "$vars_in_pki" ]; then + # Warning: Single quote + if grep -q "'" "$vars"; then + warn " Single quote (') has been found in the configuration file. This character is not supported in the configuration file. Sourcing the vars file will probably fail .. " + fi fi # shellcheck disable=SC2034 # EASYRSA_CALLER appears unused. From c18d7f2bf0dcfe625f33f463a673ecb953eb61cd Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 12 Apr 2022 20:50:55 +0100 Subject: [PATCH 28/73] Improve informational output: 'init-pki' completed Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index e81cf06..dabd4cc 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -331,6 +331,7 @@ Type the word '$value' to continue, or any other input to abort." printf %s " $prompt" #shellcheck disable=SC2162 read input + printf '\n' [ "$input" = "$value" ] && return notice "Aborting without confirmation." exit 9 @@ -591,13 +592,14 @@ and initialize a fresh PKI here." die "init-pki failed to create safe SSL conf: $EASYRSA_SAFE_CONF" fi - notice "\ -init-pki complete; you may now create a CA or requests. -Your newly created PKI dir is: -* $EASYRSA_PKI" + notice " - notice "* Easy-RSA 'vars' file has now been moved to your PKI above." - return 0 + init-pki complete; you may now create a CA or requests. + + Your newly created PKI dir is: + * $EASYRSA_PKI + + IMPORTANT: Easy-RSA 'vars' file has now been moved to your PKI above." } # => init_pki() # Copy data-files from various sources From 29a8a48638f84ef5d0b0c9b599b990fe3e16f6ea Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 01:00:08 +0100 Subject: [PATCH 29/73] build_ca() - Quote temporary password file "$out_key_pass_tmp" The problem: * crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" This cannot be reliably expanded and passed as an unquoted option. This is due to the unquoted file name $out_key_pass_tmp. The solution: * Do not polute $crypto_opts with password related options. * Specifiy the correct '-pass/-passin/-passout file:xx' for each command. This allows "$out_key_pass_tmp" to be corrrectly quoted. Also, apply the same quoting technique to $crypto_opts. Minor alterations to OpenSSL command line layout, readability. Comment out the replaced code, not removed. For comparison. (Follow-up patch will remove the comments) Full unit-tests completed throughout development. Manually tested multiple password protected PKIs. OpenSSL 1.1.1 and 3.0.2 Not tested: * OpenSSL options: -pass/-passin-/passout file:"$out_key_pass_tmp" Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 107 ++++++++++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 43 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index dabd4cc..a3a0987 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -292,7 +292,7 @@ warn() { [ "$EASYRSA_SILENT" ] && return print "* WARNING: - $1 +$1 " 1>&2 } # => warn() @@ -766,7 +766,7 @@ build_ca() { out_key="$EASYRSA_PKI/private/ca.key" if [ -z "$sub_ca" ]; then out_file="$EASYRSA_PKI/ca.crt" - opts="$opts -x509 -days $EASYRSA_CA_EXPIRE " + opts="$opts -x509 -days $EASYRSA_CA_EXPIRE" fi # Test for existing CA, and complain if already present @@ -794,7 +794,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." done printf "" > "$EASYRSA_PKI/index.txt" || die "$err_file" printf "" > "$EASYRSA_PKI/index.txt.attr" || die "$err_file" - print "01" > "$EASYRSA_PKI/serial" || die "$err_file" + printf '%s\n' "01" > "$EASYRSA_PKI/serial" || die "$err_file" # Default CN only when not in global EASYRSA_BATCH mode: # shellcheck disable=SC2015 @@ -854,7 +854,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." # * shellcheck SC2086 # Ignore unquoted variables # The "correct" solution is to not need unquoted substitutions .. # - # shellcheck disable=SC2086 # Ignore unquoted variables + # ##shellcheck disable=SC2086 # Ignore unquoted variables case "$osslv_major" in # => BEGIN SSL lib version # BEGIN SSL V3 @@ -865,7 +865,8 @@ current CA keypair. If you intended to start a new CA, run init-pki first." if [ -z "$nopass" ]; then crypto_opts="$crypto" if [ -z "$EASYRSA_PASSOUT" ]; then - crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" + #crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" + : # ok fi fi @@ -875,24 +876,31 @@ current CA keypair. If you intended to start a new CA, run init-pki first." rsa) # OpenSSL v3: 'genrsa' is deprecate, use 'genpkey' easyrsa_openssl genpkey -algorithm "$EASYRSA_ALGO" \ - -out "$out_key_tmp" ${crypto_opts} \ + -out "$out_key_tmp" \ -pkeyopt rsa_keygen_bits:"$EASYRSA_ALGO_PARAMS" \ - ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ - die "Failed create CA private key" + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" ;; ec) easyrsa_openssl genpkey -paramfile "$EASYRSA_ALGO_PARAMS" \ - -out "$out_key_tmp" ${crypto_opts} \ - ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ - die "Failed create CA private key" + -out "$out_key_tmp" \ + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" ;; ed) case "$EASYRSA_CURVE" in [eE][dD]25519|[eE][dD]448) easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" \ - -out "$out_key_tmp" ${crypto_opts} \ - ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ - die "Failed create CA private key" ;; + -out "$out_key_tmp" \ + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" + ;; *) die "Unknown curve: $EASYRSA_CURVE" esac ;; @@ -904,17 +912,20 @@ current CA keypair. If you intended to start a new CA, run init-pki first." # 'req' requires '-passin' crypto_opts="" if [ -z "$nopass" ] && [ -z "$EASYRSA_PASSIN" ]; then - crypto_opts="-passin file:$out_key_pass_tmp" + #crypto_opts="-passin file:$out_key_pass_tmp" + : # ok else crypto_opts="$no_password" fi # create the CA keypair: - easyrsa_openssl req -utf8 -new -key "$out_key_tmp" \ - -out "$out_file_tmp" ${opts} ${crypto_opts} \ - ${EASYRSA_CA_EXTRA_EXTS} \ - ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || \ - die "Failed to build the CA" + easyrsa_openssl req -utf8 -new \ + -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ + $opts $EASYRSA_CA_EXTRA_EXTS \ + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \ + || die "Failed to build the CA" ;; # END SSL V3 @@ -925,35 +936,43 @@ current CA keypair. If you intended to start a new CA, run init-pki first." if [ -z "$nopass" ]; then crypto_opts="$crypto" if [ -z "$EASYRSA_PASSOUT" ]; then - if [ "ed" = "$EASYRSA_ALGO" ]; then - crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" - else - crypto_opts="$crypto_opts -passout file:$out_key_pass_tmp" - fi + #if [ "ed" = "$EASYRSA_ALGO" ]; then + # crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" + #else + # crypto_opts="$crypto_opts -passout file:$out_key_pass_tmp" + #fi + : # ok fi fi # create the CA key case "$EASYRSA_ALGO" in rsa) - "$EASYRSA_OPENSSL" genrsa -out "$out_key_tmp" $crypto_opts \ - ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} \ - "$EASYRSA_ALGO_PARAMS" || \ - die "Failed create CA private key" + "$EASYRSA_OPENSSL" genrsa -out "$out_key_tmp" \ + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -passout file:"$out_key_pass_tmp"} \ + "$EASYRSA_ALGO_PARAMS" \ + || die "Failed create CA private key" ;; ec) "$EASYRSA_OPENSSL" ecparam -in "$EASYRSA_ALGO_PARAMS" -genkey | \ - "$EASYRSA_OPENSSL" ec -out "$out_key_tmp" $crypto_opts \ - ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || \ - die "Failed create CA private key" + "$EASYRSA_OPENSSL" ec -out "$out_key_tmp" \ + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -passout file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" ;; ed) case "$EASYRSA_CURVE" in [eE][dD]25519|[eE][dD]448) "$EASYRSA_OPENSSL" genpkey -algorithm "$EASYRSA_CURVE" \ - -out "$out_key_tmp" $crypto_opts \ - ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ - die "Failed create CA private key" ;; + -out "$out_key_tmp" \ + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ + || die "Failed create CA private key" + ;; *) die "Unknown curve: $EASYRSA_CURVE" esac ;; @@ -963,16 +982,18 @@ current CA keypair. If you intended to start a new CA, run init-pki first." # create the CA keypair: crypto_opts="" if [ -z "$nopass" ] && [ -z "$EASYRSA_PASSIN" ]; then - crypto_opts="-passin file:$out_key_pass_tmp" + #crypto_opts="-passin file:$out_key_pass_tmp" + : # ok else crypto_opts="$no_password" - fi - easyrsa_openssl req -utf8 -new -key "$out_key_tmp" \ - -keyout "$out_key_tmp" -out "$out_file_tmp" $crypto_opts $opts \ - ${EASYRSA_CA_EXTRA_EXTS} \ - ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ + easyrsa_openssl req -utf8 -new \ + -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ + $opts $EASYRSA_CA_EXTRA_EXTS \ + ${crypto_opts:+ "$crypto_opts"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \ || die "Failed to build the CA" ;; # END SSL V1 @@ -2116,7 +2137,7 @@ Priority should be given to your PKI vars file: if [ "$vars" ]; then # Sanitize vars if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then - die " + die "\ Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration file. Storing sensitive information in the configuration file is not recommended - please remove it from there before continuing. @@ -2127,7 +2148,7 @@ recommended - please remove it from there before continuing. if [ "$vars_in_pki" ]; then # Warning: Single quote if grep -q "'" "$vars"; then - warn " + warn "\ Single quote (') has been found in the configuration file. This character is not supported in the configuration file. Sourcing the vars file will probably fail .. From 1d6a5f803ef2936373ca47cec3ca8053bbf3dfb0 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 02:37:50 +0100 Subject: [PATCH 30/73] Set default EASYRSA_PKI to $EASYRSA/pki and some minor improvements Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 40 +++++++++++++++++++++------------------- op-test.sh | 21 ++++++++++++++++++--- wop-test.sh | 2 +- 3 files changed, 40 insertions(+), 23 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index dabd4cc..5f2e4ec 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -300,7 +300,9 @@ warn() { notice() { [ "$EASYRSA_SILENT" ] && return [ "$EASYRSA_BATCH" ] && return - print "* Notice: $1" + print "* Notice: +$1 +" } # => notice() # yes/no case-insensitive match (operates on stdin pipe) @@ -2087,7 +2089,7 @@ vars_setup() { 0) unset -v found_vars ;; - 1) : ;; #ok + 1) : ;; # ok *) [ "$e_pki_vars" ] && print "Found: $pki_vars" [ "$e_easy_vars" ] && print "Found: $easy_vars" @@ -2156,7 +2158,7 @@ Sourcing the vars file will probably fail .. # Set defaults, preferring existing env-vars if present set_var EASYRSA "$PWD" set_var EASYRSA_OPENSSL openssl - set_var EASYRSA_PKI "$PWD/pki" + set_var EASYRSA_PKI "$EASYRSA/pki" set_var EASYRSA_DN cn_only set_var EASYRSA_REQ_COUNTRY "US" set_var EASYRSA_REQ_PROVINCE "California" @@ -2237,6 +2239,22 @@ Sourcing the vars file will probably fail .. fi fi fi + + # Detect Windows + case "$OS" in + '') unset -v EASYRSA_WIN ;; + *) EASYRSA_WIN="$OS" + esac + + # Detect Windows git/bash + case "${EXEPATH##*\\}" in + Git) + EASYRSA_WIN_GIT_BASH=Git-bash + [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl + ;; + '') unset -v EASYRSA_WIN_GIT_BASH ;; + *) EASYRSA_WIN_GIT_BASH="$EXEPATH" + esac } # vars_setup() # variable assignment by indirection when undefined; merely exports @@ -2958,22 +2976,6 @@ init-pki|clean-all) want_init_pki=1 ;; *) unset -v want_init_pki esac -# Detect Windows -case "$OS" in - '') unset -v EASYRSA_WIN ;; - *) EASYRSA_WIN="$OS" -esac - -# Detect Windows git/bash -case "${EXEPATH##*\\}" in - Git) - EASYRSA_WIN_GIT_BASH=Git-bash - [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl - ;; - '') unset -v EASYRSA_WIN_GIT_BASH ;; - *) EASYRSA_WIN_GIT_BASH="$EXEPATH" -esac - # Intelligent env-var detection and auto-loading: vars_setup diff --git a/op-test.sh b/op-test.sh index dba7245..12ee58c 100644 --- a/op-test.sh +++ b/op-test.sh @@ -20,6 +20,7 @@ clean_up () { if [ "$no_delete" ]; then log "saved final state.." else + log "op-test: clean_up" if [ "$EASYRSA_NIX" ]; then [ "$keep_eut" ] || rm -f "$utest_bin" [ "$keep_sc" ] || rm -f "$sc_bin" @@ -181,7 +182,7 @@ download_unit_test () { # Run shellcheck run_shellcheck () { if [ "$enable_shellcheck" ] && [ "$sc_bin_ok" ] && [ "$EASYRSA_NIX" ]; then - # shellcheck easyrsa3/easyrsa + # shell-check easyrsa3/easyrsa if [ -e easyrsa3/easyrsa ]; then if "${sc_bin}" -s sh -S warning -x easyrsa3/easyrsa; then log "shellcheck easyrsa3/easyrsa completed - ok" @@ -192,7 +193,7 @@ run_shellcheck () { log "easyrsa binary not present, not using shellcheck" fi - # shellcheck easyrsa-unit-tests.sh + # shell-check easyrsa-unit-tests.sh if [ -e easyrsa-unit-tests.sh ]; then if "${sc_bin}" -s sh -S warning -x easyrsa-unit-tests.sh; then log "shellcheck easyrsa-unit-tests.sh completed - ok" @@ -239,7 +240,7 @@ download_shellcheck () { else log "version check failed: ${ERSA_UT}/${target_file}" fi - + log "shellcheck enabled" else log "curl_it ${target_file} - failed" fi @@ -307,12 +308,24 @@ download_opensslv3 () { ################################################################################ + # Register clean_up on EXIT + #trap "exited 0" 0 + # When SIGHUP, SIGINT, SIGQUIT, SIGABRT and SIGTERM, + # explicitly exit to signal EXIT (non-bash shells) + trap "clean_up" 1 + trap "clean_up" 2 + trap "clean_up" 3 + trap "clean_up" 6 + trap "clean_up" 15 + + unset -v disable_log verb enable_unit_test enable_shellcheck enable_openssl3 \ keep_sc keep_ssl keep_eut no_delete # Set by default enable_unit_test=1 enable_curl=1 +EASYRSA_NIX=1 while [ -n "$1" ]; do case "$1" in @@ -326,6 +339,7 @@ while [ -n "$1" ]; do -nt|--no-test) unset -v enable_unit_test ;; -nc|--no-curl) unset -v enable_curl ;; -nd|--no-delete) no_delete=1 ;; + -w|--windows) export EASYRSA_WIN=1; unset -v EASYRSA_NIX ;; *) log "Unknown option: $1" exit 9 @@ -362,6 +376,7 @@ download_unit_test run_shellcheck run_unit_test +# No trap required.. clean_up ################################################################################ diff --git a/wop-test.sh b/wop-test.sh index 3c6cb3f..466bd75 100644 --- a/wop-test.sh +++ b/wop-test.sh @@ -67,4 +67,4 @@ echo "Invoke './easyrsa' to call the program. Without commands, help is displaye cd .. -./op-test.sh -v +./op-test.sh -w -v From b68ffc28d71140b6b0f632397ceea9424598cecd Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 03:22:45 +0100 Subject: [PATCH 31/73] ChangeLog: Announce new maintenance Signed-off-by: Richard T Bonhomme --- ChangeLog | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ChangeLog b/ChangeLog index 341f7b8..344045a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,11 +1,17 @@ Easy-RSA 3 ChangeLog 3.1.0 (TBD) + * Support Windows-Git 'version of bash' (#533) + * Disallow use of single quote (') in vars file, Warning (#530) + * Creating a CA uses x509-types/ca and COMMON (#526) * Prefer 'PKI/vars' over all other locations (#528) * Introduce 'init-pki soft' option (#197) * Warnings are no longer silenced by --batch (#523) * Improve packaging options (#510) * Introduce basic support for OpenSSL version 3 (#492) + + * New maintenance begins. + * Upgrade OpenSSL from 1.1.0j to 1.1.1m (#405, #407) * Fix --version so it uses EASYRSA_OPENSSL (#416) * Use openssl rand instead of non-POSIX mktemp (#478) From d29aee3e1b8a24a187ba7fa6b5cd1b724af3d9a5 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 12:28:56 +0100 Subject: [PATCH 32/73] Output only - Standardise message use of notice(), warn() and die Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 106 ++++++++++++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 43 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 56b5142..8d049ad 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -461,7 +461,7 @@ verify_ssl_lib () { *) die "Unsupported SSL library: $osslv_major" esac notice "Using SSL: $EASYRSA_OPENSSL $val" ;; - *) die " + *) die "\ Missing or invalid OpenSSL Expected to find openssl command at: $EASYRSA_OPENSSL" ;; esac @@ -469,7 +469,7 @@ Expected to find openssl command at: $EASYRSA_OPENSSL" ;; EASYRSA_SSL_OK=1 # Verify EASYRSA_SSL_CONF file exists - [ -f "$EASYRSA_SSL_CONF" ] || die " + [ -f "$EASYRSA_SSL_CONF" ] || die "\ The OpenSSL config file cannot be found. Expected location: $EASYRSA_SSL_CONF" } # => verify_ssl_lib () @@ -497,15 +497,16 @@ $help_note" # verify ssl lib verify_ssl_lib + unset -v help_note } # => verify_pki_init() # Verify core CA files present verify_ca_init() { - help_note="Run without commands for usage and command help." - # First check the PKI has been initialized verify_pki_init + 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 serial index.txt index.txt.attr ca.crt private/ca.key; do @@ -530,8 +531,8 @@ $help_note" done # explicitly return success for callers + unset -v help_note return 0 - } # => verify_ca_init() # init-pki backend: @@ -549,7 +550,7 @@ init_pki() { # If EASYRSA_PKI exists, confirm before we rm -rf (skipped with EASYRSA_BATCH) if [ -e "$EASYRSA_PKI" ]; then - confirm "Confirm removal: " "yes" " + confirm "Confirm removal: " "yes" "\ WARNING!!! You are about to remove the EASYRSA_PKI at: @@ -594,7 +595,7 @@ and initialize a fresh PKI here." die "init-pki failed to create safe SSL conf: $EASYRSA_SAFE_CONF" fi - notice " + notice "\ init-pki complete; you may now create a CA or requests. @@ -1008,18 +1009,20 @@ current CA keypair. If you intended to start a new CA, run init-pki first." [ -f "$out_key_pass_tmp" ] && rm "$out_key_pass_tmp" # Success messages + [ "$EASYRSA_SILENT" ] || print # Separate Notice below if [ -n "$sub_ca" ]; then notice "\ + NOTE: Your intermediate CA request is at $out_file and now must be sent to your parent CA for signing. Place your resulting cert -at $EASYRSA_PKI/ca.crt prior to signing operations. -" +at $EASYRSA_PKI/ca.crt prior to signing operations." else notice "\ + CA creation complete and you may now import and sign cert requests. Your new CA certificate file for publishing is at: -$out_file -" +$out_file" fi + return 0 } # => build_ca() @@ -1042,9 +1045,11 @@ gen_dh() { "$EASYRSA_OPENSSL" dhparam -out "$out_file" "$EASYRSA_KEY_SIZE" || \ die "Failed to build DH params" + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below notice "\ -DH parameters of size $EASYRSA_KEY_SIZE created at $out_file -" + +DH parameters of size $EASYRSA_KEY_SIZE created at $out_file" return 0 } # => gen_dh() @@ -1136,11 +1141,13 @@ $EASYRSA_EXTRA_EXTS" || die "Failed to generate request" mv "$key_out_tmp" "$key_out" mv "$req_out_tmp" "$req_out" + notice "\ + Keypair and certificate request completed. Your files are: req: $req_out -key: $key_out -" +key: $key_out" + return 0 } # => gen_req() @@ -1267,9 +1274,13 @@ $ext_tmp" mv "$crt_out_tmp" "$crt_out" rm -f "$ext_tmp" + + [ "$EASYRSA_SILENT" ] || print # Separate Notice below + unset -v EASYRSA_BATCH # This is why batch mode should not silence output notice "\ -Certificate created at: $crt_out -" + +Certificate created at: $crt_out" + return 0 } # => sign_req() @@ -1387,12 +1398,14 @@ Failed to revoke certificate: revocation command failed." # move revoked files so we can reissue certificates with the same name move_revoked "$1" + [ "$EASYRSA_SILENT" ] || print # Separate Notice below notice "\ + IMPORTANT!!! Revocation was successful. You must run gen-crl and upload a CRL to your -infrastructure in order to prevent the revoked cert from being accepted. -" # => notice end +infrastructure in order to prevent the revoked cert from being accepted." + return 0 } #= revoke() @@ -1578,12 +1591,14 @@ subjectAltName = $san" build_full $cert_type "$1" $opts || die "\ Failed to renew certificate: renew command failed." + [ "$EASYRSA_SILENT" ] || print # Separate Notice below notice "\ + IMPORTANT!!! Renew was successful. -You may want to revoke the old certificate once the new one has been deployed. -" # => notice end +You may want to revoke the old certificate once the new one has been deployed." + return 0 } #= renew() @@ -1678,14 +1693,16 @@ gen_crl() { # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl ca -utf8 -gencrl -out "$out_file_tmp" \ ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || die "\ -CRL Generation failed. -" +CRL Generation failed." + mv "$out_file_tmp" "$out_file" + [ "$EASYRSA_SILENT" ] || print # Separate Notice below notice "\ + An updated CRL has been created. -CRL file: $out_file -" +CRL file: $out_file" + return 0 } # => gen_crl() @@ -1715,9 +1732,10 @@ Existing file at: $out_req" cp "$in_req" "$out_req" notice "\ + The request has been successfully imported with a short name of: $short_name -You may now use this name to perform signing operations on this request. -" +You may now use this name to perform signing operations on this request." + return 0 } # => import_req() @@ -1817,9 +1835,10 @@ Export of p8 failed: see above for related openssl errors." esac notice "\ + Successful export of $pkcs_type file. Your exported file is at the following -location: $pkcs_out -" +location: $pkcs_out" + return 0 } # => export_pkcs() @@ -1869,6 +1888,7 @@ error messages." mv "$out_key_tmp" "$file" || die "\ Failed to change the private key passphrase. See above for error messages." + [ "$EASYRSA_SILENT" ] || print # Separate Notice below notice "Key passphrase successfully changed" return 0 @@ -1881,6 +1901,7 @@ update_db() { easyrsa_openssl ca -utf8 -updatedb \ ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || die "\ Failed to perform update-db: see above for related openssl errors." + return 0 } # => update_db() @@ -1911,7 +1932,6 @@ display_dn() { print "X509v3 Subject Alternative Name:" print " $san" fi - } # => display_dn() # generate default SAN from req/X509, passed by full pathname @@ -1980,16 +2000,18 @@ Run easyrsa without commands for usage help." No such $type file with a basename of '$name' is present. Expected to find this file at: $in_file" + # shellcheck disable=SC2086 # Ignore unquoted variables verify_file $format "$in_file" || die "\ This file is not a valid $type file: $in_file" notice "\ -Showing $type details for '$name'. -This file is stored at: -$in_file -" + + Showing $type details for '$name'. + This file is stored at: + * $in_file" + # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl $format -in "$in_file" -noout -text\ -nameopt multiline $opts || die "\ @@ -2023,11 +2045,11 @@ $in_file" This file is not a valid $type file: $in_file" - notice " + notice "\ + Showing $type details for 'ca'. This file is stored at: - $in_file -" + * $in_file" # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl $format -in "$in_file" -noout -text\ @@ -2116,10 +2138,10 @@ vars_setup() { [ "$e_easy_vars" ] && print "Found: $easy_vars" [ "$e_pwd_vars" ] && print "Found: $pwd_vars" [ "$e_prog_vars" ] && print "Found: $prog_vars" - die "Conflicting 'vars' files found. + die "\ +Conflicting 'vars' files found. Priority should be given to your PKI vars file: - * $expected_pki_vars " esac @@ -2142,8 +2164,7 @@ Priority should be given to your PKI vars file: die "\ Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration file. Storing sensitive information in the configuration file is not -recommended - please remove it from there before continuing. -" +recommended - please remove it from there before continuing." fi # Sanitize vars further but ONLY if it is in PKI folder @@ -2153,8 +2174,7 @@ recommended - please remove it from there before continuing. warn "\ Single quote (') has been found in the configuration file. This character is not supported in the configuration file. -Sourcing the vars file will probably fail .. -" +Sourcing the vars file will probably fail .." fi fi From 7e73368a2825138b4d2cb183dab4127b84bc7c3c Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 12:36:02 +0100 Subject: [PATCH 33/73] Flip short-circuit to avoid having to capture unnecessary error Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 8d049ad..ade8728 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1257,9 +1257,7 @@ $(display_dn req "$req_in") fi # Add any advanced extensions supplied by env-var: - [ -n "$EASYRSA_EXTRA_EXTS" ] && print "$EASYRSA_EXTRA_EXTS" - - : # needed to keep die from inheriting the above test + [ -z "$EASYRSA_EXTRA_EXTS" ] || print "$EASYRSA_EXTRA_EXTS" } > "$ext_tmp" || die "\ Failed to create temp extension file (bad permissions?) at: $ext_tmp" From f4af868cbcf5cf224377dc6ae6b32b6a9477054d Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 12:47:18 +0100 Subject: [PATCH 34/73] Minor improvement to verify_curve_ed() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index ade8728..ac61125 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -441,10 +441,10 @@ $out" } # Verify if Edward Curve exists -verify_curve_ed() { - easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" > /dev/null && return 0 - die "Edward Curve $EASYRSA_CURVE not found." -} +verify_curve_ed () { + easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" > /dev/null \ + || die "Edward Curve $EASYRSA_CURVE not found." +} # => verify_curve_ed () verify_ssl_lib () { # Verify EASYRSA_OPENSSL command gives expected output From d7b5c98d69fc8f44992e741e008976e4c80b380f Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 15:09:41 +0100 Subject: [PATCH 35/73] Fix version information and avoid warnings for version and help Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index ac61125..3b88bb2 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -805,6 +805,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." out_key_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" out_file_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" + # Get password from user if necessary if [ -z "$nopass" ] && { [ -z "$EASYRSA_PASSOUT" ] || [ -z "$EASYRSA_PASSIN" ] @@ -1201,7 +1202,7 @@ File Path: $req_in" # Display the request subject in an easy-to-read format # Confirm the user wishes to sign this request - confirm "Confirm request details: " "yes" " + confirm "Confirm request details: " "yes" "\ You are about to sign the following certificate. 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 @@ -2180,7 +2181,7 @@ Sourcing the vars file will probably fail .." EASYRSA_CALLER=1 # shellcheck disable=1090 # can't follow non-constant source. vars . "$vars" - notice "Note: using Easy-RSA configuration from: $vars" + notice "Using Easy-RSA configuration from: $vars" [ "$vars_in_pki" ] || \ warn "Move your vars file to your PKI folder, where it is safe!" else @@ -2894,14 +2895,15 @@ return 0 print_version() { - cat < print_version () @@ -2993,7 +2995,9 @@ while :; do $EASYRSA_EXTRA_EXTS subjectAltName = $val" ;; --version) - print_version + shift "$#" + set -- "$@" "version" + break ;; *) break ;; @@ -3010,8 +3014,13 @@ done # Set cmd now because vars_setup needs to know if this is init-pki cmd="$1" [ -n "$1" ] && shift # scrape off command + +# This avoids unnecessary warnings and notices +# want_init_pki can probably be renamed to something more apt case "$cmd" in init-pki|clean-all) want_init_pki=1 ;; +""|help|-h|--help|--usage) want_init_pki=1 ;; +version) want_init_pki=1 ;; *) unset -v want_init_pki esac From 4fc2696a671612ce0da94d7f46bd9c2f81ebd737 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 13 Apr 2022 15:13:53 +0100 Subject: [PATCH 36/73] Minor improvement to verify_curve_ec() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 3b88bb2..99ca710 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -355,6 +355,9 @@ easyrsa_mktemp() { # remove temp files and do terminal cleanups cleanup() { [ -z "$EASYRSA_TEMP_DIR_session" ] || rm -rf "$EASYRSA_TEMP_DIR_session" + [ -n "${EASYRSA_EC_DIR%/*}" ] && [ -d "$EASYRSA_EC_DIR" ] && \ + rm -rf "$EASYRSA_EC_DIR" + # shellcheck disable=SC3040 (stty echo 2>/dev/null) || { (set -o echo 2>/dev/null) && set -o echo; } [ "$EASYRSA_SILENT" ] || echo "" # just to get a clean line @@ -416,29 +419,26 @@ easyrsa_openssl() { fi } # => easyrsa_openssl -# Verify supplied curve exists and generate curve file if needed -verify_curve_ec() { - if ! "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" > /dev/null; then - die "\ -Curve $EASYRSA_CURVE not found. Run openssl ecparam -list_curves to show a -list of supported curves." - fi - +# Verify supplied curve exists and Always generate curve file +verify_curve_ec () { # Check that the ecparams dir exists [ -d "$EASYRSA_EC_DIR" ] || mkdir "$EASYRSA_EC_DIR" || die "\ Failed creating ecparams dir (permissions?) at: $EASYRSA_EC_DIR" # Check that the required ecparams file exists - out="$EASYRSA_EC_DIR/${EASYRSA_CURVE}.pem" - [ -f "$out" ] && return 0 - "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" -out "$out" || die "\ + out="${EASYRSA_EC_DIR}/${EASYRSA_CURVE}.pem" + if "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" -out "$out" 1>/dev/null + then + return 0 + fi + + # Clean up failure + rm -rf "$EASYRSA_EC_DIR" + die "\ Failed to generate ecparam file (permissions?) when writing to: $out" - - # Explicitly return success for caller - return 0 -} +} # => verify_curve_ec () # Verify if Edward Curve exists verify_curve_ed () { From d82774760040a5619877627533bd0ff5585e3ab2 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 16 Apr 2022 16:46:37 +0100 Subject: [PATCH 37/73] Use easyrsa_openssl() wrapper for +verify_curve_ec() Plus some minor formatting tweaks. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 99ca710..443f20a 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -417,7 +417,7 @@ easyrsa_openssl() { # Exec SSL without -config temp-file "$EASYRSA_OPENSSL" "$openssl_command" "$@" || return fi -} # => easyrsa_openssl +} # => easyrsa_openssl() # Verify supplied curve exists and Always generate curve file verify_curve_ec () { @@ -428,7 +428,7 @@ $EASYRSA_EC_DIR" # Check that the required ecparams file exists out="${EASYRSA_EC_DIR}/${EASYRSA_CURVE}.pem" - if "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" -out "$out" 1>/dev/null + if easyrsa_openssl ecparam -name "$EASYRSA_CURVE" -out "$out" 1>/dev/null then return 0 fi @@ -438,15 +438,15 @@ $EASYRSA_EC_DIR" die "\ Failed to generate ecparam file (permissions?) when writing to: $out" -} # => verify_curve_ec () +} # => verify_curve_ec() # Verify if Edward Curve exists -verify_curve_ed () { +verify_curve_ed() { easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" > /dev/null \ || die "Edward Curve $EASYRSA_CURVE not found." -} # => verify_curve_ed () +} # => verify_curve_ed() -verify_ssl_lib () { +verify_ssl_lib() { # Verify EASYRSA_OPENSSL command gives expected output if [ -z "$EASYRSA_SSL_OK" ]; then val="$("$EASYRSA_OPENSSL" version)" @@ -472,7 +472,7 @@ Expected to find openssl command at: $EASYRSA_OPENSSL" ;; [ -f "$EASYRSA_SSL_CONF" ] || die "\ The OpenSSL config file cannot be found. Expected location: $EASYRSA_SSL_CONF" -} # => verify_ssl_lib () +} # => verify_ssl_lib() # Basic sanity-check of PKI init and complain if missing verify_pki_init() { From 368db7fc5cd2e16309cc46429aa87561a2b463ef Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 16 Apr 2022 16:57:27 +0100 Subject: [PATCH 38/73] Replace non-POSIX mktemp with POSIX mkdir and mv mktemp was used to create temp-files but it is not POSIX and the version shipped for Windows has known bugs. Replace mktemp with atomic directory and file creation using mkdir and mv, both of which are atomic. The temporary directory "session" directory is created using mkdir with a 32bit random number for the name. eg: /tmp/easyrsa-temp/b01dface The temporary file is created by moving another file into the place of the temp-file, with a 32bit random number for the name. eg: /tmp/easyrsa-temp/b01dface/c01dface Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 73 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 443f20a..44da8e1 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -339,18 +339,44 @@ Type the word '$value' to continue, or any other input to abort." exit 9 } # => confirm() -# mktemp wrapper -easyrsa_mktemp() { - [ -n "$EASYRSA_TEMP_DIR_session" ] || die "EASYRSA_TEMP_DIR_session not initialized!" - [ -d "$EASYRSA_TEMP_DIR_session" ] || mkdir -p "$EASYRSA_TEMP_DIR_session" || - die "Could not create temporary directory '$EASYRSA_TEMP_DIR_session'. Permission or concurrency problem?" - [ -d "$EASYRSA_TEMP_DIR_session" ] || die "Temporary directory '$EASYRSA_TEMP_DIR_session' does not exist" +# Create session directory atomically or fail +secure_session() { + # temporary directory must exist + [ -n "$EASYRSA_TEMP_DIR" ] || return + [ -d "$EASYRSA_TEMP_DIR" ] || return - tempfile="$EASYRSA_TEMP_DIR_session/tmp.$("$EASYRSA_OPENSSL" rand -hex 3)" || return - printf "" > "$tempfile" || return - - echo "$tempfile" -} # => easyrsa_mktemp + for i in 1 2 3; do + session="$(easyrsa_openssl rand -hex 4)" + EASYRSA_TEMP_DIR_session="${EASYRSA_TEMP_DIR}/${session}" + mkdir "$EASYRSA_TEMP_DIR_session" || continue + return + done + return 1 +} # => secure_session() + +# Create tempfile atomically or fail +easyrsa_mktemp() { + # session directory must exist + [ -n "$EASYRSA_TEMP_DIR_session" ] || return + [ -d "$EASYRSA_TEMP_DIR_session" ] || return + + for i in 1 2 3; do + rand="$(easyrsa_openssl rand -hex 4)" || return + + shotfile="${EASYRSA_TEMP_DIR_session}/shot.$rand" + if [ -e "$shotfile" ]; then + continue + else + printf "" > "$shotfile" || return + fi + + tempfile="${EASYRSA_TEMP_DIR_session}/temp.$rand" + mv "$shotfile" "$tempfile" || continue + printf '%s\n' "$tempfile" + return + done + return 1 +} # => easyrsa_mktemp() # remove temp files and do terminal cleanups cleanup() { @@ -420,7 +446,7 @@ easyrsa_openssl() { } # => easyrsa_openssl() # Verify supplied curve exists and Always generate curve file -verify_curve_ec () { +verify_curve_ec() { # Check that the ecparams dir exists [ -d "$EASYRSA_EC_DIR" ] || mkdir "$EASYRSA_EC_DIR" || die "\ Failed creating ecparams dir (permissions?) at: @@ -701,6 +727,9 @@ install_data_to_pki () { cp -f "${EASYRSA_PKI}/${vars_file_example}" \ "${EASYRSA_PKI}/${vars_file}" || return fi + + # Initialise temporary session for easyrsa_openssl makesafeconf + secure_session || return ;; vars-setup) shift ;; # ok @@ -710,6 +739,7 @@ install_data_to_pki () { die "install_data_to_pki - unknown context: $1" esac + # Check PKI is updated - Omit unnecessary checks #[ -e "${EASYRSA_PKI}/${vars_file}" ] || return #[ -e "${EASYRSA_PKI}/${vars_file_example}" ] || return @@ -2242,11 +2272,12 @@ Sourcing the vars file will probably fail .." # # Also, integrate a partial 'init-pki' by using 'install_data_to_pki()' # - if [ -z "$EASYRSA_TEMP_DIR_session" ]; then + # If EASYRSA_TEMP_DIR_session is not set then + if [ -d "$EASYRSA_PKI" ]; then + # Temp dir session + secure_session || die "Temporary directory secure-session failed." + if [ -d "$EASYRSA_TEMP_DIR" ]; then - EASYRSA_TEMP_DIR_session="$( - mktemp -du "$EASYRSA_TEMP_DIR/easy-rsa-$$.XXXXXX" - )" #TODO: This should be removed. Not really suitable for packaging. #set_var EASYRSA_EXT_DIR "$EASYRSA/x509-types" @@ -2269,14 +2300,8 @@ Sourcing the vars file will probably fail .." else # If the directory does not exist then we have not run init-pki - if mkdir -p "$EASYRSA_TEMP_DIR"; then - EASYRSA_TEMP_DIR_session="$( - mktemp -du "$EASYRSA_TEMP_DIR/easy-rsa-$$.XXXXXX" - )" - rm -rf "$EASYRSA_TEMP_DIR" - else - die "Cannot create $EASYRSA_TEMP_DIR (permission?)" - fi + # The temp-dir is Always created by 'install_data_to_pki' + : # ok fi fi From a289da60cf288a643698ea94d2b9b995b08a6788 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sun, 17 Apr 2022 13:55:07 +0100 Subject: [PATCH 39/73] Add hosts OS details to fatal error messages Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 50 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 44da8e1..bfbd285 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -281,8 +281,8 @@ Easy-RSA error: $1" 1>&2 - [ "$EASYRSA_WIN" ] && print "$EASYRSA_WIN" - [ "$EASYRSA_WIN_GIT_BASH" ] && print "$EASYRSA_WIN_GIT_BASH" + print " +Host: $host_out" exit "${2:-1}" } # => die() @@ -384,8 +384,12 @@ cleanup() { [ -n "${EASYRSA_EC_DIR%/*}" ] && [ -d "$EASYRSA_EC_DIR" ] && \ rm -rf "$EASYRSA_EC_DIR" - # shellcheck disable=SC3040 - (stty echo 2>/dev/null) || { (set -o echo 2>/dev/null) && set -o echo; } + # shellcheck disable=SC3040 # In POSIX sh, set option [name] is undefined + case "$easyrsa_host_os" in + nix) stty echo ;; + win) set -o echo ;; + *) warn "Host OS undefined." + esac [ "$EASYRSA_SILENT" ] || echo "" # just to get a clean line } # => cleanup() @@ -2305,21 +2309,33 @@ Sourcing the vars file will probably fail .." fi fi - # Detect Windows - case "$OS" in - '') unset -v EASYRSA_WIN ;; - *) EASYRSA_WIN="$OS" - esac + # Identify host OS + unset -v easyrsa_host_os easyrsa_host_test easyrsa_win_git_bash - # Detect Windows git/bash - case "${EXEPATH##*\\}" in - Git) - EASYRSA_WIN_GIT_BASH=Git-bash + # Detect Windows + easyrsa_host_test="${OS}" + + # shellcheck disable=SC2016 # expansion inside '' blah + easyrsa_ksh='@(#)MIRBSD KSH R39-w32-beta14 $Date: 2013/06/28 21:28:57 $' + [ "${KSH_VERSION}" = "${easyrsa_ksh}" ] && easyrsa_host_test="${easyrsa_ksh}" + unset -v easyrsa_ksh + + # If not Windows then nix + if [ "${easyrsa_host_test}" ]; then + easyrsa_host_os=win + easyrsa_host_os_version="${easyrsa_host_test}" + # Detect Windows git/bash + if [ "${EXEPATH}" ]; then + easyrsa_win_git_bash="${EXEPATH}" [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl - ;; - '') unset -v EASYRSA_WIN_GIT_BASH ;; - *) EASYRSA_WIN_GIT_BASH="$EXEPATH" - esac + fi + else + easyrsa_host_os=nix + easyrsa_host_os_version="$(uname)" + fi + host_out="$easyrsa_host_os | $easyrsa_host_os_version" + host_out="${host_out}${easyrsa_win_git_bash:+ | "$easyrsa_win_git_bash"}" + unset -v easyrsa_host_test } # vars_setup() # variable assignment by indirection when undefined; merely exports From c42364ab321b03306db4875af70f1d8196c8f923 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 18 Apr 2022 01:13:29 +0100 Subject: [PATCH 40/73] Create temporary session directory for 'init-pki' as required 'init-pki' is run in two different states: * Without a pre-existing PKI * With a pre-existing PKI This causes 'init-pki' temporary session directory status to be undefined. If a PKI does exist then a "session" directory will exist. If a PKI does not exist then a "session" will not be defined and a directory will not exist. Additionally, a 'soft' init-pki leaves the current "session" directory completely intact. Resolve this by Always deleting the old "session" and creating a new "session". * Only 'init-pki' is allowed to do this. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index bfbd285..e27ba6c 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -341,6 +341,9 @@ Type the word '$value' to continue, or any other input to abort." # Create session directory atomically or fail secure_session() { + # Session is already defined + [ "$EASYRSA_TEMP_DIR_session" ] && die "session overload" + # temporary directory must exist [ -n "$EASYRSA_TEMP_DIR" ] || return [ -d "$EASYRSA_TEMP_DIR" ] || return @@ -732,8 +735,17 @@ install_data_to_pki () { "${EASYRSA_PKI}/${vars_file}" || return fi - # Initialise temporary session for easyrsa_openssl makesafeconf - secure_session || return + # if session is already defined + if [ "$EASYRSA_TEMP_DIR_session" ]; then + # Only init-pki can inherit a previous session when deleting a PKI + # Only init-pki is allowed to create a new session + # 'init-pki soft' does not delete the old session, delete it now + [ -d "$EASYRSA_TEMP_DIR_session" ] && rm -rf "$EASYRSA_TEMP_DIR_session" ] + unset -v EASYRSA_TEMP_DIR_session + fi + + # Initialise new temporary session for easyrsa_openssl makesafeconf + secure_session || die "install_data_to_pki - secure_session" ;; vars-setup) shift ;; # ok @@ -743,7 +755,6 @@ install_data_to_pki () { die "install_data_to_pki - unknown context: $1" esac - # Check PKI is updated - Omit unnecessary checks #[ -e "${EASYRSA_PKI}/${vars_file}" ] || return #[ -e "${EASYRSA_PKI}/${vars_file_example}" ] || return From f503a22cc7cfc7441ad8bf4c53317275dfcf2be3 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 18 Apr 2022 20:50:09 +0100 Subject: [PATCH 41/73] Include option '--tmp-dir' to define the temporary directory Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index e27ba6c..bda7333 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -232,7 +232,8 @@ General options: --passin=ARG : set -passin ARG for openssl --passout=ARG : set -passout ARG for openssl ---pki-dir=DIR : declares the PKI directory +--pki-dir=DIR : declare the PKI directory +--tmp-dir=DIR : declare the temporary directory --ssl-conf=FILE : define a specific OpenSSL config file for Easy-RSA to use --vars=FILE : define a specific 'vars' file to use for Easy-RSA config --version : prints EasyRSA version and build information, then exits @@ -2984,6 +2985,8 @@ while :; do ;; --pki-dir) export EASYRSA_PKI="$val" ;; + --tmp-dir) + export EASYRSA_TEMP_DIR="$val" ;; --ssl-conf) export EASYRSA_SSL_CONF="$val" ;; --use-algo) From 7c2dd54214645ea9b87767192b3296128d2b1685 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 18 Apr 2022 22:07:47 +0100 Subject: [PATCH 42/73] Terminate if temporary directory does not exist + typ0 [shellcheck] Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index bda7333..1cd7e0a 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -347,7 +347,8 @@ secure_session() { # temporary directory must exist [ -n "$EASYRSA_TEMP_DIR" ] || return - [ -d "$EASYRSA_TEMP_DIR" ] || return + [ -d "$EASYRSA_TEMP_DIR" ] || die "\ +Non-existant temporary directory: $EASYRSA_TEMP_DIR" for i in 1 2 3; do session="$(easyrsa_openssl rand -hex 4)" @@ -741,7 +742,7 @@ install_data_to_pki () { # Only init-pki can inherit a previous session when deleting a PKI # Only init-pki is allowed to create a new session # 'init-pki soft' does not delete the old session, delete it now - [ -d "$EASYRSA_TEMP_DIR_session" ] && rm -rf "$EASYRSA_TEMP_DIR_session" ] + [ -d "$EASYRSA_TEMP_DIR_session" ] && rm -rf "$EASYRSA_TEMP_DIR_session" unset -v EASYRSA_TEMP_DIR_session fi From 1b8a1122d37fbed937014e2d0ba8febb30030a9c Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 18 Apr 2022 23:58:56 +0100 Subject: [PATCH 43/73] Remove CA specific EASYRSA_CA_EXTRA_EXTS, not required. * EASYRSA_CA_EXTRA_EXTS: Created to avoid clash with EASYRSA_EXTRA_EXTS EASYRSA_CA_EXTRA_EXTS was an interim hack to avoid triggering a code injection buried deep inside easyrsa_openssl(), when building a CA. Fixed by Commit: 057be57825616199d125dfffbc5abfa9efaae792 Remove EASYRSA_CA_EXTRA_EXTS: Created by Commit: 6f138abb5b091fe7715fa7c8c6369d7704b6f177 The result is for all extra extensions to be subject to the same code. The CA no longer has to dodge the code injection. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 1cd7e0a..ca7ba10 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -896,8 +896,6 @@ current CA keypair. If you intended to start a new CA, run init-pki first." # example: "-addext foo,a:b -addext bah,c:d -addext baz e:f,g" [ "${EASYRSA_EXTRA_EXTS%% *}" = '-addext' ] || \ die "EASYRSA_EXTRA_EXTS: $EASYRSA_EXTRA_EXTS" - EASYRSA_CA_EXTRA_EXTS="$EASYRSA_EXTRA_EXTS" - unset -v EASYRSA_EXTRA_EXTS fi # Choose SSL Library version (1, 2(LibreSSL) or 3) and build CA @@ -972,7 +970,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." # create the CA keypair: easyrsa_openssl req -utf8 -new \ -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ - $opts $EASYRSA_CA_EXTRA_EXTS \ + $opts $EASYRSA_EXTRA_EXTS \ ${crypto_opts:+ "$crypto_opts"} \ ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ ${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \ @@ -1041,7 +1039,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." easyrsa_openssl req -utf8 -new \ -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ - $opts $EASYRSA_CA_EXTRA_EXTS \ + $opts $EASYRSA_EXTRA_EXTS \ ${crypto_opts:+ "$crypto_opts"} \ ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ ${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \ From 2fe73a50400d97540053b2f15ff5a8c7cde332f2 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 19 Apr 2022 13:17:45 +0100 Subject: [PATCH 44/73] Disable shellcheck 2086 when building CA cert/key pair SC2086 - Double quote to prevent globbing and word splitting. It is not suitable to quote $opts and $EASYRSA_EXTRA_EXTS because then they are passed to SSL as a single option with spaces, which is not the intended use. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index ca7ba10..e86dbe5 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -957,6 +957,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." die "Unknown algorithm: $EASYRSA_ALGO" esac + # Apply password or not # Private key encryption password or use no_password # 'req' requires '-passin' crypto_opts="" @@ -968,6 +969,10 @@ current CA keypair. If you intended to start a new CA, run init-pki first." fi # create the CA keypair: + # It is not suitable to quote $opts and $EASYRSA_EXTRA_EXTS + # because then they are passed to SSL as a single option + # with spaces, which is not the intended use. + # shellcheck disable=SC2086 # Double quote to prevent .. easyrsa_openssl req -utf8 -new \ -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ $opts $EASYRSA_EXTRA_EXTS \ @@ -1028,7 +1033,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." *) die "Unknown algorithm: $EASYRSA_ALGO" esac - # create the CA keypair: + # Apply password or not crypto_opts="" if [ -z "$nopass" ] && [ -z "$EASYRSA_PASSIN" ]; then #crypto_opts="-passin file:$out_key_pass_tmp" @@ -1037,6 +1042,11 @@ current CA keypair. If you intended to start a new CA, run init-pki first." crypto_opts="$no_password" fi + # create the CA keypair: + # It is not suitable to quote $opts and $EASYRSA_EXTRA_EXTS + # because then they are passed to SSL as a single option + # with spaces, which is not the intended use. + # shellcheck disable=SC2086 # Double quote to prevent .. easyrsa_openssl req -utf8 -new \ -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ $opts $EASYRSA_EXTRA_EXTS \ From 993c378dac5ada7c36271a73b074fb7ba589fefa Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 19 Apr 2022 15:18:12 +0100 Subject: [PATCH 45/73] Improve shellcheck usage by adding descriptive comments Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index e86dbe5..ac64df9 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -310,7 +310,7 @@ $1 # Returns 0 when input contains yes, 1 for no, 2 for no match # If both strings are present, returns 1; first matching line returns. awk_yesno() { - #shellcheck disable=SC2016 + # shellcheck disable=SC2016 # vars don't expand in single quotes awkscript=' BEGIN {IGNORECASE=1; r=2} { if(match($0,"no")) {r=1; exit} @@ -332,7 +332,7 @@ $msg Type the word '$value' to continue, or any other input to abort." printf %s " $prompt" - #shellcheck disable=SC2162 + # shellcheck disable=SC2162 # read without -r will mangle backslashes read input printf '\n' [ "$input" = "$value" ] && return @@ -775,6 +775,8 @@ install_data_to_pki () { # Disable terminal echo, if possible, otherwise warn hide_read_pass() { + # 3040 - In POSIX sh, set option [name] is undefined + # 3045 - In POSIX sh, some-command-with-flag is undefined # shellcheck disable=SC3040,SC3045 if stty -echo 2>/dev/null; then read -r "$@" @@ -847,6 +849,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." printf '%s\n' "01" > "$EASYRSA_PKI/serial" || die "$err_file" # Default CN only when not in global EASYRSA_BATCH mode: + # 2015 - Note that A && B || C is not if-then-else. C may run when A is true # shellcheck disable=SC2015 [ "$EASYRSA_BATCH" ] && opts="$opts -batch" || export EASYRSA_REQ_CN="Easy-RSA CA" @@ -866,7 +869,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." printf "Re-Enter New CA Key Passphrase: " hide_read_pass kpass2 echo - # shellcheck disable=2154 + # shellcheck disable=2154 # var is referenced but not assigned if [ "$kpass" = "$kpass2" ]; then printf "%s" "$kpass" > "$out_key_pass_tmp" @@ -876,7 +879,7 @@ current CA keypair. If you intended to start a new CA, run init-pki first." fi # Insert x509-types COMMON and 'ca' - # shellcheck disable=SC2016 + # shellcheck disable=SC2016 # vars don't expand in single quote awkscript=' {if ( match($0, "^#%X509_TYPES%") ) { while ( getline<"/dev/stdin" ) {print} next } @@ -899,11 +902,6 @@ current CA keypair. If you intended to start a new CA, run init-pki first." fi # Choose SSL Library version (1, 2(LibreSSL) or 3) and build CA - # - # * shellcheck SC2086 # Ignore unquoted variables - # The "correct" solution is to not need unquoted substitutions .. - # - # ##shellcheck disable=SC2086 # Ignore unquoted variables case "$osslv_major" in # => BEGIN SSL lib version # BEGIN SSL V3 @@ -1157,7 +1155,7 @@ Continuing with key generation will replace this key." req_extensions = req_extra [ req_extra ] $EASYRSA_EXTRA_EXTS" - #shellcheck disable=SC2016 + # shellcheck disable=SC2016 # vars don't expand in single quote awkscript=' {if ( match($0, "^#%EXTRA_EXTS%") ) { while ( getline<"/dev/stdin" ) {print} next } @@ -1375,7 +1373,7 @@ Matching file found at: " # create request EASYRSA_REQ_CN="$name" - #shellcheck disable=SC2086 # Ignore unquoted variables + # shellcheck disable=SC2086 # Ignore unquoted variables gen_req "$name" batch $req_opts # Sign it @@ -1744,7 +1742,6 @@ gen_crl() { out_file="$EASYRSA_PKI/crl.pem" out_file_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" - # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl ca -utf8 -gencrl -out "$out_file_tmp" \ ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || die "\ CRL Generation failed." @@ -1864,7 +1861,6 @@ Export of p12 failed: see above for related openssl errors." pkcs_out="$EASYRSA_PKI/issued/$short_name.p7b" # export the p7: - # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl crl2pkcs7 -nocrl -certfile "$crt_in" \ -out "$pkcs_out" \ ${pkcs_certfile_path:+-certfile "$pkcs_certfile_path"} \ @@ -1996,7 +1992,8 @@ default_server_san() { awk -F'=' '/^ *CN=/{print $2}' ) echo "$cn" | grep -E -q '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' - #shellcheck disable=SC2181 + # Check exit code directly with e.g. if mycmd;, not indirectly with $?. + # shellcheck disable=SC2181 if [ $? -eq 0 ]; then print "subjectAltName = IP:$cn" else From 60f3fc2728c53a655ee8f390a2394e6f6702f0ad Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 19 Apr 2022 15:20:54 +0100 Subject: [PATCH 46/73] Quote $cert_ext_key_usage in renew() 'case' is "immune" to standard word splitting and globbing but code-style now demands that 'case' does not get treated differently. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index ac64df9..7187405 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1607,7 +1607,7 @@ Renewal not allowed." sed -n "/X509v3 Extended Key Usage:/{n;s/^ *//g;p;}" ) - case $cert_ext_key_usage in + case "$cert_ext_key_usage" in "TLS Web Client Authentication") cert_type=client ;; From adc2cbed58912ff124456efb7397493e8670b684 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 19 Apr 2022 15:27:20 +0100 Subject: [PATCH 47/73] Check status of command, not exit-code, in default_server_san() Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 7187405..0a89e4e 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1991,10 +1991,8 @@ default_server_san() { easyrsa_openssl req -in "$path" -noout -subject -nameopt sep_multiline | awk -F'=' '/^ *CN=/{print $2}' ) - echo "$cn" | grep -E -q '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' - # Check exit code directly with e.g. if mycmd;, not indirectly with $?. - # shellcheck disable=SC2181 - if [ $? -eq 0 ]; then + + if echo "$cn" | grep -E -q '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'; then print "subjectAltName = IP:$cn" else print "subjectAltName = DNS:$cn" From 0cf547feab0412a9de6148873ecce6e48458b7ca Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 20 Apr 2022 14:37:32 +0100 Subject: [PATCH 48/73] Add placeholder for CA $X509_TYPES and $EXTRA_EXTS Placeholder: %CA_X509_TYPES_EXTRA_EXTS% Signed-off-by: Richard T Bonhomme --- easyrsa3/openssl-easyrsa.cnf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easyrsa3/openssl-easyrsa.cnf b/easyrsa3/openssl-easyrsa.cnf index bee05b1..7c45bcf 100644 --- a/easyrsa3/openssl-easyrsa.cnf +++ b/easyrsa3/openssl-easyrsa.cnf @@ -128,8 +128,8 @@ keyUsage = cRLSign, keyCertSign # nsCertType omitted by default. Let's try to let the deprecated stuff die. # nsCertType = sslCA -# A placeholder to handle the $X509_TYPES: -#%X509_TYPES% # Do NOT remove or change this line as $X509_TYPES demands it +# A placeholder to handle the $X509_TYPES and CA extra extensions $EXTRA_EXTS: +#%CA_X509_TYPES_EXTRA_EXTS% # Do NOT remove or change this line as $X509_TYPES and EXTRA_EXTS demands it # CRL extensions. [ crl_ext ] From e80c229559dec4ce71e79d891faa4540e513cb9c Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 20 Apr 2022 15:52:20 +0100 Subject: [PATCH 49/73] Make build-ca() almost completely SSL library version independent The only option which is not SSL version independent is: -nodes (version 1) -noenc (version 3) This is managed via $no_password, which is set by verify_ssl_lib(). * Use SSL 'genpkey' to create All CA private keys. 'genpkey' options are SSL version independent. * Use SSL 'req' to create All CA certificate/key pairs. 'req' options are SSL version independent. * Replace $opts, $crypto and $crypto_opts with individual variables for each purpose. * '$opts' usage: -x509 - Replaced by $x509 -date - Replaced by $date_stamp ($date would be too common) -batch - Replaced by $ssl_batch * '$crypto' usage: -aes256 - Replaced by $cipher * '$crypto_opts' usage: -aes256 - Replaced by $cipher (2nd layer of unnecessary complexity) -nodes/-noenc - Replaced by $no_password * Additional variable $digest for SSL 'req' - Defaults to '-sha256' Insert $EASYRSA_EXTRA_EXTS into the config file along with x509-types files 'ca' and COMMON. Replaces the previous method of passing SSL option '-addext foo:bar' directly to SSL command. Create new EasyRSA option '--verbose'. This prints the command passed to the SSL library by easyrsa_openssl(). Add a shellcheck directive to install_data_to_pki(). Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 221 ++++++++++++++--------------------------------- 1 file changed, 66 insertions(+), 155 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 0a89e4e..c7c7871 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -444,11 +444,19 @@ easyrsa_openssl() { mv "$easyrsa_openssl_conf" "$EASYRSA_SAFE_CONF" || \ die "easyrsa_openssl - makesafeconf failed" else + # Verbose log + [ "$EASYRSA_VERBOSE" ] && printf '%s\n' \ + "$EASYRSA_OPENSSL $openssl_command -config $easyrsa_openssl_conf $*" + # Exec SSL with -config temp-file "$EASYRSA_OPENSSL" "$openssl_command" \ -config "$easyrsa_openssl_conf" "$@" || return fi else + # Verbose log + [ "$EASYRSA_VERBOSE" ] && [ ! "$openssl_command" = rand ] \ + && printf '%s\n' "$EASYRSA_OPENSSL $openssl_command $*" + # Exec SSL without -config temp-file "$EASYRSA_OPENSSL" "$openssl_command" "$@" || return fi @@ -765,6 +773,8 @@ install_data_to_pki () { # EASYRSA_EXT_DIR must be found! No exceptions! # The shellcheck warning 2015 is valid, however, this code works correctly. + # Note that A && B || C is not if-then-else. C may run when A is true + # shellcheck disable=SC2015 [ -n "$EASYRSA_EXT_DIR" ] && [ -e "$EASYRSA_EXT_DIR" ] || \ die "x509-types folder cannot be found" @@ -795,16 +805,15 @@ hide_read_pass() # build-ca backend: build_ca() { - opts="" - sub_ca="" - nopass="" - crypto="-aes256" + cipher="-aes256" + digest="-sha256" + unset -v nopass sub_ca ssl_batch date_stamp x509 while [ -n "$1" ]; do case "$1" in intca) sub_ca=1 ;; subca) sub_ca=1 ;; nopass) nopass=1 ;; - *) warn "Ignoring unknown command option: '$1'" ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -813,12 +822,23 @@ build_ca() { [ "$EASYRSA_ALGO" = "ec" ] && verify_curve_ec [ "$EASYRSA_ALGO" = "ed" ] && verify_curve_ed - # setup for the simpler intermediate CA situation and overwrite with root-CA if needed: - out_file="$EASYRSA_PKI/reqs/ca.req" + out_file="$EASYRSA_PKI/ca.crt" out_key="$EASYRSA_PKI/private/ca.key" - if [ -z "$sub_ca" ]; then - out_file="$EASYRSA_PKI/ca.crt" - opts="$opts -x509 -days $EASYRSA_CA_EXPIRE" + # setup for an intermediate CA + if [ "$sub_ca" ]; then + # Gerate a CSR + out_file="$EASYRSA_PKI/reqs/ca.req" + else + # Gerate a certificate + date_stamp=1 + x509=1 + fi + + # If encrypted then create the CA key using AES256 cipher + if [ "$nopass" ]; then + unset -v cipher + else + unset -v no_password fi # Test for existing CA, and complain if already present @@ -849,9 +869,8 @@ current CA keypair. If you intended to start a new CA, run init-pki first." printf '%s\n' "01" > "$EASYRSA_PKI/serial" || die "$err_file" # Default CN only when not in global EASYRSA_BATCH mode: - # 2015 - Note that A && B || C is not if-then-else. C may run when A is true - # shellcheck disable=SC2015 - [ "$EASYRSA_BATCH" ] && opts="$opts -batch" || export EASYRSA_REQ_CN="Easy-RSA CA" + [ "$EASYRSA_BATCH" ] && ssl_batch=1 + [ "$EASYRSA_REQ_CN" = ChangeMe ] && export EASYRSA_REQ_CN="Easy-RSA CA" out_key_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" out_file_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" @@ -870,62 +889,45 @@ current CA keypair. If you intended to start a new CA, run init-pki first." hide_read_pass kpass2 echo # shellcheck disable=2154 # var is referenced but not assigned - if [ "$kpass" = "$kpass2" ]; - then + if [ "$kpass" = "$kpass2" ]; then printf "%s" "$kpass" > "$out_key_pass_tmp" else die "Passphrases do not match." fi fi - # Insert x509-types COMMON and 'ca' + # Insert x509-types COMMON and 'ca' and EASYRSA_EXTRA_EXTS, if defined. # shellcheck disable=SC2016 # vars don't expand in single quote awkscript=' -{if ( match($0, "^#%X509_TYPES%") ) +{if ( match($0, "^#%CA_X509_TYPES_EXTRA_EXTS%") ) { while ( getline<"/dev/stdin" ) {print} next } {print} }' conf_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" - cat "${EASYRSA_EXT_DIR}/ca" "${EASYRSA_EXT_DIR}/COMMON" | \ + { + cat "$EASYRSA_EXT_DIR/ca" "$EASYRSA_EXT_DIR/COMMON" + [ "$EASYRSA_EXTRA_EXTS" ] && print "$EASYRSA_EXTRA_EXTS" + } | \ awk "$awkscript" "$EASYRSA_SSL_CONF" \ > "$conf_tmp" \ - || die "Copying SSL config to temp file failed" + || die "Copying X509_TYPES to config file failed" # Use this new SSL config for the rest of this function EASYRSA_SSL_CONF="$conf_tmp" - # When EASYRSA_EXTRA_EXTS is defined, pass it as-is to SSL -addext - if [ -n "$EASYRSA_EXTRA_EXTS" ]; then - # example: "-addext foo,a:b -addext bah,c:d -addext baz e:f,g" - [ "${EASYRSA_EXTRA_EXTS%% *}" = '-addext' ] || \ - die "EASYRSA_EXTRA_EXTS: $EASYRSA_EXTRA_EXTS" - fi - # Choose SSL Library version (1, 2(LibreSSL) or 3) and build CA - case "$osslv_major" in # => BEGIN SSL lib version + case "$osslv_major" in - # BEGIN SSL V3 - 3) - # If encrypted then create the CA key using AES256 cipher ($crypto) - # 'genpkey' requires '-pass' - crypto_opts="" - if [ -z "$nopass" ]; then - crypto_opts="$crypto" - if [ -z "$EASYRSA_PASSOUT" ]; then - #crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" - : # ok - fi - fi - - # Generate CA Key - OpenSSL v3 'genpkey' is not compatible - # with easyrsa $opts and $no_password, do NOT use them here + # Version agnostic CA generation + # The only remaining option which is version dependent is -nodes/-noenc + 1|2|3) + # Generate CA Key case "$EASYRSA_ALGO" in rsa) - # OpenSSL v3: 'genrsa' is deprecate, use 'genpkey' easyrsa_openssl genpkey -algorithm "$EASYRSA_ALGO" \ - -out "$out_key_tmp" \ -pkeyopt rsa_keygen_bits:"$EASYRSA_ALGO_PARAMS" \ - ${crypto_opts:+ "$crypto_opts"} \ + -out "$out_key_tmp" \ + ${cipher+ "$cipher"} \ ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ || die "Failed create CA private key" @@ -933,130 +935,38 @@ current CA keypair. If you intended to start a new CA, run init-pki first." ec) easyrsa_openssl genpkey -paramfile "$EASYRSA_ALGO_PARAMS" \ -out "$out_key_tmp" \ - ${crypto_opts:+ "$crypto_opts"} \ - ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} \ + ${cipher+ "$cipher"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ || die "Failed create CA private key" ;; ed) - case "$EASYRSA_CURVE" in - [eE][dD]25519|[eE][dD]448) - easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" \ - -out "$out_key_tmp" \ - ${crypto_opts:+ "$crypto_opts"} \ - ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ - ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ - || die "Failed create CA private key" - ;; - *) die "Unknown curve: $EASYRSA_CURVE" - esac - ;; - *) - die "Unknown algorithm: $EASYRSA_ALGO" - esac - - # Apply password or not - # Private key encryption password or use no_password - # 'req' requires '-passin' - crypto_opts="" - if [ -z "$nopass" ] && [ -z "$EASYRSA_PASSIN" ]; then - #crypto_opts="-passin file:$out_key_pass_tmp" - : # ok - else - crypto_opts="$no_password" - fi - - # create the CA keypair: - # It is not suitable to quote $opts and $EASYRSA_EXTRA_EXTS - # because then they are passed to SSL as a single option - # with spaces, which is not the intended use. - # shellcheck disable=SC2086 # Double quote to prevent .. - easyrsa_openssl req -utf8 -new \ - -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ - $opts $EASYRSA_EXTRA_EXTS \ - ${crypto_opts:+ "$crypto_opts"} \ - ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ - ${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \ - || die "Failed to build the CA" - ;; - # END SSL V3 - - # BEGIN SSL V1 - Includes LibreSSL 2.x - 1|2) - # If encrypted then create the CA key using AES256 cipher ($crypto) - crypto_opts="" - if [ -z "$nopass" ]; then - crypto_opts="$crypto" - if [ -z "$EASYRSA_PASSOUT" ]; then - #if [ "ed" = "$EASYRSA_ALGO" ]; then - # crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" - #else - # crypto_opts="$crypto_opts -passout file:$out_key_pass_tmp" - #fi - : # ok - fi - fi - - # create the CA key - case "$EASYRSA_ALGO" in - rsa) - "$EASYRSA_OPENSSL" genrsa -out "$out_key_tmp" \ - ${crypto_opts:+ "$crypto_opts"} \ - ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ - ${out_key_pass_tmp:+ -passout file:"$out_key_pass_tmp"} \ - "$EASYRSA_ALGO_PARAMS" \ + easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" \ + -out "$out_key_tmp" \ + ${cipher+ "$cipher"} \ + ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ + ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ || die "Failed create CA private key" ;; - ec) - "$EASYRSA_OPENSSL" ecparam -in "$EASYRSA_ALGO_PARAMS" -genkey | \ - "$EASYRSA_OPENSSL" ec -out "$out_key_tmp" \ - ${crypto_opts:+ "$crypto_opts"} \ - ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \ - ${out_key_pass_tmp:+ -passout file:"$out_key_pass_tmp"} \ - || die "Failed create CA private key" - ;; - ed) - case "$EASYRSA_CURVE" in - [eE][dD]25519|[eE][dD]448) - "$EASYRSA_OPENSSL" genpkey -algorithm "$EASYRSA_CURVE" \ - -out "$out_key_tmp" \ - ${crypto_opts:+ "$crypto_opts"} \ - ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \ - ${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \ - || die "Failed create CA private key" - ;; - *) die "Unknown curve: $EASYRSA_CURVE" - esac - ;; *) die "Unknown algorithm: $EASYRSA_ALGO" esac - # Apply password or not - crypto_opts="" - if [ -z "$nopass" ] && [ -z "$EASYRSA_PASSIN" ]; then - #crypto_opts="-passin file:$out_key_pass_tmp" - : # ok - else - crypto_opts="$no_password" - fi - - # create the CA keypair: - # It is not suitable to quote $opts and $EASYRSA_EXTRA_EXTS - # because then they are passed to SSL as a single option - # with spaces, which is not the intended use. + # Generate the CA keypair: # shellcheck disable=SC2086 # Double quote to prevent .. easyrsa_openssl req -utf8 -new \ - -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \ - $opts $EASYRSA_EXTRA_EXTS \ - ${crypto_opts:+ "$crypto_opts"} \ + -key "$out_key_tmp" -keyout "$out_key_tmp" \ + -out "$out_file_tmp" \ + ${ssl_batch+ -batch} \ + ${x509+ -x509} \ + ${date_stamp+ -days "$EASYRSA_CA_EXPIRE"} \ + "$digest" \ + ${no_password+ "$no_password"} \ ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ ${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \ || die "Failed to build the CA" ;; - # END SSL V1 - *) die "build-ca ssl lib: $osslv_major" - esac # => END SSL lib version + esac mv "$out_key_tmp" "$out_key" mv "$out_file_tmp" "$out_file" @@ -1076,8 +986,6 @@ CA creation complete and you may now import and sign cert requests. Your new CA certificate file for publishing is at: $out_file" fi - - return 0 } # => build_ca() # gen-dh backend: @@ -3038,6 +2946,9 @@ while :; do empty_ok=1 export EASYRSA_SILENT=1 export EASYRSA_BATCH=1 ;; + --verbose) + empty_ok=1 + export EASYRSA_VERBOSE=1 ;; --passin) export EASYRSA_PASSIN="$val";; --passout) From a0ed1203f212579c12ff325c9f0f2a65816b4b13 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 20 Apr 2022 22:06:25 +0100 Subject: [PATCH 50/73] Priorise trap above vars_setup() vars_setup() has become more complex, therefore, trap should be set earlier. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index c7c7871..7820c52 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2981,6 +2981,16 @@ subjectAltName = $val" ;; shift done +# Register cleanup on EXIT +trap "cleanup" EXIT +# When SIGHUP, SIGINT, SIGQUIT, SIGABRT and SIGTERM, +# explicitly exit to signal EXIT (non-bash shells) +trap "exit 1" 1 +trap "exit 2" 2 +trap "exit 3" 3 +trap "exit 6" 6 +trap "exit 14" 15 + # Set cmd now because vars_setup needs to know if this is init-pki cmd="$1" [ -n "$1" ] && shift # scrape off command @@ -2997,16 +3007,6 @@ esac # Intelligent env-var detection and auto-loading: vars_setup -# Register cleanup on EXIT -trap "cleanup" EXIT -# When SIGHUP, SIGINT, SIGQUIT, SIGABRT and SIGTERM, -# explicitly exit to signal EXIT (non-bash shells) -trap "exit 1" 1 -trap "exit 2" 2 -trap "exit 3" 3 -trap "exit 6" 6 -trap "exit 14" 15 - # determine how we were called, then hand off to the function responsible case "$cmd" in init-pki|clean-all) From df526695d8b475cb844347d814c4984a7bda53c3 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 20 Apr 2022 22:14:11 +0100 Subject: [PATCH 51/73] Prioritise detecting host OS over setting defaults This allows EasyRSA to detect and use OpenSSL shipped with Git-for-Windows. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 57 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 7820c52..869e6d1 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2153,6 +2153,35 @@ Sourcing the vars file will probably fail .." # END: Find vars fi + # Identify host OS + unset -v easyrsa_host_os easyrsa_host_test easyrsa_win_git_bash + + # Detect Windows + easyrsa_host_test="${OS}" + + # shellcheck disable=SC2016 # expansion inside '' blah + easyrsa_ksh='@(#)MIRBSD KSH R39-w32-beta14 $Date: 2013/06/28 21:28:57 $' + [ "${KSH_VERSION}" = "${easyrsa_ksh}" ] && easyrsa_host_test="${easyrsa_ksh}" + unset -v easyrsa_ksh + + # If not Windows then nix + if [ "${easyrsa_host_test}" ]; then + easyrsa_host_os=win + easyrsa_host_os_version="${easyrsa_host_test}" + # Detect Windows git/bash + if [ "${EXEPATH}" ]; then + easyrsa_win_git_bash="${EXEPATH}" + # If found then set openssl NOW! + [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl + fi + else + easyrsa_host_os=nix + easyrsa_host_os_version="$(uname)" + fi + host_out="$easyrsa_host_os | $easyrsa_host_os_version" + host_out="${host_out}${easyrsa_win_git_bash:+ | "$easyrsa_win_git_bash"}" + unset -v easyrsa_host_test + # Set defaults, preferring existing env-vars if present set_var EASYRSA "$PWD" set_var EASYRSA_OPENSSL openssl @@ -2232,34 +2261,6 @@ Sourcing the vars file will probably fail .." : # ok fi fi - - # Identify host OS - unset -v easyrsa_host_os easyrsa_host_test easyrsa_win_git_bash - - # Detect Windows - easyrsa_host_test="${OS}" - - # shellcheck disable=SC2016 # expansion inside '' blah - easyrsa_ksh='@(#)MIRBSD KSH R39-w32-beta14 $Date: 2013/06/28 21:28:57 $' - [ "${KSH_VERSION}" = "${easyrsa_ksh}" ] && easyrsa_host_test="${easyrsa_ksh}" - unset -v easyrsa_ksh - - # If not Windows then nix - if [ "${easyrsa_host_test}" ]; then - easyrsa_host_os=win - easyrsa_host_os_version="${easyrsa_host_test}" - # Detect Windows git/bash - if [ "${EXEPATH}" ]; then - easyrsa_win_git_bash="${EXEPATH}" - [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl - fi - else - easyrsa_host_os=nix - easyrsa_host_os_version="$(uname)" - fi - host_out="$easyrsa_host_os | $easyrsa_host_os_version" - host_out="${host_out}${easyrsa_win_git_bash:+ | "$easyrsa_win_git_bash"}" - unset -v easyrsa_host_test } # vars_setup() # variable assignment by indirection when undefined; merely exports From 9a8e77e04319f13497e5abb607e920ab5c50fab9 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 20 Apr 2022 22:18:41 +0100 Subject: [PATCH 52/73] install_data_to_pki(): Use 'cp --no-clobber' to install a blank vars In the context of 'vars-setup', install_data_to_pki() will only copy the example vars file to a live vars file in the event that no other vars file exists. This final check will never over-write vars file which is in the PKI. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 869e6d1..cf2ac80 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -680,6 +680,9 @@ install_data_to_pki () { # # Copying 'vars' to the PKI is complicated, code is included but DISABLED. + context="$1" + shift + # Set required sources vars_file='vars' vars_file_example='vars.example' @@ -735,9 +738,8 @@ install_data_to_pki () { fi # If this is init-pki then create PKI/vars from PKI/example - case "$1" in + case "$context" in init-pki) - shift if [ -e "${EASYRSA_PKI}/${vars_file_example}" ] && \ [ ! -e "${EASYRSA_PKI}/${vars_file}" ] then @@ -758,11 +760,22 @@ install_data_to_pki () { secure_session || die "install_data_to_pki - secure_session" ;; vars-setup) - shift ;; # ok + if [ "$found_vars" ]; then + : # ok - Do not make a PKI/vars if another vars exists + else + if [ -e "${EASYRSA_PKI}/${vars_file_example}" ] && \ + [ ! -e "${EASYRSA_PKI}/${vars_file}" ] + then + # This is allowed to fail because it should not be necessary + cp -n "${EASYRSA_PKI}/${vars_file_example}" \ + "${EASYRSA_PKI}/${vars_file}" || : + fi + fi + ;; '') die "install_data_to_pki - unspecified context" ;; *) - die "install_data_to_pki - unknown context: $1" + die "install_data_to_pki - unknown context: $context" esac # Check PKI is updated - Omit unnecessary checks From 8d82501fd079214d96b83d9ad33be884f5ae4f58 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 20 Apr 2022 22:33:21 +0100 Subject: [PATCH 53/73] Minor improvements to vars_setup() and build_ca() These changes are only for readabilty and simplicity. No functional changes. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index cf2ac80..669c013 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -835,7 +835,6 @@ build_ca() { [ "$EASYRSA_ALGO" = "ec" ] && verify_curve_ec [ "$EASYRSA_ALGO" = "ed" ] && verify_curve_ed - out_file="$EASYRSA_PKI/ca.crt" out_key="$EASYRSA_PKI/private/ca.key" # setup for an intermediate CA if [ "$sub_ca" ]; then @@ -843,6 +842,7 @@ build_ca() { out_file="$EASYRSA_PKI/reqs/ca.req" else # Gerate a certificate + out_file="$EASYRSA_PKI/ca.crt" date_stamp=1 x509=1 fi @@ -2041,7 +2041,6 @@ vars_setup() { prog_file="$0" # Removed for basic sanity - To re-enable provide a REASON #prog_file2="$(which -- "$prog_file" 2>/dev/null)" && prog_file="$prog_file2" - # Removed for breaking New Windows - To re-enable provide a SOLUTION #prog_file2="$(readlink -f "$prog_file" 2>/dev/null)" && prog_file="$prog_file2" prog_dir="${prog_file%/*}" @@ -2121,12 +2120,15 @@ Priority should be given to your PKI vars file: [ "$easy_vars" ] && vars="$easy_vars" [ "$prog_vars" ] && vars="$prog_vars" # Prioritise vars_in_pki - [ "$pki_vars" ] && vars="$pki_vars" && vars_in_pki=1 + [ "$pki_vars" ] && vars="$pki_vars" fi # If $EASYRSA_NO_VARS is defined (not blank) then do not use vars # if $want_init_pki then do not use vars - if [ -z "$EASYRSA_NO_VARS" ] && [ -z "$want_init_pki" ]; then + if [ "$EASYRSA_NO_VARS" ] || [ "$want_init_pki" ]; then + # EASYRSA_NO_VARS is defined or want_init_pki, no vars is required. + : # ok + else # If a vars file was located then source it if [ "$vars" ]; then # Sanitize vars @@ -2138,7 +2140,7 @@ recommended - please remove it from there before continuing." fi # Sanitize vars further but ONLY if it is in PKI folder - if [ "$vars_in_pki" ]; then + if [ "$pki_vars" ]; then # Warning: Single quote if grep -q "'" "$vars"; then warn "\ @@ -2157,11 +2159,8 @@ Sourcing the vars file will probably fail .." warn "Move your vars file to your PKI folder, where it is safe!" else # $vars remains undefined .. no vars found - warn "No vars file found! Please create one in your PKI folder." + : # ok fi - else - # EASYRSA_NO_VARS is defined or want_init_pki, no vars is required. - : # ok fi # END: Find vars fi @@ -2242,8 +2241,9 @@ Sourcing the vars file will probably fail .." # # Also, integrate a partial 'init-pki' by using 'install_data_to_pki()' # - # If EASYRSA_TEMP_DIR_session is not set then + # If EASYRSA_PKI directory exists then if [ -d "$EASYRSA_PKI" ]; then + # Temp dir session secure_session || die "Temporary directory secure-session failed." From 59dc15ac517534a1c18f36cec70d990f9b3eb464 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Thu, 21 Apr 2022 01:42:30 +0100 Subject: [PATCH 54/73] vars_setup(): Remove $vars_in_pki, unused. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 669c013..ac5b8e6 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2078,7 +2078,7 @@ vars_setup() { # Clear flags - This is the preferred order to find: unset -v e_pki_vars e_easy_vars e_pwd_vars e_prog_vars \ - found_vars vars_in_pki + found_vars # PKI location, if present: { [ -e "$pki_vars" ] && e_pki_vars=1; } || unset -v pki_vars @@ -2119,18 +2119,19 @@ Priority should be given to your PKI vars file: [ "$pwd_vars" ] && vars="$pwd_vars" [ "$easy_vars" ] && vars="$easy_vars" [ "$prog_vars" ] && vars="$prog_vars" - # Prioritise vars_in_pki [ "$pki_vars" ] && vars="$pki_vars" fi # If $EASYRSA_NO_VARS is defined (not blank) then do not use vars - # if $want_init_pki then do not use vars + # if $want_init_pki then no vars is required. if [ "$EASYRSA_NO_VARS" ] || [ "$want_init_pki" ]; then - # EASYRSA_NO_VARS is defined or want_init_pki, no vars is required. : # ok else # If a vars file was located then source it - if [ "$vars" ]; then + if [ -z "$vars" ]; then + # $vars remains undefined .. no vars found + : # ok + else # Sanitize vars if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then die "\ @@ -2140,7 +2141,7 @@ recommended - please remove it from there before continuing." fi # Sanitize vars further but ONLY if it is in PKI folder - if [ "$pki_vars" ]; then + if [ "$vars_in_pki" ]; then # Warning: Single quote if grep -q "'" "$vars"; then warn "\ @@ -2155,11 +2156,8 @@ Sourcing the vars file will probably fail .." # shellcheck disable=1090 # can't follow non-constant source. vars . "$vars" notice "Using Easy-RSA configuration from: $vars" - [ "$vars_in_pki" ] || \ + [ "$pki_vars" ] || \ warn "Move your vars file to your PKI folder, where it is safe!" - else - # $vars remains undefined .. no vars found - : # ok fi fi # END: Find vars From bf19e794d379654fa4cc7df308fb650fda729169 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Thu, 21 Apr 2022 01:46:10 +0100 Subject: [PATCH 55/73] Correction to: 59dc15ac517534a1c18f36cec70d990f9b3eb464 Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index ac5b8e6..cef3b82 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2141,7 +2141,7 @@ recommended - please remove it from there before continuing." fi # Sanitize vars further but ONLY if it is in PKI folder - if [ "$vars_in_pki" ]; then + if [ "$pki_vars" ]; then # Warning: Single quote if grep -q "'" "$vars"; then warn "\ From ceb9a2093c8a90bae3b32be86ef58764960fd9ea Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 17:07:11 +0100 Subject: [PATCH 56/73] Refactor show_ca() - Quote all expansions (#494) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index cef3b82..746e349 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1992,10 +1992,10 @@ OpenSSL failure to process the input" # Prints CA cert details in a readable format show_ca() { # opts support - opts="-certopt no_pubkey,no_sigdump" + out_opts="no_pubkey,no_sigdump" while [ -n "$1" ]; do case "$1" in - full) opts= ;; + full) out_opts= ;; *) warn "Ignoring unknown command option: '$1'" ;; esac shift @@ -2011,7 +2011,7 @@ 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" || die "\ This file is not a valid $type file: $in_file" @@ -2021,9 +2021,8 @@ $in_file" This file is stored at: * $in_file" - # shellcheck disable=SC2086 # Ignore unquoted variables - easyrsa_openssl $format -in "$in_file" -noout -text\ - -nameopt multiline $opts || die "\ + easyrsa_openssl "$format" -in "$in_file" -noout -text\ + -nameopt multiline -certopt "$out_opts" || die "\ OpenSSL failure to process the input" } # => show_ca() From 757b2776d7c85b3998998ce13114227793236eac Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 17:17:51 +0100 Subject: [PATCH 57/73] Refactor show() - Quote all expansions (#494) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 746e349..8984161 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1941,11 +1941,12 @@ Run easyrsa without commands for usage help." shift 2 # opts support - opts="-${type}opt no_pubkey,no_sigdump" + type_opts="-${type}opt" + out_opts="no_pubkey,no_sigdump" while [ -n "$1" ]; do case "$1" in full) - opts="" + out_opts= ;; *) warn "Ignoring unknown command option: '$1'" @@ -1972,7 +1973,7 @@ Expected to find this file at: $in_file" # shellcheck disable=SC2086 # Ignore unquoted variables - verify_file $format "$in_file" || die "\ + verify_file "$format" "$in_file" || die "\ This file is not a valid $type file: $in_file" @@ -1983,8 +1984,8 @@ $in_file" * $in_file" # shellcheck disable=SC2086 # Ignore unquoted variables - easyrsa_openssl $format -in "$in_file" -noout -text\ - -nameopt multiline $opts || die "\ + easyrsa_openssl "$format" -in "$in_file" -noout -text \ + -nameopt multiline "$type_opts" "$out_opts" || die "\ OpenSSL failure to process the input" } # => show() From 2a9cd44902bce4d4d953640b57c13adc3f040c20 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 17:21:27 +0100 Subject: [PATCH 58/73] Refactor default_server_san() - Quote all expansions (#494) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 8984161..0300495 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1908,10 +1908,10 @@ display_dn() { # generate default SAN from req/X509, passed by full pathname default_server_san() { path="$1" - cn=$( + cn="$( easyrsa_openssl req -in "$path" -noout -subject -nameopt sep_multiline | awk -F'=' '/^ *CN=/{print $2}' - ) + )" if echo "$cn" | grep -E -q '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'; then print "subjectAltName = IP:$cn" From a466f96b4eecb6a8aa4837c38ce5d37b10763c5a Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 17:32:58 +0100 Subject: [PATCH 59/73] Refactor display_san() and display_dn() - Quote all exansions (#494) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 0300495..4bf5994 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1883,21 +1883,21 @@ display_san() { print "$(echo "$EASYRSA_EXTRA_EXTS" | grep subjectAltName | sed 's/^\s*subjectAltName\s*=\s*//')" else - san=$( + san="$( 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;}" - ) + )" [ -n "$san" ] && print "$san" fi -} +} # => display_san() # display cert DN info on a req/X509, passed by full pathname display_dn() { format="$1" path="$2" print "$("$EASYRSA_OPENSSL" "$format" -in "$path" -noout -subject -nameopt multiline)" - san=$(display_san "$1" "$2") + san="$(display_san "$1" "$2")" if [ -n "$san" ]; then print "" print "X509v3 Subject Alternative Name:" From 9b4bd19545ebc7faf0e281483ddb53748c40eb07 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 17:53:21 +0100 Subject: [PATCH 60/73] Refactor set_pass() - Quote all expansions (#494) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 4bf5994..99929d6 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1829,16 +1829,24 @@ See help output for usage details." # parse command options shift 2 - crypto="-aes256" + cipher="-aes256" + unset nopass while [ -n "$1" ]; do case "$1" in - nopass) crypto="" ;; + nopass) nopass=1 ;; file) file="$raw_file" ;; *) warn "Ignoring unknown command option: '$1'" ;; esac shift done + # If nopass then do not encrypt else encrypt with password. + if [ "$nopass" ]; then + unset -v cipher + else + unset -v no_password + fi + [ -f "$file" ] || die "\ Missing private key: expected to find the private key component at: $file" @@ -1849,10 +1857,11 @@ ${crypto:+You will then enter a new PEM passphrase for this key.$NL}" # Set password out_key_tmp="$(easyrsa_mktemp)" || die "Failed to create temporary file" - # shellcheck disable=SC2086 # Ignore unquoted variables - easyrsa_openssl "$key_type" -in "$file" -out "$out_key_tmp" $crypto \ - ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ - ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ + easyrsa_openssl "$key_type" -in "$file" -out "$out_key_tmp" \ + ${cipher:+ "$cipher"} \ + ${no_password:+ "$no_password"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ Failed to change the private key passphrase. See above for possible openssl error messages." @@ -1983,7 +1992,6 @@ $in_file" This file is stored at: * $in_file" - # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl "$format" -in "$in_file" -noout -text \ -nameopt multiline "$type_opts" "$out_opts" || die "\ OpenSSL failure to process the input" From 4b9b3ed6571ebecfd394f15c07f84be3b8a79b3c Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 20:41:32 +0100 Subject: [PATCH 61/73] Exporting P7b files does not support password information Remove EasyRSA addition: '-pass $EASYRSA_PASSIN/OUT' Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 99929d6..7cddaa6 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1785,8 +1785,7 @@ Export of p12 failed: see above for related openssl errors." easyrsa_openssl crl2pkcs7 -nocrl -certfile "$crt_in" \ -out "$pkcs_out" \ ${pkcs_certfile_path:+-certfile "$pkcs_certfile_path"} \ - ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ - ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ + || die "\ Export of p7 failed: see above for related openssl errors." ;; p8) From 2396b2f41aa9c8f82dff9a60bde78b3350571dad Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 21:00:28 +0100 Subject: [PATCH 62/73] Refactor export_pkcs() - Quote all expansions (#494) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 7cddaa6..e448907 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1742,7 +1742,6 @@ Run easyrsa without commands for usage and command help." shift done - pkcs_opts= pkcs_certfile_path= if [ "$want_ca" ]; then verify_file x509 "$crt_ca" || die "\ @@ -1766,16 +1765,17 @@ 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" else - pkcs_opts="-nokeys" + nokeys=1 fi # export the p12: # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl pkcs12 -in "$crt_in" -inkey "$key_in" -export \ - -out "$pkcs_out" $pkcs_opts \ - ${pkcs_certfile_path:+-certfile "$pkcs_certfile_path"} \ - ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ - ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ + -out "$pkcs_out" \ + ${nokeys:+ -nokeys} \ + ${pkcs_certfile_path:+ -certfile "$pkcs_certfile_path"} \ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ Export of p12 failed: see above for related openssl errors." ;; p7) @@ -1784,22 +1784,24 @@ Export of p12 failed: see above for related openssl errors." # export the p7: easyrsa_openssl crl2pkcs7 -nocrl -certfile "$crt_in" \ -out "$pkcs_out" \ - ${pkcs_certfile_path:+-certfile "$pkcs_certfile_path"} \ + ${pkcs_certfile_path:+ -certfile "$pkcs_certfile_path"} \ || die "\ Export of p7 failed: see above for related openssl errors." ;; p8) - if [ -z "$want_pass" ]; then - pkcs_opts="-nocrypt" - fi pkcs_out="$EASYRSA_PKI/private/$short_name.p8" + if [ -z "$want_pass" ]; then + EASYRSA_PASSIN=pass: + EASYRSA_PASSOUT=pass: + fi + # export the p8: # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl pkcs8 -in "$key_in" -topk8 \ -out "$pkcs_out" $pkcs_opts \ - ${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ - ${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || die "\ + ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ + ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ Export of p8 failed: see above for related openssl errors." ;; esac From 867444b705a811305ea642e52619c17764eb26f8 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 21:21:25 +0100 Subject: [PATCH 63/73] Remove Obsolete shellcheck directives for 2086, unquoted variables Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index e448907..24e140a 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1711,7 +1711,7 @@ You may now use this name to perform signing operations on this request." return 0 } # => import_req() -# export pkcs#12 or pkcs#7 +# export pkcs12 pkcs7 pkcs8 export_pkcs() { pkcs_type="$1" shift @@ -1769,7 +1769,6 @@ Missing key expected at: $key_in" fi # export the p12: - # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl pkcs12 -in "$crt_in" -inkey "$key_in" -export \ -out "$pkcs_out" \ ${nokeys:+ -nokeys} \ @@ -1797,9 +1796,8 @@ Export of p7 failed: see above for related openssl errors." fi # export the p8: - # shellcheck disable=SC2086 # Ignore unquoted variables easyrsa_openssl pkcs8 -in "$key_in" -topk8 \ - -out "$pkcs_out" $pkcs_opts \ + -out "$pkcs_out" \ ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ Export of p8 failed: see above for related openssl errors." @@ -1886,6 +1884,7 @@ Failed to perform update-db: see above for related openssl errors." return 0 } # => update_db() +# Display subjectAltName display_san() { format="$1" path="$2" @@ -1982,7 +1981,6 @@ No such $type file with a basename of '$name' is present. Expected to find this file at: $in_file" - # shellcheck disable=SC2086 # Ignore unquoted variables verify_file "$format" "$in_file" || die "\ This file is not a valid $type file: $in_file" From dea7ca4f401ef2e5581a9fb669b7013261715c79 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 22 Apr 2022 22:49:57 +0100 Subject: [PATCH 64/73] Replace '--verbose' mode with $EASYRSA_DUBUG $EASYRSA_DUBUG must be deliberately set outside of easyrsa. '--verbose' mode was a bad hack. $EASYRSA_DUBUG is also broken from the start but it is the simplest way to verify what data is being fed to SSL. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 24e140a..21cf880 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -444,18 +444,29 @@ easyrsa_openssl() { mv "$easyrsa_openssl_conf" "$EASYRSA_SAFE_CONF" || \ die "easyrsa_openssl - makesafeconf failed" else - # Verbose log - [ "$EASYRSA_VERBOSE" ] && printf '%s\n' \ - "$EASYRSA_OPENSSL $openssl_command -config $easyrsa_openssl_conf $*" + # !!! + # this debug CANNOT be used in automated testing + # to function correctly easyrsa_openssl() + # must ONLY output SSL layer output + # debug log + if [ "$EASYRSA_DEBUG" ]; then + printf '%s%s\n' "$EASYRSA_OPENSSL $openssl_command" \ + "-config $easyrsa_openssl_conf $*" + fi # Exec SSL with -config temp-file "$EASYRSA_OPENSSL" "$openssl_command" \ -config "$easyrsa_openssl_conf" "$@" || return fi else - # Verbose log - [ "$EASYRSA_VERBOSE" ] && [ ! "$openssl_command" = rand ] \ - && printf '%s\n' "$EASYRSA_OPENSSL $openssl_command $*" + # !!! + # this debug CANNOT be used in automated testing + # to function correctly easyrsa_openssl() + # must ONLY output SSL layer output + # debug log + if [ "$EASYRSA_DEBUG" ] && [ ! "$openssl_command" = rand ]; then + printf '%s\n' "$EASYRSA_OPENSSL $openssl_command $*" + fi # Exec SSL without -config temp-file "$EASYRSA_OPENSSL" "$openssl_command" "$@" || return @@ -2965,9 +2976,6 @@ while :; do empty_ok=1 export EASYRSA_SILENT=1 export EASYRSA_BATCH=1 ;; - --verbose) - empty_ok=1 - export EASYRSA_VERBOSE=1 ;; --passin) export EASYRSA_PASSIN="$val";; --passout) From 5af34056cbaffeab652b3141de6d9a12df9b4266 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 23 Apr 2022 16:37:38 +0100 Subject: [PATCH 65/73] Standardise use of 'case' - Provide default '*)' for all usage. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 91 +++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 21cf880..48a2246 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -205,7 +205,7 @@ cmd_help() { "") usage ;; *) text=" - Unknown command: '$1' (try without commands for a list of commands)" ;; + Unknown command: '$1' (try without commands for a list of commands)" esac # display the help text @@ -391,9 +391,9 @@ cleanup() { # shellcheck disable=SC3040 # In POSIX sh, set option [name] is undefined case "$easyrsa_host_os" in - nix) stty echo ;; - win) set -o echo ;; - *) warn "Host OS undefined." + nix) stty echo ;; + win) set -o echo ;; + *) warn "Host OS undefined." esac [ "$EASYRSA_SILENT" ] || echo "" # just to get a clean line } # => cleanup() @@ -517,7 +517,7 @@ verify_ssl_lib() { notice "Using SSL: $EASYRSA_OPENSSL $val" ;; *) die "\ Missing or invalid OpenSSL -Expected to find openssl command at: $EASYRSA_OPENSSL" ;; +Expected to find openssl command at: $EASYRSA_OPENSSL" esac fi EASYRSA_SSL_OK=1 @@ -597,7 +597,7 @@ init_pki() { case "$1" in hard-reset|hard) reset="hard" ;; soft-reset|soft) reset="soft" ;; - *) warn "Ignoring unknown command option: '$1'" ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -627,7 +627,7 @@ and initialize a fresh PKI here." # More modes could be added here, e.g. only remove # issued certs (and clean database), but keep CA intact. *) - die "Removal of PKI dir failed. Unknown reset type." + die "Removal of PKI dir failed. Unknown reset type: $reset" esac fi @@ -1063,7 +1063,7 @@ Run easyrsa without commands for usage and commands." nopass) opts="$opts $no_password" ;; # batch flag supports internal callers needing silent operation batch) openssl_batch=1 ;; - *) warn "Ignoring unknown command option: '$1'" ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -1156,7 +1156,7 @@ sign_req() { check_serial="$("$EASYRSA_OPENSSL" ca -config "$EASYRSA_SSL_CONF" -status "$serial" 2>&1)" case "$check_serial" in *"not present in db"*) break ;; - *) continue ;; + *) continue esac done fi @@ -1216,10 +1216,11 @@ $(display_dn req "$req_in") [ -n "$EASYRSA_NS_COMMENT" ] && \ print "nsComment = \"$EASYRSA_NS_COMMENT\"" case "$crt_type" in - serverClient) print "nsCertType = serverClient" ;; - server) print "nsCertType = server" ;; - client) print "nsCertType = client" ;; - ca) print "nsCertType = sslCA" ;; + serverClient) print "nsCertType = serverClient" ;; + server) print "nsCertType = server" ;; + client) print "nsCertType = client" ;; + ca) print "nsCertType = sslCA" ;; + *) die "Unknown certificate type: $crt_type" esac fi @@ -1289,7 +1290,7 @@ Run easyrsa without commands for usage and commands." case "$1" in nopass) req_opts="$req_opts nopass" ;; inline) EASYRSA_INLINE=1 ;; - *) warn "Ignoring unknown command option: '$1'" ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -1524,7 +1525,6 @@ at: $crt_in" # This works on Windows, too, since uname doesn't exist and this is catch-all expire_date=$(date -d "$expire_date" +%s) allow_renew_date=$(date -d "+${EASYRSA_CERT_RENEW}day" +%s) - ;; esac [ "$expire_date" -lt "$allow_renew_date" ] || die "\ @@ -1549,6 +1549,7 @@ Renewal not allowed." "TLS Web Server Authentication, TLS Web Client Authentication") cert_type=serverClient ;; + *) die "Unknown key usage: $cert_ext_key_usage" esac # Use SAN from --subject-alt-name if set else use SAN from old cert @@ -1748,7 +1749,7 @@ Run easyrsa without commands for usage and command help." noca) want_ca="" ;; nokey) want_key="" ;; nopass) want_pass="" ;; - *) warn "Ignoring unknown command option: '$1'" ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -1812,8 +1813,9 @@ Export of p7 failed: see above for related openssl errors." ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ Export of p8 failed: see above for related openssl errors." - ;; -esac + ;; + *) die "Unknown PKCS type: $pkcs_type" + esac notice "\ @@ -1843,9 +1845,9 @@ See help output for usage details." unset nopass while [ -n "$1" ]; do case "$1" in - nopass) nopass=1 ;; - file) file="$raw_file" ;; - *) warn "Ignoring unknown command option: '$1'" ;; + nopass) nopass=1 ;; + file) file="$raw_file" ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -1965,12 +1967,8 @@ Run easyrsa without commands for usage help." out_opts="no_pubkey,no_sigdump" while [ -n "$1" ]; do case "$1" in - full) - out_opts= - ;; - *) - warn "Ignoring unknown command option: '$1'" - ;; + full) out_opts= ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -2015,7 +2013,7 @@ show_ca() { while [ -n "$1" ]; do case "$1" in full) out_opts= ;; - *) warn "Ignoring unknown command option: '$1'" ;; + *) warn "Ignoring unknown command option: '$1'" esac shift done @@ -2116,16 +2114,14 @@ vars_setup() { # If found_vars greater than 1 then output user info and exit case "$found_vars" in - 0) - unset -v found_vars - ;; - 1) : ;; # ok - *) - [ "$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 "\ + 0) unset -v found_vars ;; + 1) : ;; # ok + *) + [ "$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 "\ Conflicting 'vars' files found. Priority should be given to your PKI vars file: @@ -2240,10 +2236,10 @@ Sourcing the vars file will probably fail .." # EASYRSA_ALGO_PARAMS must be set depending on selected algo case "$EASYRSA_ALGO" in - ec) EASYRSA_ALGO_PARAMS="$EASYRSA_EC_DIR/${EASYRSA_CURVE}.pem" ;; - rsa) EASYRSA_ALGO_PARAMS="${EASYRSA_KEY_SIZE}" ;; - ed) : ;; # ok - *) die "Alg '$EASYRSA_ALGO' is invalid: must be 'rsa', 'ec' or 'ed' " + rsa) EASYRSA_ALGO_PARAMS="${EASYRSA_KEY_SIZE}" ;; + ec) EASYRSA_ALGO_PARAMS="$EASYRSA_EC_DIR/${EASYRSA_CURVE}.pem" ;; + ed) : ;; # ok + *) die "Alg '$EASYRSA_ALGO' is invalid: must be 'rsa', 'ec' or 'ed' " esac # Assign value to $EASYRSA_TEMP_DIR_session @@ -2997,7 +2993,7 @@ subjectAltName = $val" ;; break ;; *) - break ;; + break esac # fatal error when no value was provided @@ -3025,10 +3021,10 @@ cmd="$1" # This avoids unnecessary warnings and notices # want_init_pki can probably be renamed to something more apt case "$cmd" in -init-pki|clean-all) want_init_pki=1 ;; -""|help|-h|--help|--usage) want_init_pki=1 ;; -version) want_init_pki=1 ;; -*) unset -v want_init_pki + init-pki|clean-all) want_init_pki=1 ;; + ""|help|-h|--help|--usage) want_init_pki=1 ;; + version) want_init_pki=1 ;; + *) unset -v want_init_pki esac # Intelligent env-var detection and auto-loading: @@ -3111,7 +3107,6 @@ case "$cmd" in ;; *) die "Unknown command '$cmd'. Run without commands for usage help." - ;; esac # vim: ft=sh nu ai sw=8 ts=8 noet From 1ba11bfd12c17a26e8358859baff74a3c05b06dc Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 23 Apr 2022 20:04:38 +0100 Subject: [PATCH 66/73] Always keep locally installed binaries during clean up Signed-off-by: Richard T Bonhomme --- op-test.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/op-test.sh b/op-test.sh index 12ee58c..e53e780 100644 --- a/op-test.sh +++ b/op-test.sh @@ -138,7 +138,6 @@ download_unit_test () { target_hash="${utest_hash}" if [ "$enable_unit_test" ]; then if [ -e "${ERSA_UT}/${target_file}" ]; then - keep_eut=1 [ -x "${ERSA_UT}/${target_file}" ] || \ chmod +x "${ERSA_UT}/${target_file}" # version check @@ -160,6 +159,7 @@ download_unit_test () { utest_bin="${ERSA_UT}/${target_file}" utest_bin_ok=1 export ERSA_UTEST_CURL_TARGET=online + unset -v keep_eut else log "version check failed: ${target_file}" fi @@ -219,7 +219,6 @@ download_shellcheck () { if [ "$enable_shellcheck" ] && [ "$EASYRSA_NIX" ]; then log "setup shellcheck" if [ -e "${ERSA_UT}/${target_file}" ]; then - keep_sc=1 [ -x "${ERSA_UT}/${target_file}" ] || \ chmod +x "${ERSA_UT}/${target_file}" "${ERSA_UT}/${target_file}" -V || \ @@ -237,6 +236,7 @@ download_shellcheck () { if "${ERSA_UT}/${target_file}" -V; then sc_bin="${ERSA_UT}/${target_file}" sc_bin_ok=1 + unset -v keep_sc else log "version check failed: ${ERSA_UT}/${target_file}" fi @@ -259,7 +259,6 @@ download_opensslv3 () { target_hash="${ssl_hash}" if [ "$enable_openssl3" ] && [ "$EASYRSA_NIX" ]; then if [ -e "${ERSA_UT}/${target_file}" ]; then - keep_ssl=1 [ -x "${ERSA_UT}/${target_file}" ] || \ chmod +x "${ERSA_UT}/${target_file}" # version check 'openssl version' @@ -280,6 +279,7 @@ download_opensslv3 () { if "${ERSA_UT}/${target_file}" version; then ssl_bin="${ERSA_UT}/${target_file}" ssl_bin_ok=1 + unset -v keep_ssl # Set up Easy-RSA Unit-Test for OpenSSL-v3 export EASYRSA_OPENSSL="${ssl_bin}" else @@ -319,8 +319,12 @@ download_opensslv3 () { trap "clean_up" 15 -unset -v disable_log verb enable_unit_test enable_shellcheck enable_openssl3 \ - keep_sc keep_ssl keep_eut no_delete +unset -v disable_log verb no_delete \ + enable_unit_test enable_shellcheck enable_openssl3 + +keep_sc=1 +keep_ssl=1 +keep_eut=1 # Set by default enable_unit_test=1 From d3f4fdb17728969dbcc3246a7badec37d1992bf6 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 23 Apr 2022 20:09:26 +0100 Subject: [PATCH 67/73] Wrap two long lines (No functional change) Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 48a2246..54f6c92 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -450,7 +450,7 @@ easyrsa_openssl() { # must ONLY output SSL layer output # debug log if [ "$EASYRSA_DEBUG" ]; then - printf '%s%s\n' "$EASYRSA_OPENSSL $openssl_command" \ + printf '%s %s\n' "$EASYRSA_OPENSSL $openssl_command" \ "-config $easyrsa_openssl_conf $*" fi @@ -1153,7 +1153,10 @@ sign_req() { for i in 1 2 3 4 5; do "$EASYRSA_OPENSSL" rand -hex -out "$EASYRSA_PKI/serial" 16 serial="$(cat "$EASYRSA_PKI/serial")" - check_serial="$("$EASYRSA_OPENSSL" ca -config "$EASYRSA_SSL_CONF" -status "$serial" 2>&1)" + check_serial="$( + "$EASYRSA_OPENSSL" ca -config "$EASYRSA_SSL_CONF" \ + -status "$serial" 2>&1 + )" case "$check_serial" in *"not present in db"*) break ;; *) continue From 133d7c7843429aa295e4ac142018dc889dbfc12a Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sat, 23 Apr 2022 22:30:16 +0100 Subject: [PATCH 68/73] Allow OpenSSL to function without a "Safe" ssl-configuration file Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 102 +++++++++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 44 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 54f6c92..1d1a0b7 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -283,7 +283,9 @@ Easy-RSA error: $1" 1>&2 print " -Host: $host_out" +Host: $host_out +${EASYRSA_DEBUG+ +*** Disable EASYRSA_DEBUG mode ***}" exit "${2:-1}" } # => die() @@ -416,29 +418,43 @@ easyrsa_openssl() { if [ "$has_config" ]; then # Make LibreSSL safe config file from OpenSSL config file - easyrsa_openssl_conf="$(easyrsa_mktemp)" || \ - die "easyrsa_openssl - Failed to create temporary file" - sed \ - -e "s\`ENV::EASYRSA\`EASYRSA\`g" \ - -e "s\`\$dir\`$EASYRSA_PKI\`g" \ - -e "s\`\$EASYRSA_PKI\`$EASYRSA_PKI\`g" \ - -e "s\`\$EASYRSA_CERT_EXPIRE\`$EASYRSA_CERT_EXPIRE\`g" \ - -e "s\`\$EASYRSA_CRL_DAYS\`$EASYRSA_CRL_DAYS\`g" \ - -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ - -e "s\`\$EASYRSA_KEY_SIZE\`$EASYRSA_KEY_SIZE\`g" \ - -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ - -e "s\`\$EASYRSA_DN\`$EASYRSA_DN\`g" \ - -e "s\`\$EASYRSA_REQ_COUNTRY\`$EASYRSA_REQ_COUNTRY\`g" \ - -e "s\`\$EASYRSA_REQ_PROVINCE\`$EASYRSA_REQ_PROVINCE\`g" \ - -e "s\`\$EASYRSA_REQ_CITY\`$EASYRSA_REQ_CITY\`g" \ - -e "s\`\$EASYRSA_REQ_ORG\`$EASYRSA_REQ_ORG\`g" \ - -e "s\`\$EASYRSA_REQ_OU\`$EASYRSA_REQ_OU\`g" \ - -e "s\`\$EASYRSA_REQ_CN\`$EASYRSA_REQ_CN\`g" \ - -e "s\`\$EASYRSA_REQ_EMAIL\`$EASYRSA_REQ_EMAIL\`g" \ - "$EASYRSA_SSL_CONF" > "$easyrsa_openssl_conf" || \ + # Do not use easyrsa_mktemp() for init-pki + if [ "$want_init_pki" ]; then + # for init-pki $EASYRSA_SAFE_CONF is always set in the PKI, use it. + easyrsa_openssl_conf="${EASYRSA_SAFE_CONF}.init-tmp" + else + easyrsa_openssl_conf="$(easyrsa_mktemp)" || \ + die "easyrsa_openssl - Failed to create temporary file" + fi + + # OpenSSL does not need a safe config, skip this stage + if [ "$no_safe_ssl_conf" ]; then + cp -f "$EASYRSA_SSL_CONF" "$easyrsa_openssl_conf" || \ die "easyrsa_openssl - Failed to make temporary config" + else + sed \ + -e "s\`ENV::EASYRSA\`EASYRSA\`g" \ + -e "s\`\$dir\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_PKI\`$EASYRSA_PKI\`g" \ + -e "s\`\$EASYRSA_CERT_EXPIRE\`$EASYRSA_CERT_EXPIRE\`g" \ + -e "s\`\$EASYRSA_CRL_DAYS\`$EASYRSA_CRL_DAYS\`g" \ + -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ + -e "s\`\$EASYRSA_KEY_SIZE\`$EASYRSA_KEY_SIZE\`g" \ + -e "s\`\$EASYRSA_DIGEST\`$EASYRSA_DIGEST\`g" \ + -e "s\`\$EASYRSA_DN\`$EASYRSA_DN\`g" \ + -e "s\`\$EASYRSA_REQ_COUNTRY\`$EASYRSA_REQ_COUNTRY\`g" \ + -e "s\`\$EASYRSA_REQ_PROVINCE\`$EASYRSA_REQ_PROVINCE\`g" \ + -e "s\`\$EASYRSA_REQ_CITY\`$EASYRSA_REQ_CITY\`g" \ + -e "s\`\$EASYRSA_REQ_ORG\`$EASYRSA_REQ_ORG\`g" \ + -e "s\`\$EASYRSA_REQ_OU\`$EASYRSA_REQ_OU\`g" \ + -e "s\`\$EASYRSA_REQ_CN\`$EASYRSA_REQ_CN\`g" \ + -e "s\`\$EASYRSA_REQ_EMAIL\`$EASYRSA_REQ_EMAIL\`g" \ + "$EASYRSA_SSL_CONF" > "$easyrsa_openssl_conf" || \ + die "easyrsa_openssl - Failed to make temporary config" + fi + if [ "$openssl_command" = "makesafeconf" ]; then # move temp file to safessl-easyrsa.cnf mv "$easyrsa_openssl_conf" "$EASYRSA_SAFE_CONF" || \ @@ -500,26 +516,30 @@ verify_curve_ed() { || die "Edward Curve $EASYRSA_CURVE not found." } # => verify_curve_ed() +# Verify the SSL library is functional and establish version dependencies verify_ssl_lib() { - # Verify EASYRSA_OPENSSL command gives expected output if [ -z "$EASYRSA_SSL_OK" ]; then val="$("$EASYRSA_OPENSSL" version)" case "${val%% *}" in - OpenSSL|LibreSSL) - osslv_major="${val#* }" - osslv_major="${osslv_major%%.*}" - case "$osslv_major" in - 1) no_password='-nodes' ;; - 2) no_password='-nodes' ;; # LibreSSL Only - 3) no_password='-noenc' ;; - *) die "Unsupported SSL library: $osslv_major" - esac - notice "Using SSL: $EASYRSA_OPENSSL $val" ;; + # OpenSSL does not require a safe config-file + OpenSSL) no_safe_ssl_conf=1 ;; + LibreSSL) : ;; # ok *) die "\ Missing or invalid OpenSSL Expected to find openssl command at: $EASYRSA_OPENSSL" esac fi + + # Set SSL version dependent $no_password option + osslv_major="${val#* }" + osslv_major="${osslv_major%%.*}" + case "$osslv_major" in + 1) no_password='-nodes' ;; + 2) no_password='-nodes' ;; # LibreSSL Only + 3) no_password='-noenc' ;; + *) die "Unsupported SSL library: $osslv_major" + esac + notice "Using SSL: $EASYRSA_OPENSSL $val" EASYRSA_SSL_OK=1 # Verify EASYRSA_SSL_CONF file exists @@ -757,18 +777,6 @@ install_data_to_pki () { cp -f "${EASYRSA_PKI}/${vars_file_example}" \ "${EASYRSA_PKI}/${vars_file}" || return fi - - # if session is already defined - if [ "$EASYRSA_TEMP_DIR_session" ]; then - # Only init-pki can inherit a previous session when deleting a PKI - # Only init-pki is allowed to create a new session - # 'init-pki soft' does not delete the old session, delete it now - [ -d "$EASYRSA_TEMP_DIR_session" ] && rm -rf "$EASYRSA_TEMP_DIR_session" - unset -v EASYRSA_TEMP_DIR_session - fi - - # Initialise new temporary session for easyrsa_openssl makesafeconf - secure_session || die "install_data_to_pki - secure_session" ;; vars-setup) if [ "$found_vars" ]; then @@ -1153,10 +1161,13 @@ sign_req() { for i in 1 2 3 4 5; do "$EASYRSA_OPENSSL" rand -hex -out "$EASYRSA_PKI/serial" 16 serial="$(cat "$EASYRSA_PKI/serial")" + + # Calls LibreSSL directly with a broken config and still works check_serial="$( "$EASYRSA_OPENSSL" ca -config "$EASYRSA_SSL_CONF" \ -status "$serial" 2>&1 )" + case "$check_serial" in *"not present in db"*) break ;; *) continue @@ -2233,8 +2244,11 @@ Sourcing the vars file will probably fail .." 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 OPENSSL_CONF "$EASYRSA_SAFE_CONF" + set_var EASYRSA_KDC_REALM "CHANGEME.EXAMPLE.COM" # EASYRSA_ALGO_PARAMS must be set depending on selected algo From 33acf0db1b7892ed8df97759f9314fa20cc4950e Mon Sep 17 00:00:00 2001 From: Joerg Delker Date: Sun, 24 Apr 2022 19:57:11 +0200 Subject: [PATCH 69/73] added option to set PKCS#12 alias name --- easyrsa3/easyrsa | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 1d1a0b7..1f2b7b0 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -163,8 +163,9 @@ cmd_help() { export-p12 [ cmd-opts ] Export a PKCS#12 file with the keypair specified by " opts=" - noca - do not include the ca.crt file in the PKCS12 output - nokey - do not include the private key in the PKCS12 output" ;; + noca - do not include the ca.crt file in the PKCS12 output + nokey - do not include the private key in the PKCS12 output + usealias - use as friendly name" ;; export-p7) text=" export-p7 [ cmd-opts ] Export a PKCS#7 file with the pubkey specified by " @@ -1763,6 +1764,7 @@ Run easyrsa without commands for usage and command help." noca) want_ca="" ;; nokey) want_key="" ;; nopass) want_pass="" ;; + usealias) pkcs_friendly_name=$short_name ;; *) warn "Ignoring unknown command option: '$1'" esac shift @@ -1798,6 +1800,7 @@ Missing key expected at: $key_in" easyrsa_openssl pkcs12 -in "$crt_in" -inkey "$key_in" -export \ -out "$pkcs_out" \ ${nokeys:+ -nokeys} \ + ${pkcs_friendly_name:+ -name "$pkcs_friendly_name"} \ ${pkcs_certfile_path:+ -certfile "$pkcs_certfile_path"} \ ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \ ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} || die "\ From 554dfa56a4fb1a930a89df4ea6fa6c9374e24652 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sun, 24 Apr 2022 20:21:32 +0100 Subject: [PATCH 70/73] Correct 'date' and 'cp' syntax for Busybox Add new 'date' test to identify a working command. Also: Remove the '-n' "no clobber" option from 'cp' in install_data_to_pki(). Rely on the shell to determine if 'vars' exists. Closes: #543 Also: Correctly quote related expansions. Also: Minor improvements to host detection. Unit test completed on Alpine Linux with Busybox v1.34.1 Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 77 ++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 1d1a0b7..46cd75b 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -771,23 +771,20 @@ install_data_to_pki () { # If this is init-pki then create PKI/vars from PKI/example case "$context" in init-pki) - if [ -e "${EASYRSA_PKI}/${vars_file_example}" ] && \ - [ ! -e "${EASYRSA_PKI}/${vars_file}" ] - then - cp -f "${EASYRSA_PKI}/${vars_file_example}" \ - "${EASYRSA_PKI}/${vars_file}" || return + if [ -e "${EASYRSA_PKI}/${vars_file_example}" ]; then + [ -e "${EASYRSA_PKI}/${vars_file}" ] || \ + cp "${EASYRSA_PKI}/${vars_file_example}" \ + "${EASYRSA_PKI}/${vars_file}" || : fi ;; vars-setup) if [ "$found_vars" ]; then : # ok - Do not make a PKI/vars if another vars exists else - if [ -e "${EASYRSA_PKI}/${vars_file_example}" ] && \ - [ ! -e "${EASYRSA_PKI}/${vars_file}" ] - then - # This is allowed to fail because it should not be necessary - cp -n "${EASYRSA_PKI}/${vars_file_example}" \ - "${EASYRSA_PKI}/${vars_file}" || : + if [ -e "${EASYRSA_PKI}/${vars_file_example}" ]; then + [ -e "${EASYRSA_PKI}/${vars_file}" ] || \ + cp "${EASYRSA_PKI}/${vars_file_example}" \ + "${EASYRSA_PKI}/${vars_file}" || : fi fi ;; @@ -1499,9 +1496,10 @@ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and command help." crt_in="$EASYRSA_PKI/issued/$1.crt" - opts="" + # Append 'nopass' + opt_nopass="" if [ "$2" ]; then - opts="$2" + opt_nopass="$2" fi verify_file x509 "$crt_in" || die "\ @@ -1523,22 +1521,33 @@ at: $crt_in" # Check if old cert is expired or expires within 30 # - NOT using: shellcheck disable=SC2086 # Ignore unquoted variables # - The "correct" solution is to not need unquoted substitutions .. - expire_date=$( + cert_expire_date="$( easyrsa_openssl x509 -in "$crt_in" -noout -enddate | sed 's/^notAfter=//' - ) + )" # - NOT using: shellcheck disable=SC2086 # Ignore unquoted variables # - The "correct" solution is to not need unquoted substitutions .. - case $(uname 2>/dev/null) in + case "$easyrsa_uname" in "Darwin"|*"BSD") - expire_date=$(date -j -f '%b %d %T %Y %Z' "$expire_date" +%s) - allow_renew_date=$(($(date -j +%s) + 24*60*60*EASYRSA_CERT_RENEW)) + expire_date="$(date -j -f '%b %d %T %Y %Z' "$cert_expire_date" +%s)" + allow_renew_date="$(( $(date -j +%s) + 86400 * EASYRSA_CERT_RENEW ))" ;; *) - # This works on Windows, too, since uname doesn't exist and this is catch-all - expire_date=$(date -d "$expire_date" +%s) - allow_renew_date=$(date -d "+${EASYRSA_CERT_RENEW}day" +%s) + # Linux and Windows + if expire_date="$(date -d "$cert_expire_date" +%s)" + then + allow_renew_date="$(date -d "+${EASYRSA_CERT_RENEW}day" +%s)" + + # Alpine Linux and busybox + elif expire_date="$(date -D "%b %e %H:%M:%S %Y" -d "$cert_expire_date" +%s)" + then + allow_renew_date="$(( $(date +%s) + 86400 * EASYRSA_CERT_RENEW ))" + + # Something else + else + die "Date failed" + fi esac [ "$expire_date" -lt "$allow_renew_date" ] || die "\ @@ -1548,10 +1557,10 @@ Renewal not allowed." # Extract certificate usage from old cert # - NOT using: shellcheck disable=SC2086 # Ignore unquoted variables # - The "correct" solution is to not need unquoted substitutions .. - cert_ext_key_usage=$( + cert_ext_key_usage="$( easyrsa_openssl x509 -in "$crt_in" -noout -text | sed -n "/X509v3 Extended Key Usage:/{n;s/^ *//g;p;}" - ) + )" case "$cert_ext_key_usage" in "TLS Web Client Authentication") @@ -1572,10 +1581,11 @@ Renewal not allowed." # How did this ever get in ? echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName || \ { - san=$( + san="$( easyrsa_openssl x509 -in "$crt_in" -noout -text | sed -n "/X509v3 Subject Alternative Name:/{n;s/IP Address:/IP:/;s/ //g;p;}" - ) + )" + [ -n "$san" ] && export EASYRSA_EXTRA_EXTS="\ $EASYRSA_EXTRA_EXTS subjectAltName = $san" @@ -1587,7 +1597,7 @@ subjectAltName = $san" # renew certificate # shellcheck disable=SC2086 # Ignore unquoted variables - build_full $cert_type "$1" $opts || die "\ + build_full "$cert_type" "$1" "$opt_nopass" || die "\ Failed to renew certificate: renew command failed." [ "$EASYRSA_SILENT" ] || print # Separate Notice below @@ -2195,29 +2205,32 @@ Sourcing the vars file will probably fail .." unset -v easyrsa_host_os easyrsa_host_test easyrsa_win_git_bash # Detect Windows - easyrsa_host_test="${OS}" + [ "${OS}" ] && easyrsa_host_test="${OS}" # shellcheck disable=SC2016 # expansion inside '' blah easyrsa_ksh='@(#)MIRBSD KSH R39-w32-beta14 $Date: 2013/06/28 21:28:57 $' [ "${KSH_VERSION}" = "${easyrsa_ksh}" ] && easyrsa_host_test="${easyrsa_ksh}" - unset -v easyrsa_ksh + #unset -v easyrsa_ksh # If not Windows then nix if [ "${easyrsa_host_test}" ]; then easyrsa_host_os=win - easyrsa_host_os_version="${easyrsa_host_test}" + easyrsa_uname="${easyrsa_host_test}" + easyrsa_shell="$easyrsa_ksh" # Detect Windows git/bash if [ "${EXEPATH}" ]; then + easyrsa_shell="$SHELL (Git)" easyrsa_win_git_bash="${EXEPATH}" # If found then set openssl NOW! [ -e /usr/bin/openssl ] && set_var EASYRSA_OPENSSL /usr/bin/openssl fi else easyrsa_host_os=nix - easyrsa_host_os_version="$(uname)" + easyrsa_uname="$(uname 2>/dev/null)" + easyrsa_shell="$SHELL" fi - host_out="$easyrsa_host_os | $easyrsa_host_os_version" - host_out="${host_out}${easyrsa_win_git_bash:+ | "$easyrsa_win_git_bash"}" + host_out="$easyrsa_host_os | $easyrsa_uname | $easyrsa_shell" + host_out="${host_out}${easyrsa_win_git_bash+ | "$easyrsa_win_git_bash"}" unset -v easyrsa_host_test # Set defaults, preferring existing env-vars if present From 69819242db5c6ad85e5ad7dc380ff66570dc7523 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sun, 24 Apr 2022 20:42:29 +0100 Subject: [PATCH 71/73] Remove obsolete shellcheck commentary and dispose of a short-circuit Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 46cd75b..6682e7f 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1519,15 +1519,11 @@ Unable to renew as no certificate was found. Certificate was expected at: $crt_in" # Check if old cert is expired or expires within 30 - # - NOT using: shellcheck disable=SC2086 # Ignore unquoted variables - # - The "correct" solution is to not need unquoted substitutions .. cert_expire_date="$( easyrsa_openssl x509 -in "$crt_in" -noout -enddate | sed 's/^notAfter=//' )" - # - NOT using: shellcheck disable=SC2086 # Ignore unquoted variables - # - The "correct" solution is to not need unquoted substitutions .. case "$easyrsa_uname" in "Darwin"|*"BSD") expire_date="$(date -j -f '%b %d %T %Y %Z' "$cert_expire_date" +%s)" @@ -1555,8 +1551,6 @@ Certificate expires in more than $EASYRSA_CERT_RENEW days. Renewal not allowed." # Extract certificate usage from old cert - # - NOT using: shellcheck disable=SC2086 # Ignore unquoted variables - # - The "correct" solution is to not need unquoted substitutions .. cert_ext_key_usage="$( easyrsa_openssl x509 -in "$crt_in" -noout -text | sed -n "/X509v3 Extended Key Usage:/{n;s/^ *//g;p;}" @@ -1576,11 +1570,9 @@ Renewal not allowed." esac # Use SAN from --subject-alt-name if set else use SAN from old cert - # - NOT using: shellcheck disable=SC2086 # Ignore unquoted variables - # - The "correct" solution is to not need unquoted substitutions .. - # How did this ever get in ? - echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName || \ - { + if echo "$EASYRSA_EXTRA_EXTS" | grep -q subjectAltName; then + : # ok - Use current subjectAltName + else san="$( easyrsa_openssl x509 -in "$crt_in" -noout -text | sed -n "/X509v3 Subject Alternative Name:/{n;s/IP Address:/IP:/;s/ //g;p;}" @@ -1589,14 +1581,13 @@ Renewal not allowed." [ -n "$san" ] && export EASYRSA_EXTRA_EXTS="\ $EASYRSA_EXTRA_EXTS subjectAltName = $san" - } + fi # move renewed files so we can reissue certificate with the same name # FIXME: Modify revoke() to also work on the renewed certs subdir move_renewed "$1" # renew certificate - # shellcheck disable=SC2086 # Ignore unquoted variables build_full "$cert_type" "$1" "$opt_nopass" || die "\ Failed to renew certificate: renew command failed." From 2c71e06e0b916974dd232edf4f30321947db532c Mon Sep 17 00:00:00 2001 From: Joerg Delker Date: Sun, 24 Apr 2022 23:39:30 +0200 Subject: [PATCH 72/73] changed option name to usefn --- easyrsa3/easyrsa | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 1f2b7b0..8b609c7 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -163,9 +163,9 @@ cmd_help() { export-p12 [ cmd-opts ] Export a PKCS#12 file with the keypair specified by " opts=" - noca - do not include the ca.crt file in the PKCS12 output - nokey - do not include the private key in the PKCS12 output - usealias - use as friendly name" ;; + noca - do not include the ca.crt file in the PKCS12 output + nokey - do not include the private key in the PKCS12 output + usefn - use as friendly name" ;; export-p7) text=" export-p7 [ cmd-opts ] Export a PKCS#7 file with the pubkey specified by " @@ -1764,7 +1764,7 @@ Run easyrsa without commands for usage and command help." noca) want_ca="" ;; nokey) want_key="" ;; nopass) want_pass="" ;; - usealias) pkcs_friendly_name=$short_name ;; + usefn) pkcs_friendly_name=$short_name ;; *) warn "Ignoring unknown command option: '$1'" esac shift From 33a4914abb981cf01e3e09146059a100101db495 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 25 Apr 2022 12:08:18 +0100 Subject: [PATCH 73/73] renew() - Ensure CA index.txt.attr has 'unique_subject = no' This is required to support renewal of a certificate. Closes: #419 Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 3 +++ 1 file changed, 3 insertions(+) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 6682e7f..7c4a412 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1496,6 +1496,9 @@ Error: didn't find a file base name as the first argument. Run easyrsa without commands for usage and command help." crt_in="$EASYRSA_PKI/issued/$1.crt" + # Upgrade CA index.txt.attr - unique_subject = no + up23_upgrade_ca || die "Failed to upgrade CA to support renewal." + # Append 'nopass' opt_nopass="" if [ "$2" ]; then