%PDF- %PDF-
| Direktori : /proc/self/root/backups/router/usr/local/bin/ |
| Current File : //proc/self/root/backups/router/usr/local/bin/easyrsa-tools.lib |
#!/bin/sh
# Easy-RSA 3 Tools library
#
# Copyright (C) 2024 - The Open-Source OpenVPN development community.
# A full list of contributors can be found on Github at:
# https://github.com/OpenVPN/easy-rsa/graphs/contributors
#
# This code released under version 2 of the GNU GPL; see COPYING
# and the Licensing/ directory of this project for full licensing
# details.
# Easy-RSA 3.x does not source into the environment directly.
# Complain if a user tries to do this:
if [ -z "$EASYRSA_TOOLS_CALLER" ]; then
return 1
fi
# Set tools version
export EASYRSA_TOOLS_VERSION=321
# Verify OpenVPN binary
verify_openvpn() {
# Try to find openvpn
set_var EASYRSA_OPENVPN "$(which openvpn)"
if [ -f "$EASYRSA_OPENVPN" ]; then
verbose \
"verify_openvpn - EASYRSA_OPENVPN='$EASYRSA_OPENVPN'"
else
user_error "Cannot find an OpenVPN binary."
fi
} # => verify_openvpn()
# OpenVPN TLS Auth/Crypt Key
tls_key_gen() {
case "$1" in
tls-crypt-v2)
print "Unavailable."
cleanup
;;
tls-crypt) tls_key_type=TLS-CRYPT ;;
tls-auth) tls_key_type=TLS-AUTH ;;
*) die "Unknown key type: '$1'"
esac
# Over write error message
tls_key_error_msg="
If this file is changed then it MUST be redistributed to ALL servers
AND clients, to be in effect. Do NOT change this existing file."
# Assign possible TLS key sources
tls_key_file="$EASYRSA_PKI"/private/easyrsa-tls.key
old_tls_key_file="$EASYRSA_PKI"/easyrsa-keepsafe-tls.key
# Forbid overwrite - default TLS key
if [ -f "$tls_key_file" ]; then
tls_key_data="$(cat "$tls_key_file")"
case "$tls_key_data" in
*'TLS-CRYPT'*) tls_key_type=TLS-CRYPT ;;
*'TLS-AUTH'*) tls_key_type=TLS-AUTH ;;
*) tls_key_type=UNKNOWN
esac
user_error "\
Cannot overwrite existing $tls_key_type Key:
* $tls_key_file
$tls_key_error_msg"
fi
# Forbid overwrite - Old TLS key
if [ -f "$old_tls_key_file" ]; then
old_tls_key_data="$(cat "$old_tls_key_file")"
case "$old_tls_key_data" in
*'TLS-CRYPT'*) tls_key_type=TLS-CRYPT ;;
*'TLS-AUTH'*) tls_key_type=TLS-AUTH ;;
*) tls_key_type=UNKNOWN
esac
user_error "\
Cannot overwrite existing $tls_key_type Key:
* $old_tls_key_file
$tls_key_error_msg"
fi
verify_openvpn
tls_key_tmp=
easyrsa_mktemp tls_key_tmp || \
die "tls_key_gen - easyrsa_mktemp tls_key_tmp"
# Generate TLS Key
"$EASYRSA_OPENVPN" --genkey "$1" "$tls_key_tmp" || \
die "tls_key_gen - --genkey $tls_key_type FAIL"
# Insert type label
{
print "# Easy-RSA $tls_key_type Key"
cat "$tls_key_tmp"
} > "$tls_key_file" || \
die "tls_key_gen - Insert type label FAIL"
notice "\
$tls_key_type Key generated at:
* $tls_key_file
$tls_key_error_msg"
verbose "tls_key_gen: openvpn --genkey $tls_key_type OK"
} # => tls_key_gen()
# Get certificate start date
# shellcheck disable=2317 # Unreach - ssl_cert_not_before_date()
ssl_cert_not_before_date() {
verbose "DEPRECATED: ssl_cert_not_before_date()"
[ "$#" = 2 ] || die "\
ssl_cert_not_before_date - input error"
[ -f "$1" ] || die "\
ssl_cert_not_before_date - missing cert"
fn_ssl_out="$(
"$EASYRSA_OPENSSL" x509 -in "$1" -noout -startdate
)" || die "\
ssl_cert_not_before_date - failed: -startdate"
fn_ssl_out="${fn_ssl_out#*=}"
force_set_var "$2" "$fn_ssl_out" || die "\
ssl_cert_not_before_date - failed to set var '$*'"
unset -v fn_ssl_out
} # => ssl_cert_not_before_date()
# Get certificate end date
ssl_cert_not_after_date() {
verbose "DEPRECATED: ssl_cert_not_after_date()"
[ "$#" = 2 ] || die "\
ssl_cert_not_after_date - input error"
[ -f "$1" ] || die "\
ssl_cert_not_after_date - missing cert"
fn_ssl_out="$(
"$EASYRSA_OPENSSL" x509 -in "$1" -noout -enddate
)" || die "\
ssl_cert_not_after_date - failed: -enddate"
fn_ssl_out="${fn_ssl_out#*=}"
force_set_var "$2" "$fn_ssl_out" || die "\
ssl_cert_not_after_date - failed to set var '$*'"
unset -v fn_ssl_out
} # => ssl_cert_not_after_date()
# SSL -- v3 -- startdate iso_8601
# shellcheck disable=2317 # Unreach - iso_8601_cert_startdate()
iso_8601_cert_startdate() {
verbose "NEW: iso_8601_cert_startdate"
[ "$#" = 2 ] || die "\
iso_8601_cert_startdate: input error"
[ -f "$1" ] || die "\
iso_8601_cert_startdate: missing cert"
# On error return, let the caller decide what to do
if fn_ssl_out="$(
"$EASYRSA_OPENSSL" x509 -in "$1" -noout \
-startdate -dateopt iso_8601
)"
then
: # ok
else
# The caller MUST assess this error
verbose "\
iso_8601_cert_startdate: GENERATED ERROR"
return 1
fi
fn_ssl_out="${fn_ssl_out#*=}"
force_set_var "$2" "$fn_ssl_out" || die "\
iso_8601_cert_startdate: failed to set var '$*'"
unset -v fn_ssl_out
} # => iso_8601_cert_startdate()
# SSL -- v3 -- enddate iso_8601
iso_8601_cert_enddate() {
verbose "NEW: iso_8601_cert_enddate"
[ "$#" = 2 ] || die "\
iso_8601_cert_enddate: input error"
[ -f "$1" ] || die "\
iso_8601_cert_enddate: missing cert"
# On error return, let the caller decide what to do
if fn_ssl_out="$(
"$EASYRSA_OPENSSL" x509 -in "$1" -noout \
-enddate -dateopt iso_8601
)"
then
: # ok
else
# The caller MUST assess this error
verbose "\
iso_8601_cert_enddate: GENERATED ERROR"
return 1
fi
fn_ssl_out="${fn_ssl_out#*=}"
force_set_var "$2" "$fn_ssl_out" || die "\
iso_8601_cert_enddate: failed to set var '$*'"
unset -v fn_ssl_out
} # => iso_8601_cert_enddate()
# Number of days from NOW@today as timestamp seconds
days_to_timestamp_s() {
verbose "REQUIRED: days_to_timestamp_s: uses date"
# check input
[ "$#" = 2 ] || die "\
days_to_timestamp_s: input error"
in_days="$1"
in_seconds="$(( in_days * 60 * 60 * 24 ))"
# There are NO OS dependencies for this use of date
# OS dependencies
# Linux and Windows
# date.exe does not allow +%s as input
# MacPorts GNU date
if timestamp_s="$(
date +%s 2>/dev/null
)"
then : # ok
# Darwin, BSD
elif timestamp_s="$(
date +%s 2>/dev/null
)"
then : # ok
# busybox
elif timestamp_s="$(
busybox date +%s 2>/dev/null
)"
then : # ok
# Something else
else
die "\
days_to_timestamp_s: 'date +%s' failed"
fi
# Add period
timestamp_s="$(( timestamp_s + in_seconds ))"
# Return timestamp_s
force_set_var "$2" "$timestamp_s" || die "\
days_to_timestamp_s: force_set_var - $2 - $timestamp_s"
unset -v in_days in_seconds timestamp_s
} # => days_to_timestamp_s()
# Convert certificate date to timestamp seconds since epoch
# Used to verify iso_8601 calculated seconds since epoch
cert_date_to_timestamp_s() {
verbose "DEPRECATED: cert_date_to_timestamp_s"
# check input
[ "$#" = 2 ] || die "\
cert_date_to_timestamp_s: input error"
#die "* NOT ALLOWED: cert_date_to_timestamp_s()"
in_date="$1"
# OS dependencies
# Linux and Windows
# date.exe does not allow +%s as input
# MacPorts GNU date
if timestamp_s="$(
date -d "$in_date" +%s \
2>/dev/null
)"
then : # ok
# Darwin, BSD
elif timestamp_s="$(
date -j -f '%b %d %T %Y %Z' \
"$in_date" +%s 2>/dev/null
)"
then : # ok
# busybox
elif timestamp_s="$(
busybox date -D "%b %e %H:%M:%S %Y" \
-d "$in_date" +%s 2>/dev/null
)"
then : # ok
# Something else
else
die "\
cert_date_to_timestamp_s:
'date' failed for in_date=$in_date"
fi
# Return timestamp_s
force_set_var "$2" "$timestamp_s" || die "\
cert_date_to_timestamp_s: force_set_var - $2 - $timestamp_s"
unset -v in_date timestamp_s
} # => cert_date_to_timestamp_s()
# Build a Windows date.exe compatible input field
# iso_8601 date
db_date_to_iso_8601_date() {
verbose "iso_8601: db_date_to_iso_8601_date"
# check input
[ "$#" = 2 ] || die "\
db_date_to_iso_8601_date - input error"
# Expected format: '230612235959Z'
in_date="$1"
verbose "db_date_to_iso_8601_date: in_date=$in_date"
# Consume $in_date string
# yyyy is expected to be only 'yy'
yyyy="${in_date%???????????}"
in_date="${in_date#"$yyyy"}"
# When yyyy is only two digits prepend century
if [ "${#yyyy}" = 2 ]; then
yyyy="${yyyy#0}"
if [ "$yyyy" -lt 70 ]; then
if [ "${#yyyy}" = 2 ]; then
yyyy="20${yyyy}"
else
yyyy="200${yyyy}"
fi
else
if [ "${#yyyy}" = 2 ]; then
yyyy="19${yyyy}"
else
yyyy="190${yyyy}"
fi
fi
fi
verbose "db_date_to_iso_8601_date: yyyy=$yyyy"
mm="${in_date%?????????}"
in_date="${in_date#"$mm"}"
dd="${in_date%???????}"
in_date="${in_date#"$dd"}"
HH="${in_date%?????}"
in_date="${in_date#"$HH"}"
MM="${in_date%???}"
in_date="${in_date#"$MM"}"
SS="${in_date%?}"
in_date="${in_date#"$SS"}"
TZ="$in_date"
# Assign iso_8601 date
out_date="${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}${TZ}"
verbose "db_date_to_iso_8601_date: out_date=$out_date"
# Return out_date
force_set_var "$2" "$out_date" || die "\
db_date_to_iso_8601_date: force_set_var - $2 - $out_date"
unset -v in_date out_date yyyy mm dd HH MM SS TZ
} # => db_date_to_iso_8601_date()
# Certificate expiry
will_cert_be_valid() {
[ -f "$1" ] || die "will_cert_be_valid - Missing file"
case "$2" in (*[!1234567890]*|0*)
die "will_cert_be_valid - Non-decimal" ;;
esac
# is the cert still valid at this future date
"$EASYRSA_OPENSSL" x509 -in "$1" -noout -checkend "$2"
} # => will_cert_be_valid()
# 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.
# Try in sh.exe: t=' '; s="a${t}b${t}c"; echo "${s%%"${t}"*}"
# Read db
# shellcheck disable=SC2295 # nested expand - read_db()
read_db() {
TCT=' ' # tab character
db_in="$EASYRSA_PKI/index.txt"
pki_r_issued="$EASYRSA_PKI/renewed/issued"
pki_r_by_sno="$EASYRSA_PKI/renewed/certs_by_serial"
unset -v target_found
while read -r db_status db_notAfter db_record; do
verbose "***** Read next record *****"
# Recreate temp session
remove_secure_session || \
die "read_db - remove_secure_session"
locate_support_files
secure_session || \
die "read_db - secure_session"
# Recreate openssl-easyrsa.cnf (Temp)
write_global_safe_ssl_cnf_tmp
# Interpret the db/certificate record
unset -v db_serial db_cn db_revoke_date db_reason
case "$db_status" in
V|E)
# Valid
db_serial="${db_record%%${TCT}*}"
db_record="${db_record#*${TCT}}"
db_cn="${db_record#*/CN=}"; db_cn="${db_cn%%/*}"
cert_issued="$EASYRSA_PKI/issued/$db_cn.crt"
cert_r_issued="$pki_r_issued/$db_cn.crt"
cert_r_by_sno="$pki_r_by_sno/$db_serial.crt"
;;
R)
# Revoked
db_revoke_date="${db_record%%${TCT}*}"
db_reason="${db_revoke_date#*,}"
if [ "$db_reason" = "$db_revoke_date" ]; then
db_reason="None given"
else
db_revoke_date="${db_revoke_date%,*}"
fi
db_record="${db_record#*${TCT}}"
db_serial="${db_record%%${TCT}*}"
db_record="${db_record#*${TCT}}"
db_cn="${db_record#*/CN=}"; db_cn="${db_cn%%/*}"
;;
*) die "Unexpected status: $db_status"
esac
# Output selected status report for this record
case "$report" in
expire)
# Certs which expire before EASYRSA_PRE_EXPIRY_WINDOW days
case "$db_status" in
V|E)
case "$target" in
'') expire_status_v2 "$cert_issued" ;;
*)
if [ "$target" = "$db_cn" ]; then
expire_status_v2 "$cert_issued"
fi
esac
;;
*)
: # Ignore ok
esac
;;
revoke)
# Certs which have been revoked
case "$db_status" in
R)
case "$target" in
'') revoke_status ;;
*)
if [ "$target" = "$db_cn" ]; then
revoke_status
fi
esac
;;
*)
: # Ignore ok
esac
;;
renew)
# Certs which have been renewed but not revoked
case "$db_status" in
V|E)
case "$target" in
'') renew_status ;;
*)
if [ "$target" = "$db_cn" ]; then
renew_status
fi
esac
;;
*)
: # Ignore ok
esac
;;
*) die "Unrecognised report: $report"
esac
# Is db record for target found
if [ "$target" = "$db_cn" ]; then
target_found=1
fi
done < "$db_in"
# Add CA to show-expire
case "$report" in
expire)
# Extract -endate
ca_enddate="$(
"$EASYRSA_OPENSSL" x509 -in "$EASYRSA_PKI"/ca.crt \
-noout -enddate
)"
ca_enddate="${ca_enddate#*=}"
# Check CA for expiry
if will_cert_be_valid "$EASYRSA_PKI"/ca.crt \
"$pre_expire_window_s" 1>/dev/null
then
: # cert will still be valid by expiry window
else
# Print CA expiry date
printf '%s%s\n' \
"CA certificate will expire on $ca_enddate"
fi
esac
# Check for target found/valid commonName, if given
if [ "$target" ]; then
[ "$target_found" ] || \
warn "Certificate for $target was not found"
fi
} # => read_db()
# Expire status
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
if [ -f "$1" ]; then
verbose "expire_status: cert exists"
if will_cert_be_valid "$1" "$pre_expire_window_s" \
1>/dev/null
then
: # cert will still be valid by expiry window
else
# cert will expire
# ISO8601 date - OpenSSL v3 only
if ! iso_8601_cert_enddate "$1" cert_not_after_date \
2>/dev/null
then
# Standard date - OpenSSL v1
ssl_cert_not_after_date "$1" cert_not_after_date
fi
# show expiring cert details
printf '%s%s\n' \
"$db_status | Serial: $db_serial | " \
"$cert_not_after_date | CN: $db_cn"
fi
else
: # issued cert does not exist, ignore other certs
fi
} # => expire_status_v2()
# Revoke status
revoke_status() {
# Translate db date to usable date
cert_revoke_date=
db_date_to_iso_8601_date "$db_revoke_date" cert_revoke_date
printf '%s%s%s\n' \
"$db_status | Serial: $db_serial | " \
"Revoked: $cert_revoke_date | " \
"Reason: $db_reason | CN: $db_cn"
} # => revoke_status()
# Renewed status
# renewed certs only remain in the renewed folder until revoked
# Only ONE renewed cert with unique CN can exist in renewed folder
renew_status() {
# Does a Renewed cert exist ?
# files in issued are file name, or in serial are SerialNumber
unset -v \
cert_file_in cert_is_issued cert_is_serial renew_is_old
# Find renewed/issued/CN
if [ -f "$cert_r_issued" ]; then
cert_file_in="$cert_r_issued"
cert_is_issued=1
fi
# Find renewed/cert_by_serial/SN
if [ -f "$cert_r_by_sno" ]; then
cert_file_in="$cert_r_by_sno"
cert_is_serial=1
renew_is_old=1
fi
# Both should not exist
if [ "$cert_is_issued" ] && [ "$cert_is_serial" ]; then
die "Too many certs"
fi
# If a renewed cert exists
if [ "$cert_file_in" ]; then
# get the serial number of the certificate
ssl_cert_serial "$cert_file_in" cert_serial
# db serial must match certificate serial, otherwise
# this is an issued cert that replaces a renewed cert
if [ "$db_serial" != "$cert_serial" ]; then
information "\
serial mismatch:
db_serial: $db_serial
cert_serial: $cert_serial
cert_file_in: $cert_file_in"
return 0
fi
# Use cert date
# Assigns cert_not_after_date
ssl_cert_not_after_date \
"$cert_file_in" cert_not_after_date
# Highlight renewed/cert_by_serial
if [ "$renew_is_old" ]; then
printf '%s%s\n' \
"*** $db_status | Serial: $db_serial | " \
"Expires: $cert_not_after_date | CN: $db_cn"
else
printf '%s%s\n' \
"$db_status | Serial: $db_serial | " \
"Expires: $cert_not_after_date | CN: $db_cn"
fi
else
# Cert is valid but not renewed
: # ok - ignore
fi
} # => renew_status()
# cert status reports
status() {
[ "$#" -gt 0 ] || die "status - input error"
report="$1"
target="$2"
# test fix: https://github.com/OpenVPN/easy-rsa/issues/819
export LC_TIME=C.UTF-8
# If no target file then add Notice
if [ -z "$target" ]; then
# Select correct Notice
case "$report" in
expire)
notice "\
* Showing certificates which expire in less than \
$EASYRSA_PRE_EXPIRY_WINDOW days (--days):"
;;
revoke)
notice "\
* Showing certificates which are revoked:"
;;
renew)
notice "\
* Showing certificates which have been renewed but NOT revoked:
*** Marks those which require 'rewind-renew' \
before they can be revoked."
;;
*) warn "Unrecognised report: $report"
esac
fi
# Create report
read_db
} # => status()
# renew backend
renew() {
# pull filename base:
[ "$1" ] || user_error "\
Error: didn't find a file base name as the first argument.
Run easyrsa without commands for usage and command help."
# Assign file_name_base and dust off!
file_name_base="$1"
shift
# Assign input files
in_dir="$EASYRSA_PKI"
crt_in="$in_dir/issued/${file_name_base}.crt"
key_in="$in_dir/private/${file_name_base}.key"
req_in="$in_dir/reqs/${file_name_base}.req"
creds_in="$in_dir/${file_name_base}.creds"
inline_in="$in_dir/inline/${file_name_base}.inline"
# Upgrade CA index.txt.attr - unique_subject = no
print 'unique_subject = no' > "$EASYRSA_PKI/index.txt.attr" || \
die "Failed to upgrade CA to support renewal."
# deprecate ALL options
while [ "$1" ]; do
case "$1" in
nopass)
warn "\
Option 'nopass' is not supported by command 'renew'."
;;
*) user_error "Unknown option: $1"
esac
shift
done
# Verify certificate
if [ -f "$crt_in" ]; then
verify_file x509 "$crt_in" || user_error "\
Input file is not a valid certificate:
* $crt_in"
else
user_error "\
Missing certificate file:
* $crt_in"
fi
# Verify request
if [ -f "$req_in" ]; then
verify_file req "$req_in" || user_error "\
Input file is not a valid request:
* $req_in"
else
user_error "\
Missing request file:
* $req_in"
fi
# Get cert commonName
cert_CN="$(
display_dn x509 "$crt_in" | grep 'commonName'
)" || die "renew - display_dn of cert failed"
# Get req commonName
req_CN="$(
display_dn req "$req_in" | grep 'commonName'
)" || die "renew - display_dn of req failed"
# For renew, cert_CN must match req_CN
[ "$cert_CN" = "$req_CN" ] || user_error \
"Certificate cannot be renewed due to commonName mismatch"
verbose "renew - cert_CN MATCH req_CN"
# get the serial number of the certificate
ssl_cert_serial "$crt_in" cert_serial || \
die "$cmd: Failed to get cert serial number!"
# Duplicate cert by serial file
dup_dir="$EASYRSA_PKI/certs_by_serial"
dup_crt_by_serial="$dup_dir/${cert_serial}.pem"
# Set out_dir
out_dir="$EASYRSA_PKI/renewed"
crt_out="$out_dir/issued/${file_name_base}.crt"
# NEVER over-write a renewed cert, revoke it first
deny_msg="\
Cannot renew this certificate, a conflicting file exists:
*"
[ -f "$crt_out" ] && \
user_error "$deny_msg certificate: $crt_out"
unset -v deny_msg
# Make inline directory
[ -d "$EASYRSA_PKI/inline" ] || \
mkdir -p "$EASYRSA_PKI/inline" || \
die "Failed to create inline directoy."
# Extract certificate usage from old cert
ssl_cert_x509v3_eku "$crt_in" cert_type
# Use SAN from old cert ONLY
if grep 'X509v3 Subject Alternative Name' "$crt_in"; then
EASYRSA_SAN="$(
"$EASYRSA_OPENSSL" x509 -in "$crt_in" -noout -text | \
grep -A 1 'X509v3 Subject Alternative Name' | \
sed -e s/'^\ *'// \
-e /'X509v3 Subject Alternative Name'/d
)" || die "renew - EASYRSA_SAN: easyrsa_openssl subshell"
verbose "renew: EASYRSA_SAN: ${EASYRSA_SAN}"
# --san-crit
unset -v EASYRSA_SAN_CRIT
if grep -q 'X509v3 Subject Alternative Name: critical' \
"$crt_in"
then
export EASYRSA_SAN_CRIT='critical,'
verbose "renew: --san-crit ENABLED"
fi
export EASYRSA_EXTRA_EXTS="\
$EASYRSA_EXTRA_EXTS
subjectAltName = ${EASYRSA_SAN_CRIT}${EASYRSA_SAN}"
verbose "renew: EASYRSA_EXTRA_EXTS: ${EASYRSA_EXTRA_EXTS}"
fi
# --bc-crit
if grep -q 'X509v3 Basic Constraints: critical' "$crt_in"
then
export EASYRSA_BC_CRIT=1
verbose "renew: --bc-crit ENABLED"
fi
# --ku-crit
if grep -q 'X509v3 Key Usage: critical' "$crt_in"
then
export EASYRSA_KU_CRIT=1
verbose "renew: --ku-crit ENABLED"
fi
# --eku-crit
if grep -q 'X509v3 Extended Key Usage: critical' "$crt_in"
then
export EASYRSA_EKU_CRIT=1
verbose "renew: --eku-crit ENABLED"
fi
# Disable options not supported by renew
unset -v EASYRSA_CP_EXTS EASYRSA_AUTO_SAN EASYRSA_NEW_SUBJECT
# confirm operation by displaying Warning
confirm "Continue with 'renew' ? " yes "\
WARNING: This process is destructive!
These files will be MOVED to the 'renewed' sub-directory:
* $crt_in
These files will be DELETED:
All PKCS files for commonName: $file_name_base
The inline credentials files:
* $creds_in
* $inline_in"
# move renewed files
# so we can reissue certificate with the same name
renew_move
error_undo_renew_move=1
# Set to modify sign-req confirmation message
local_request=1
# renew certificate
# EASYRSA_BATCH=1
if sign_req "$cert_type" "$file_name_base"
then
unset -v error_undo_renew_move
else
# If renew failed then restore cert.
# Otherwise, issue a warning
renew_restore_move
die "Renewal has failed to build a new certificate."
fi
# inline it
# Over write existing because renew is successful
if inline_creds "$file_name_base" > "$inline_in"
then
notice "\
Inline file created:
* $inline_in"
else
warn "\
INCOMPLETE Inline file created:
* $inline_in"
fi
# Success messages
notice "\
Renew was successful.
* IMPORTANT *
Renew has created a new certificate, to replace the old one.
To revoke the old certificate, once the new one has been deployed,
use command 'revoke-renewed $file_name_base'"
} # => renew()
# Restore files on failure to renew
renew_restore_move() {
# restore crt file to PKI folders
rrm_err=
if mv "$restore_crt_out" "$restore_crt_in"; then
: # ok
else
warn "Failed to restore: $restore_crt_in"
rrm_err=1
fi
# messages
if [ "$rrm_err" ]; then
warn "Failed to restore renewed files."
else
notice "\
Renew FAILED but files have been successfully restored."
fi
} # => renew_restore_move()
# renew_move
# moves renewed certificates to the 'renewed' folder
# allows reissuing certificates with the same name
renew_move() {
# make sure renewed dirs exist
easyrsa_mkdir "$out_dir"
easyrsa_mkdir "$out_dir"/issued
# move crt to renewed folders
# After this point, renew is possible!
restore_crt_in="$crt_in"
restore_crt_out="$crt_out"
mv "$crt_in" "$crt_out" || \
die "Failed to move: $crt_in"
# Remove files that can be recreated:
# remove any pkcs files
for pkcs in p12 p7b p8 p1; do
# issued
rm -f "$in_dir/issued/$file_name_base.$pkcs"
# private
rm -f "$in_dir/private/$file_name_base.$pkcs"
done
# remove credentials file
if [ -f "$creds_in" ]; then
rm "$creds_in" || warn "\
Failed to remove credentials file:
* $creds_in"
fi
# remove inline file
if [ -f "$inline_in" ]; then
rm "$inline_in" || warn "\
Failed to remove inline file:
* $inline_in"
fi
} # => renew_move()
# Verify certificate against CA
verify_cert() {
# pull filename base:
[ "$1" ] || user_error "\
Error: didn't find a <file-name-base> as the first argument.
Run easyrsa without commands for usage and command help."
# Assign file_name_base and dust off!
file_name_base="$1"
shift
# function opts support
while [ "$1" ]; do
case "$1" in
# batch flag, return status [0/1] to calling
# program. Otherwise, exit 0 on completion.
batch) EASYRSA_BATCH=1 ;;
*) warn "Ignoring unknown command option: '$1'"
esac
shift
done
in_dir="$EASYRSA_PKI"
ca_crt="$in_dir/ca.crt"
crt_in="$in_dir/issued/$file_name_base.crt"
# Cert file must exist
[ -f "$crt_in" ] || user_error "\
No certificate found for the input:
* '$crt_in'"
# Verify file is a valid cert
verify_file x509 "$crt_in" || user_error "\
Input is not a valid certificate:
* $crt_in"
# Silent SSL or not
if [ "$EASYRSA_SILENT_SSL" ]; then
# Test SSL out
# openssl direct call because error is expected
if "$EASYRSA_OPENSSL" verify \
-CAfile "$ca_crt" "$crt_in" >/dev/null
then
verify_cert_ok=1
else
unset -v verify_cert_ok
fi
else
if "$EASYRSA_OPENSSL" verify \
-CAfile "$ca_crt" "$crt_in"
then
verify_cert_ok=1
else
unset -v verify_cert_ok
fi
fi
# Return cert status
if [ "$verify_cert_ok" ]; then
notice "\
Certificate name: $file_name_base
Verification status: GOOD"
else
notice "\
Certificate name: $file_name_base
Verification status: FAILED"
# Exit with error (batch mode)
if [ "$EASYRSA_BATCH" ]; then
# exit with error at cleanup
easyrsa_exit_with_error=1
# Return error for internal callers
return 1
fi
fi
} # => verify_cert()
# vim: ft=sh nu ai sw=8 ts=8 noet