Introduce extensible PKI reporting tool framework

Comes with 'expiry' and 'revoke' report.

Could do with 'renewed-not-revoked' report.

Signed-off-by: Richard T Bonhomme <tincantech@protonmail.com>
This commit is contained in:
Richard T Bonhomme 2022-05-07 01:41:36 +01:00
parent a03a839685
commit 1137a54cc1
No known key found for this signature in database
GPG Key ID: 2D767DB92FB6C246

View File

@ -44,6 +44,8 @@ Here is the list of commands available with a short syntax reminder. Use the
show-cert <filename_base> [ cmd-opts ]
show-ca [ cmd-opts ]
show-crl
show-expire
show-revoke
verify <filename_base>
import-req <request_file_path> <short_basename>
export-p1 <filename_base> [ cmd-opts ]
@ -169,6 +171,16 @@ cmd_help() {
show-crl
Shows details of the current certificate revocation list (CRL)
Human-readable output is shown." ;;
show-expire) text="
show-expire [ cmd-opts ]
Shows details of expiring certificates
Human-readable output is shown." ;;
show-revoke) text="
show-revoke [ cmd-opts ]
Shows details of revoked certificates
Human-readable output is shown." ;;
verify) text="
verify <filename_base>
@ -1604,7 +1616,7 @@ revoke_move() {
# Set certificate expire date, renew date and variables needed for fixdate
cert_dates() {
if [ "$1" ]; then
if [ -e "$1" ]; then
# Required for renewal
# Call openssl directly, otherwise this is not debug compatible
crt_not_before="$("$EASYRSA_OPENSSL" x509 -in "$1" -noout -startdate 2>&1)" \
@ -1614,6 +1626,9 @@ cert_dates() {
|| die "cert_dates - crt_not_after: $crt_not_after"
crt_not_after="${crt_not_after#*=}"
shift
elif [ "$1" ]; then
# Required for status
crt_not_after="$1"
else
# Required for --fix-offset
# This is a fake date to satisfy the 'if expire_date' command test
@ -2533,6 +2548,145 @@ $in_file"
OpenSSL failure to process the input"
} # => show_ca()
# Fixed format date
# Build a Windows date.exe compatible input field
build_ff_date_string() {
ff_date="$1"
[ "$ff_date" ] || die "ff_date: '$ff_date'"
yy="${ff_date%???????????}"
ff_date="${ff_date#"$yy"}"
mm="${ff_date%?????????}"
ff_date="${ff_date#"$mm"}"
dd="${ff_date%???????}"
ff_date="${ff_date#"$dd"}"
HH="${ff_date%?????}"
ff_date="${ff_date#"$HH"}"
MM="${ff_date%???}"
ff_date="${ff_date#"$MM"}"
SS="${ff_date%?}"
ff_date="${ff_date#"$SS"}"
TZ="$ff_date"
ff_date="${yy}-${mm}-${dd} ${HH}:${MM}:${SS}${TZ}"
} # => build_date_string()
# SC2295: (info): Expansions inside ${..} need to be quoted separately,
# otherwise they match as patterns. (what-ever that means .. ;-)
# Unfortunately, Windows sh.exe has an absolutely ridiculous bug.
# Try this in sh.exe: t=' '; s="a${t}b${t}c"; echo "${s%%"${t}"*}"
# Read db
# shellcheck disable=SC2295
read_db() {
report="$1"; shift
tab_char=' '
db_in="$EASYRSA_PKI/index.txt"
while read -r crt_stat crt_notAfter crt_record; do
# Interpret the db/certificate record
unset -v crt_serial crt_cn crt_revokedate crt_reason
case "$crt_stat" in
V)
# Valid
crt_serial="${crt_record%%${tab_char}*}"
crt_record="${crt_record#*${tab_char}}"
crt_cn="${crt_record#*/CN=}"; crt_cn="${crt_cn%%/*}"
crt_file="$EASYRSA_PKI/issued/$crt_cn.crt"
;;
R)
# Revoked
crt_revokedate="${crt_record%%${tab_char}*}"
crt_reason="${crt_revokedate#*,}"
[ -z "$crt_reason" ] || crt_revokedate="${crt_revokedate%,*}"
crt_record="${crt_record#*${tab_char}}"
crt_serial="${crt_record%%${tab_char}*}"
crt_record="${crt_record#*${tab_char}}"
crt_cn="${crt_record#*/CN=}"; crt_cn="${crt_cn%%/*}"
;;
*) die "Unexpected status: $crt_stat"
esac
# do status report for this record
# TODO: renewed-not-revoked
case "$report" in
expire) if [ "$crt_stat" = V ]; then expire_status; fi ;;
revoke) if [ "$crt_stat" = R ]; then revoke_status; fi ;;
*) die "Unrecognised report: $report"
esac
done < "$db_in"
} # => read_db()
# Expire status
expire_status() {
build_ff_date_string "$crt_notAfter"
crt_file="$EASYRSA_PKI/issued/${crt_cn}.crt"
if [ -e "$crt_file" ]; then
# Use cert date
cert_dates "$crt_file"
else
# Use db translated date
cert_dates "$crt_notAfter"
fi
if [ "$expire_date" -lt "$allow_renew_date" ]; then
# cert expires in less than grace period
printf '%s%s\n' "$crt_stat | Serial: $crt_serial | " \
"Expires: $ff_date | CN: $crt_cn"
fi
} # => expire_status()
# Revoke status
revoke_status() {
build_ff_date_string "$crt_revokedate"
crt_file="$EASYRSA_PKI/revoked/certs_by_serial/$crt_serial.crt"
if [ -e "$crt_file" ]; then
# Use cert file
cert_dates "$crt_file"
else
# Use db translated date
cert_dates "$crt_notAfter"
fi
printf '%s%s\n' "$crt_stat | Serial: $crt_serial | " \
"Revoked: $ff_date | Reason: $crt_reason | CN: $crt_cn"
} # => revoke_status()
# cert status reports
status() {
report="$1"
in_crt="$2"
shift 2
verify_ca_init
case "$report" in
expire)
case "$in_crt" in
all)
print "Showing certificates which expire in less than $EASYRSA_CERT_RENEW days:"
print
read_db expire
;;
*) print "Coming soon.."
esac
;;
revoke)
case "$in_crt" in
all)
print "Showing certificates which are revoked:"
print
read_db revoke ;;
*) print "Coming soon.."
esac
;;
*)
# TODO: renewed-not-revoked
warn "Unrecognised report: $report"
esac
} # => status()
# set_var is not known by shellcheck, therefore:
# Fake declare known variables for shellcheck
# Use these options without this function:
@ -3693,6 +3847,20 @@ case "$cmd" in
verify)
verify_cert "$@"
;;
show-expire)
if [ -z "$*" ]; then
status expire all
else
status expire "$@"
fi
;;
show-revoke)
if [ -z "$*" ]; then
status revoke all
else
status revoke "$@"
fi
;;
upgrade)
up23_manage_upgrade_23 "$@"
;;