URI: 
       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}