For those frequently examining SSL/TLS certificates, the openssl
command often becomes a recurring presence in the shell history. However, while openssl
is powerful, it often requires users to juggle between various parameters like host, servername, and port, not to mention the subtle annoyance of needing to provide just the host, rather than a more intuitive URL.
Recognizing this, I’ve crafted a shell function/alias to streamline the process. This tool is designed to accept both hosts and URLs as parameters, providing flexibility to the user. Moreover, it effortlessly handles ports, whether they’re explicitly defined in the host or embedded within the URL.
Functions:
showcert. Retrieves the SSL/TLS certificate for a given host or URL and displays detailed information about the certificate.
showchain. Retrieves the certificate chain for a given host or URL and displays the subject and issuer of each certificate in the chain.
Here is examples of the usage (output abbreviated here):
❯ showcert https://example.com:443/main.html -v
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
0c:1f:cb:18:45:18:c7:e3:86:67:41:23:6d:6b:73:f1
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
Validity
Not Before: Jan 13 00:00:00 2023 GMT
Not After : Feb 13 23:59:59 2024 GMT
Subject: C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org
[...]
X509v3 Authority Key Identifier:
B7:6B:A2:EA:A8:AA:84:8C:79:EA:B4:DA:0F:98:B2:C5:95:76:B9:F4
X509v3 Subject Key Identifier:
B0:93:3F:E8:17:82:FD:6C:B2:B6:17:87:CB:E3:80:FE:82:9B:01:9E
X509v3 Subject Alternative Name:
DNS:www.example.org, DNS:example.net, DNS:example.edu, DNS:example.com, DNS:example.org, DNS:www.example.com, DNS:www.example.edu, DNS:www.example.net
[...]
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
59:e4:4a:d8:a9:82:ba:9a:4a:f1:63:0c:6d:76:26:75:b3:3c:
74:be:c5:f7:3d:a7:91:92:f8:cf:06:2d:58:10:ed:f3:b8:d6:
fc:6c:ff:13:96:32:cd:4f:e9:87:24:85:0b:74:a2:c2:f6:0f:
f5:a7:d8:7d:76:8a:ae:e9:c9:58:2b:6e:00:6f:b9:cd:24:ee:
c4:42:c5:4c:16:85:9d:34:61:39:23:bf:c6:8e:95:c9:84:a9:
b2:e5:41:0f:44:78:d7:95:b9:cf:d9:74:bf:58:4f:e7:16:ff:
7c:40:30:c4:6c:4e:22:4d:cb:83:67:3a:93:bf:2b:c5:c5:9c:
1a:f2:43:a1:25:3b:84:f6:f7:53:6e:a8:85:ae:de:14:74:91:
30:06:0d:f2:07:d4:c4:08:ba:43:64:c5:e2:3f:da:ac:c5:41:
af:a4:37:e8:42:76:74:f7:13:bb:4a:7d:36:59:81:9b:c7:44:
df:89:73:b9:33:42:e8:60:c2:4d:61:5d:12:5a:10:f6:ef:ff:
33:89:14:50:e8:d6:9f:c6:b9:5c:2b:35:db:ad:ed:dd:36:b6:
25:f2:95:8a:ac:69:3f:9a:fe:1a:f8:15:28:6d:ea:18:5a:c2:
d2:62:18:af:40:78:b5:fa:5e:09:8f:53:f9:cc:f8:23:a1:83:
31:23:f4:c6
❯ showchain https://example.com:443/main.html
subject=C = US, ST = California, L = Los Angeles, O = Internet\C2\A0Corporation\C2\A0for\C2\A0Assigned\C2\A0Names\C2\A0and\C2\A0Numbers, CN = www.example.org
issuer=C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
subject=C = US, O = DigiCert Inc, CN = DigiCert TLS RSA SHA256 2020 CA1
issuer=C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
You can find below the snippets to add to your respective shell configuration :
##############################################################
# Function: showcert
#
# Description:
# Retrieves the SSL/TLS certificate for a given host or URL and
# displays detailed information about the certificate. This function
# simplifies the usage of the `openssl` tool by allowing users to input
# either a host, a full URL, or a host with a specified port.
#
# Usage:
# showcert <host|URL> (-v)
#
# Parameters:
# host|URL: The host or full URL of the server to retrieve the certificate
# from. A port can be specified using the format: host:port
# or https://url:port/path
# v : verbose output for the certificate with details
#
# Examples:
# showcert example.com
# showcert https://example.com/main.html
# showchain https://example.com:443/main.html
# showchain example.com:443
# showcert example.com -v
#
# Note:
# This function uses the `openssl` tool. Ensure that `openssl` is installed
# and available in your PATH.
##############################################################
certfunc() {
verbose=false
if [[ "$2" == "-v" ]]; then
verbose=true
fi
host_and_port="${${${1#https://}#http://}%%/*}"
host="${host_and_port%%:*}"
port="${host_and_port#*:}"
[ "$port" = "$host" ] && port=443
cert=$(echo | openssl s_client -showcerts -servername $host -connect $host:$port 2>/dev/null | openssl x509 -outform pem)
if $verbose; then
echo "$cert" | openssl x509 -noout -text
else
name=$(echo "$cert" | openssl x509 -noout -subject | cut -d'/' -f 6- | sed 's/subject=//')
all_san=$(echo "$cert" | openssl x509 -noout -text | grep -A1 'Subject Alternative Name:' | tail -n1 | sed 's/DNS:/\n DNS:/g')
start_validity=$(echo "$cert" | openssl x509 -noout -startdate | cut -d'=' -f2)
end_validity=$(echo "$cert" | openssl x509 -noout -enddate | cut -d'=' -f2)
if [[ "$(uname)" == "Darwin" ]]; then
start_date=$(date -j -f "%b %d %T %Y %Z" "$start_validity" +"%Y-%m-%d")
end_date=$(date -j -f "%b %d %T %Y %Z" "$end_validity" +"%Y-%m-%d")
days_left=$(( ( $(date -j -f "%Y-%m-%d" "$end_date" +%s) - $(date +%s) ) / 86400 ))
else
start_date=$(date -d "$start_validity" +"%Y-%m-%d")
end_date=$(date -d "$end_validity" +"%Y-%m-%d")
days_left=$(( ( $(date -d "$end_date" +%s) - $(date +%s) ) / 86400 ))
fi
hash_algo=$(echo "$cert" | openssl x509 -noout -text | grep "Signature Algorithm" | head -n 1 | cut -d: -f2 | xargs)
pubkey_info=$(echo "$cert" | openssl x509 -noout -text | grep "Public Key Algorithm" | cut -d: -f2 | xargs)
pubkey_size=$(echo "$cert" | openssl x509 -noout -text | grep "Public-Key" | awk '{print $2}' | tr -d '(')
echo -e "\e[1;34mCertificate Information:\e[0m"
{
echo -e "\e[32mName\e[0m;$name"
echo -e "\e[32mSAN\e[0m;$all_san"
echo -e "\e[32mValidity Period\e[0m;$start_date to $end_date (expires in $days_left days)"
echo -e "\e[32mHash Algorithm\e[0m;$hash_algo"
echo -e "\e[32mPublic Key Info\e[0m;$pubkey_info ($pubkey_size bits)"
} | column -t -s ";"
echo -e "\n\e[1;34mIssuer Chain:\e[0m"
chainfunc $1
fi
}
alias showcert=certfunc
##############################################################
# Function: showchain
#
# Description:
# Retrieves the certificate chain for a given host or URL and
# displays the subject and issuer of each certificate in the chain.
# This function is designed to simplify the `openssl` command usage,
# allowing users to input either a host, a full URL, or a host with
# a specified port.
#
# Usage:
# showchain <host|URL>
#
# Parameters:
# host|URL: The host or full URL of the server to retrieve the certificate
# chain from. A port can be specified using the format: host:port
# or https://url:port/path
#
# Examples:
# showchain example.com
# showchain https://example.com/main.html
# showchain https://example.com:443/main.html
# showchain example.com:443
#
# Note:
# This function uses the `openssl` tool. Ensure that `openssl` is installed
# and available in your PATH.
##############################################################
chainfunc() {
host_and_port="${${${1#https://}#http://}%%/*}"
host="${host_and_port%%:*}"
port="${host_and_port#*:}"
[ "$port" = "$host" ] && port=443
indent="\t"
skip_first=true
echo | openssl s_client -showcerts -servername $host -connect $host:$port 2>/dev/null | awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' | while read -r line; do
cert="${cert}${line}\n"
if [[ $line == "-----END CERTIFICATE-----" ]]; then
subj=$(echo -e "$cert" | openssl x509 -noout -subject 2>/dev/null | cut -d'=' -f2-)
iss=$(echo -e "$cert" | openssl x509 -noout -issuer 2>/dev/null | cut -d'=' -f2-)
if $skip_first; then
skip_first=false
else
echo -e "${indent}$subj ->"
indent="${indent}\t"
fi
cert=""
fi
done
echo -e "${indent}$iss"
}
alias showchain=chainfunc
Info: Bash version is only with the full details
##############################################################
# Function: showcert
#
# Description:
# Retrieves the SSL/TLS certificate for a given host or URL and
# displays detailed information about the certificate. This function
# simplifies the usage of the `openssl` tool by allowing users to input
# either a host, a full URL, or a host with a specified port.
#
# Usage:
# showcert <host|URL>
#
# Parameters:
# host|URL: The host or full URL of the server to retrieve the certificate
# from. A port can be specified using the format: host:port
# or https://url:port/path
#
# Examples:
# showcert example.com
# showcert https://example.com/main.html
# showchain https://example.com:443/main.html
# showchain example.com:443
#
# Note:
# This function uses the `openssl` tool. Ensure that `openssl` is installed
# and available in your PATH.
##############################################################
certfunc() {
host_and_port="${1#https://}"
host_and_port="${host_and_port#http://}"
host_and_port="${host_and_port%%/*}"
host="${host_and_port%%:*}"
port="${host_and_port#*:}"
[ "$port" = "$host" ] && port=443
echo | openssl s_client -showcerts -servername "$host" -connect "$host:$port" 2>/dev/null | openssl x509 -inform pem -noout -text
}
alias showcert=certfunc
##############################################################
# Function: showchain
#
# Description:
# Retrieves the certificate chain for a given host or URL and
# displays the subject and issuer of each certificate in the chain.
# This function is designed to simplify the `openssl` command usage,
# allowing users to input either a host, a full URL, or a host with
# a specified port.
#
# Usage:
# showchain <host|URL>
#
# Parameters:
# host|URL: The host or full URL of the server to retrieve the certificate
# chain from. A port can be specified using the format: host:port
# or https://url:port/path
#
# Examples:
# showchain example.com
# showchain https://example.com/main.html
# showchain https://example.com:443/main.html
# showchain example.com:443
#
# Note:
# This function uses the `openssl` tool. Ensure that `openssl` is installed
# and available in your PATH.
##############################################################
chainfunc() {
local proto="${1%%://*}"
local host_and_port="${1#$proto://}"
host_and_port="${host_and_port%%/*}"
local host="${host_and_port%%:*}"
local port="${host_and_port#*:}"
[ "$port" = "$host" ] && port=443
local cert_data=""
echo | openssl s_client -showcerts -servername "$host" -connect "$host:$port" 2>/dev/null | while IFS= read -r line; do
cert_data+="$line"$'\n'
if [[ "$line" == "-----END CERTIFICATE-----" ]]; then
echo "$cert_data" | openssl x509 -noout -subject -issuer
cert_data=""
fi
done
}
alias showchain=chainfunc