diff --git a/httpsig/tests/test_verify.py b/httpsig/tests/test_verify.py index d5f9785..0e1ada6 100755 --- a/httpsig/tests/test_verify.py +++ b/httpsig/tests/test_verify.py @@ -242,3 +242,17 @@ def setUp(self): self.sign_secret = private_key self.verify_secret = public_key self.sign_algorithm = PSS(salt_length=0) + + def test_algorithm_mismatch(self): + unsigned = { + 'Date': self.header_date + } + + hs = HeaderSigner( + key_id="Test", secret=self.sign_secret, algorithm=self.algorithm, + sign_header=self.sign_header, sign_algorithm=self.sign_algorithm) + signed = hs.sign(unsigned) + + hv = HeaderVerifier( + headers=signed, secret=self.verify_secret, sign_header=self.sign_header, algorithm="rsa-sha256", sign_algorithm=self.sign_algorithm) + self.assertFalse(hv.verify()) \ No newline at end of file diff --git a/httpsig/verify.py b/httpsig/verify.py index 7158c7b..33cb2b2 100644 --- a/httpsig/verify.py +++ b/httpsig/verify.py @@ -51,7 +51,7 @@ class HeaderVerifier(Verifier): """ def __init__(self, headers, secret, required_headers=None, method=None, - path=None, host=None, sign_header='authorization', sign_algorithm=None): + path=None, host=None, sign_header='authorization', algorithm=None, sign_algorithm=None): """ Instantiate a HeaderVerifier object. @@ -70,6 +70,7 @@ def __init__(self, headers, secret, required_headers=None, method=None, header, if not supplied in :param:headers. :param sign_header: Optional. The header where the signature is. Default is 'authorization'. + :param algorithm: Algorithm derived from keyId (required for draft version >= 12) :param sign_algorithm: Required for 'hs2019' algorithm, specifies the digital signature algorithm (derived from keyId) to use. """ @@ -89,11 +90,7 @@ def __init__(self, headers, secret, required_headers=None, method=None, self.method = method self.path = path self.host = host - - if 'algorithm' in self.auth_dict and self.auth_dict['algorithm'] != self.algorithm: - raise HttpSigException( - "Algorithm mismath, signature parameter algorithm was: {}, but algorithm dervice from key is: {}".format( - self.auth_dict['algorithm'], self.algorithm)) + self.derived_algorithm = algorithm if self.auth_dict['algorithm'] != DEFAULT_ALGORITHM: print("Algorithm: {} is deprecated please update to {}".format(self.auth_dict['algorithm'], DEFAULT_ALGORITHM)) @@ -112,6 +109,11 @@ def verify(self): not found in the signature. Returns True or False. """ + if 'algorithm' in self.auth_dict and self.derived_algorithm is not None and self.auth_dict['algorithm'] != self.derived_algorithm: + print("Algorithm mismatch, signature parameter algorithm was: {}, but algorithm derived from key is: {}".format( + self.auth_dict['algorithm'], self.derived_algorithm)) + return False + auth_headers = self.auth_dict.get('headers', 'date').split(' ') if len(set(self.required_headers) - set(auth_headers)) > 0: