Last active
November 14, 2023 09:45
-
-
Save GwynethLlewelyn/3199572df5521dff87ef6955314aaf14 to your computer and use it in GitHub Desktop.
Viktor Dukhovni's shell script to generate all possible TLSA records for DANE from the full certificate chain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env bash | |
# Bash needed for PIPESTATUS array | |
# Author: Viktor Dukhovni <[email protected]> (@ietf-dane) | |
# Date: 28 December 2015 | |
# From https://community.letsencrypt.org/t/making-a-dane-tlsa-to-work-with-le/2129/8 | |
# See also https://community.letsencrypt.org/t/please-avoid-3-0-1-and-3-0-2-dane-tlsa-records-with-le-certificates/7022 | |
extract() { | |
case "$4" in | |
0) openssl x509 -in "$1" -outform DER;; | |
1) openssl x509 -in "$1" -noout -pubkey | openssl pkey -pubin -outform DER;; | |
esac | |
} | |
digest() { | |
case "$5" in | |
0) cat;; | |
1) openssl dgst -sha256 -binary;; | |
2) openssl dgst -sha512 -binary;; | |
esac | |
} | |
encode() { | |
local cert=$1; shift | |
local hostport=$1; shift | |
local u=$1; shift | |
local s=$1; shift | |
local m=$1; shift | |
local host=$hostport | |
local port=25 | |
OIFS="$IFS"; IFS=":"; set -- $hostport; IFS="$OIFS" | |
if [ $# -eq 2 ]; then host=$1; port=$2; fi | |
printf "_%d._tcp.%s. IN TLSA %d %d %d %s\n" \ | |
"$port" "$host" "$u" "$s" "$m" \ | |
"$(hexdump -ve '/1 "%02X"')" | |
} | |
genrr() { | |
rr=$( | |
extract "$@" | digest "$@" | encode "$@" | |
exit $(( ${PIPESTATUS[0]} | ${PIPESTATUS[1]} | ${PIPESTATUS[2]} )) | |
) | |
status=$?; if [ $status -ne 0 ]; then exit $status; fi | |
echo "$rr" | |
} | |
error() { echo "$1" 1>&2; exit 1; } | |
usage() { error "Usage: $0 chain.pem host[:port]"; } | |
if [ $# -ne 2 ]; then usage; fi | |
# Validate and normalize the chain | |
# | |
certfile=$1; shift | |
chain="$( | |
openssl crl2pkcs7 -nocrl -certfile "$certfile" | | |
openssl pkcs7 -print_certs | |
exit $(( ${PIPESTATUS[0]} | ${PIPESTATUS[1]} )) | |
)" | |
status=$?; if [ $status -ne 0 ]; then exit $status; fi | |
hostport=$1; shift | |
usage=3 | |
cert= | |
printf "%s\n\n" "$chain" | | |
while read line | |
do | |
if [[ -z "$cert" && ! "$line" =~ ^-----BEGIN ]]; then | |
continue | |
fi | |
cert=$(printf "%s\n%s" "$cert" "$line") | |
if [ -z "$line" -a ! -z "$cert" ]; then | |
echo "$cert" | | |
openssl x509 -noout -subject -issuer -dates | | |
sed -e 's/^/;; /' | |
echo ";;" | |
genrr <(echo "$cert") "$hostport" $usage 0 1 | |
genrr <(echo "$cert") "$hostport" $usage 1 1 | |
genrr <(echo "$cert") "$hostport" $usage 0 2 | |
genrr <(echo "$cert") "$hostport" $usage 1 2 | |
echo | |
cert="" | |
usage=2 | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment