Skip to content

Instantly share code, notes, and snippets.

@jasherai
Forked from gwire/tinydkim.py
Created August 3, 2022 19:22
Show Gist options
  • Save jasherai/77df5c0ee1062a5db91ed799a9b52726 to your computer and use it in GitHub Desktop.
Save jasherai/77df5c0ee1062a5db91ed799a9b52726 to your computer and use it in GitHub Desktop.
takes an RSA public key on stdin and outputs a tinydns / djbdns DKIM record
#!/usr/bin/env python
# tinydkim - takes an RSA public key on stdin and outputs a tinydns / djbdns DKIM record
#
# example: openssl rsa -in test.pem -pubout | ./tinydkim.py -s test -d foo.com
#
# TODO: add support for notes field?
#
# 2016 Lee Maguire
import getopt
import sys
import re
bind = ''
opt_h = ''
opt_t = ''
ttl = "86400"
selector = "selector"
domain = "example.com"
def extractPubKey( key ):
output = ""
key = key.replace('-----BEGIN PUBLIC KEY-----','')
key = key.replace('-----END PUBLIC KEY-----','')
key = key.replace('-----BEGIN RSA PUBLIC KEY-----','')
key = key.replace('-----END RSA PUBLIC KEY-----','')
for c in key:
if not c in ["\r","\n","\t"," "]:
output = output + c
return( output );
def escapeText( text ):
output = ""
for c in text:
if c in ["\r","\n","\t",":"," ","\\","/"]:
output = output + "\\{0:03o}".format(ord(c))
else:
output = output + c
return( output );
def dnsQuotedText( text ):
output = ""
for c in text:
if c in [";"]:
output = output + "\\;"
else:
output = output + c
return( "\"" + output + "\"");
def characterCount( text ):
return( "\\{0:03o}".format(len(text)) );
def tinyTxtRecord( domain, record, ttl):
return(":" + escapeText( domain ) + ":16:" + characterCount( record ) + escapeText( record ) + ":" + ttl);
def dnsTxtRecord( domain, record, ttl):
return(domain + ". " + ttl + " IN TXT " + dnsQuotedText( record ) );
opts, args = getopt.getopt(sys.argv[1:],"hs:d:t:l:b",["selector=","domain=","hash=","testing=","ttl=","bind"])
for opt, arg in opts:
if opt == '-h':
print 'Usage: tinydkim.py -s selector -d example.com -t y < pubkey.pem'
sys.exit()
elif opt in ("-s", "--selector"):
selector = arg
elif opt in ("-d", "--domain"):
domain = arg
elif opt in ("-h", "--hash"):
opt_h = arg
elif opt in ("-t", "--testing"):
opt_t = arg
elif opt in ("-l", "--ttl"):
ttl = arg
elif opt in ("-b", "--bind"):
bind = 1
input_text = "".join(sys.stdin)
rdata = "v=DKIM1"
if opt_h:
rdata = rdata + "; h=" + opt_h
rdata = rdata + "; p=" + extractPubKey( input_text )
if opt_t:
rdata = rdata + "; t=" + opt_t
fqdn = selector + "._domainkey." + domain
line = tinyTxtRecord( fqdn, rdata, ttl )
sys.stdout.write( line + "\n")
## optionally output the format used by lookup tools for comparison
if bind:
line = dnsTxtRecord( fqdn, rdata, ttl )
sys.stdout.write( "\n# " + line + "\n" )
sys.exit(0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment