dnspython: Update to newer upstream snapshot.
[samba.git] / lib / dnspython / dns / tsig.py
index b4deeca859dcaac594acd4733326c17b64f5a4c7..5e58ea884135934481bf80f5d2a84d3a828f89dd 100644 (file)
 
 import hmac
 import struct
+import sys
 
 import dns.exception
+import dns.hash
 import dns.rdataclass
 import dns.name
 
@@ -50,7 +52,16 @@ class PeerBadTruncation(PeerError):
     """Raised if the peer didn't like amount of truncation in the TSIG we sent"""
     pass
 
-default_algorithm = "HMAC-MD5.SIG-ALG.REG.INT"
+# TSIG Algorithms
+
+HMAC_MD5 = dns.name.from_text("HMAC-MD5.SIG-ALG.REG.INT")
+HMAC_SHA1 = dns.name.from_text("hmac-sha1")
+HMAC_SHA224 = dns.name.from_text("hmac-sha224")
+HMAC_SHA256 = dns.name.from_text("hmac-sha256")
+HMAC_SHA384 = dns.name.from_text("hmac-sha384")
+HMAC_SHA512 = dns.name.from_text("hmac-sha512")
+
+default_algorithm = HMAC_MD5
 
 BADSIG = 16
 BADKEY = 17
@@ -167,6 +178,24 @@ def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata,
         raise BadSignature
     return ctx
 
+_hashes = None
+
+def _maybe_add_hash(tsig_alg, hash_alg):
+    try:
+        _hashes[tsig_alg] = dns.hash.get(hash_alg)
+    except KeyError:
+        pass
+
+def _setup_hashes():
+    global _hashes
+    _hashes = {}
+    _maybe_add_hash(HMAC_SHA224, 'SHA224')
+    _maybe_add_hash(HMAC_SHA256, 'SHA256')
+    _maybe_add_hash(HMAC_SHA384, 'SHA384')
+    _maybe_add_hash(HMAC_SHA512, 'SHA512')
+    _maybe_add_hash(HMAC_SHA1, 'SHA1')
+    _maybe_add_hash(HMAC_MD5, 'MD5')
+
 def get_algorithm(algorithm):
     """Returns the wire format string and the hash module to use for the
     specified TSIG algorithm
@@ -175,42 +204,20 @@ def get_algorithm(algorithm):
     @raises NotImplementedError: I{algorithm} is not supported
     """
 
-    hashes = {}
-    try:
-        import hashlib
-        hashes[dns.name.from_text('hmac-sha224')] = hashlib.sha224
-        hashes[dns.name.from_text('hmac-sha256')] = hashlib.sha256
-        hashes[dns.name.from_text('hmac-sha384')] = hashlib.sha384
-        hashes[dns.name.from_text('hmac-sha512')] = hashlib.sha512
-        hashes[dns.name.from_text('hmac-sha1')] = hashlib.sha1
-        hashes[dns.name.from_text('HMAC-MD5.SIG-ALG.REG.INT')] = hashlib.md5
-
-        import sys
-        if sys.hexversion < 0x02050000:
-            # hashlib doesn't conform to PEP 247: API for
-            # Cryptographic Hash Functions, which hmac before python
-            # 2.5 requires, so add the necessary items.
-            class HashlibWrapper:
-                def __init__(self, basehash):
-                    self.basehash = basehash
-                    self.digest_size = self.basehash().digest_size
-
-                def new(self, *args, **kwargs):
-                    return self.basehash(*args, **kwargs)
-
-            for name in hashes:
-                hashes[name] = HashlibWrapper(hashes[name])
-
-    except ImportError:
-        import md5, sha
-        hashes[dns.name.from_text('HMAC-MD5.SIG-ALG.REG.INT')] =  md5.md5
-        hashes[dns.name.from_text('hmac-sha1')] = sha.sha
+    global _hashes
+    if _hashes is None:
+        _setup_hashes()
 
     if isinstance(algorithm, (str, unicode)):
         algorithm = dns.name.from_text(algorithm)
 
-    if algorithm in hashes:
-        return (algorithm.to_digestable(), hashes[algorithm])
+    if sys.hexversion < 0x02050200 and \
+       (algorithm == HMAC_SHA384 or algorithm == HMAC_SHA512):
+        raise NotImplementedError("TSIG algorithm " + str(algorithm) +
+                                  " requires Python 2.5.2 or later")
 
-    raise NotImplementedError("TSIG algorithm " + str(algorithm) +
-                              " is not supported")
+    try:
+        return (algorithm.to_digestable(), _hashes[algorithm])
+    except KeyError:
+        raise NotImplementedError("TSIG algorithm " + str(algorithm) +
+                                  " is not supported")