Making a DANE TLSA to work with LE

The DANE-TA(2) SPKI(1) SHA2-256(1) (aka “2 1 1”) digest that everyone else publishes for the current LE issuer CA that is the immediate (depth 1) signer of LE leaf certificates is:

_25._tcp.example.com. IN TLSA 2 1 1 60b87575447dcba2a36b7d11ac09fb24a9db406fee12d2cc90180517616e8a18

Not sure which cacert you’re taking the digest of, perhaps it is the depth 2 issuer?

FWIW, the commands look correct, you just need to make sure that the right issuer certificate is at the top of the .pem file in question.

I use the bash script below to generate all possible DANE-EE(3) or DANE-TA(2) TLSA records for a chain file with multiple certificates (leaf followed by issuers)

#! /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
2 Likes