[dns-operations] calculating DNSSEC keytags in sed (was: RE: calculating DNSSEC keytags in awk)

Matthäus Wander matthaeus.wander at uni-due.de
Thu Apr 16 14:45:22 UTC 2015


* Frank [2015-04-16 15:27]:
> I do not want to read it. I want to calculate it.
> In order to save it in my zone file.

See attached keytag.py.

Usage:
> $ python keytag.py DNSKEY  257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0=
> RSA exponent: 65537
> RSA keylength: 2048 bit
> keytag: 19036

Regards,
Matt
-------------- next part --------------
#!/usr/bin/env python

import base64
import struct
import sys

def keytag(flags, protocol, algorithm, key):
    # legacy specification for RSA/MD5 in RFC 4034 Appendix B.1
    if algorithm == 1:
        (keytag,) = struct.unpack('>H', key[-3:-1])
        return keytag

    # all RDATA in wire format
    rdata = struct.pack(">HBB", flags, protocol, algorithm)
    rdata += key

    # RFC 4034 Appendix B
    ac = 0
    for i in xrange(0, len(rdata)):
        (ubyte,) = struct.unpack('B', rdata[i])
        ac += ubyte if (i & 1) else ubyte << 8

    ac += (ac >> 16) & 0xFFFF
    return ac & 0xFFFF

# works only for RSA keys as specified in RFC 3110 Sec. 2
def parsekey(key):
    # read first byte
    (explength,) = struct.unpack('>B', key[0])
    offset = 1
    if explength == 0:
        print >>sys.stderr, "Exponent length is two bytes!"
        # read next two bytes
        (explength,) = struct.unpack('>H', key[1:3])
        offset = 3

    # read binary of variable length as big-endian decimal number
    expbuf = struct.unpack('>{0}B'.format(explength), key[offset:(offset+explength)])
    exponent = reduce(lambda x,y: (x<<8) + y, expbuf, 0)
    
    offset += explength
    modulus = key[offset:]
    keysize = len(modulus) * 8
    return (exponent, keysize, modulus) # exponent is decimal number, keysize is decimal number of public key bits

if len(sys.argv) < 5:
    print "usage:", sys.argv[0], "DNSKEY flags protocol algorithm key"
    sys.exit(1)
    
offset = 2 if sys.argv[1] == 'DNSKEY' else 1

flags = int(sys.argv[offset])
protocol = int(sys.argv[offset+1])
algorithm = int(sys.argv[offset+2])
keytext = ''.join(sys.argv[offset+3:])
key = base64.b64decode(keytext)

if algorithm in (1, 3, 5, 7, 8):
    (exponent, keysize, modulus) = parsekey(key)
    print "RSA exponent:", exponent
    print "RSA keylength:", keysize, "bit"
print "keytag:", keytag(flags, protocol, algorithm, key)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5414 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://lists.dns-oarc.net/pipermail/dns-operations/attachments/20150416/3b9266fa/attachment.bin>


More information about the dns-operations mailing list