tdnssec: fix hash, and skip SOA - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit 71243c2a57e74c0c39e71ae16b61f1700ebabe3c DIR parent 094ce2e4b391c187ba38b3706fbe8b0340790605 HTML Author: ThomasV <thomasv@gitorious> Date: Thu, 9 Jul 2015 09:02:39 +0200 dnssec: fix hash, and skip SOA Diffstat: M lib/dnssec.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) --- DIR diff --git a/lib/dnssec.py b/lib/dnssec.py t@@ -64,11 +64,14 @@ def check_query(ns, sub, _type, keys): response = dns.query.tcp(q, ns, timeout=5) assert response.rcode() == 0, 'No 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: rrsig, rrset = answer - else: + elif answer[1].rdtype == dns.rdatatype.RRSIG: rrset, rrsig = answer + else: + raise BaseException('No signature set in record') if keys is None: keys = {dns.name.from_text(sub):rrset} dns.dnssec.validate(rrset, rrsig, keys) t@@ -84,6 +87,14 @@ def get_and_validate(ns, url, _type): for i in range(len(parts), 0, -1): sub = '.'.join(parts[i-1:]) 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) rrset = check_query(ns, sub, dns.rdatatype.DNSKEY, None) # get DS (signed by parent) t@@ -91,14 +102,14 @@ def get_and_validate(ns, url, _type): # verify that a signed DS validates DNSKEY for ds in ds_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: break else: continue break else: - print ds_rrset raise BaseException("DS does not match DNSKEY") # set key for next iteration keys = {name: rrset}