1# All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); you may 4# not use this file except in compliance with the License. You may obtain 5# a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12# License for the specific language governing permissions and limitations 13# under the License. 14 15""" 16Secret utilities. 17 18.. versionadded:: 3.5 19""" 20 21import hashlib 22import hmac 23 24 25def _constant_time_compare(first, second): 26 """Return True if both string or binary inputs are equal, otherwise False. 27 28 This function should take a constant amount of time regardless of 29 how many characters in the strings match. This function uses an 30 approach designed to prevent timing analysis by avoiding 31 content-based short circuiting behaviour, making it appropriate 32 for cryptography. 33 """ 34 first = str(first) 35 second = str(second) 36 if len(first) != len(second): 37 return False 38 result = 0 39 for x, y in zip(first, second): 40 result |= ord(x) ^ ord(y) 41 return result == 0 42 43 44try: 45 constant_time_compare = hmac.compare_digest 46except AttributeError: 47 constant_time_compare = _constant_time_compare 48 49try: 50 _ = hashlib.md5(usedforsecurity=False) # nosec 51 52 def md5(string=b'', usedforsecurity=True): 53 """Return an md5 hashlib object using usedforsecurity parameter 54 55 For python distributions that support the usedforsecurity keyword 56 parameter, this passes the parameter through as expected. 57 See https://bugs.python.org/issue9216 58 """ 59 return hashlib.md5(string, usedforsecurity=usedforsecurity) # nosec 60except TypeError: 61 def md5(string=b'', usedforsecurity=True): 62 """Return an md5 hashlib object without usedforsecurity parameter 63 64 For python distributions that do not yet support this keyword 65 parameter, we drop the parameter 66 """ 67 return hashlib.md5(string) # nosec 68