Merge branch 'TinCanTech-verbose-revoke-renew'

Signed-off-by: Richard T Bonhomme <tincantech@protonmail.com>
This commit is contained in:
Richard T Bonhomme 2022-05-22 15:03:22 +01:00
commit 9fd6fe4cf0
No known key found for this signature in database
GPG Key ID: 2D767DB92FB6C246

View File

@ -191,10 +191,12 @@ cmd_help() {
text=" text="
* rewind-renew <certificate-serial-number> * rewind-renew <certificate-serial-number>
Rewind EasyRSA version 3.0 style renewed certificates. Rewind an EasyRSA version 3.0 'style' renewed certificate.
Once 'rewind' has completed the certificate can be revoked
by using: 'revoke-renewed <file_name_base> [reason]'
Moves and renames certs, keys and reqs. Use with caution! * NOTE: This does NOT 'unrenew' or 'unrevoke' a certificate.
Ref: https://github.com/OpenVPN/easy-rsa/issues/578" Ref : https://github.com/OpenVPN/easy-rsa/issues/578"
;; ;;
gen-crl) gen-crl)
text=" text="
@ -473,9 +475,6 @@ print() { printf "%s\n" "$*" || exit 1; }
# Exit fatally with a message to stderr # Exit fatally with a message to stderr
# present even with EASYRSA_BATCH as these are fatal problems # present even with EASYRSA_BATCH as these are fatal problems
die() { die() {
# If renew failed then restore cert, key and req. Otherwise, issue a warning
# If *restore* fails then at least the file-names are not serial-numbers
[ "$restore_failed_renew" ] && renew_restore_move
print " print "
Easy-RSA error: Easy-RSA error:
@ -1661,7 +1660,7 @@ input in file: $crt_in"
# Verify request # Verify request
if [ -e "$req_in" ]; then if [ -e "$req_in" ]; then
verify_file req "$req_in" || die "\ verify_file req "$req_in" || die "\
Unable to move request. The file is not a valid request. Unable to verify request. The file is not a valid request.
Unexpected input in file: $req_in" Unexpected input in file: $req_in"
fi fi
@ -1687,9 +1686,22 @@ Cannot revoke this certificate because a conflicting file exists.
unset -v deny_msg unset -v deny_msg
# confirm operation by displaying DN: # confirm operation by displaying DN:
warn "\
This process is destructive!
These files will be moved to the 'revoked' storage sub-directory:
* $crt_in
* $key_in
* $req_in
These files will be DELETED:
* All PKCS files for commonName : $file_name_base
* The inline credentials file : $creds_in
* The duplicate certificate : $duplicate_crt_by_serial"
confirm " Continue with revocation: " "yes" "\ confirm " Continue with revocation: " "yes" "\
Please confirm you wish to revoke the certificate Please confirm you wish to revoke the certificate
with the following subject: with the following subject:
$(display_dn x509 "$crt_in") $(display_dn x509 "$crt_in")
@ -1717,14 +1729,14 @@ infrastructure in order to prevent the revoked certificate from being accepted."
# moves revoked certificates to the 'revoked' folder # moves revoked certificates to the 'revoked' folder
# allows reissuing certificates with the same name # allows reissuing certificates with the same name
revoke_move() { revoke_move() {
# make sure revoked dirs exist for target in "$out_dir" \
if [ ! -d "$out_dir" ]; then "$out_dir/certs_by_serial" \
mkdir -p "$out_dir" || die "Failed to mkdir: $out_dir" "$out_dir/private_by_serial" \
fi "$out_dir/reqs_by_serial"
for target in certs_by_serial private_by_serial reqs_by_serial; do do
[ -d "$out_dir/$target" ] && continue [ -d "$target" ] && continue
mkdir -p "$out_dir/$target" \ mkdir -p "$target" ||
|| die "Failed to mkdir: $out_dir/$target" die "Failed to mkdir: $target"
done done
# move crt, key and req file to renewed_then_revoked folders # move crt, key and req file to renewed_then_revoked folders
@ -1732,40 +1744,41 @@ revoke_move() {
# only move the key if we have it # only move the key if we have it
if [ -e "$key_in" ]; then if [ -e "$key_in" ]; then
mv "$key_in" "$key_out" || die "Failed to move: $key_in" mv "$key_in" "$key_out" || warn "Failed to move: $key_in"
fi fi
# only move the req if we have it # only move the req if we have it
if [ -e "$req_in" ]; then if [ -e "$req_in" ]; then
mv "$req_in" "$req_out" || die "Failed to move: $req_in" mv "$req_in" "$req_out" || warn "Failed to move: $req_in"
fi fi
# move any pkcs files # remove any pkcs files
for pkcs in p12 p7b p8 p1; do for pkcs in p12 p7b p8 p1; do
if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then
# issued # issued
mv "$in_dir/issued/$file_name_base.$pkcs" \ rm "$in_dir/issued/$file_name_base.$pkcs" ||
"$out_dir/certs_by_serial/$cert_serial.$pkcs" \ warn "Failed to remove: $file_name_base.$pkcs"
|| die "Failed to move: $file_name_base.$pkcs"
elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then
# private # private
mv "$in_dir/private/$file_name_base.$pkcs" \ rm "$in_dir/private/$file_name_base.$pkcs" ||
"$out_dir/private_by_serial/$cert_serial.$pkcs" \ warn "Failed to remove: $file_name_base.$pkcs"
|| die "Failed to move: $file_name_base.$pkcs"
else else
: # ok : # ok
fi fi
done done
# remove the duplicate certificate in the certs_by_serial folder # remove the duplicate certificate in the certs_by_serial folder
rm "$duplicate_crt_by_serial" || warn \ if [ -e "$duplicate_crt_by_serial" ]; then
"Failed to remove the duplicate certificate in the certs_by_serial folder" rm "$duplicate_crt_by_serial" || warn "\
Failed to remove the duplicate certificate in the certs_by_serial folder"
fi
# remove credentials file (if exists) # remove credentials file (if exists)
if [ -e "$creds_in" ]; then if [ -e "$creds_in" ]; then
confirm "Remove inline file ? " "yes" "An inline file exists. $creds_in" confirm "Remove inline file ? " "yes" "An inline file exists. $creds_in"
rm "$creds_in" || warn "Failed to remove the inline file." rm "$creds_in" || warn "\
Failed to remove inline file: $creds_in"
fi fi
return 0 return 0
@ -1818,7 +1831,7 @@ input in file: $crt_in"
# Verify request # Verify request
if [ -e "$req_in" ]; then if [ -e "$req_in" ]; then
verify_file req "$req_in" || die "\ verify_file req "$req_in" || die "\
Unable to move request. The file is not a valid request. Unable to verify request. The file is not a valid request.
Unexpected input in file: $req_in" Unexpected input in file: $req_in"
fi fi
@ -1884,9 +1897,22 @@ subjectAltName = $san"
fi fi
# confirm operation by displaying DN: # confirm operation by displaying DN:
warn "\
This process is destructive!
These files will be moved to the 'renewed' storage sub-directory:
* $crt_in
* $key_in
* $req_in
These files will be DELETED:
* All PKCS files for commonName : $file_name_base
* The inline credentials file : $creds_in
* The duplicate certificate : $duplicate_crt_by_serial"
confirm " Continue with renewal: " "yes" "\ confirm " Continue with renewal: " "yes" "\
Please confirm you wish to renew the certificate Please confirm you wish to renew the certificate
with the following subject: with the following subject:
$(display_dn x509 "$crt_in") $(display_dn x509 "$crt_in")
@ -1896,34 +1922,42 @@ subjectAltName = $san"
# move renewed files so we can reissue certificate with the same name # move renewed files so we can reissue certificate with the same name
renew_move renew_move
# Set restore on error flag
restore_failed_renew=1
# renew certificate # renew certificate
build_full "$cert_type" "$file_name_base" "$opt_nopass" || die "\ if build_full "$cert_type" "$file_name_base" "$opt_nopass"; then
Failed to renew certificate: renew command failed." : # ok
else
# If renew failed then restore cert, key and req. Otherwise, issue a warning
# If *restore* fails then at least the file-names are not serial-numbers
renew_restore_move
die "\
Renewal has failed to build a new certificate/key pair."
fi
# Success messages # Success messages
notice " * IMPORTANT * notice " * IMPORTANT *
Renew was successful. To revoke the old certificate once the new one has been Renew was successful. To revoke the old certificate, once the new one
deployed, use 'revoke-renewed $file_name_base'" has been deployed, use 'revoke-renewed $file_name_base'"
return 0 return 0
} # => renew() } # => renew()
# Restore files on failure to renew # Restore files on failure to renew
renew_restore_move() { renew_restore_move() {
unset -v restore_failed_renew rrm_err unset -v rrm_err
# restore crt, key and req file to PKI folders # restore crt, key and req file to PKI folders
if ! mv "$restore_crt_out" "$restore_crt_in"; then if mv "$restore_crt_out" "$restore_crt_in"; then
: # ok
else
warn "Failed to restore: $restore_crt_out" warn "Failed to restore: $restore_crt_out"
rrm_err=1 rrm_err=1
fi fi
# only restore the key if we have it # only restore the key if we have it
if [ -e "$restore_key_out" ]; then if [ -e "$restore_key_out" ]; then
if ! mv "$restore_key_out" "$restore_key_in"; then if mv "$restore_key_out" "$restore_key_in"; then
: # ok
else
warn "Failed to restore: $restore_key_out" warn "Failed to restore: $restore_key_out"
rrm_err=1 rrm_err=1
fi fi
@ -1931,18 +1965,19 @@ renew_restore_move() {
# only restore the req if we have it # only restore the req if we have it
if [ -e "$restore_req_out" ]; then if [ -e "$restore_req_out" ]; then
if ! mv "$restore_req_out" "$restore_req_in"; then if mv "$restore_req_out" "$restore_req_in"; then
: # ok
else
warn "Failed to restore: $restore_req_out" warn "Failed to restore: $restore_req_out"
rrm_err=1 rrm_err=1
fi fi
fi fi
# messages # messages
[ "$EASYRSA_SILENT" ] || print # Separate Notice below
if [ "$rrm_err" ]; then if [ "$rrm_err" ]; then
warn "Failed to restore renewed files." warn "Failed to restore renewed files."
else else
notice "Renewed files have been restored." notice "Renewed files have been successfully restored."
fi fi
return 0 return 0
@ -1953,13 +1988,14 @@ renew_restore_move() {
# allows reissuing certificates with the same name # allows reissuing certificates with the same name
renew_move() { renew_move() {
# make sure renewed dirs exist # make sure renewed dirs exist
if [ ! -d "$out_dir" ]; then for target in "$out_dir" \
mkdir -p "$out_dir" || die "Failed to mkdir: $out_dir" "$out_dir/issued" \
fi "$out_dir/private" \
for target in issued private reqs; do "$out_dir/reqs"
[ -d "$out_dir/$target" ] && continue do
mkdir -p "$out_dir/$target" \ [ -d "$target" ] && continue
|| die "Failed to mkdir: $out_dir/$target" mkdir -p "$target" ||
die "Failed to mkdir: $target"
done done
# move crt, key and req file to renewed folders # move crt, key and req file to renewed folders
@ -1971,27 +2007,27 @@ renew_move() {
restore_key_in="$key_in" restore_key_in="$key_in"
restore_key_out="$key_out" restore_key_out="$key_out"
if [ -e "$key_in" ]; then if [ -e "$key_in" ]; then
mv "$key_in" "$key_out" || die "Failed to move: $key_in" mv "$key_in" "$key_out" || warn "Failed to move: $key_in"
fi fi
# only move the req if we have it # only move the req if we have it
restore_req_in="$req_in" restore_req_in="$req_in"
restore_req_out="$req_out" restore_req_out="$req_out"
if [ -e "$req_in" ]; then if [ -e "$req_in" ]; then
mv "$req_in" "$req_out" || die "Failed to move: $req_in" mv "$req_in" "$req_out" || warn "Failed to move: $req_in"
fi fi
# remove any pkcs files # remove any pkcs files
for pkcs in p12 p7b p8 p1; do for pkcs in p12 p7b p8 p1; do
if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then
# issued # issued
rm "$in_dir/issued/$file_name_base.$pkcs" \ rm "$in_dir/issued/$file_name_base.$pkcs" ||
|| die "Failed to remove: $file_name_base.$pkcs" warn "Failed to remove: $file_name_base.$pkcs"
elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then
# private # private
rm "$in_dir/private/$file_name_base.$pkcs" \ rm "$in_dir/private/$file_name_base.$pkcs" ||
|| die "Failed to remove: $file_name_base.$pkcs" warn "Failed to remove: $file_name_base.$pkcs"
else else
: # ok : # ok
fi fi
@ -1999,13 +2035,12 @@ renew_move() {
# remove the duplicate certificate in the certs_by_serial folder # remove the duplicate certificate in the certs_by_serial folder
if [ -e "$duplicate_crt_by_serial" ]; then if [ -e "$duplicate_crt_by_serial" ]; then
rm "$duplicate_crt_by_serial" || warn \ rm "$duplicate_crt_by_serial" || warn "\
"Failed to remove the duplicate certificate in the certs_by_serial folder" Failed to remove the duplicate certificate in the certs_by_serial folder"
fi fi
# remove credentials file (if exists) # remove credentials file (if exists)
if [ -e "$creds_in" ]; then if [ -e "$creds_in" ]; then
confirm "Remove inline file ? " "yes" "An inline file exists. $creds_in"
rm "$creds_in" || warn "Failed to remove the inline file." rm "$creds_in" || warn "Failed to remove the inline file."
fi fi
@ -2068,7 +2103,7 @@ input in file: $crt_in"
# Verify request # Verify request
if [ -e "$req_in" ]; then if [ -e "$req_in" ]; then
verify_file req "$req_in" || die "\ verify_file req "$req_in" || die "\
Unable to move request. The file is not a valid request. Unable to verify request. The file is not a valid request.
Unexpected input in file: $req_in" Unexpected input in file: $req_in"
fi fi
@ -2077,6 +2112,7 @@ Unexpected input in file: $req_in"
|| die "renew-revoked - Failed to retrieve certificate serial number" || die "renew-revoked - Failed to retrieve certificate serial number"
# remove the serial= part -> we only need the XXXX part # remove the serial= part -> we only need the XXXX part
cert_serial="${cert_serial##*=}" cert_serial="${cert_serial##*=}"
duplicate_crt_by_serial="$EASYRSA_PKI/certs_by_serial/$cert_serial.pem"
# output # output
out_dir="$EASYRSA_PKI/revoked" out_dir="$EASYRSA_PKI/revoked"
@ -2094,6 +2130,19 @@ Cannot revoke this certificate because a conflicting file exists.
unset -v deny_msg unset -v deny_msg
# confirm operation by displaying DN: # confirm operation by displaying DN:
warn "\
This process is destructive!
These files will be moved to the 'revoked' storage sub-directory:
* $crt_in
* $key_in
* $req_in
These files will be DELETED:
* All PKCS files for commonName : $file_name_base
* The inline credentials file : $creds_in
* The duplicate certificate : $duplicate_crt_by_serial"
confirm " Continue with revocation: " "yes" "\ confirm " Continue with revocation: " "yes" "\
Please confirm you wish to revoke the renewed certificate Please confirm you wish to revoke the renewed certificate
with the following subject: with the following subject:
@ -2124,13 +2173,14 @@ infrastructure in order to prevent the revoked certificate from being accepted."
# moves renewed then revoked certificates to the 'revoked' folder # moves renewed then revoked certificates to the 'revoked' folder
revoke_renewed_move() { revoke_renewed_move() {
# make sure revoked dirs exist # make sure revoked dirs exist
if [ ! -d "$out_dir" ]; then for target in "$out_dir" \
mkdir -p "$out_dir" || die "Failed to mkdir: $out_dir" "$out_dir/certs_by_serial" \
fi "$out_dir/private_by_serial" \
for target in certs_by_serial private_by_serial reqs_by_serial; do "$out_dir/reqs_by_serial"
[ -d "$out_dir/$target" ] && continue do
mkdir -p "$out_dir/$target" \ [ -d "$target" ] && continue
|| die "Failed to mkdir: $out_dir/$target" mkdir -p "$target" ||
die "Failed to mkdir: $target"
done done
# move crt, key and req file to renewed_then_revoked folders # move crt, key and req file to renewed_then_revoked folders
@ -2138,27 +2188,25 @@ revoke_renewed_move() {
# only move the key if we have it # only move the key if we have it
if [ -e "$key_in" ]; then if [ -e "$key_in" ]; then
mv "$key_in" "$key_out" || die "Failed to move: $key_in" mv "$key_in" "$key_out" || warn "Failed to move: $key_in"
fi fi
# only move the req if we have it # only move the req if we have it
if [ -e "$req_in" ]; then if [ -e "$req_in" ]; then
mv "$req_in" "$req_out" || die "Failed to move: $req_in" mv "$req_in" "$req_out" || warn "Failed to move: $req_in"
fi fi
# move any pkcs files # move any pkcs files
for pkcs in p12 p7b p8 p1; do for pkcs in p12 p7b p8 p1; do
if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then if [ -e "$in_dir/issued/$file_name_base.$pkcs" ]; then
# issued # issued
mv "$in_dir/issued/$file_name_base.$pkcs" \ rm "$in_dir/issued/$file_name_base.$pkcs" ||
"$out_dir/certs_by_serial/$cert_serial.$pkcs" \ warn "Failed to remove: $file_name_base.$pkcs"
|| die "Failed to move: $file_name_base.$pkcs"
elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then elif [ -e "$in_dir/private/$file_name_base.$pkcs" ]; then
# private # private
mv "$in_dir/private/$file_name_base.$pkcs" \ rm "$in_dir/private/$file_name_base.$pkcs" ||
"$out_dir/private_by_serial/$cert_serial.$pkcs" \ warn "Failed to remove: $file_name_base.$pkcs"
|| die "Failed to move: $file_name_base.$pkcs"
else else
: # ok : # ok
fi fi
@ -2234,7 +2282,7 @@ input in file: $crt_in"
# Verify request # Verify request
if [ -e "$req_in" ]; then if [ -e "$req_in" ]; then
verify_file req "$req_in" || die "\ verify_file req "$req_in" || die "\
Unable to move request. The file is not a valid request. Unable to verify request. The file is not a valid request.
Unexpected input in file: $req_in" Unexpected input in file: $req_in"
fi fi
@ -2242,7 +2290,7 @@ Unexpected input in file: $req_in"
crt_cn="$( crt_cn="$(
easyrsa_openssl x509 -in "$crt_in" -noout -subject -nameopt \ easyrsa_openssl x509 -in "$crt_in" -noout -subject -nameopt \
utf8,multiline | grep '^[[:blank:]]*commonName[[:blank:]]*= ' utf8,multiline | grep '^[[:blank:]]*commonName[[:blank:]]*= '
)" )" || die "Failed to find commonName in certificate"
crt_cn="${crt_cn#*= }" crt_cn="${crt_cn#*= }"
# Set out_dir # Set out_dir
@ -2270,7 +2318,6 @@ Cannot renew this certificate because a conflicting file exists.
else else
# Attempt restore # Attempt restore
mv -f "$crt_out" "$crt_in" mv -f "$crt_out" "$crt_in"
mv -f "$key_out" "$key_in" 2>/dev/null
die "Failed to move: $key_in" die "Failed to move: $key_in"
fi fi
fi fi