Skip to content

Commit

Permalink
Merge pull request #47 from rmbolger/new-records
Browse files Browse the repository at this point in the history
Add support for DS, SSHFP, and TLSA records
  • Loading branch information
paulc authored Oct 28, 2022
2 parents a99a458 + d089533 commit 175f101
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 1 deletion.
131 changes: 130 additions & 1 deletion dnslib/dns.py
Original file line number Diff line number Diff line change
Expand Up @@ -1528,6 +1528,50 @@ def __repr__(self):

attrs = ('order','preference','flags','service','regexp','replacement')

class DS(RD):
"""
DS (delegation signer) record as specified in RFC 4034 Section 5.
https://www.rfc-editor.org/rfc/rfc4034#section-5
"""

key_tag = H('key_tag')
algorithm = B('algorithm')
digest_type = B('digest_type')

@classmethod
def parse(cls,buffer,length):
try:
(key_tag,algorithm,digest_type) = buffer.unpack("!HBB")
digest = buffer.get(length - 4)
return cls(key_tag,algorithm,digest_type,digest)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DS [offset=%d]: %s" %
(buffer.offset,e))

@classmethod
def fromZone(cls,rd,origin=None):
return cls(int(rd[0]),int(rd[1]),int(rd[2]),
binascii.unhexlify("".join(rd[3:]).encode('ascii')))

def __init__(self,key_tag,algorithm,digest_type,digest):
self.key_tag = key_tag
self.algorithm = algorithm
self.digest_type = digest_type
self.digest = _force_bytes(digest)

def pack(self,buffer):
buffer.pack("!HBB",self.key_tag,self.algorithm,self.digest_type)
buffer.append(self.digest)

def __repr__(self):
return "%d %d %d %s" % (
self.key_tag,
self.algorithm,
self.digest_type,
binascii.hexlify(self.digest).decode().upper())

attrs = ('key_tag','algorithm','digest_type','digest')

class DNSKEY(RD):

flags = H('flags')
Expand Down Expand Up @@ -2119,13 +2163,98 @@ def __repr__(self):
targ = ".".join([self.zf_tostr(t) for t in self.target]) + "."
return " ".join([pri, targ] + [self.zf_format_param(k, v) for k,v in self.params])

class SSHFP(RD):
"""
SSHFP record as specified in RFC 4255
https://www.rfc-editor.org/rfc/rfc4255.html
"""

algorithm = B('algorithm')
fp_type = B('fp_type')

@classmethod
def parse(cls,buffer,length):
try:
(algorithm,fp_type) = buffer.unpack("!BB")
fingerprint = buffer.get(length - 2)
return cls(algorithm,fp_type,fingerprint)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DS [offset=%d]: %s" %
(buffer.offset,e))

@classmethod
def fromZone(cls,rd,origin=None):
return cls(int(rd[0]),int(rd[1]),
binascii.unhexlify("".join(rd[2:]).encode('ascii')))

def __init__(self,algorithm,fp_type,fingerprint):
self.algorithm = algorithm
self.fp_type = fp_type
self.fingerprint = _force_bytes(fingerprint)

def pack(self,buffer):
buffer.pack("!BB",self.algorithm,self.fp_type)
buffer.append(self.fingerprint)

def __repr__(self):
return "%d %d %s" % (
self.algorithm,
self.fp_type,
binascii.hexlify(self.fingerprint).decode().upper())

attrs = ('algorithm','fp_type','fingerprint')

class TLSA(RD):
"""
TLSA record as specified in RFC 6698
https://www.rfc-editor.org/rfc/rfc6698
"""

cert_usage = B('cert_usage')
selector = B('selector')
matching_type = B('matching_type')

@classmethod
def parse(cls,buffer,length):
try:
(cert_usage,selector,matching_type) = buffer.unpack("!BBB")
cert_data = buffer.get(length - 3)
return cls(cert_usage,selector,matching_type,cert_data)
except (BufferError,BimapError) as e:
raise DNSError("Error unpacking DS [offset=%d]: %s" %
(buffer.offset,e))

@classmethod
def fromZone(cls,rd,origin=None):
return cls(int(rd[0]),int(rd[1]),int(rd[2]),
binascii.unhexlify("".join(rd[3:]).encode('ascii')))

def __init__(self,cert_usage,selector,matching_type,cert_data):
self.cert_usage = cert_usage
self.selector = selector
self.matching_type = matching_type
self.cert_data = _force_bytes(cert_data)

def pack(self,buffer):
buffer.pack("!BBB",self.cert_usage,self.selector,self.matching_type)
buffer.append(self.cert_data)

def __repr__(self):
return "%d %d %d %s" % (
self.cert_usage,
self.selector,
self.matching_type,
binascii.hexlify(self.cert_data).decode().upper())

attrs = ('cert_usage','selector','matching_type','cert_data')

# Map from RD type to class (used to pack/unpack records)
# If you add a new RD class you must add to RDMAP

RDMAP = { 'CNAME':CNAME, 'A':A, 'AAAA':AAAA, 'TXT':TXT, 'MX':MX,
'PTR':PTR, 'SOA':SOA, 'NS':NS, 'NAPTR': NAPTR, 'SRV':SRV,
'DNSKEY':DNSKEY, 'RRSIG':RRSIG, 'NSEC':NSEC, 'CAA':CAA,
'HTTPS': HTTPS
'HTTPS': HTTPS, 'DS':DS, 'SSHFP':SSHFP, 'TLSA':TLSA
}

