def test_strings_differ(self): # We can't really test the timing-invariance, but # we can test that we actually compute equality! self.assertTrue(strings_differ("", "a")) self.assertTrue(strings_differ("b", "a")) self.assertTrue(strings_differ("cc", "a")) self.assertTrue(strings_differ("cc", "aa")) self.assertFalse(strings_differ("", "")) self.assertFalse(strings_differ("D", "D")) self.assertFalse(strings_differ("EEE", "EEE"))
def check_signature(request, key, hashmod=None, params=None, nonces=None): """Check that the request is correctly signed with the given MAC key. This function checks the MAC signature in the given request against its expected value, returning True if they match and false otherwise. If the "params" parameter is not None, it is assumed to be a pre-parsed dict of MAC parameters as one might find in the Authorization header. If it is missing or None then the Authorization header from the request will be parsed to determine the necessary parameters. If the "nonces" parameter is not None, it must be a NonceCache object used to check validity of the signature nonce. If not specified then a default global cache will be used. To disable nonce checking (e.g. during testing) pass nonces=False. """ global DEFAULT_NONCE_CACHE if nonces is None: nonces = DEFAULT_NONCE_CACHE if nonces is None: nonces = DEFAULT_NONCE_CACHE = NonceCache() if params is None: params = utils.parse_authz_header(request, {}) if params.get("scheme") != "MAC": return False # Any KeyError here indicates a missing parameter. # Any ValueError here indicates an invalid parameter. try: id = params["id"] timestamp = int(params["ts"]) nonce = params["nonce"] # Check validity of the signature. expected_sig = get_signature(request, key, hashmod, params) if utils.strings_differ(params["mac"], expected_sig): return False # Check freshness of the nonce. # This caches it so future use of the nonce will fail. # We do this *after* successul sig check to avoid DOS attacks. if nonces is not False: if not nonces.check_nonce(id, timestamp, nonce): return False except (KeyError, ValueError): return False return True