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
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 ..