From: Bob Halley Date: Sun, 17 Oct 2010 14:40:10 +0000 (+0100) Subject: Add DNSSEC helpers key_id() and make_ds() X-Git-Tag: v1.9.0~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2a3547ac216ed3604a7425bba24af4ad66085e94;p=thirdparty%2Fdnspython.git Add DNSSEC helpers key_id() and make_ds() --- diff --git a/ChangeLog b/ChangeLog index b987d162..e49a6eef 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,8 @@ -2010-10-17 Bob Halley +2010-10-17 Bob Halley + + * dns/dnssec.py: Added key_id() and make_ds(). + +2010-10-17 Bob Halley * dns/message.py: message.py needs to import dns.edns since it uses it. diff --git a/dns/dnssec.py b/dns/dnssec.py index 54fd78d9..eab12ad5 100644 --- a/dns/dnssec.py +++ b/dns/dnssec.py @@ -15,6 +15,11 @@ """Common DNSSEC-related functions and constants.""" +import dns.name +import dns.rdata +import dns.rdatatype +import dns.rdataclass + RSAMD5 = 1 DH = 2 DSA = 3 @@ -56,7 +61,7 @@ class UnknownAlgorithm(Exception): def algorithm_from_text(text): """Convert text into a DNSSEC algorithm value @rtype: int""" - + value = _algorithm_by_text.get(text.upper()) if value is None: value = int(text) @@ -65,8 +70,46 @@ def algorithm_from_text(text): def algorithm_to_text(value): """Convert a DNSSEC algorithm value to text @rtype: string""" - + text = _algorithm_by_value.get(value) if text is None: text = str(value) return text + +def _to_rdata(record): + s = cStringIO.StringIO() + record.to_wire(s) + return s.getvalue() + +def key_id(key): + rdata = _to_rdata(key) + if key.algorithm == RSAMD5: + return (ord(rdata[-3]) << 8) + ord(rdata[-2]) + else: + total = 0 + for i in range(len(rdata) / 2): + total += (ord(rdata[2 * i]) << 8) + ord(rdata[2 * i + 1]) + if len(rdata) % 2 != 0: + total += ord(rdata[len(rdata) - 1]) << 8 + total += ((total >> 16) & 0xffff); + return total & 0xffff + +def make_ds(name, key, algorithm): + if algorithm.upper() == 'SHA1': + dsalg = 1 + hash = hashlib.sha1() + elif algorithm.upper() == 'SHA256': + dsalg = 2 + hash = hashlib.sha256() + else: + raise ValueError, 'unsupported algorithm "%s"' % algorithm + + if isinstance(name, str): + name = dns.name.from_text(name) + hash.update(name.canonicalize().to_wire()) + hash.update(_to_rdata(key)) + digest = hash.digest() + + dsrdata = struct.pack("!HBB", key_id(key), key.algorithm, dsalg) + digest + return dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.DS, dsrdata, 0, + len(dsrdata))