+++ /dev/null
-"""HMAC (Keyed-Hashing for Message Authentication) Python module.\r
-\r
-Implements the HMAC algorithm as described by RFC 2104.\r
-"""\r
-\r
-import warnings as _warnings\r
-\r
-trans_5C = "".join ([chr (x ^ 0x5C) for x in xrange(256)])\r
-trans_36 = "".join ([chr (x ^ 0x36) for x in xrange(256)])\r
-\r
-# The size of the digests returned by HMAC depends on the underlying\r
-# hashing module used. Use digest_size from the instance of HMAC instead.\r
-digest_size = None\r
-\r
-# A unique object passed by HMAC.copy() to the HMAC constructor, in order\r
-# that the latter return very quickly. HMAC("") in contrast is quite\r
-# expensive.\r
-_secret_backdoor_key = []\r
-\r
-class HMAC:\r
- """RFC 2104 HMAC class. Also complies with RFC 4231.\r
-\r
- This supports the API for Cryptographic Hash Functions (PEP 247).\r
- """\r
- blocksize = 64 # 512-bit HMAC; can be changed in subclasses.\r
-\r
- def __init__(self, key, msg = None, digestmod = None):\r
- """Create a new HMAC object.\r
-\r
- key: key for the keyed hash object.\r
- msg: Initial input for the hash, if provided.\r
- digestmod: A module supporting PEP 247. *OR*\r
- A hashlib constructor returning a new hash object.\r
- Defaults to hashlib.md5.\r
- """\r
-\r
- if key is _secret_backdoor_key: # cheap\r
- return\r
-\r
- if digestmod is None:\r
- import hashlib\r
- digestmod = hashlib.md5\r
-\r
- if hasattr(digestmod, '__call__'):\r
- self.digest_cons = digestmod\r
- else:\r
- self.digest_cons = lambda d='': digestmod.new(d)\r
-\r
- self.outer = self.digest_cons()\r
- self.inner = self.digest_cons()\r
- self.digest_size = self.inner.digest_size\r
-\r
- if hasattr(self.inner, 'block_size'):\r
- blocksize = self.inner.block_size\r
- if blocksize < 16:\r
- # Very low blocksize, most likely a legacy value like\r
- # Lib/sha.py and Lib/md5.py have.\r
- _warnings.warn('block_size of %d seems too small; using our '\r
- 'default of %d.' % (blocksize, self.blocksize),\r
- RuntimeWarning, 2)\r
- blocksize = self.blocksize\r
- else:\r
- _warnings.warn('No block_size attribute on given digest object; '\r
- 'Assuming %d.' % (self.blocksize),\r
- RuntimeWarning, 2)\r
- blocksize = self.blocksize\r
-\r
- if len(key) > blocksize:\r
- key = self.digest_cons(key).digest()\r
-\r
- key = key + chr(0) * (blocksize - len(key))\r
- self.outer.update(key.translate(trans_5C))\r
- self.inner.update(key.translate(trans_36))\r
- if msg is not None:\r
- self.update(msg)\r
-\r
-## def clear(self):\r
-## raise NotImplementedError, "clear() method not available in HMAC."\r
-\r
- def update(self, msg):\r
- """Update this hashing object with the string msg.\r
- """\r
- self.inner.update(msg)\r
-\r
- def copy(self):\r
- """Return a separate copy of this hashing object.\r
-\r
- An update to this copy won't affect the original object.\r
- """\r
- other = self.__class__(_secret_backdoor_key)\r
- other.digest_cons = self.digest_cons\r
- other.digest_size = self.digest_size\r
- other.inner = self.inner.copy()\r
- other.outer = self.outer.copy()\r
- return other\r
-\r
- def _current(self):\r
- """Return a hash object for the current state.\r
-\r
- To be used only internally with digest() and hexdigest().\r
- """\r
- h = self.outer.copy()\r
- h.update(self.inner.digest())\r
- return h\r
-\r
- def digest(self):\r
- """Return the hash value of this hashing object.\r
-\r
- This returns a string containing 8-bit data. The object is\r
- not altered in any way by this function; you can continue\r
- updating the object after calling this function.\r
- """\r
- h = self._current()\r
- return h.digest()\r
-\r
- def hexdigest(self):\r
- """Like digest(), but returns a string of hexadecimal digits instead.\r
- """\r
- h = self._current()\r
- return h.hexdigest()\r
-\r
-def new(key, msg = None, digestmod = None):\r
- """Create a new hashing object and return it.\r
-\r
- key: The starting key for the hash.\r
- msg: if available, will immediately be hashed into the object's starting\r
- state.\r
-\r
- You can now feed arbitrary strings into the object using its update()\r
- method, and can ask for the hash value at any time by calling its digest()\r
- method.\r
- """\r
- return HMAC(key, msg, digestmod)\r