266 lines
9.1 KiB
Bash
Executable File
266 lines
9.1 KiB
Bash
Executable File
#!/bin/bash
|
||
#############################################################
|
||
# Script name: info-cert.sh
|
||
# Author: Gilles Mouchet (gilles.mouchet@gmail.com
|
||
# Version: 1.0.0
|
||
# Description: Display cert info
|
||
# License: GNU GPL v3
|
||
#
|
||
# This program is distributed in the hope that it will be useful,
|
||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
# GNU General Public License for more details.
|
||
#
|
||
# Changelog
|
||
# [1.0.0] - 2026-04-05
|
||
# Added:
|
||
# - show certificate info
|
||
# - show ca list
|
||
# - show expiration date
|
||
# Project initialization
|
||
# - initialization by gilles.mouchet@gmail.com
|
||
#
|
||
############################################################
|
||
#
|
||
version=1.0.0
|
||
|
||
############################################################
|
||
# FUNCTIONS
|
||
############################################################
|
||
#-----------------------------------------------------------
|
||
# Display usage
|
||
usage() {
|
||
cat << EOF
|
||
Usage: ./$(basename "$0") options
|
||
Template script
|
||
Options:
|
||
-a, --all
|
||
Show all cert information
|
||
-c, --ca
|
||
List all CA name
|
||
-d, --expire-day <days>
|
||
List the certificates expiring in the next <days> days
|
||
-i, --info <ca_name_pattern>
|
||
Display certificate info. You can use wirdcard * in pattern
|
||
-n, --cn
|
||
List all cn
|
||
-h, --help
|
||
Show this help
|
||
-v, --version
|
||
Show script version
|
||
|
||
Examples:
|
||
List all CA name
|
||
./$(basename "$0") --list-ca
|
||
|
||
List all certs cn
|
||
./$(basename "$0") --cn
|
||
|
||
Show infos for certificates whose CN begins with 'doe'
|
||
./$(basename "$0") -i "doe*"
|
||
|
||
Show infos for certificates whose CN ends with 'doe'
|
||
./$(basename "$0") -i "*doe"
|
||
|
||
Show infos for certificates where CN contains 'doe'
|
||
./$(basename "$0") -i "*doe*"
|
||
|
||
Show infos for certificates where CN is 'www.gmolab.net'
|
||
./$(basename "$0") -i www.gmolab.net
|
||
|
||
List the certificates expiring in the next 10 days
|
||
./$(basename "$0") -d 10
|
||
EOF
|
||
}
|
||
#-----------------------------------------------------------
|
||
# Certificates info
|
||
cert_info() {
|
||
echo -e "Number of certificates : ${CYAN}${#certList[@]}${NC}"
|
||
for certFile in "${certList[@]}"; do
|
||
# extract informations from certificates
|
||
cname=$(openssl x509 -noout -subject -in $certFile | cut -d"=" -f3)
|
||
issuer=$(openssl x509 -noout -issuer -in $certFile | sed 's/^issuer=//')
|
||
notAfter=$(openssl x509 -noout -enddate -in $certFile | cut -d"=" -f2)
|
||
notBefore=$(openssl x509 -noout -startdate -in $certFile | cut -d"=" -f2)
|
||
|
||
# extract Subject Alternative Name
|
||
san=$(openssl x509 -text -noout -in $certFile | \
|
||
grep -A 1 "Subject Alternative Name" | tail -n 1 | \
|
||
sed 's/,/\n/g' | \
|
||
sed -E 's/^\s*(DNS:|IP:|IPAddress:|IP Address:)//g' | \
|
||
sed 's/ //g')
|
||
|
||
# extract SAN dns
|
||
dnsList=$(echo "$san" | grep -v '^[0-9.]*$')
|
||
dnsArray=()
|
||
while IFS= read -r line; do
|
||
[[ -n "$line" ]] && dnsArray+=("$line")
|
||
done <<< "$dnsList"
|
||
|
||
# extract SAN ip
|
||
ipList=$(echo "$san" | grep -E '^[0-9.]+$')
|
||
ipArray=()
|
||
while IFS= read -r line; do
|
||
[[ -n "$line" ]] && ipArray+=("$line")
|
||
done <<< "$ipList"
|
||
|
||
echo -e "\n******************************************************"
|
||
echo -e "CA name: ${CYAN}$cname${NC}"
|
||
echo -e "******************************************************"
|
||
echo "Subject Alternative Name"
|
||
echo -e " DNS:"
|
||
for san_dns in "${dnsArray[@]}"; do
|
||
echo -e " ${CYAN} - $san_dns${NC}"
|
||
done
|
||
|
||
echo -e " IP:"
|
||
for san_ip in "${ipArray[@]}"; do
|
||
echo -e " ${CYAN} - $san_ip${NC}"
|
||
done
|
||
|
||
echo -e "Not valid before: ${CYAN}$notBefore${NC}"
|
||
echo -e "Not valid after : ${CYAN}$notAfter${NC}"
|
||
echo -e "Issuer: ${CYAN}$issuer${NC}"
|
||
done
|
||
}
|
||
|
||
############################################################
|
||
# MAIN
|
||
############################################################
|
||
|
||
main(){
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
ROOT_DIR="$(dirname "$SCRIPT_DIR")"
|
||
|
||
# read library
|
||
source "$ROOT_DIR/lib/stdlib.sh"
|
||
|
||
# init config
|
||
init_default
|
||
init_env
|
||
|
||
# set color
|
||
set_color
|
||
|
||
# check if script is run with sudo
|
||
check_sudo
|
||
|
||
# check if param exist
|
||
if [ -z "$1" ]; then
|
||
usage
|
||
exit 1
|
||
fi
|
||
|
||
# set color
|
||
set_color
|
||
|
||
# read cli parameters
|
||
while [[ "$#" -gt 0 ]]; do
|
||
case "$1" in
|
||
-a|--all)
|
||
# set - if no .crt → files=() (empty)
|
||
shopt -s nullglob
|
||
certList=("$CERTS_PATH"/*.crt)
|
||
shopt -u nullglob
|
||
cert_info
|
||
shift
|
||
;;
|
||
-c|--ca)
|
||
files=( $CRT_CA_PATH/*.crt )
|
||
for f in "${files[@]}"; do
|
||
filename=$(basename "$f" .crt)
|
||
if [ "$filename" == "ca-bundle" ] || [ "$filename" == "ca-bundle.trust" ]; then
|
||
continue
|
||
else
|
||
echo "CA name: $filename"
|
||
fi
|
||
done
|
||
shift
|
||
;;
|
||
-d|--expire-day)
|
||
if [[ -z "$2" || "$2" == -* ]]; then
|
||
echo -e "\n${RED}Error: Argument missing for option -d or --validity-date. See ./$(basename "$0") --help${NC}\n"
|
||
exit 1
|
||
|
||
# check if nbr days is numeric and > 1 and < $DAYS
|
||
elif [[ "$2" =~ ^[0-9]+$ ]] && [ "$2" -ge 1 ] && [ "$2" -le "$DAYS" ]; then
|
||
expired_date $2
|
||
if [ "${#expireDate[@]}" == "0" ]; then
|
||
msg_warn "There are no certificates that expire in less than $2 days."
|
||
fi
|
||
for certData in "${expireDate[@]}"; do
|
||
daysLeft=$(echo $certData | cut -d"|" -f1 )
|
||
cn=$(echo $certData | cut -d"|" -f2 )
|
||
expDate=$(echo $certData | cut -d"|" -f3 )
|
||
if [ "$daysLeft" -le 0 ]; then
|
||
color="$RED!! EXPIRED CERTIFICATE ---> "
|
||
elif [ "$daysLeft" -le 5 ]; then
|
||
color="$RED"
|
||
elif [ "$daysLeft" -le 10 ]; then
|
||
color="$ORANGE"
|
||
else
|
||
color="$GREEN"
|
||
fi
|
||
echo -e "${color}$cn expires in $daysLeft days ($expDate)${NC}"
|
||
done
|
||
else
|
||
echo -e "\n${RED}The number of days must be between 1 and $DAYS. See ./$(basename "$0") --help${NC}\n"
|
||
fi
|
||
shift 2
|
||
;;
|
||
-i|--info)
|
||
if [[ -z "$2" || "$2" == -* ]]; then
|
||
msg_error "\nError: Argument missing for option -i or --info.\n"
|
||
usage
|
||
exit 1
|
||
else
|
||
# check if $2 is not a glob ("*tto*")
|
||
if [[ ! "$2" == *[*?\[]* ]]; then
|
||
# it's not a glob, we test if file existe
|
||
if [ -f "$CERTS_PATH/$2.crt" ]; then
|
||
certList=("$CERTS_PATH/$2.crt")
|
||
cert_info
|
||
else
|
||
certList=()
|
||
cert_info
|
||
fi
|
||
else
|
||
# it's a glob
|
||
# set - if no .crt → files=() (empty)
|
||
shopt -s nullglob
|
||
certList=("$CERTS_PATH"/$2.crt)
|
||
shopt -u nullglob
|
||
cert_info
|
||
fi
|
||
fi
|
||
shift 2
|
||
;;
|
||
-n|--cn)
|
||
i=0
|
||
files=( $CERTS_PATH/*.crt )
|
||
for f in "${files[@]}"; do
|
||
cn=$(basename "$f" .crt)
|
||
echo $cn
|
||
((i++))
|
||
done
|
||
echo -e "\nThere are ${ORANGE}$i${NC} certificates."
|
||
shift
|
||
;;
|
||
-v|--version)
|
||
cat << EOF
|
||
$(basename "$0") $version (c) 1990 - $(date +%Y) by Gilles Mouchet
|
||
|
||
This script is provided "as is", WITHOUT ANY WARRANTY OF ANY KIND.
|
||
Non-Commercial Use License – See LICENSE for details
|
||
|
||
EOF
|
||
exit
|
||
;;
|
||
*|-h|--help)
|
||
usage
|
||
exit
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
main "$@" |