Skip to content

Instantly share code, notes, and snippets.

@poppyschmo
Last active March 15, 2018 01:47
Show Gist options
  • Save poppyschmo/0fbebe98575dba747e3e70c491bedd34 to your computer and use it in GitHub Desktop.
Save poppyschmo/0fbebe98575dba747e3e70c491bedd34 to your computer and use it in GitHub Desktop.
Validate and/or fingerprint the latest DV cert for Freenode's onion domain
#!/bin/sh
# License: Apache 2.0
# https://gist.github.com/poppyschmo/0fbebe98575dba747e3e70c491bedd34
#
# Validate the latest DV cert (for zettle.freenode.net) used by Freenode's
# onion domain, freenodeok2gncmy.onion. These certs are currently issued by
# Let's Encrypt and are good for three months but usually renewed early.
#
#
# USAGE: this_script.sh [<path>]
#
# Default:
# Show the fingerprint of the first cert (Freenode's) and exit.
#
# <path>
# If this points to an existing cert, show its validation info.
# Otherwise, save the cert chain to <path> (session output will
# include validation info).
# Export this to check a different onion address (like OFTC's)
address=${ONION_ADDRESS:-freenodeok2gncmy.onion:6697}
if ! { openssl version && torsocks --version; } >/dev/null 2>&1; then
cat <<EOF
Script requires torsocks and openssl's s_client:
>$ apt-get install openssl torsocks
>$ dnf install openssl torsocks
EOF
exit 1
fi >&2
if [ "$1" = -h ] || [ "$1" = --help ]; then
# Show help
exec awk '/^# *USAGE/,/^$/ {sub("^# ?", "")'"
sub(\"USAGE.+[.]sh\", \"${0##*/}\"); print}" "$0"
elif pem_chain=$(
if [ -e "$1" ]; then
{ printf "Verifying: "
openssl verify -untrusted "$1" -show_chain "$1"
} >&2
cat "$1"
elif ! (
# Connect and show verification info (if <path> given)
[ -z "$1" ] && { set -- /dev/null; exec 2>&-; }
# Let pipeline finish rather than set ERR trap to rm file
set -o pipefail
# The awk filter only helps when saving
torsocks openssl s_client -connect "$address" \
-showcerts </dev/null | awk '/^-+BEG/,/^-+END/' | tee "$1"
); then
{ printf 'Problem with torsocks connection or s_client session\n'
if [ -f "$1" ]; then
rm -vf "$1"
else
printf 'Pass a temporary <path> as $1 to show error messages\n'
fi
} >&2
exit 1
fi
); then
[ -z "$1" ] || printf 'Fingerprint:\n' >&2
# The fingerprint option needs some massaging (no dgst-style -r option)
printf %s "$pem_chain" | \
openssl x509 -sha256 -noout -fingerprint | \
cut -d '=' -f2 | tr -d ':' | tr '[:upper:]' '[:lower:]'
fi
# Note: as of mid-January 2018, Freenode's knowledge base article on the
# subject <https://freenode.net/kb/answer/chat> shows a fingerprint for an
# expired cert.
#
# Other relevant commands:
#
# Split a chain cert into separate files:
#
# >$ csplit -z -f depth -b '%d.pem' fullchain.cer '/^-*END/1' '{*}'
#
# View cert info (akin to clicking on the lock in a browser's address bar):
#
# >$ openssl x509 -in some_cert.pem -noout -text
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment