#!/bin/sh # GPG-->DNS CERT/TXT tool. # Dan Mahoney (danm@prime.gushi.org) and Evan Hunt (each@isc.org) # ISC License Applies # $Id: make-dns-cert.sh,v 1.4 2009/10/30 19:20:18 danm Exp $ # requires echo, xxd, openssl, dc, expr, cut, wc, tr, printf, test... # and of course, gpg # tested on FreeBSD 6.x, let me know if it works, or doesn't for you. # season to taste, only used on long certs exportoptions="export-minimal" # we don't really care about secure memory, we're only working with public keys gpgargs="--no-secmem-warning" # for testing, you may want this short, blank is okay as well. ttl="30" # usage: make-dns-cert.sh email keyid [url] # Note that this order follows the order in the DNS records email=$1 keyid=$2 url=$3 pkaemail=`echo -n "$email" | sed 's/@/._pka./'` certmail=`echo -n "$email" | sed 's/@/./'` ## echo "pkaemail is $pkaemail, certmail is $certmail" b64_split() { splitlen=36 slpo=`expr $splitlen + 1` el=`echo -n "$1" | wc -c |tr -d ' '` split='' line=$1 if [ $el -le $splitlen ] then printf "\t\t\t\t\t%s\n" $line else while [ $el -gt ${splitlen} ] do begin=`echo "${line}" | cut -c 1-$splitlen` line=`echo -n "${line}" | cut -c $slpo-$el` el=`expr $el - $splitlen` printf "\t\t\t\t\t%s\n" $begin done if [ $el -gt 0 ]; then printf "\t\t\t\t\t%s\n" $line fi fi } # Lines with a single # are comments, ## are debugs you can uncomment if need be. ## echo "Extracting keyid $keyid" cert=`gpg $gpgargs --list-keys --fingerprint $keyid | grep "Key fingerprint" |tr -d ' '|cut -c 16-60` ## echo "fingerprint is ($cert)" length=`echo -n "$cert"|wc -c|tr -d ' '` ## echo "fp length is $length" hexlength=`dc -e "16 o $length 2 / p"` ## echo "hexlength is $hexlength" #URL in hex. Useful for generating a TYPE37 record, not for this. #hexurl=`echo -n "$url"|xxd -p|tr 'a-f' 'A-F'|tr -d '\n'` #echo "hexurl is $hexurl" binfp=`echo -n "$hexlength$cert"|tr 'A-F' 'a-f'|xxd -p -r` b64=`echo -n "$binfp$url"|openssl enc -base64|tr -d '\n'` ## echo "base64 is $b64" # Headers echo "; generated with make-dns-cert.sh on `date` on `hostname`" echo "; Run as:'$0 $*'" echo # PKA record if [ "$url" ] then echo ";PKA record for keyid $keyid:" printf '%s. %s IN\tTXT\t"v=pka1\\;fpr=%s\\;uri=%s"\n' $pkaemail $ttl $cert $url else echo ";No URL specified, not printing a PKA record" fi echo "; You should probably only use one cert, the short or the long. " echo "; Using both will cause GPG to simply try whichever DNS hands it" echo "; first." echo ";" if [ "$url" ] then echo "; If using the short, or the PKA method above, be sure to publish" echo "; your keys at $url." echo "; You can export it with:" echo "; gpg --export --armor --export-options $exportoptions $keyid" else echo "; IPGP certs are technically legal without a URI, as a means of circulating" echo "; fingerprint info, but gpg does not currently validate these." fi # short cert (just a fingerprint and a url): # CERT 6 0 0 [fplength][fp][url] echo ";Short CERT Record for keyid $keyid:" echo ";This is fingerprint length, fingerprint, and optional key URL, in binary" printf "%s.\t%s\t%s\n" $certmail $ttl "IN CERT 6 0 0 (" b64_split ${b64} printf "\t\t\t\t\t%s\n" ")"; # long cert : # CERT PGP 0 0 [blob] bigkey=`gpg $gpgargs --export --export-options $exportoptions $keyid | openssl enc -base64 | tr -d "\n"` echo ";Long CERT Record for keyid $keyid:" printf "%s.\t%s\t%s\n" $certmail $ttl "IN CERT 3 0 0 (" b64_split ${bigkey} printf "\t\t\t\t\t%s\n" ")";