Skip to content

Commit

Permalink
Merge branch 'TinCanTech-tools-expire_status_v2'
Browse files Browse the repository at this point in the history
Signed-off-by: Richard T Bonhomme <[email protected]>
  • Loading branch information
TinCanTech committed Aug 15, 2024
2 parents 5d84784 + cf8b082 commit 788c2ed
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 193 deletions.
1 change: 1 addition & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Easy-RSA 3 ChangeLog

3.2.1 (TBD)

* easyrsa-tools.lib: expire_status_v2() (show-expire version 2) (1e43bf5) (#1214)
* sign-req: Require 128bit serial number (806ee19) (#1213)
* Move command 'verify-cert' to Tools-lib; drop 'verify' shortcut (ddbf304) (#1209)
* Windows secure_session(): Ensure $secured_session dir is created (d99b242) (#1203)
Expand Down
222 changes: 29 additions & 193 deletions dev/easyrsa-tools.lib
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,17 @@ cert_date_to_iso_8601: force_set_var - $2 - $out_date"
unset -v in_date out_date yyyy mmm mm dd HH MM SS TZ
} # => cert_date_to_iso_8601()

# Certificate expiry
will_cert_expire() {
[ -f "$1" ] || die "will_cert_expire - Missing file"
case "$2" in (*[!1234567890]*|0*)
die "will_cert_expire - Non-decimal" ;;
esac

"$EASYRSA_OPENSSL" x509 -in "$1" -noout -checkend "$2"
} # => will_cert_expire()


# SC2295: Expansion inside ${..} need to be quoted separately,
# otherwise they match as patterns. (what-ever that means ;-)
# Unfortunately, Windows sh.exe has an weird bug.
Expand Down Expand Up @@ -537,10 +548,10 @@ read_db() {
case "$db_status" in
V|E)
case "$target" in
'') expire_status ;;
'') expire_status_v2 "$cert_issued" ;;
*)
if [ "$target" = "$db_cn" ]; then
expire_status
expire_status_v2 "$cert_issued"
fi
esac
;;
Expand Down Expand Up @@ -598,214 +609,39 @@ read_db() {
} # => read_db()

# Expire status
expire_status() {
unset -v expire_status_cert_exists
expire_status_v2() {
# expiry seconds
pre_expire_window_s="$((
EASYRSA_PRE_EXPIRY_WINDOW * 60*60*24
))"

# The certificate for CN should exist but may not
unset -v expire_status_cert_exists
if [ -f "$cert_issued" ]; then

if [ -f "$1" ]; then
verbose "expire_status: cert exists"
expire_status_cert_exists=1

# get the serial number of the certificate
ssl_cert_serial "$cert_issued" cert_serial

# db serial must match certificate serial, otherwise
# this is a renewed cert which has been replaced by
# an issued cert
if [ "$db_serial" != "$cert_serial" ]; then
information "\
expire_status: SERIAL MISMATCH
db_serial: $db_serial
cert_serial: $cert_serial
commonName: $db_cn
cert_issued: $cert_issued${NL}"
#return 0
fi

# Get cert end date in iso_8601 format from SSL
# or fall-back to old format
# Redirect SSL error to /dev/null here not in function
cert_not_after_date=
if iso_8601_cert_enddate \
"$cert_issued" cert_not_after_date 2>/dev/null
then
: # ok
else
verbose "\
expire_status: ACCEPTED ERROR-1: \
from iso_8601_cert_enddate"
verbose "\
expire_status: CONSUMED ERROR: \
FALL-BACK to default SSL date format"
ssl_cert_not_after_date \
"$cert_issued" cert_not_after_date
verbose "\
expire_status: FALL-BACK completed"
fi

else
verbose "expire_status: cert does NOT exist"
# Translate db date to 8601_date
cert_not_after_date=
db_date_to_iso_8601_date \
"$db_notAfter" cert_not_after_date

# Translate 8601_date to time-stamp-seconds
iso_8601_timestamp_to_seconds \
"$cert_not_after_date" cert_expire_date_s
# Cert does not exist
fi

# Only verify if there is a certificate
if [ "$expire_status_cert_exists" ]; then

# Check cert expiry against window
# openssl direct call because error is expected
if "$EASYRSA_OPENSSL" x509 -in "$cert_issued" \
-noout -checkend "$pre_expire_window_s" \
1>/dev/null
if will_cert_expire "$1" "$pre_expire_window_s" \
1>/dev/null
then
expire_msg="will NOT expire"
will_not_expire=1
unset -v will_expire
: # cert will NOT expire
else
expire_msg="will expire"
will_expire=1
unset -v will_not_expire
fi
verbose "expire_status: SSL checkend: $expire_msg"

