From c11135d19b2e7e7385d28abb1132978c849dfa74 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Sun, 21 May 2023 21:31:57 +0100 Subject: [PATCH 1/4] build-ca: Use OpenSSL password I/O argument 'stdin' When OpenSSL is built "for Windows", it does not support password input/output via argument 'fd:N', file-descriptors. However, OpenSSL built "for Windows" does allow use of 'stdin'. eg: -pass:stdin (-passin/-passout) There is one drawback; When using 'stdin' openssl cannot allow further user input to customise the 'commonName', or any other organisational fields used by '--dn-mode=org'. OpenSSL enforces '-batch' when 'stdin' is used. Therefore, EasyRSA must set batch mode, to correctly use 'stdin' to pass the CA password. Creating CA key pair this way also requires that SSL option '-keyout' be dropped from the create CA request command. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index dfb025d..1f61e4b 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1612,6 +1612,10 @@ to the latest Easy-RSA release." else # CA password via file-descriptors CA_key_pass="$p" + + # To use stdin for -passin and -passout + # MUST use -batch + ssl_batch=1 fi unset -v p q else @@ -1654,8 +1658,8 @@ to the latest Easy-RSA release." rsa_keygen_bits:"$EASYRSA_ALGO_PARAMS" \ -out "$out_key_tmp" \ ${cipher:+ "$cipher"} \ - -pass fd:3 \ - 3<<-EOF + -pass stdin \ + <<-EOF ${CA_key_pass} EOF then @@ -1669,8 +1673,8 @@ to the latest Easy-RSA release." -paramfile "$EASYRSA_ALGO_PARAMS" \ -out "$out_key_tmp" \ ${cipher:+ "$cipher"} \ - -pass fd:3 \ - 3<<-EOF + -pass stdin \ + <<-EOF ${CA_key_pass} EOF then @@ -1684,8 +1688,8 @@ to the latest Easy-RSA release." -algorithm "$EASYRSA_CURVE" \ -out "$out_key_tmp" \ ${cipher:+ "$cipher"} \ - -pass fd:3 \ - 3<<-EOF + -pass stdin \ + <<-EOF ${CA_key_pass} EOF then @@ -1738,21 +1742,21 @@ build_ca: CA key password created via temp-files" # Generate the CA keypair: if [ "$CA_key_pass" ]; then if easyrsa_openssl req -utf8 -new \ - -key "$out_key_tmp" -keyout "$out_key_tmp" \ + -key "$out_key_tmp" \ -out "$out_file_tmp" \ ${ssl_batch:+ -batch} \ ${x509:+ -x509} \ ${date_stamp:+ -days "$EASYRSA_CA_EXPIRE"} \ ${EASYRSA_DIGEST:+ -"$EASYRSA_DIGEST"} \ - -passin fd:3 \ - 3<<-EOF + -passin stdin \ + <<-EOF ${CA_key_pass} EOF then verbose "\ build_ca: CA certificate password created via FD" else - die "Failed to build the CA keypair" + die "Failed to build the CA keypair." fi else @@ -6202,7 +6206,7 @@ while :; do --passout) export EASYRSA_PASSOUT="$val" ;; - --ca-via-tf) + --ca-via-textfile|--ca-via-tf) empty_ok=1 export EASYRSA_CA_PASS_OLD=1 ;; From 51cb520887ca3d48377e7117ba3b9b7fe3aaebf2 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 22 May 2023 18:16:32 +0100 Subject: [PATCH 2/4] build-ca: Force the unit-test to build CA with pass via 'stdin' method ERSA_UTEST_VERSION and EASYRSA_USE_PASS are only defined when the unit-tests are run. When they are detected, force use of CA password via 'stdin'. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 1f61e4b..37731cb 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1575,6 +1575,15 @@ to the latest Easy-RSA release." then : # No passphrase required + # Strictly for use only by easyrsa-unit-tests.sh + elif [ "$ERSA_UTEST_VERSION" ] && [ "$EASYRSA_USE_PASS" ] + then + # Set a test password and use file-descriptor method + CA_key_pass='EasyRSA' + # To use stdin for -passin and -passout + # MUST use -batch + ssl_batch=1 + elif [ "$EASYRSA_PASSOUT" ] && [ "$EASYRSA_PASSIN" ] then : # passphrase defined @@ -1700,8 +1709,14 @@ to the latest Easy-RSA release." ;; *) die "Unknown algorithm: $EASYRSA_ALGO" esac + verbose "\ -build_ca: CA key password created via FD" +build_ca: CA key password created via stdin" + if [ "$ERSA_UTEST_VERSION" ] && \ + [ "$EASYRSA_USE_PASS" ] + then + print "CA key via stdin" + fi else case "$EASYRSA_ALGO" in @@ -1753,12 +1768,19 @@ build_ca: CA key password created via temp-files" ${CA_key_pass} EOF then - verbose "\ -build_ca: CA certificate password created via FD" + : # ok else die "Failed to build the CA keypair." fi + verbose "\ +build_ca: CA certificate password created via stdin" + if [ "$ERSA_UTEST_VERSION" ] && \ + [ "$EASYRSA_USE_PASS" ] + then + print "CA Cert via stdin" + fi + else easyrsa_openssl req -utf8 -new \ -key "$out_key_tmp" -keyout "$out_key_tmp" \ From 5d7ad1306d5ebf1588aef77eb3445e70cf5b4ebc Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Mon, 22 May 2023 23:08:42 +0100 Subject: [PATCH 3/4] build-ca: Revert manual CA password method to temp-files Change the integration of the following: * build-ca: Replace password temp-file method with file-descriptors * commit 27870d695a324e278854146afdac5d6bdade9bba Instead of 'replacing' the standard temp-file method, the new 'stdin' method is offered as an alternative by using option '--ca-via-stdin' Discussion: Using EasyRSA temp-files means that these files can be written to specific places. In the case of the CA password, it is recommended to use a RAM-Disk to write CA password temp-files to. Using heredocs to pass data via file-descriptors, in all probability, will write the heredoc data to a temp-file managed by the shell in use. Thus, there are temp-files written in both methods. The difference being that, the EasyRSA managed temp-files can be written to specific places, while the shell managed temp-files are out of EasyRSA scope. In conclusion, both methods are offered, however, the default remains as EasyRSA temp-files for the CA password method. Signed-off-by: Richard T Bonhomme --- ChangeLog | 7 ++++++- easyrsa3/easyrsa | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 33 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index ed774a7..ddb11ed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,12 @@ Easy-RSA 3 ChangeLog -3.1.3 (ETA: 2023-05-19) +3.1.4 (ETA: 2023-06-02) + * build-ca: Revert manual CA password method to temp-files (#959) + Supersedes #955 + +3.1.3 (2023-05-19) * build-ca: Replace password temp-files with file-descriptors (#955) + Superseded by #959 * Replace --fix-offset with --startdate, --enddate (#918) * Introduce option -S|--silent-ssl: Silence SSL output (#913) * Only create a random serial number file when expected (#896) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index 37731cb..b5463ee 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -470,7 +470,7 @@ General options: Can not be used with --passin or --passout --passin=ARG : Set -passin ARG for openssl (eg: pass:xEasyRSAy) --passout=ARG : Set -passout ARG for openssl (eg: pass:xEasyRSAy) ---ca-via-tf : Build CA with password via temp-files (Old method) +--ca-via-stdin : Build CA with password via 'stdin' (New method) --vars=FILE : Define a specific 'vars' file to use for Easy-RSA config (Default vars file is in the EasyRSA PKI directory) @@ -542,6 +542,10 @@ Easy-RSA error: $1 " + if [ "$error_info" ]; then + print "${error_info}${NL}" + fi + show_host exit "${2:-1}" } # => die() @@ -1450,7 +1454,7 @@ get_passphrase() { # build-ca backend: build_ca() { cipher="-aes256" - unset -v sub_ca ssl_batch date_stamp x509 + unset -v sub_ca ssl_batch date_stamp x509 error_info while [ "$1" ]; do case "$1" in intca|subca) sub_ca=1 ;; @@ -1606,7 +1610,20 @@ to the latest Easy-RSA release." # Validate passphrase if [ "$p" ] && [ "$p" = "$q" ]; then - if [ "$EASYRSA_CA_PASS_OLD" ]; then + if [ "$EASYRSA_CA_PASS_NEW" ]; then + # CA password via stdin + CA_key_pass="$p" + + # To use stdin for -passin and -passout + # MUST use -batch + ssl_batch=1 + + # Helpful info, in case of failure + error_info="\ + EasyRSA 'build-ca' has failed due to use of OpenSSL password + argument 'stdin'. Please report this error to EasyRSA." + + else # CA password via temp-files in_key_pass_tmp="" easyrsa_mktemp in_key_pass_tmp || \ @@ -1618,13 +1635,6 @@ to the latest Easy-RSA release." die "in_key_pass_tmp: write" printf "%s" "$p" > "$out_key_pass_tmp" || \ die "out_key_pass_tmp: write" - else - # CA password via file-descriptors - CA_key_pass="$p" - - # To use stdin for -passin and -passout - # MUST use -batch - ssl_batch=1 fi unset -v p q else @@ -1658,7 +1668,7 @@ to the latest Easy-RSA release." EASYRSA_SSL_CONF="$conf_tmp" # Generate CA Key - if [ "$CA_key_pass" ]; then + if [ "$EASYRSA_CA_PASS_NEW" ]; then case "$EASYRSA_ALGO" in rsa) if easyrsa_openssl genpkey \ @@ -1755,7 +1765,7 @@ build_ca: CA key password created via temp-files" fi # Generate the CA keypair: - if [ "$CA_key_pass" ]; then + if [ "$EASYRSA_CA_PASS_NEW" ]; then if easyrsa_openssl req -utf8 -new \ -key "$out_key_tmp" \ -out "$out_file_tmp" \ @@ -1769,6 +1779,7 @@ build_ca: CA key password created via temp-files" EOF then : # ok + unset -v error_info else die "Failed to build the CA keypair." fi @@ -5091,8 +5102,8 @@ Your Easy-RSA PKI CA Private Key is WORLD readable. To correct this problem, it is recommended that you either: * Copy Easy-RSA to your User folders and run it from there, OR * Define your PKI to be in your User folders. EG: - 'easyrsa --pki-dir=C:/Users//easy-rsa/pki\"'\ - " + 'easyrsa --pki-dir=\"C:/Users//easy-rsa/pki\"\ + '" fi fi @@ -6228,9 +6239,9 @@ while :; do --passout) export EASYRSA_PASSOUT="$val" ;; - --ca-via-textfile|--ca-via-tf) + --ca-via-stdin) empty_ok=1 - export EASYRSA_CA_PASS_OLD=1 + export EASYRSA_CA_PASS_NEW=1 ;; --notext|--no-text) empty_ok=1 From c1bf6a43d7bd9180c3fe228492c857698fec36b2 Mon Sep 17 00:00:00 2001 From: Richard T Bonhomme Date: Tue, 23 May 2023 13:24:00 +0100 Subject: [PATCH 4/4] build-ca: Remove obsolete unit-test CA password variant If this code s left in then the unit test always falls through to testing a CA without a password. Signed-off-by: Richard T Bonhomme --- easyrsa3/easyrsa | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/easyrsa3/easyrsa b/easyrsa3/easyrsa index b5463ee..20b28e4 100755 --- a/easyrsa3/easyrsa +++ b/easyrsa3/easyrsa @@ -1579,15 +1579,6 @@ to the latest Easy-RSA release." then : # No passphrase required - # Strictly for use only by easyrsa-unit-tests.sh - elif [ "$ERSA_UTEST_VERSION" ] && [ "$EASYRSA_USE_PASS" ] - then - # Set a test password and use file-descriptor method - CA_key_pass='EasyRSA' - # To use stdin for -passin and -passout - # MUST use -batch - ssl_batch=1 - elif [ "$EASYRSA_PASSOUT" ] && [ "$EASYRSA_PASSIN" ] then : # passphrase defined @@ -1722,11 +1713,6 @@ to the latest Easy-RSA release." verbose "\ build_ca: CA key password created via stdin" - if [ "$ERSA_UTEST_VERSION" ] && \ - [ "$EASYRSA_USE_PASS" ] - then - print "CA key via stdin" - fi else case "$EASYRSA_ALGO" in @@ -1786,11 +1772,6 @@ build_ca: CA key password created via temp-files" verbose "\ build_ca: CA certificate password created via stdin" - if [ "$ERSA_UTEST_VERSION" ] && \ - [ "$EASYRSA_USE_PASS" ] - then - print "CA Cert via stdin" - fi else easyrsa_openssl req -utf8 -new \