On Thu, Dec 10, 2015 at 10:02:38PM +0100, Dirk Stöcker wrote: > P.S. Maybe some is interested. I'm currently improving the "tlsa" tool from > hash-slinger (https://github.com/letoams/hash-slinger) to properly support > STARTTLS and SNI. Some changes are still pending, but I'm positive they will > get accepted. That makes generating and verifying TLSA data somewhat easier > (and more automatic).
The posttls-finger program available with Postfix source since 2.11 supports STARTTLS and SNI (when using DANE), the chain is encoded by a reasonably shell script that uses openssl(1) to do the chain parsing and digest computations. The only caveat is that SNI is not currently sent when the site has no TLSA records (I've not yet run into any SMTP servers whose certificate depends on the SNI name). $ for mx in $( dig +short -t mx bund.de | sort -k1n | awk '{sub(/\.$/, "", $NF); print $NF}' ) do posttls-finger -C "$mx" bund.de | chaingen /dev/stdin "$mx:25" echo done ;; subject= /C=DE/O=Service/OU=ivbb-betrieb/L=ivbb-betrieb/CN=mx2.bund.de ;; issuer= /C=DE/O=PKI-1-Verwaltung/OU=Bund/CN=CA IVBB Deutsche Telekom AG 12 ;; notBefore=Oct 16 09:01:29 2014 GMT ;; notAfter=Oct 16 23:59:59 2017 GMT ;; _25._tcp.mx2.bund.de. IN TLSA 3 0 1 BB76A3708223C910C46867D5586D0DD0E14C821ECC4BDDD2A98F5C975BEC29F8 _25._tcp.mx2.bund.de. IN TLSA 3 1 1 89B726D4CF817143066286D48E9E9AFD15526D659A1EF729B2852CA8A463308C _25._tcp.mx2.bund.de. IN TLSA 3 0 2 2053064A642E9D788A12CC0C32030347556C36BE11655CA5F454D9408416711936318171B06A4259348E6EEA75CBC697B7985E3DF5FF4401EF94E85D95222C27 _25._tcp.mx2.bund.de. IN TLSA 3 1 2 7D141F158729140D9AF66A1088653837E5C58B0659869410791C1DC8561C3F30CD3BC15D342AB558E6BC619D6AFBBAE690FE99A623EEE6E7B2AB4F8D73A81F24 ;; subject= /C=DE/O=PKI-1-Verwaltung/OU=Bund/CN=CA IVBB Deutsche Telekom AG 12 ;; issuer= /C=DE/O=PKI-1-Verwaltung/CN=PCA-1-Verwaltung-11 ;; notBefore=Jan 30 00:00:00 2012 GMT ;; notAfter=Feb 1 23:59:59 2018 GMT ;; _25._tcp.mx2.bund.de. IN TLSA 2 0 1 9B3D5CA00E78730FD22C297C0D50139F883DBB033ABEB9C3A95B8FE76B62F109 _25._tcp.mx2.bund.de. IN TLSA 2 1 1 73E422BB47F1E20A298DE06D69E9401B0F5468C53E46D7C1584367B55E6051A6 _25._tcp.mx2.bund.de. IN TLSA 2 0 2 4FE3DC463F11ED7F2B5CF9E6CC2C55B153676C3254C11712CC9FCC4E0AC0A625F106F5E3630A51F9E09CA8ED54BFC41117380EFBA1D4B2A512A7EF3FCBC529CE _25._tcp.mx2.bund.de. IN TLSA 2 1 2 56F5188F4163FB52988ED62AD7919CF25C988B470CF3A30C22A39F6AB0F3629AC22DD1515939717C4B904907A817F20270A4115753F86FCDDE5ABC824B1C48BF ;; subject= /C=DE/O=PKI-1-Verwaltung/CN=PCA-1-Verwaltung-11 ;; issuer= /C=DE/O=PKI-1-Verwaltung/CN=PCA-1-Verwaltung-11 ;; notBefore=Sep 1 08:56:53 2011 GMT ;; notAfter=Sep 1 23:59:59 2021 GMT ;; _25._tcp.mx2.bund.de. IN TLSA 2 0 1 DCF7D577CAD991ED7B04BFE9F165DF8768BB49DCEBFD86A8F1BBBAAADF069FC5 _25._tcp.mx2.bund.de. IN TLSA 2 1 1 63B7ADEE8407840DD738B052A5D148BC8427645CC7A9AD9B23500DFB55676C16 _25._tcp.mx2.bund.de. IN TLSA 2 0 2 F4568DCA29A645F869CBA766091549F16A3612CEEF0711259CDC80F6FB52BC9DDCC0821842B58D4957D268106231A4307776AC965C01F2DC0D9EE4B50DD72D20 _25._tcp.mx2.bund.de. IN TLSA 2 1 2 6CAC2F2A30BC1657FCEC29348DCFC127C5585969DC80B96B6A0C354D3C75DD19C347704FDD7618594F706B034C6C22E4DFA80BF0548D726C77B303DD38DBD4FB ;; subject= /C=DE/O=Service/OU=ivbb-betrieb/L=ivbb-betrieb/CN=mx1.bund.de ;; issuer= /C=DE/O=PKI-1-Verwaltung/OU=Bund/CN=CA IVBB Deutsche Telekom AG 12 ;; notBefore=Oct 16 09:00:04 2014 GMT ;; notAfter=Oct 16 23:59:59 2017 GMT ;; _25._tcp.mx1.bund.de. IN TLSA 3 0 1 DF6F4F2C4035A14E0C3647D6DE4785B8EB67AF4B81E089A76E33C579C720CE31 _25._tcp.mx1.bund.de. IN TLSA 3 1 1 CEBA01B6867EF252F150E993BA253BC3678E1118A21F56FD5585D4DFDCF97B5E _25._tcp.mx1.bund.de. IN TLSA 3 0 2 EFF2FFCC63BF521DCADDBC12E9C68371316E5C11160FE0E34788A9FB812958A61DA96695F2DD1FB1FE8DF489103CFC212B78E8901D79A0E50B1FD7128A2C9BA3 _25._tcp.mx1.bund.de. IN TLSA 3 1 2 9B7BE0167312B887BAC8E60BA5944590FBBB796C85C44ED5D2A00D2B4F0B05A9DCE0C7AAABC74ED7C92870EC91C458F306965C718AD02BC93509A21245B57EDB ;; subject= /C=DE/O=PKI-1-Verwaltung/OU=Bund/CN=CA IVBB Deutsche Telekom AG 12 ;; issuer= /C=DE/O=PKI-1-Verwaltung/CN=PCA-1-Verwaltung-11 ;; notBefore=Jan 30 00:00:00 2012 GMT ;; notAfter=Feb 1 23:59:59 2018 GMT ;; _25._tcp.mx1.bund.de. IN TLSA 2 0 1 9B3D5CA00E78730FD22C297C0D50139F883DBB033ABEB9C3A95B8FE76B62F109 _25._tcp.mx1.bund.de. IN TLSA 2 1 1 73E422BB47F1E20A298DE06D69E9401B0F5468C53E46D7C1584367B55E6051A6 _25._tcp.mx1.bund.de. IN TLSA 2 0 2 4FE3DC463F11ED7F2B5CF9E6CC2C55B153676C3254C11712CC9FCC4E0AC0A625F106F5E3630A51F9E09CA8ED54BFC41117380EFBA1D4B2A512A7EF3FCBC529CE _25._tcp.mx1.bund.de. IN TLSA 2 1 2 56F5188F4163FB52988ED62AD7919CF25C988B470CF3A30C22A39F6AB0F3629AC22DD1515939717C4B904907A817F20270A4115753F86FCDDE5ABC824B1C48BF ;; subject= /C=DE/O=PKI-1-Verwaltung/CN=PCA-1-Verwaltung-11 ;; issuer= /C=DE/O=PKI-1-Verwaltung/CN=PCA-1-Verwaltung-11 ;; notBefore=Sep 1 08:56:53 2011 GMT ;; notAfter=Sep 1 23:59:59 2021 GMT ;; _25._tcp.mx1.bund.de. IN TLSA 2 0 1 DCF7D577CAD991ED7B04BFE9F165DF8768BB49DCEBFD86A8F1BBBAAADF069FC5 _25._tcp.mx1.bund.de. IN TLSA 2 1 1 63B7ADEE8407840DD738B052A5D148BC8427645CC7A9AD9B23500DFB55676C16 _25._tcp.mx1.bund.de. IN TLSA 2 0 2 F4568DCA29A645F869CBA766091549F16A3612CEEF0711259CDC80F6FB52BC9DDCC0821842B58D4957D268106231A4307776AC965C01F2DC0D9EE4B50DD72D20 _25._tcp.mx1.bund.de. IN TLSA 2 1 2 6CAC2F2A30BC1657FCEC29348DCFC127C5585969DC80B96B6A0C354D3C75DD19C347704FDD7618594F706B034C6C22E4DFA80BF0548D726C77B303DD38DBD4FB -- Viktor.
#! /usr/bin/env bash # Bash needed for PIPESTATUS array 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