From 9966676638c7d511623e6d0d4356b20d443370fc Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 31 May 2024 16:02:41 +0100 Subject: [PATCH 1/4] easyrsa_mktemp(): Make variable names more unique to avoid conflicts Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 56a9a623c..fe40a00bf 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -851,11 +851,11 @@ easyrsa_mktemp - input error" easyrsa_mktemp - Temporary session undefined (--tmp-dir)" # Assign internal temp-file name - t="${secured_session}/temp.${mktemp_counter}" + local_fname="${secured_session}/temp.${mktemp_counter}" # Create shotfile - for h in x y z; do - shotfile="${t}.${h}" + for ext_alpha in x y z; do + shotfile="${local_fname}.${ext_alpha}" if [ -e "$shotfile" ]; then verbose "\ easyrsa_mktemp: shot-file EXISTS: $shotfile" @@ -868,12 +868,12 @@ easyrsa_mktemp: create shotfile failed (1) $1" # subshells do not update mktemp_counter, # which is why this extension is required. # Current max required is 3 attempts - for i in 1 2 3 4 5 6 7 8 9; do - want_tmp_file="${t}.${i}" + for ext_number in 1 2 3 4 5 6 7 8 9; do + want_tmp_file="${local_fname}.${ext_number}" # Warn to error log file for max reached - [ "$EASYRSA_MAX_TEMP" -gt "$i" ] || print "\ -Max temp-file limit $i, hit for: $1" >> "$easyrsa_err_log" + [ "$EASYRSA_MAX_TEMP" -gt "$ext_number" ] || print "\ +Max temp-file limit $ext_number, hit for: $1" >> "$easyrsa_err_log" if [ -e "$want_tmp_file" ]; then verbose "\ @@ -886,18 +886,19 @@ easyrsa_mktemp: temp-file EXISTS: $want_tmp_file" fi if mv "$shotfile" "$want_tmp_file"; then - # Update counter - mktemp_counter="$(( mktemp_counter + 1 ))" - # Assign external temp-file name if force_set_var "$1" "$want_tmp_file" then verbose "\ -easyrsa_mktemp: $1 OK: $want_tmp_file" +:: easyrsa_mktemp: $1 OK: $want_tmp_file" if [ "$easyrsa_host_os" = win ]; then set +o noclobber fi + + # Update counter + mktemp_counter="$(( mktemp_counter + 1 ))" + unset -v want_tmp_file shotfile return else @@ -912,7 +913,7 @@ easyrsa_mktemp - force_set_var $1 failed" # In case of subshell abuse, report to error log err_msg="\ -easyrsa_mktemp - failed for: $1 @ attempt=$i +easyrsa_mktemp - failed for: $1 @ attempt=$ext_number want_tmp_file: $want_tmp_file" print "$err_msg" >> "$easyrsa_err_log" die "$err_msg" From e95cda9cf769b49db85a7e29e265829d78296254 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 31 May 2024 17:13:05 +0100 Subject: [PATCH 2/4] Move openssl-easyrsa.cnf install and expansion for LibreSSl This change moves the expansion of openssl-easyrsa.cnf to the same code where the file is either found or created. The high level requirements are: * OpenSSL does not require exanding the SSL config file. * LibreSSL requires expanding the SSL config file. * EASYRSA_FORCE_SAFE_SSL forces expanding the SSL config file. The specific requirements are: 1. Expanding openssl-easyrsa.cnf MUST be done after EASYRSA_REQ_CN is set. Thus, it cannot be done Globally, one time, at the start of execution. This is required by commands: build-ca, gen-req and sign-req. Change: Create the required OpenSSL:Unexpanded / LibreSSL:Expanded SSL config file for the commands above, after setting EASYRSA_REQ_CN. 2. check_serial_unique(): $check_serial (SSL command: ca) does not require an SSL config file, the error message for it being 'missing' is ignored. Change: check_serial_unique(), call $EASYRSA_OPENSSL directly. 3. verify_file() does require openssl-easyrsa.cnf - Follow-up change. Other changes are: * verify_working_env(): Do not create openssl-easyrsa.cnf temp-file. * Minor comments and verbose message improvements Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 81 ++++++++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 30 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index fe40a00bf..8ad9cb18e 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -856,6 +856,7 @@ easyrsa_mktemp - Temporary session undefined (--tmp-dir)" # Create shotfile for ext_alpha in x y z; do shotfile="${local_fname}.${ext_alpha}" + if [ -e "$shotfile" ]; then verbose "\ easyrsa_mktemp: shot-file EXISTS: $shotfile" @@ -1191,15 +1192,11 @@ easyrsa_openssl() { die "easyrsa_openssl: Illegal SSL command: rand" esac - # Auto-escape hazardous characters - escape_hazard || \ - die "easyrsa_openssl - escape_hazard failed" - - # Rewrite SSL config - expand_ssl_config || \ - die "easyrsa_openssl - expand_ssl_config failed" + # Verify or create temp EASYRSA_SSL_CONF + # Auto-expanded for LibreSSL or $EASYRSA_FORCE_SAFE_SSL + write_easyrsa_ssl_cnf_tmp - # VERIFY safe temp-file exists + # Finally, export $OPENSSL_CONF - Only ever done here! export OPENSSL_CONF="$EASYRSA_SSL_CONF" verbose "easyrsa_openssl: OPENSSL_CONF = $OPENSSL_CONF" @@ -1644,8 +1641,16 @@ Unable to create necessary PKI files (permissions?)" fi fi - # Check for insert-marker in ssl config file + # Verify or create openssl-easyrsa.cnf temp-file + # Must be done after setting EASYRSA_REQ_CN + write_easyrsa_ssl_cnf_tmp + + # When EASYRSA_EXTRA_EXTS is defined, if [ "$EASYRSA_EXTRA_EXTS" ]; then + [ -f "$EASYRSA_SSL_CONF" ] || \ + die "gen_req - Missing openssl-easyrsa.cnf" + + # Check for insert-marker in ssl config file if ! grep -q '^#%CA_X509_TYPES_EXTRA_EXTS%' \ "$EASYRSA_SSL_CONF" then @@ -2162,9 +2167,16 @@ An existing private key was found at $key_out Continuing with key generation will replace this key." fi + # Verify or create openssl-easyrsa.cnf temp-file + # Must be done after setting EASYRSA_REQ_CN + write_easyrsa_ssl_cnf_tmp + # When EASYRSA_EXTRA_EXTS is defined, # append it to openssl's [req] section: if [ "$EASYRSA_EXTRA_EXTS" ]; then + [ -f "$EASYRSA_SSL_CONF" ] || \ + die "gen_req - Missing openssl-easyrsa.cnf" + # Check for insert-marker in ssl config file if ! grep -q '^#%EXTRA_EXTS%' "$EASYRSA_SSL_CONF" then @@ -2363,6 +2375,9 @@ $check_serial" # When EASYRSA_CP_EXT is defined, # adjust openssl's [default_ca] section: if [ "$EASYRSA_CP_EXT" ]; then + [ -f "$EASYRSA_SSL_CONF" ] || \ + die "gen_req - Missing openssl-easyrsa.cnf" + # Check for insert-marker in ssl config file if ! grep -q '^#%COPY_EXTS%' "$EASYRSA_SSL_CONF" then @@ -2641,8 +2656,7 @@ check_serial_unique() { # unset EASYRSA_SILENT_SSL to capure all output # Do NOT unset check_serial for sign-req error msg check_serial="$( - unset -v EASYRSA_SILENT_SSL - easyrsa_openssl ca -status "$1" 2>&1 + "$EASYRSA_OPENSSL" ca -status "$1" 2>&1 )" || : # Check for duplicate serial in CA db @@ -2750,7 +2764,7 @@ Option conflict --req-cn: remove_secure_session locate_support_files secure_session - write_easyrsa_ssl_cnf_tmp + #write_easyrsa_ssl_cnf_tmp # Require --copy-ext export EASYRSA_CP_EXT=1 @@ -4348,13 +4362,8 @@ verify_working_env() { # Verify PKI is initialised verify_pki_init - # Temp dir session and default SSL conf file - if [ -z "$secured_session" ]; then - secure_session - - # Verify or create temp EASYRSA_SSL_CONF - write_easyrsa_ssl_cnf_tmp - fi + # Temp dir session + secure_session # Verify selected algorithm and parameters verify_algo_params @@ -4369,13 +4378,8 @@ verify_working_env() { # If there is a valid temp-dir: # Create temp-session and openssl-easyrsa.cnf (Temp) now if [ -d "$EASYRSA_TEMP_DIR" ]; then - # Temp dir session and default SSL conf file - if [ -z "$secured_session" ]; then - secure_session - - # Verify or create: EASYRSA_SSL_CONF - write_easyrsa_ssl_cnf_tmp - fi + # Temp dir session + secure_session fi fi verbose "verify_working_env: COMPLETED Handover-to: $cmd" @@ -4478,6 +4482,8 @@ f97425686fa1976d436fa31f550641aa" # File is unknown or has been changed # leave in place hash_is_unknown=1 + verbose "write_easyrsa_ssl_cnf_tmp: SSL config UNKNOWN!" + verbose "write_easyrsa_ssl_cnf_tmp: $file_hash" esac # Cleanup @@ -4488,12 +4494,27 @@ f97425686fa1976d436fa31f550641aa" known_file_308 # Use the existing file ONLY - if [ "$hash_is_unknown" ]; then + if [ "$hash_is_unknown" ] || \ + [ "$EASYRSA_FORCE_SAFE_SSL" ] + then unset -v hash_is_unknown - verbose "write_easyrsa_ssl_cnf_tmp: SSL config UNKNOWN!" - # Force 'sed' expnsion of file in place - export EASYRSA_LEGACY_SAFE_SSL=1 + # LibreSSL expansion + if [ "$ssl_lib" = libressl ] || \ + [ "$EASYRSA_FORCE_SAFE_SSL" ] + then + # Force 'sed' expnsion of file in place + export EASYRSA_LEGACY_SAFE_SSL=1 + + # Auto-escape hazardous characters + escape_hazard || \ + die "easyrsa_openssl - escape_hazard failed" + + # Rewrite SSL config + expand_ssl_config || \ + die "easyrsa_openssl - expand_ssl_config failed" + fi + return 0 fi From 761736f4d139d41319f85c4675df3b738daf99e3 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 31 May 2024 18:42:02 +0100 Subject: [PATCH 3/4] build-ca, gen-req, sign-req: Use write_easyrsa_ssl_cnf_tmp() earlier This guarantees that a working EasyRSA SSL config file exists and that both $EASYRSA_SSL_CONF and $OPENSSL_CONF are set to that file. If the initial file has been user, or by EasyRSA internally, edited then that file is used, in place. With these expanson rules applied: This file will be OpenSSL:Un-expanded, LibreSSL:Expanded or expanded by global option --force-safe-ssl or $EASYRSA_FORCE_SAFE_SSL. If the file in place is absent or recognised by SHA256 hash then it will be replaced by here-doc expansion, including SSL Lib expansion as required. The effected code here is verify_file(), which now calls $EASYRSA_OPENSSL directly. Submitting to $OPENSSL_CONF place, or error. Improve comments in the code. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 8ad9cb18e..ae6da405d 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1643,7 +1643,11 @@ Unable to create necessary PKI files (permissions?)" # Verify or create openssl-easyrsa.cnf temp-file # Must be done after setting EASYRSA_REQ_CN + # Must be done before using $EASYRSA_EXTRA_EXTS etc + # And export $OPENSSL_CONF write_easyrsa_ssl_cnf_tmp + export OPENSSL_CONF="$EASYRSA_SSL_CONF" + verbose "sign_req: OPENSSL_CONF = $OPENSSL_CONF" # When EASYRSA_EXTRA_EXTS is defined, if [ "$EASYRSA_EXTRA_EXTS" ]; then @@ -1955,6 +1959,14 @@ Conflicting certificate exists at: verbose "\ self-sign: Use ALGO/CURVE to $EASYRSA_ALGO/$EASYRSA_CURVE" + # Verify or create openssl-easyrsa.cnf temp-file + # Must be done after setting EASYRSA_REQ_CN + # Must be done before using verify_file() etc + # And export $OPENSSL_CONF + write_easyrsa_ssl_cnf_tmp + export OPENSSL_CONF="$EASYRSA_SSL_CONF" + verbose "sign_req: OPENSSL_CONF = $OPENSSL_CONF" + # Assign tmp-file for config adjusted_ssl_cnf_tmp="" easyrsa_mktemp adjusted_ssl_cnf_tmp || \ @@ -2135,6 +2147,14 @@ Option conflict --req-cn: # Enforce commonName export EASYRSA_REQ_CN="$file_name_base" + # Verify or create openssl-easyrsa.cnf temp-file + # Must be done after setting EASYRSA_REQ_CN + # Must be done before using $EASYRSA_EXTRA_EXTS etc + # And export $OPENSSL_CONF + write_easyrsa_ssl_cnf_tmp + export OPENSSL_CONF="$EASYRSA_SSL_CONF" + verbose "sign_req: OPENSSL_CONF = $OPENSSL_CONF" + # Output files key_out="$EASYRSA_PKI/private/${file_name_base}.key" req_out="$EASYRSA_PKI/reqs/${file_name_base}.req" @@ -2167,10 +2187,6 @@ An existing private key was found at $key_out Continuing with key generation will replace this key." fi - # Verify or create openssl-easyrsa.cnf temp-file - # Must be done after setting EASYRSA_REQ_CN - write_easyrsa_ssl_cnf_tmp - # When EASYRSA_EXTRA_EXTS is defined, # append it to openssl's [req] section: if [ "$EASYRSA_EXTRA_EXTS" ]; then @@ -2293,6 +2309,14 @@ Option conflict --req-cn: # Enforce commonName export EASYRSA_REQ_CN="$file_name_base" + # Verify or create openssl-easyrsa.cnf temp-file + # Must be done after setting EASYRSA_REQ_CN + # Must be done before using verify_file() etc + # And export $OPENSSL_CONF + write_easyrsa_ssl_cnf_tmp + export OPENSSL_CONF="$EASYRSA_SSL_CONF" + verbose "sign_req: OPENSSL_CONF = $OPENSSL_CONF" + # Check optional subject force_subj= while [ "$1" ]; do @@ -3723,7 +3747,7 @@ Input is not a valid certificate: verify_file() { format="$1" path="$2" - easyrsa_openssl "$format" -in "$path" -noout 2>/dev/null + "$EASYRSA_OPENSSL" "$format" -in "$path" -noout 2>/dev/null } # => verify_file() # show-* command backend @@ -4423,6 +4447,16 @@ force_set_var() { # Create as needed: $EASYRSA_SSL_CONF pki/openssl-easyrsa.cnf # If the existing file has a known hash then use temp-file. # Otherwise, use the file in place. +# +# v3.2.x +# If $EASYRSA_SSL_CONF exists and is changed from default, +# by either user edits or insertions from code, +# then the existing file remains 'in-tact'. +# For LibreSSL, the 'in-tact' file will be expanded by 'sed' +# +# If $EASYRSA_SSL_CONF does not exist or is known by sha256 hash +# then it is replaced by a here-doc file: +# OpenSSL:Unexpanded, LibreSSL:Expanded write_easyrsa_ssl_cnf_tmp() { if [ -f "$EASYRSA_SSL_CONF" ]; then verbose "write_easyrsa_ssl_cnf_tmp: SSL config EXISTS" From 98952afc6fe2e3cd1aa478d7161861cc72337265 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Fri, 31 May 2024 18:57:00 +0100 Subject: [PATCH 4/4] import-req, revoke: Provide SSL Config file for verify_file() use Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index ae6da405d..21c0091d1 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -2980,6 +2980,14 @@ Unable to revoke as no certificate was found. Certificate was expected at: * $crt_in" + # Verify or create openssl-easyrsa.cnf temp-file + # Must be done after setting EASYRSA_REQ_CN + # Must be done before using $EASYRSA_EXTRA_EXTS etc + # And export $OPENSSL_CONF + write_easyrsa_ssl_cnf_tmp + export OPENSSL_CONF="$EASYRSA_SSL_CONF" + verbose "sign_req: OPENSSL_CONF = $OPENSSL_CONF" + # Verify certificate verify_file x509 "$crt_in" || user_error "\ Unable to revoke as the input-file is not a valid certificate. @@ -3302,6 +3310,15 @@ No request found for the input: '$2' Expected to find the request at: * $in_req" + # Verify or create openssl-easyrsa.cnf temp-file + # Must be done after setting EASYRSA_REQ_CN + # Must be done before using $EASYRSA_EXTRA_EXTS etc + # And export $OPENSSL_CONF + write_easyrsa_ssl_cnf_tmp + export OPENSSL_CONF="$EASYRSA_SSL_CONF" + verbose "sign_req: OPENSSL_CONF = $OPENSSL_CONF" + + # Verify request verify_file req "$in_req" || user_error "\ The certificate request file is not in a valid X509 format: * $in_req"