import hmac
import struct
+import sys
import dns.exception
import dns.rdataclass
# TSIG Algorithms
-HMAC_MD5 = "HMAC-MD5.SIG-ALG.REG.INT"
-HMAC_SHA1 = "hmac-sha1"
-HMAC_SHA224 = "hmac-sha224"
-HMAC_SHA256 = "hmac-sha256"
-HMAC_SHA384 = "hmac-sha384"
-HMAC_SHA512 = "hmac-sha512"
+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
raise BadSignature
return ctx
-def get_algorithm(algorithm):
- """Returns the wire format string and the hash module to use for the
- specified TSIG algorithm
+_hashes = None
- @rtype: (string, hash constructor)
- @raises NotImplementedError: I{algorithm} is not supported
- """
-
- hashes = {}
+def _setup_hashes():
+ global _hashes
+ _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)] = hashlib.md5
-
- import sys
+ _hashes[HMAC_SHA224] = hashlib.sha224
+ _hashes[HMAC_SHA256] = hashlib.sha256
+ _hashes[HMAC_SHA384] = hashlib.sha384
+ _hashes[HMAC_SHA512] = hashlib.sha512
+ _hashes[HMAC_SHA1] = hashlib.sha1
+ _hashes[HMAC_MD5] = hashlib.md5
+
if sys.hexversion < 0x02050000:
# hashlib doesn't conform to PEP 247: API for
# Cryptographic Hash Functions, which hmac before python
def new(self, *args, **kwargs):
return self.basehash(*args, **kwargs)
- for name in hashes:
- hashes[name] = HashlibWrapper(hashes[name])
+ for name in _hashes:
+ _hashes[name] = HashlibWrapper(_hashes[name])
except ImportError:
import md5, sha
- hashes[dns.name.from_text(HMAC_MD5)] = md5
- hashes[dns.name.from_text(HMAC_SHA1)] = sha
+ _hashes[dns.name.from_text(HMAC_MD5)] = md5
+ _hashes[dns.name.from_text(HMAC_SHA1)] = sha
+
+def get_algorithm(algorithm):
+ """Returns the wire format string and the hash module to use for the
+ specified TSIG algorithm
+
+ @rtype: (string, hash constructor)
+ @raises NotImplementedError: I{algorithm} is not supported
+ """
+
+ 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")