##
Expand Down
20 changes: 20 additions & 0 deletions dnslib/test/example.org-DS
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
;; Sending:
;; QUERY: f1c001000001000000000000076578616d706c65036f726700002b0001
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61888
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;example.org. IN DS

;; Got answer:
;; RESPONSE: f1c081800001000600000000076578616d706c65036f726700002b0001c00c002b000100000e10001893940801b4a5cce8d82dc585e327e5896eae82e0b9a76dc6c00c002b000100000e1000240d450802ed1168604bc6a14068b9905401e62698bb3663b6ec2073ebd3599b882a785bf6c00c002b000100000e1000187b6508017b8370002875dda781390a8e586c31493847d9bcc00c002b000100000e10002493940802d96afa9022000d368b5f497877df289a1e9a13a1ab1f97bc1bf4d5de16879134c00c002b000100000e1000180d450801dee10345942c98711eb058b25a749ee342fce1dcc00c002b000100000e1000247b6508023fdc4c11fa3ad3535ea8c1ce3eaf7bfa5ca9ae8a834d98fee10085cfaeb625aa
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 61888
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;example.org. IN DS
;; ANSWER SECTION:
example.org. 3600 IN DS 37780 8 1 B4A5CCE8D82DC585E327E5896EAE82E0B9A76DC6
example.org. 3600 IN DS 3397 8 2 ED1168604BC6A14068B9905401E62698BB3663B6EC2073EBD3599B882A785BF6
example.org. 3600 IN DS 31589 8 1 7B8370002875DDA781390A8E586C31493847D9BC
example.org. 3600 IN DS 37780 8 2 D96AFA9022000D368B5F497877DF289A1E9A13A1AB1F97BC1BF4D5DE16879134
example.org. 3600 IN DS 3397 8 1 DEE10345942C98711EB058B25A749EE342FCE1DC
example.org. 3600 IN DS 31589 8 2 3FDC4C11FA3AD3535EA8C1CE3EAF7BFA5CA9AE8A834D98FEE10085CFAEB625AA
15 changes: 15 additions & 0 deletions dnslib/test/fedoraproject.org-TLSA
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
;; Sending:
;; QUERY: 77cc01000001000000000000045f343433045f7463700d6665646f726170726f6a656374036f72670000340001
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30668
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;_443._tcp.fedoraproject.org. IN TLSA

;; Got answer:
;; RESPONSE: 77cc81800001000100000000045f343433045f7463700d6665646f726170726f6a656374036f72670000340001c00c003400010000012c0023010101a268847da80175457baf603df3b0ab9cc99d1f6bb84b83c351f97e9e6f397bb4
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30668
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;_443._tcp.fedoraproject.org. IN TLSA
;; ANSWER SECTION:
_443._tcp.fedoraproject.org. 300 IN TLSA 1 1 1 A268847DA80175457BAF603DF3B0AB9CC99D1F6BB84B83C351F97E9E6F397BB4
15 changes: 15 additions & 0 deletions dnslib/test/openssl.org-TLSA
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
;; Sending:
;; QUERY: 30b801000001000000000000045f353837045f746370036d7461076f70656e73736c036f72670000340001
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12472
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;_587._tcp.mta.openssl.org. IN TLSA

;; Got answer:
;; RESPONSE: 30b881800001000100000000045f353837045f746370036d7461076f70656e73736c036f72670000340001c00c0034000100000e1000230301016cf12d78fbf242909d01b96ab5590812954058dc32f8415f048fff064291921e
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12472
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;_587._tcp.mta.openssl.org. IN TLSA
;; ANSWER SECTION:
_587._tcp.mta.openssl.org. 3600 IN TLSA 3 1 1 6CF12D78FBF242909D01B96AB5590812954058DC32F8415F048FFF064291921E
18 changes: 18 additions & 0 deletions dnslib/test/salsa.debian.org-SSHFP
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
;; Sending:
;; QUERY: 5afb010000010000000000000573616c73610664656269616e036f726700002c0001
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23291
;; flags: rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;salsa.debian.org. IN SSHFP

;; Got answer:
;; RESPONSE: 5afb818000010004000000000573616c73610664656269616e036f726700002c0001c00c002c00010000025800160401676b02929dc7908278bcee876ea0f1640b8264e0c00c002c000100000258002204023800f7a464b070e0c8b61c45fb3211bcf4d9f1408901823be44e365c37c6afcec00c002c00010000025800160101eaa6c147facf35bc49946d9e8b90e2235c7da361c00c002c00010000025800220102f3c03414b13a6df37a3296b81774ec3e28d92e7c003667ca8e17d88433820a70
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23291
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;salsa.debian.org. IN SSHFP
;; ANSWER SECTION:
salsa.debian.org. 600 IN SSHFP 4 1 676B02929DC7908278BCEE876EA0F1640B8264E0
salsa.debian.org. 600 IN SSHFP 4 2 3800F7A464B070E0C8B61C45FB3211BCF4D9F1408901823BE44E365C37C6AFCE
salsa.debian.org. 600 IN SSHFP 1 1 EAA6C147FACF35BC49946D9E8B90E2235C7DA361
salsa.debian.org. 600 IN SSHFP 1 2 F3C03414B13A6DF37A3296B81774EC3E28D92E7C003667CA8E17D88433820A70

0 comments on commit 175f101

Please sign in to comment.