]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Add DNSSEC helpers key_id() and make_ds()
authorBob Halley <halley@nominum.com>
Sun, 17 Oct 2010 14:40:10 +0000 (15:40 +0100)
committerBob Halley <halley@nominum.com>
Sun, 17 Oct 2010 14:40:10 +0000 (15:40 +0100)
ChangeLog
dns/dnssec.py

index b987d16288f852d61ceaf1f1eb0889aa48af3773..e49a6eeffedadab296afa0252fb16b1b4bc44fc9 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,8 @@
-2010-10-17  Bob Halley  <halley@dnspython.org> 
+2010-10-17  Bob Halley  <halley@dnspython.org>
+
+       * dns/dnssec.py: Added key_id() and make_ds().
+
+2010-10-17  Bob Halley  <halley@dnspython.org>
 
        * dns/message.py: message.py needs to import dns.edns since it uses
          it.
index 54fd78d9c9b91491e5736627dd0662863d888297..eab12ad502ca9204be7f49d5f1de80b41845e0e3 100644 (file)
 
 """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))