#!/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 List the certificates expiring in the next days -i, --info 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 "$@"