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 <tincantech@protonmail.com>
This commit is contained in:
Richard T Bonhomme 2022-04-13 01:00:08 +01:00
parent c18d7f2bf0
commit 29a8a48638
No known key found for this signature in database
GPG Key ID: 2D767DB92FB6C246

View File

@ -292,7 +292,7 @@ warn() {
[ "$EASYRSA_SILENT" ] && return [ "$EASYRSA_SILENT" ] && return
print "* WARNING: print "* WARNING:
$1 $1
" 1>&2 " 1>&2
} # => warn() } # => warn()
@ -766,7 +766,7 @@ build_ca() {
out_key="$EASYRSA_PKI/private/ca.key" out_key="$EASYRSA_PKI/private/ca.key"
if [ -z "$sub_ca" ]; then if [ -z "$sub_ca" ]; then
out_file="$EASYRSA_PKI/ca.crt" out_file="$EASYRSA_PKI/ca.crt"
opts="$opts -x509 -days $EASYRSA_CA_EXPIRE " opts="$opts -x509 -days $EASYRSA_CA_EXPIRE"
fi fi
# Test for existing CA, and complain if already present # 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 done
printf "" > "$EASYRSA_PKI/index.txt" || die "$err_file" printf "" > "$EASYRSA_PKI/index.txt" || die "$err_file"
printf "" > "$EASYRSA_PKI/index.txt.attr" || 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: # Default CN only when not in global EASYRSA_BATCH mode:
# shellcheck disable=SC2015 # 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 # * shellcheck SC2086 # Ignore unquoted variables
# The "correct" solution is to not need unquoted substitutions .. # 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 case "$osslv_major" in # => BEGIN SSL lib version
# BEGIN SSL V3 # 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 if [ -z "$nopass" ]; then
crypto_opts="$crypto" crypto_opts="$crypto"
if [ -z "$EASYRSA_PASSOUT" ]; then 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
fi fi
@ -875,24 +876,31 @@ current CA keypair. If you intended to start a new CA, run init-pki first."
rsa) rsa)
# OpenSSL v3: 'genrsa' is deprecate, use 'genpkey' # OpenSSL v3: 'genrsa' is deprecate, use 'genpkey'
easyrsa_openssl genpkey -algorithm "$EASYRSA_ALGO" \ easyrsa_openssl genpkey -algorithm "$EASYRSA_ALGO" \
-out "$out_key_tmp" ${crypto_opts} \ -out "$out_key_tmp" \
-pkeyopt rsa_keygen_bits:"$EASYRSA_ALGO_PARAMS" \ -pkeyopt rsa_keygen_bits:"$EASYRSA_ALGO_PARAMS" \
${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ ${crypto_opts:+ "$crypto_opts"} \
die "Failed create CA private key" ${EASYRSA_PASSOUT:+ -pass "$EASYRSA_PASSOUT"} \
${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \
|| die "Failed create CA private key"
;; ;;
ec) ec)
easyrsa_openssl genpkey -paramfile "$EASYRSA_ALGO_PARAMS" \ easyrsa_openssl genpkey -paramfile "$EASYRSA_ALGO_PARAMS" \
-out "$out_key_tmp" ${crypto_opts} \ -out "$out_key_tmp" \
${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ ${crypto_opts:+ "$crypto_opts"} \
die "Failed create CA private key" ${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} \
${out_key_pass_tmp:+ -pass file:"$out_key_pass_tmp"} \
|| die "Failed create CA private key"
;; ;;
ed) ed)
case "$EASYRSA_CURVE" in case "$EASYRSA_CURVE" in
[eE][dD]25519|[eE][dD]448) [eE][dD]25519|[eE][dD]448)
easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" \ easyrsa_openssl genpkey -algorithm "$EASYRSA_CURVE" \
-out "$out_key_tmp" ${crypto_opts} \ -out "$out_key_tmp" \
${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ ${crypto_opts:+ "$crypto_opts"} \
die "Failed create CA private key" ;; ${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" *) die "Unknown curve: $EASYRSA_CURVE"
esac esac
;; ;;
@ -904,17 +912,20 @@ current CA keypair. If you intended to start a new CA, run init-pki first."
# 'req' requires '-passin' # 'req' requires '-passin'
crypto_opts="" crypto_opts=""
if [ -z "$nopass" ] && [ -z "$EASYRSA_PASSIN" ]; then 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 else
crypto_opts="$no_password" crypto_opts="$no_password"
fi fi
# create the CA keypair: # create the CA keypair:
easyrsa_openssl req -utf8 -new -key "$out_key_tmp" \ easyrsa_openssl req -utf8 -new \
-out "$out_file_tmp" ${opts} ${crypto_opts} \ -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \
${EASYRSA_CA_EXTRA_EXTS} \ $opts $EASYRSA_CA_EXTRA_EXTS \
${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} || \ ${crypto_opts:+ "$crypto_opts"} \
die "Failed to build the CA" ${EASYRSA_PASSIN:+ -passin "$EASYRSA_PASSIN"} \
${out_key_pass_tmp:+ -passin file:"$out_key_pass_tmp"} \
|| die "Failed to build the CA"
;; ;;
# END SSL V3 # 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 if [ -z "$nopass" ]; then
crypto_opts="$crypto" crypto_opts="$crypto"
if [ -z "$EASYRSA_PASSOUT" ]; then if [ -z "$EASYRSA_PASSOUT" ]; then
if [ "ed" = "$EASYRSA_ALGO" ]; then #if [ "ed" = "$EASYRSA_ALGO" ]; then
crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp" # crypto_opts="$crypto_opts -pass file:$out_key_pass_tmp"
else #else
crypto_opts="$crypto_opts -passout file:$out_key_pass_tmp" # crypto_opts="$crypto_opts -passout file:$out_key_pass_tmp"
fi #fi
: # ok
fi fi
fi fi
# create the CA key # create the CA key
case "$EASYRSA_ALGO" in case "$EASYRSA_ALGO" in
rsa) rsa)
"$EASYRSA_OPENSSL" genrsa -out "$out_key_tmp" $crypto_opts \ "$EASYRSA_OPENSSL" genrsa -out "$out_key_tmp" \
${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} \ ${crypto_opts:+ "$crypto_opts"} \
"$EASYRSA_ALGO_PARAMS" || \ ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \
die "Failed create CA private key" ${out_key_pass_tmp:+ -passout file:"$out_key_pass_tmp"} \
"$EASYRSA_ALGO_PARAMS" \
|| die "Failed create CA private key"
;; ;;
ec) ec)
"$EASYRSA_OPENSSL" ecparam -in "$EASYRSA_ALGO_PARAMS" -genkey | \ "$EASYRSA_OPENSSL" ecparam -in "$EASYRSA_ALGO_PARAMS" -genkey | \
"$EASYRSA_OPENSSL" ec -out "$out_key_tmp" $crypto_opts \ "$EASYRSA_OPENSSL" ec -out "$out_key_tmp" \
${EASYRSA_PASSOUT:+-passout "$EASYRSA_PASSOUT"} || \ ${crypto_opts:+ "$crypto_opts"} \
die "Failed create CA private key" ${EASYRSA_PASSOUT:+ -passout "$EASYRSA_PASSOUT"} \
${out_key_pass_tmp:+ -passout file:"$out_key_pass_tmp"} \
|| die "Failed create CA private key"
;; ;;
ed) ed)
case "$EASYRSA_CURVE" in case "$EASYRSA_CURVE" in
[eE][dD]25519|[eE][dD]448) [eE][dD]25519|[eE][dD]448)
"$EASYRSA_OPENSSL" genpkey -algorithm "$EASYRSA_CURVE" \ "$EASYRSA_OPENSSL" genpkey -algorithm "$EASYRSA_CURVE" \
-out "$out_key_tmp" $crypto_opts \ -out "$out_key_tmp" \
${EASYRSA_PASSOUT:+-pass "$EASYRSA_PASSOUT"} || \ ${crypto_opts:+ "$crypto_opts"} \
die "Failed create CA private key" ;; ${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" *) die "Unknown curve: $EASYRSA_CURVE"
esac esac
;; ;;
@ -963,16 +982,18 @@ current CA keypair. If you intended to start a new CA, run init-pki first."
# create the CA keypair: # create the CA keypair:
crypto_opts="" crypto_opts=""
if [ -z "$nopass" ] && [ -z "$EASYRSA_PASSIN" ]; then 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 else
crypto_opts="$no_password" crypto_opts="$no_password"
fi fi
easyrsa_openssl req -utf8 -new -key "$out_key_tmp" \ easyrsa_openssl req -utf8 -new \
-keyout "$out_key_tmp" -out "$out_file_tmp" $crypto_opts $opts \ -key "$out_key_tmp" -keyout "$out_key_tmp" -out "$out_file_tmp" \
${EASYRSA_CA_EXTRA_EXTS} \ $opts $EASYRSA_CA_EXTRA_EXTS \
${EASYRSA_PASSIN:+-passin "$EASYRSA_PASSIN"} \ ${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" || die "Failed to build the CA"
;; ;;
# END SSL V1 # END SSL V1
@ -2116,7 +2137,7 @@ Priority should be given to your PKI vars file:
if [ "$vars" ]; then if [ "$vars" ]; then
# Sanitize vars # Sanitize vars
if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then if grep -Eq 'EASYRSA_PASSIN|EASYRSA_PASSOUT' "$vars"; then
die " die "\
Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration Variable EASYRSA_PASSIN or EASYRSA_PASSOUT has been found in the configuration
file. Storing sensitive information in the configuration file is not 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.
@ -2127,7 +2148,7 @@ recommended - please remove it from there before continuing.
if [ "$vars_in_pki" ]; then if [ "$vars_in_pki" ]; then
# Warning: Single quote # Warning: Single quote
if grep -q "'" "$vars"; then if grep -q "'" "$vars"; then
warn " warn "\
Single quote (') has been found in the configuration file. Single quote (') has been found in the configuration file.
This character is not supported 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 ..