From: Bob Halley Date: Sun, 17 Oct 2010 17:11:07 +0000 (+0100) Subject: Set up the TSIG hashes table only once. X-Git-Tag: v1.9.0~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=96b5c4c8dfa00579c1b6c1e6f99bdc8dd503e451;p=thirdparty%2Fdnspython.git Set up the TSIG hashes table only once. Make algorithm constants domain names. Detect attempts to use HMAC-SHA384 and HMAC-SHA512 on Python versions less than 2.5.2, and raise a NotImplemented exception. (We want to do this because old versions of Python do not compute them correctly.) --- diff --git a/ChangeLog b/ChangeLog index a07c67b2..5a90235a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2010-10-17 Bob Halley + * Python prior to 2.5.2 doesn't compute the correct values for + HMAC-SHA384 and HMAC-SHA512. We now detect attempts to use + them and raise NotImplemented if the Python version is too old. + Thanks to Kevin Chen for reporting the problem. + * Various routines that took the string forms of rdata types and classes did not permit the strings to be Unicode strings. Thanks to Ryan Workman for reporting the issue. diff --git a/dns/tsig.py b/dns/tsig.py index 7d4c3e03..e09572ee 100644 --- a/dns/tsig.py +++ b/dns/tsig.py @@ -17,6 +17,7 @@ import hmac import struct +import sys import dns.exception import dns.rdataclass @@ -52,12 +53,12 @@ class PeerBadTruncation(PeerError): # 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 @@ -176,25 +177,20 @@ def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata, 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 @@ -207,19 +203,36 @@ def get_algorithm(algorithm): 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")