xref: /minix/external/bsd/bind/dist/contrib/dane/mkdane.sh (revision fb9c64b2)
1#!/bin/sh
2# Copyright (C) 2010, 2012  Internet Systems Consortium, Inc. ("ISC")
3#
4# Permission to use, copy, modify, and/or distribute this software for any
5# purpose with or without fee is hereby granted, provided that the above
6# copyright notice and this permission notice appear in all copies.
7#
8# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14# PERFORMANCE OF THIS SOFTWARE.
15#
16# Generate a DNS RR from an x.509 certificate
17# Currently only supports TLSA, but can be extended to support
18# other DANE types such as SMIMEA in the future.
19#
20# Requires: openssl
21
22USAGE="$BASENAME [options] <filename>
23Options:
24        -f <input format>: PEM | DLR
25        -n <name>: record name (default: _443._tcp)
26        -o <origin>: zone origin (default: none; name will be relative)
27        -m <matching type>: NONE (0) | SHA256 (1) | SHA512 (2)
28        -r <RR type>: TLSA
29        -s <selector>: FULL (0) | PK (1)
30        -t <ttl>: TTL of the TLSA record (default: none)
31        -u <certificate usage>: CA (0) | SERVICE (1) | TA (2) | DOMAIN (3)"
32
33NM="_443._tcp"
34CU=2
35SELECTOR=0
36MTYPE=1
37IN=
38FORM=PEM
39TTL=
40RRTYPE=TLSA
41BASENAME=`basename $0`;
42
43while getopts "xn:o:u:s:t:m:i:f:r:" c; do
44    case $c in
45	x) set -x; DEBUG=-x;;
46	m) MTYPE="$OPTARG";;
47        n) NM="$OPTARG";;
48        o) ORIGIN="$OPTARG";;
49        r) RRTYPE="$OPTARG";;
50	s) SELECTOR="$OPTARG";;
51        t) TTL="$OPTARG";;
52	u) CU="$OPTARG";;
53	*) echo "$USAGE" 1>&2; exit 1;;
54    esac
55done
56shift `expr $OPTIND - 1 || true`
57
58if test "$#" -eq 1; then
59    IN=$1
60else
61    echo "$USAGE" 1>&2; exit 1
62fi
63
64ORIGIN=`echo $ORIGIN | sed 's/\([^.]$\)/\1./'`
65if [ -n "$ORIGIN" ]; then
66    NM=`echo $NM | sed 's/\.$//'`
67    NM="$NM.$ORIGIN"
68fi
69
70case "$CU" in
71    [Cc][Aa]) CU=0;;
72    [Ss][Ee][Rr][Vv]*) CU=1;;
73    [Tt][Aa]) CU=2;;
74    [Dd][Oo][Mm]*) CU=3;;
75    [0123]) ;;
76    *) echo "bad certificate usage -u \"$CU\"" 1>&2; exit 1;;
77esac
78
79case "$SELECTOR" in
80    [Ff][Uu][Ll][Ll]) SELECTOR=0;;
81    [Pp][Kk]) SELECTOR=1;;
82    [01]) ;;
83    *) echo "bad selector -s \"$SELECTOR\"" 1>&2; exit 1;;
84esac
85
86case "$MTYPE" in
87    0|[Nn][Oo][Nn][Ee]) HASH='od -A n -v -t xC';;
88    1|[Ss][Hh][Aa]256) HASH='openssl dgst -sha256';;
89    2|[Ss][Hh][Aa]512) HASH='openssl dgst -sha512';;
90    *) echo "bad matching type -m \"$MTYPE\"" 1>&2; exit 1;;
91esac
92
93case "$FORM" in
94    [Pp][Ee][Mm]) FORM=PEM;;
95    [Dd][Ll][Rr]) FORM=DLR;;
96    *) echo "bad input file format -f \"$FORM\"" 1>&2; exit 1
97esac
98
99case "$RRTYPE" in
100    [Tt][Ll][Ss][Aa]) RRTYPE=TLSA;;
101    *) echo "invalid RR type" 1>&2; exit 1
102esac
103
104if test -z "$IN" -o ! -s "$IN"; then
105    echo "bad input file -i \"$IN\"" 1>&2; exit 1
106fi
107
108echo "; $BASENAME -o$NM -u$CU -s$SELECTOR -m$MTYPE -f$FORM $IN"
109
110(if test "$SELECTOR" = 0; then
111    openssl x509 -in "$IN" -inform "$FORM" -outform DER
112else
113    openssl x509 -in "$IN" -inform "$FORM" -noout -pubkey		\
114	| sed -e '/PUBLIC KEY/d'					\
115	| openssl base64 -d
116fi)									\
117    | $HASH								\
118    | awk '
119	# format Association Data as in Appendix C of the DANE RFC
120	BEGIN {
121		print "'"$NM\t\t$TTL\tIN TLSA\t$CU $SELECTOR $MTYPE"' (";
122		leader = "\t\t\t\t\t";
123	}
124	/.+/ {
125	    gsub(/ +/, "", $0);
126	    buf = buf $0;
127	    while (length(buf) >= 36) {
128		print leader substr(buf, 1, 36);
129		buf = substr(buf, 37);
130	    }
131	}
132	END {
133            if (length(buf) > 34)
134                print leader buf "\n" leader ")";
135            else
136                print leader buf " )";
137        }'
138