# Get timestamp seconds for certificate expiry date
# Redirection for errout is not necessary here
cert_expire_date_s=
if iso_8601_timestamp_to_seconds \
"$cert_not_after_date" cert_expire_date_s
then
: # ok

# Verify dates via 'date +%s' format
verbose "\
expire_status: cert_date_to_timestamp_s: for comparison"
old_cert_expire_date_s=
cert_date_to_timestamp_s \
"$cert_not_after_date" old_cert_expire_date_s

# Prove this works
if [ "$cert_expire_date_s" = "$old_cert_expire_date_s" ]
# cert will expire
# ISO8601 date - OpenSSL v3 only
if ! iso_8601_cert_enddate "$1" cert_not_after_date \
2>/dev/null
then
verbose "\
expire_status: ABSOLUTE seconds MATCH:
cert_expire_date_s= $cert_expire_date_s
old_cert_expire_date_s= $old_cert_expire_date_s"
else
verbose "\
expire_status: ABSOLUTE seconds do not MATCH:
cert_expire_date_s= $cert_expire_date_s
old_cert_expire_date_s= $old_cert_expire_date_s
difference= \
$(( cert_expire_date_s - old_cert_expire_date_s ))"

# If there is an error then use --days-margin=10
[ "$EASYRSA_iso_8601_MARGIN" ] || \
die "\
expire_status - ABSOLUTE seconds mismatch: Use --allow-margin=N"

# Allows days for margin of error in seconds
margin_s="$((
EASYRSA_iso_8601_MARGIN * (60 * 60 * 24) + 1
))"
margin_plus_s="$((
old_cert_expire_date_s + margin_s
))"
margin_minus_s="$((
old_cert_expire_date_s - margin_s
))"

if [ "$cert_expire_date_s" -lt "$margin_plus_s" ] &&
[ "$cert_expire_date_s" -gt "$margin_minus_s" ]
then
: # ok
verbose "\
expire_status: MARGIN seconds ACCEPTED:
cert_expire_date_s= $cert_expire_date_s
old_cert_expire_date_s= $old_cert_expire_date_s
difference= \
$(( cert_expire_date_s - old_cert_expire_date_s ))
margin_plus_s= $margin_plus_s
margin_minus_s= $margin_minus_s"
else
verbose "\
expire_status: MARGIN seconds REJECTED:
cert_expire_date_s= $cert_expire_date_s
old_cert_expire_date_s= $old_cert_expire_date_s
margin_plus_s= $margin_plus_s
margin_minus_s= $margin_minus_s"

die "\
expire_status: Verify cert expire date EXCESS mismatch!"
fi
# Standard date - OpenSSL v1
ssl_cert_not_after_date "$1" cert_not_after_date
fi

verbose "\
expire_status: cert_date_to_timestamp_s: comparison complete"

else
verbose "\
expire_status: ACCEPTED ERROR-2: \
iso_8601_timestamp_to_seconds"
verbose "\
expire_status: CONSUMED ERROR: \
FALL-BACK to default SSL date format"

cert_date_to_timestamp_s \
"$cert_not_after_date" cert_expire_date_s

verbose "\
expire_status: FALL-BACK completed"
fi
fi

# Convert number of days to a timestamp in seconds
cutoff_date_s=
days_to_timestamp_s \
"$EASYRSA_PRE_EXPIRY_WINDOW" cutoff_date_s

# Get the current date/time as a timestamp in seconds
now_date_s=
days_to_timestamp_s \
0 now_date_s

# Compare and print output
if [ "$cert_expire_date_s" -lt "$cutoff_date_s" ]; then
# Cert expires in less than grace period
if [ "$will_not_expire" ]; then
die "\
EasyRSA: will expire - SSL: will NOT expire"
fi
if [ "$cert_expire_date_s" -gt "$now_date_s" ]; then
verbose "expire_status: Valid -> expiring"
# show expiring cert details
printf '%s%s\n' \
"$db_status | Serial: $db_serial | " \
"Expires: $cert_not_after_date | CN: $db_cn"
else
verbose "expire_status: Expired"
printf '%s%s\n' \
"$db_status | Serial: $db_serial | " \
"Expired: $cert_not_after_date | CN: $db_cn"
"$cert_not_after_date | CN: $db_cn"
fi
else
if [ "$will_expire" ]; then
die "\
EasyRSA: will NOT expire - SSL: will expire"
fi
verbose "expire_status: Valid -> NOT expiring"
: # issued cert does not exist, ignore other certs
fi
} # => expire_status()
} # => expire_status_v2()

# Revoke status
revoke_status() {
Expand Down

0 comments on commit 788c2ed

Please sign in to comment.