From a8da3925d7b38eab568852f6815c424c802b6cbe Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 6 Oct 2025 01:35:39 +0100 Subject: [PATCH 1/7] init-pki: Introduce configurable cryptography init-pki can now create a preconfigured 'vars' file, to use Elliptic curve or Edwards curve cryptography. These options can be used to configure init-pki, in the following order: * init-pki curve-name: Acepted values any Elliptic or Edwards curve 'curve-name' will preset algorithm. * init-pki algorithm: Acepted values ec or ed 'algorithm' will opportunistically preset 'curve-name' Command options take priority over Global options * Global option --curve * Global option --use-algo Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 164 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 25 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 400d9e2f5..0719517d2 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -64,6 +64,7 @@ Certificate & Request options: (these impact cert/req field values) --use-algo=ALG : Crypto alg to use: choose rsa (default), ec or ed --curve=NAME : For elliptic curve, sets the named curve (Default: algo ec: secp384r1, algo ed: ed25519) + (--use-algo and --curve can be used to configure 'init-pki') --subca-len=# : Path length of signed intermediate CA certificates --copy-ext : Copy included request X509 extensions (namely subjAltName) @@ -110,7 +111,7 @@ Deprecated features: Command list: - init-pki + init-pki [ cmd-opts ] self-sign-server [ cmd-opts ] self-sign-client [ cmd-opts ] build-ca [ cmd-opts ] @@ -169,7 +170,19 @@ Usage: easyrsa [ OPTIONS.. ] [ cmd-opts.. ]" text=" * init-pki [ cmd-opts ] - Removes & re-initializes the PKI directory for a new PKI" + Removes & re-initializes the PKI directory for a new PKI + + The new PKI can be auto-configured to use alternative cryptography. + + The following command line examples are equivalent: + $ easyrsa init-pki ed448 + $ easyrsa init-pki ed ed448 + $ easyrsa --use-algo=ed --curve=ed448 init-pki + + Note: cmd-opts take priority over '--' global options" + opts=" + * Optional algorithm 'ec' or 'ed' (Default: rsa) + * Optional curve name (Default: None, secp384r1 or ed25519)" ;; self-sign*) text=" @@ -1380,6 +1393,52 @@ $verify_ca_help_note" # init-pki backend: init_pki() { + verbose "BEGIN: algo: '$EASYRSA_ALGO' | curve: '$EASYRSA_CURVE'" + + # Parse options for algo/curve - overwrite defaults + while [ "$1" ]; do + case "$1" in + rsa) + export EASYRSA_ALGO="$1" + unset -v EASYRSA_CURVE + ;; + ec) + export EASYRSA_ALGO="$1" + export EASYRSA_CURVE=secp384r1 + ;; + ed) + export EASYRSA_ALGO="$1" + export EASYRSA_CURVE=ed25519 + ;; + *) + export EASYRSA_CURVE="$1" + case "$EASYRSA_CURVE" in + ed*) export EASYRSA_ALGO=ed ;; + *) export EASYRSA_ALGO=ec + esac + esac + shift + done + + # Set default curve based on algo + case "$EASYRSA_ALGO" in + rsa) : ;; # ok + ec) set_var EASYRSA_CURVE secp384r1 ;; + ed) set_var EASYRSA_CURVE ed25519 ;; + *) die "Unknown EASYRSA_ALGO: '$EASYRSA_ALGO'" + esac + + # Set default algo based on curve + case "$EASYRSA_CURVE" in + '') : ;; # ok + ed*) set_var EASYRSA_ALGO ed ;; + *) set_var EASYRSA_ALGO ec + esac + + # Verify user settings + verbose "TRY: algo: '$EASYRSA_ALGO' | curve: '$EASYRSA_CURVE'" + verify_algo_params + # EasyRSA will NOT do 'rm -rf /' case "$EASYRSA_PKI" in .|..|./|../|.//*|..//*|/|//*|\\|?:|'') @@ -1394,12 +1453,12 @@ WARNING!!! You are about to remove the EASYRSA_PKI at: * $EASYRSA_PKI -and initialize a fresh PKI here." - fi +and initialize a fresh PKI here. $auto_algo" - # # # shellcheck disable=SC2115 # Use "${var:?}" - rm -rf "$EASYRSA_PKI" || \ - die "init-pki hard reset failed." + # Remove existing PKI + rm -rf "$EASYRSA_PKI" || \ + die "Failed to remove existing PKI: '$EASYRSA_PKI'" + fi # new dirs: for i in issued private reqs; do @@ -1409,7 +1468,32 @@ and initialize a fresh PKI here." # write pki/vars.example - no temp-file because no session write_legacy_file_v2 vars "$EASYRSA_PKI"/vars.example || \ - warn "init_pki() - Failed to create vars.example" + die "init_pki() - Failed to create vars.example" + + # Auto-configuration $pki/vars for ec/ed + case "$EASYRSA_ALGO" in + rsa) : ;; # ok + ec|ed) + # Set comment for vars file + case "$EASYRSA_ALGO" in + ec) auto_algo="Auto-configured for Elliptic curve '$EASYRSA_CURVE'" ;; + ed) auto_algo="Auto-configured for Edwards curve '$EASYRSA_CURVE'" + esac + + # sed search and replace regex + s_alg='#set_var[[:blank:]]*EASYRSA_ALGO[[:blank:]]*rsa' + r_alg="set_var EASYRSA_ALGO $EASYRSA_ALGO # --> $auto_algo" + s_crv='#set_var[[:blank:]]*EASYRSA_CURVE[[:blank:]]*secp384r1' + r_crv="set_var EASYRSA_CURVE $EASYRSA_CURVE # --> $auto_algo" + + # Create Auto-configured vars file + # Note: pki/vars.example is Always created by Easy-RSA above + sed -e s/"$s_alg"/"$r_alg"/ -e s/"$s_crv"/"$r_crv"/ \ + "$EASYRSA_PKI"/vars.example > "$EASYRSA_PKI"/vars || \ + die "sed auto-vars" + ;; + *) die "Auto-configuration, Unknown EASYRSA_ALGO: '$EASYRSA_ALGO'" + esac # User notice notice "\ @@ -1418,12 +1502,15 @@ and initialize a fresh PKI here." Your newly created PKI dir is: * $EASYRSA_PKI" - # Select and show vars file - unset -v EASYRSA_VARS_FILE + # Select and show Auto-configured vars file + unset -v ignore_vars EASYRSA_VARS_FILE select_vars - information "\ -Using Easy-RSA configuration: -* ${EASYRSA_VARS_FILE:-undefined}" + if [ "$EASYRSA_VARS_FILE" ]; then + information "\ +IMPORTANT: PKI algorithm is $auto_algo${NL} +Using Easy-RSA Auto-configured 'vars' file: +* ${EASYRSA_VARS_FILE}${NL}" + fi } # => init_pki() # Find support files from various sources @@ -5322,36 +5409,54 @@ show_host() { verify_algo_params() { case "$EASYRSA_ALGO" in rsa) + [ "$EASYRSA_CURVE" ] && user_error "\ +Elliptic curve cryptography cannot be use with algo '$EASYRSA_ALGO'" # Set RSA key size EASYRSA_ALGO_PARAMS="$EASYRSA_KEY_SIZE" ;; ec) - # Verify Elliptic curve - EASYRSA_ALGO_PARAMS="" - easyrsa_mktemp EASYRSA_ALGO_PARAMS - - # Create the required ecparams file, temp-file - # call openssl directly because error is expected + case "$cmd" in + build-ca|gen-req|build-*-full) + # build ec-params file as $EASYRSA_ALGO_PARAMS + build_ecparam_file + ;; + *) + # Verify Elliptic curve "$EASYRSA_OPENSSL" ecparam \ -name "$EASYRSA_CURVE" \ - -out "$EASYRSA_ALGO_PARAMS" \ >/dev/null 2>&1 || user_error "\ Failed to generate ecparam file for curve '$EASYRSA_CURVE'" + esac ;; ed) # Verify Edwards curve - # call openssl directly because error is expected - "$EASYRSA_OPENSSL" genpkey \ - -algorithm "$EASYRSA_CURVE" \ - >/dev/null 2>&1 || user_error "\ + "$EASYRSA_OPENSSL" genpkey \ + -algorithm "$EASYRSA_CURVE" \ + >/dev/null 2>&1 || user_error "\ Edwards Curve '$EASYRSA_CURVE' not found." ;; *) user_error "\ Unknown algorithm '$EASYRSA_ALGO': Must be 'rsa', 'ec' or 'ed'" esac - verbose "verify_algo_params; OK: algo '$EASYRSA_ALGO'" + verbose "\ +verify_algo_params; OK: algo '$EASYRSA_ALGO' | curve '$EASYRSA_CURVE'" } # => verify_algo_params() +# build ecparam file +build_ecparam_file() { + # Only valid for algo ec + [ "$EASYRSA_ALGO" = ec ] || return 0 + + # User specified algo params file exists + [ "$EASYRSA_ALGO_PARAMS" ] && [ -f "$EASYRSA_ALGO_PARAMS" ] && return + easyrsa_mktemp EASYRSA_ALGO_PARAMS + + # Create the required ecparams file, temp-file + "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" \ + -out "$EASYRSA_ALGO_PARAMS" >/dev/null 2>&1 || user_error \ + "Failed to generate ecparam file for curve '$EASYRSA_CURVE'" +} # => build_ec_param_file() + # Check for conflicting input options mutual_exclusions() { # --nopass cannot be used with --passout @@ -5439,6 +5544,9 @@ To correct this problem, it is recommended that you either: # If not present, defaults are used to support # running without a sourced config format. select_vars() { + # Deliberately ignore vars + [ "$ignore_vars" ] && return 1 + # User specified vars file will be used ONLY if [ "$EASYRSA_VARS_FILE" ]; then : # Takes priority, nothing to do @@ -6543,6 +6651,7 @@ unset -v \ secured_session \ alias_days text \ prohibit_no_pass \ + ignore_vars \ invalid_vars \ local_request error_build_full_cleanup \ selfsign_eku \ @@ -6618,6 +6727,10 @@ while :; do ;; --curve) export EASYRSA_CURVE="$val" + case "$EASYRSA_CURVE" in + ed*) set_var EASYRSA_ALGO ed ;; + *) set_var EASYRSA_ALGO ec + esac ;; --dn-mode) export EASYRSA_DN="$val" @@ -6818,6 +6931,7 @@ cmd="$1" # ONLY verify_working_env() for valid commands case "$cmd" in init-pki|clean-all) + ignore_vars=1 # Deliberately ignore vars require_pki=""; require_ca=""; verify_working_env init_pki "$@" ;; From fe9d03ec6a4d4245d132c73ae360e6e4f2cd6ab8 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 6 Oct 2025 01:50:48 +0100 Subject: [PATCH 2/7] ChangeLog: init-pki: Introduce configurable cryptography Signed-off-by: Richard T Bonhomme --- ChangeLog | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ChangeLog b/ChangeLog index 487ebc9ad..0a5b8e911 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ Easy-RSA 3 ChangeLog 3.2.5 (TBD) + * init-pki: Introduce configurable cryptography (a8da392) (#1397) + * Replace "local" openssl-easyrsa.cnf (80702d6..b31443d) (#1394) Original bug report: #1390 'OpenBSD/LibreSSL failure' From 7669cc701c92fd3be58ddd33f477b7ad893f385f Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 7 Oct 2025 20:44:01 +0100 Subject: [PATCH 3/7] Fold build_ecparam_file() into verify_algo_params() Generate an EC parameters file only when a tmp-dir exists and only for algorithm 'ec'. Allow a user supplied EC parameters file as $EASYRSA_ALGO_PARAMS. Remove build_ecparam_file(). Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 67 +++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 0719517d2..ef38f2790 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1436,7 +1436,7 @@ init_pki() { esac # Verify user settings - verbose "TRY: algo: '$EASYRSA_ALGO' | curve: '$EASYRSA_CURVE'" + verbose "TRY: Algo: '$EASYRSA_ALGO' - Curve: '$EASYRSA_CURVE'" verify_algo_params # EasyRSA will NOT do 'rm -rf /' @@ -2253,13 +2253,16 @@ $EASYRSA_EXTRA_EXTS" # Set algorithm options algo_opts="" case "$EASYRSA_ALGO" in - rsa|ec) - # Set elliptic curve parameters-file - # or RSA bit-length + rsa) + # RSA bit-length + algo_opts="$EASYRSA_ALGO:$EASYRSA_ALGO_PARAMS" + ;; + ec) + # Elliptic curve parameters-file algo_opts="$EASYRSA_ALGO:$EASYRSA_ALGO_PARAMS" ;; ed) - # Set Edwards curve name + # Edwards curve name algo_opts="$EASYRSA_CURVE" ;; *) @@ -5415,48 +5418,36 @@ Elliptic curve cryptography cannot be use with algo '$EASYRSA_ALGO'" EASYRSA_ALGO_PARAMS="$EASYRSA_KEY_SIZE" ;; ec) - case "$cmd" in - build-ca|gen-req|build-*-full) - # build ec-params file as $EASYRSA_ALGO_PARAMS - build_ecparam_file - ;; - *) - # Verify Elliptic curve - "$EASYRSA_OPENSSL" ecparam \ - -name "$EASYRSA_CURVE" \ - >/dev/null 2>&1 || user_error "\ -Failed to generate ecparam file for curve '$EASYRSA_CURVE'" - esac + if [ -f "$EASYRSA_ALGO_PARAMS" ]; then + # User supplied file + verbose "External ecparams file '$EASYRSA_ALGO_PARAMS'" + elif [ -d "$EASYRSA_TEMP_DIR" ]; then + # generate file + unset -v EASYRSA_ALGO_PARAMS + easyrsa_mktemp EASYRSA_ALGO_PARAMS + "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" \ + -out "$EASYRSA_ALGO_PARAMS" >/dev/null 2>&1 || user_error \ + "Failed to generate ecparams for curve '$EASYRSA_CURVE'" + else + # Verify only + "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" \ + >/dev/null 2>&1 || user_error \ + "Failed to verify ecparams for curve '$EASYRSA_CURVE'" + fi ;; ed) # Verify Edwards curve - "$EASYRSA_OPENSSL" genpkey \ - -algorithm "$EASYRSA_CURVE" \ - >/dev/null 2>&1 || user_error "\ -Edwards Curve '$EASYRSA_CURVE' not found." + "$EASYRSA_OPENSSL" genpkey -algorithm "$EASYRSA_CURVE" \ + >/dev/null 2>&1 || user_error \ + "Edwards Curve '$EASYRSA_CURVE' not found." ;; *) user_error "\ Unknown algorithm '$EASYRSA_ALGO': Must be 'rsa', 'ec' or 'ed'" esac verbose "\ -verify_algo_params; OK: algo '$EASYRSA_ALGO' | curve '$EASYRSA_CURVE'" +verify_algo_params; OK: Algo '$EASYRSA_ALGO' - Curve '${EASYRSA_CURVE:-None}'" } # => verify_algo_params() -# build ecparam file -build_ecparam_file() { - # Only valid for algo ec - [ "$EASYRSA_ALGO" = ec ] || return 0 - - # User specified algo params file exists - [ "$EASYRSA_ALGO_PARAMS" ] && [ -f "$EASYRSA_ALGO_PARAMS" ] && return - easyrsa_mktemp EASYRSA_ALGO_PARAMS - - # Create the required ecparams file, temp-file - "$EASYRSA_OPENSSL" ecparam -name "$EASYRSA_CURVE" \ - -out "$EASYRSA_ALGO_PARAMS" >/dev/null 2>&1 || user_error \ - "Failed to generate ecparam file for curve '$EASYRSA_CURVE'" -} # => build_ec_param_file() - # Check for conflicting input options mutual_exclusions() { # --nopass cannot be used with --passout @@ -5878,7 +5869,7 @@ Using Easy-RSA 'vars' configuration: # Create temp-session and global safe ssl config tmp-file # if required, openssl-easyrsa.cnf tmp-file if [ -d "$EASYRSA_TEMP_DIR" ]; then - verbose "temp-dir: Found: $EASYRSA_TEMP_DIR" + verbose "temp-dir: FOUND: $EASYRSA_TEMP_DIR" # Temp dir session secure_session From 7cf55e003d43e63fa237743528e940a0c2e4bcf0 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 7 Oct 2025 21:21:49 +0100 Subject: [PATCH 4/7] Allow 'show-cert' in peer-fingerprint mode 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 ef38f2790..50ee44752 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -7044,7 +7044,7 @@ case "$cmd" in show req "$@" ;; show-cert) - require_pki=1; require_ca=1; verify_working_env + require_pki=1; require_ca=""; verify_working_env show cert "$@" ;; show-crl) From 1761678afee47ca91235b7038503a4d7e8394fe0 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 7 Oct 2025 21:34:15 +0100 Subject: [PATCH 5/7] ChangeLog: peer-fingerprint mode, Allow 'show-cert' to be used Signed-off-by: Richard T Bonhomme --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 0a5b8e911..f0c8d1cc1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,7 @@ Easy-RSA 3 ChangeLog 3.2.5 (TBD) + * peer-fingerprint: Allow 'show-cert' to be used (7cf55e0) (#1397) * init-pki: Introduce configurable cryptography (a8da392) (#1397) * Replace "local" openssl-easyrsa.cnf (80702d6..b31443d) (#1394) From 76598e3178be3da474e47ed1c182d49829ace443 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 7 Oct 2025 22:02:46 +0100 Subject: [PATCH 6/7] remove_secure_session(): Print verbose message before unsetting variables 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 50ee44752..3a81b9c2d 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -914,8 +914,8 @@ secure_session - Missing temporary directory: remove_secure_session() { [ -d "$secured_session" ] || return 0 if rm -rf "$secured_session"; then - unset -v secured_session EASYRSA_SSL_CONF OPENSSL_CONF verbose "remove_secure_session; DELETED $secured_session" + unset -v secured_session EASYRSA_SSL_CONF OPENSSL_CONF return fi die "remove_secure_session Failed: $secured_session" From 1c38fbb272e5f4c7f5eda5fa293c2a1252b2eb84 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Wed, 8 Oct 2025 21:27:07 +0100 Subject: [PATCH 7/7] init-pki: Move auto-vars configuration to before confirmation prompt Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 3a81b9c2d..6f4326018 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1445,6 +1445,14 @@ init_pki() { user_error "Invalid PKI: $EASYRSA_PKI" esac + # Auto-configuration $pki/vars for ec/ed + case "$EASYRSA_ALGO" in + rsa) auto_algo= ;; # ok + ec) auto_algo="Auto-configured for Elliptic curve '$EASYRSA_CURVE'" ;; + ed) auto_algo="Auto-configured for Edwards curve '$EASYRSA_CURVE'" ;; + *) die "Auto-configuration, Unknown EASYRSA_ALGO: '$EASYRSA_ALGO'" + esac + # If EASYRSA_PKI exists, confirm before deletion if [ -d "$EASYRSA_PKI" ]; then confirm "Confirm removal: " "yes" " @@ -1472,14 +1480,7 @@ and initialize a fresh PKI here. $auto_algo" # Auto-configuration $pki/vars for ec/ed case "$EASYRSA_ALGO" in - rsa) : ;; # ok ec|ed) - # Set comment for vars file - case "$EASYRSA_ALGO" in - ec) auto_algo="Auto-configured for Elliptic curve '$EASYRSA_CURVE'" ;; - ed) auto_algo="Auto-configured for Edwards curve '$EASYRSA_CURVE'" - esac - # sed search and replace regex s_alg='#set_var[[:blank:]]*EASYRSA_ALGO[[:blank:]]*rsa' r_alg="set_var EASYRSA_ALGO $EASYRSA_ALGO # --> $auto_algo" @@ -1491,8 +1492,6 @@ and initialize a fresh PKI here. $auto_algo" sed -e s/"$s_alg"/"$r_alg"/ -e s/"$s_crv"/"$r_crv"/ \ "$EASYRSA_PKI"/vars.example > "$EASYRSA_PKI"/vars || \ die "sed auto-vars" - ;; - *) die "Auto-configuration, Unknown EASYRSA_ALGO: '$EASYRSA_ALGO'" esac # User notice