Browse Source

dnssec: fix hash, and skip SOA

283
ThomasV 10 years ago
parent
commit
71243c2a57
  1. 19
      lib/dnssec.py

19
lib/dnssec.py

@ -64,11 +64,14 @@ def check_query(ns, sub, _type, keys):
response = dns.query.tcp(q, ns, timeout=5) response = dns.query.tcp(q, ns, timeout=5)
assert response.rcode() == 0, 'No answer' assert response.rcode() == 0, 'No answer'
answer = response.answer answer = response.answer
assert len(answer) == 2, 'No DNSSEC record found' assert len(answer) != 0, ('No DNS record found', sub, _type)
assert len(answer) != 1, ('No DNSSEC record found', sub, _type)
if answer[0].rdtype == dns.rdatatype.RRSIG: if answer[0].rdtype == dns.rdatatype.RRSIG:
rrsig, rrset = answer rrsig, rrset = answer
else: elif answer[1].rdtype == dns.rdatatype.RRSIG:
rrset, rrsig = answer rrset, rrsig = answer
else:
raise BaseException('No signature set in record')
if keys is None: if keys is None:
keys = {dns.name.from_text(sub):rrset} keys = {dns.name.from_text(sub):rrset}
dns.dnssec.validate(rrset, rrsig, keys) dns.dnssec.validate(rrset, rrsig, keys)
@ -84,6 +87,14 @@ def get_and_validate(ns, url, _type):
for i in range(len(parts), 0, -1): for i in range(len(parts), 0, -1):
sub = '.'.join(parts[i-1:]) sub = '.'.join(parts[i-1:])
name = dns.name.from_text(sub) name = dns.name.from_text(sub)
# If server is authoritative, don't fetch DNSKEY
query = dns.message.make_query(sub, dns.rdatatype.NS)
response = dns.query.udp(query, ns, 3)
assert response.rcode() == dns.rcode.NOERROR, "query error"
rrset = response.authority[0] if len(response.authority) > 0 else response.answer[0]
rr = rrset[0]
if rr.rdtype == dns.rdatatype.SOA:
continue
# get DNSKEY (self-signed) # get DNSKEY (self-signed)
rrset = check_query(ns, sub, dns.rdatatype.DNSKEY, None) rrset = check_query(ns, sub, dns.rdatatype.DNSKEY, None)
# get DS (signed by parent) # get DS (signed by parent)
@ -91,14 +102,14 @@ def get_and_validate(ns, url, _type):
# verify that a signed DS validates DNSKEY # verify that a signed DS validates DNSKEY
for ds in ds_rrset: for ds in ds_rrset:
for dnskey in rrset: for dnskey in rrset:
good_ds = dns.dnssec.make_ds(name, dnskey, 'SHA256') htype = 'SHA256' if ds.digest_type == 2 else 'SHA1'
good_ds = dns.dnssec.make_ds(name, dnskey, htype)
if ds == good_ds: if ds == good_ds:
break break
else: else:
continue continue
break break
else: else:
print ds_rrset
raise BaseException("DS does not match DNSKEY") raise BaseException("DS does not match DNSKEY")
# set key for next iteration # set key for next iteration
keys = {name: rrset} keys = {name: rrset}

Loading…
Cancel
Save