Hello,

I'm trying to sign a zone, however I would like to have other's users input here, am I doing this correctly? Is there a shortcut in dnspython that I am not seeing?

Thank you in advance!

----- Attached Python Script -----
#!/usr/bin/env python2

import dns.rdtypes.ANY.DNSKEY
import dns.rdtypes.ANY.RRSIG
import dns.rrset
import dns.dnssec
import time
try:
    import Crypto
    import Crypto.Hash.SHA
except ImportError:
    print "Please install PyCrypto"
    import sys
    sys.exit(-1)


##
# DEFINITIONS
##
KEY_SEP = 0x0100
KEY_ZSK = 0x0001

def generate_key_pair(bits=1024):
    """
    Generate a SHA1 Key pair
    @return tuple (private, public)
    """
    G = Crypto.PublicKey.RSA.generate(bits=bits)
return (G.exportKey(format='DER'), G.publickey().exportKey(format='DER'))

def get_key_tag(key):
    """
    Logic is ripped from RFC4034
http://tools.ietf.org/html/rfc4034#appendix-B
    """
    ac = 0
    counter = 0

    while counter < len(key):
        if (counter & 1) == True:
            ac += ord(key[counter])
        else:
            ac += ord(key[counter]) << 8
        counter += 1
    ac += (ac >> 16) & 0xFFFF
    return ac & 0xFFFF

def sign_rrset(rrset, zsk, owner):
    """
    Sign the rrset object and return a RRSIG
    """
    def _rrset_to_string_for_signing(rrset, pos=0):
        if pos > len(rrset.items):
            return ''
        # concatenation based on rules outlined in RFC4034#3.1.8.1
        return rrset.name.to_text() +\
               str(rrset.rdtype)    +\
               str(rrset.rdclass)   +\
               str(rrset.ttl)       +\
               str(len(rrset.items[0].to_digestable())) +\
               rrset.items[0].to_digestable() +\
               _rrset_to_string_for_signing(rrset, pos+1)
    return dns.rdtypes.ANY.RRSIG.RRSIG(
        rdclass      = 1,  # IN
        rdtype       = 46, # RRSIG
        type_covered = 1,  # A?
        algorithm    = dns.dnssec.RSASHA1,
        labels       = len(zone.labels)-1,# rfc4034#3.1.3
        original_ttl = 3600,
        expiration   = time.time(),
        inception    = time.time() + 864600,
        key_tag      = get_key_tag(ZSK[1]),
        signer       = owner,
        signature    = _rrset_to_string_for_signing(rrset)
        )


if __name__ == '__main__':
    assert get_key_tag('hi howdie hay') == 41780

    zone = dns.name.from_text('example.com')
    rrset = dns.rrset.from_text_list(
        name = zone,
        ttl  = 3600,
        rdclass = 1, # IN
        rdtype  = 1, # A
        text_rdatas = [
            '127.0.0.1',
            '127.0.0.2'
            ]
        )
    ZSK = generate_key_pair()

    zsk_dnskey = dns.rdtypes.ANY.DNSKEY.DNSKEY(
        rdclass   = 1,     # IN
        rdtype    = 48,    # DNSKEY
        flags     = KEY_SEP|KEY_ZSK, # sets SEP and that it is a Zone Key
        protocol  = 3,     # fixed protocol by RFC4034
        algorithm = dns.dnssec.RSASHA1,
        key       = ZSK[1] # pubic key
        )
    print "@ 86400 IN DNSKEY "+ zsk_dnskey.to_text()
    # HAVE ZSK NOW, now lets sign some shit!
    rrsig = sign_rrset(rrset=rrset, zsk=zsk_dnskey, owner=zone)
    print "@ 3600 IN RRSIG "+rrsig.to_text()

    print rrset.to_text()

--
Brian Smith
_______________________________________________
dnspython-users mailing list
[email protected]
http://howl.play-bow.org/mailman/listinfo.cgi/dnspython-users

Reply via email to