ยปCore Development>Code coverage>Lib/hmac.py

Python code coverage for Lib/hmac.py

#countcontent
1n/a"""HMAC (Keyed-Hashing for Message Authentication) Python module.
2n/a
3n/aImplements the HMAC algorithm as described by RFC 2104.
4n/a"""
5n/a
6n/aimport warnings as _warnings
7n/afrom _operator import _compare_digest as compare_digest
8n/aimport hashlib as _hashlib
9n/a
10n/atrans_5C = bytes((x ^ 0x5C) for x in range(256))
11n/atrans_36 = bytes((x ^ 0x36) for x in range(256))
12n/a
13n/a# The size of the digests returned by HMAC depends on the underlying
14n/a# hashing module used. Use digest_size from the instance of HMAC instead.
15n/adigest_size = None
16n/a
17n/a
18n/a
19n/aclass HMAC:
20n/a """RFC 2104 HMAC class. Also complies with RFC 4231.
21n/a
22n/a This supports the API for Cryptographic Hash Functions (PEP 247).
23n/a """
24n/a blocksize = 64 # 512-bit HMAC; can be changed in subclasses.
25n/a
26n/a def __init__(self, key, msg = None, digestmod = None):
27n/a """Create a new HMAC object.
28n/a
29n/a key: key for the keyed hash object.
30n/a msg: Initial input for the hash, if provided.
31n/a digestmod: A module supporting PEP 247. *OR*
32n/a A hashlib constructor returning a new hash object. *OR*
33n/a A hash name suitable for hashlib.new().
34n/a Defaults to hashlib.md5.
35n/a Implicit default to hashlib.md5 is deprecated and will be
36n/a removed in Python 3.6.
37n/a
38n/a Note: key and msg must be a bytes or bytearray objects.
39n/a """
40n/a
41n/a if not isinstance(key, (bytes, bytearray)):
42n/a raise TypeError("key: expected bytes or bytearray, but got %r" % type(key).__name__)
43n/a
44n/a if digestmod is None:
45n/a _warnings.warn("HMAC() without an explicit digestmod argument "
46n/a "is deprecated.", PendingDeprecationWarning, 2)
47n/a digestmod = _hashlib.md5
48n/a
49n/a if callable(digestmod):
50n/a self.digest_cons = digestmod
51n/a elif isinstance(digestmod, str):
52n/a self.digest_cons = lambda d=b'': _hashlib.new(digestmod, d)
53n/a else:
54n/a self.digest_cons = lambda d=b'': digestmod.new(d)
55n/a
56n/a self.outer = self.digest_cons()
57n/a self.inner = self.digest_cons()
58n/a self.digest_size = self.inner.digest_size
59n/a
60n/a if hasattr(self.inner, 'block_size'):
61n/a blocksize = self.inner.block_size
62n/a if blocksize < 16:
63n/a _warnings.warn('block_size of %d seems too small; using our '
64n/a 'default of %d.' % (blocksize, self.blocksize),
65n/a RuntimeWarning, 2)
66n/a blocksize = self.blocksize
67n/a else:
68n/a _warnings.warn('No block_size attribute on given digest object; '
69n/a 'Assuming %d.' % (self.blocksize),
70n/a RuntimeWarning, 2)
71n/a blocksize = self.blocksize
72n/a
73n/a # self.blocksize is the default blocksize. self.block_size is
74n/a # effective block size as well as the public API attribute.
75n/a self.block_size = blocksize
76n/a
77n/a if len(key) > blocksize:
78n/a key = self.digest_cons(key).digest()
79n/a
80n/a key = key.ljust(blocksize, b'\0')
81n/a self.outer.update(key.translate(trans_5C))
82n/a self.inner.update(key.translate(trans_36))
83n/a if msg is not None:
84n/a self.update(msg)
85n/a
86n/a @property
87n/a def name(self):
88n/a return "hmac-" + self.inner.name
89n/a
90n/a def update(self, msg):
91n/a """Update this hashing object with the string msg.
92n/a """
93n/a self.inner.update(msg)
94n/a
95n/a def copy(self):
96n/a """Return a separate copy of this hashing object.
97n/a
98n/a An update to this copy won't affect the original object.
99n/a """
100n/a # Call __new__ directly to avoid the expensive __init__.
101n/a other = self.__class__.__new__(self.__class__)
102n/a other.digest_cons = self.digest_cons
103n/a other.digest_size = self.digest_size
104n/a other.inner = self.inner.copy()
105n/a other.outer = self.outer.copy()
106n/a return other
107n/a
108n/a def _current(self):
109n/a """Return a hash object for the current state.
110n/a
111n/a To be used only internally with digest() and hexdigest().
112n/a """
113n/a h = self.outer.copy()
114n/a h.update(self.inner.digest())
115n/a return h
116n/a
117n/a def digest(self):
118n/a """Return the hash value of this hashing object.
119n/a
120n/a This returns a string containing 8-bit data. The object is
121n/a not altered in any way by this function; you can continue
122n/a updating the object after calling this function.
123n/a """
124n/a h = self._current()
125n/a return h.digest()
126n/a
127n/a def hexdigest(self):
128n/a """Like digest(), but returns a string of hexadecimal digits instead.
129n/a """
130n/a h = self._current()
131n/a return h.hexdigest()
132n/a
133n/adef new(key, msg = None, digestmod = None):
134n/a """Create a new hashing object and return it.
135n/a
136n/a key: The starting key for the hash.
137n/a msg: if available, will immediately be hashed into the object's starting
138n/a state.
139n/a
140n/a You can now feed arbitrary strings into the object using its update()
141n/a method, and can ask for the hash value at any time by calling its digest()
142n/a method.
143n/a """
144n/a return HMAC(key, msg, digestmod)