Re: [exim] Next Exim release

Top Page
Delete this message
Reply to this message
Author: Viktor Dukhovni
Date:  
To: exim-users
Subject: Re: [exim] Next Exim release
On Wed, Dec 23, 2015 at 06:01:33PM +0000, Jeremy Harris wrote:

> Then it's all DNS configuration - and there are several options.
> If you want EE cert-usage (end-entity, meaning "the leaf
> cert should match this") then records like this:
>
>
> dane256ee            A      HOSTIPV4
> _25._tcp.dane256ee TLSA  3 1 1 2bb55f418bb03411a5007cecbfcd3ec1c94404312c0d53a44bb2166b32654db3


For things NOT to do, see:

    https://dane.sys4.de/common_mistakes
    https://community.letsencrypt.org/t/please-avoid-3-0-1-and-3-0-2-dane-tlsa-records-with-le-certificates/7022


I'm attaching two scripts that make it easier to generate TLSA records
for a leaf certificate, or a complete chain, respectively.

> Duplicate TLSAs for any other ports needed apart from 25.
> Other variants are possible; see rfc 6698 section 2 for
> details - but pretty much only EE & TA cert-usage are
> useful for SMTP.


Only DANE-EE and DANE-TA are useful for SMTP, the PKIX-EE and
PKIX-TA usages are undefined for SMTP and should be avoided.

    https://tools.ietf.org/html/rfc7672#section-3.1
    https://tools.ietf.org/html/rfc7671#section-5


-- 
    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"')"
}


error() { echo "$1" 1>&2; exit 1; }
usage() { error "Usage: $0 cert.pem host[:port] usage selector mtype"; }
if [ $# -ne 5 ]; then usage; fi

case "$(echo $3 | tr '[A-Z]' '[a-z]')" in
0|pkix-[ct]a)    usage=0;;
1|pkix-ee)    usage=1;;
2|dane-[ct]a)    usage=2;;
3|dane-ee)    usage=3;;
*)        error "Invalid certificate usage: $3";;
esac


case "$(echo $4 | tr '[A-Z]' '[a-z]')" in
0|cert)        selector=0;;
1|spki|pkey)    selector=1;;
*)         error "Invalid selector: $4";;
esac


case "$(echo $5 | tr '[A-Z]' '[a-z]')" in
0|full)             mtype=0;;
1|sha2-256|sha256|sha-256)     mtype=1;;
2|sha2-512|sha512|sha-512)     mtype=2;;
*)                error "Invalid matching type: $5";;
esac


set -- "$1" "$2" "$usage" "$selector" "$mtype"
rr=$(
    extract "$@" | digest "$@" | encode "$@"
    exit $(( ${PIPESTATUS[0]} | ${PIPESTATUS[1]} | ${PIPESTATUS[2]} ))
)
status=$?


if [ $status -ne 0 ]; then
    exit $status
fi
echo "$rr"

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