Skip to content
This repository has been archived by the owner on Jan 18, 2025. It is now read-only.

Commit

Permalink
Making crypt._verify_signature accept list instead of dict.
Browse files Browse the repository at this point in the history
  • Loading branch information
dhermes committed Sep 1, 2015
1 parent fb335b8 commit ef4d070
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 22 deletions.
9 changes: 4 additions & 5 deletions oauth2client/crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,19 @@ def make_signed_jwt(signer, payload):
return b'.'.join(segments)


def _verify_signature(message, signature, certs):
def _verify_signature(message, signature, cert_list):
"""Verifies signed content using a list of certificates.
Args:
message: string or bytes, The message to verify.
signature: string or bytes, The signature on the message.
certs: dict, with the keys as certificate ID strings and the values
certificates in PEM format.
cert_list: list, certificates in PEM format.
Raises:
AppIdentityError: If none of the certificates can verify the message
against the signature.
"""
for pem in certs.values():
for pem in cert_list:
verifier = Verifier.from_string(pem, is_x509_cert=True)
if verifier.verify(message, signature):
return
Expand Down Expand Up @@ -233,7 +232,7 @@ def verify_signed_jwt_with_certs(jwt, certs, audience=None):
raise AppIdentityError('Can\'t parse token: %s' % (payload_bytes,))

# Verify that the signature matches the message.
_verify_signature(message_to_sign, signature, certs)
_verify_signature(message_to_sign, signature, certs.values())

# Verify the issued at and created times in the payload.
_verify_time_range(payload_dict)
Expand Down
29 changes: 12 additions & 17 deletions tests/test_crypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class Test__verify_signature(unittest.TestCase):

def test_success_single_cert(self):
cert_value = 'cert-value'
certs = {None: cert_value}
cert_list = [cert_value]
message = object()
signature = object()

Expand All @@ -90,7 +90,7 @@ def test_success_single_cert(self):
with mock.patch('oauth2client.crypt.Verifier') as Verifier:
Verifier.from_string = mock.MagicMock(name='from_string',
return_value=verifier)
result = crypt._verify_signature(message, signature, certs)
result = crypt._verify_signature(message, signature, cert_list)
self.assertEqual(result, None)

# Make sure our mocks were called as expected.
Expand All @@ -102,7 +102,7 @@ def test_success_multiple_certs(self):
cert_value1 = 'cert-value1'
cert_value2 = 'cert-value2'
cert_value3 = 'cert-value3'
certs = _MockOrderedDict(cert_value1, cert_value2, cert_value3)
cert_list = [cert_value1, cert_value2, cert_value3]
message = object()
signature = object()

Expand All @@ -114,7 +114,7 @@ def test_success_multiple_certs(self):
with mock.patch('oauth2client.crypt.Verifier') as Verifier:
Verifier.from_string = mock.MagicMock(name='from_string',
return_value=verifier)
result = crypt._verify_signature(message, signature, certs)
result = crypt._verify_signature(message, signature, cert_list)
self.assertEqual(result, None)

# Make sure our mocks were called three times.
Expand All @@ -131,7 +131,7 @@ def test_success_multiple_certs(self):

def test_failure(self):
cert_value = 'cert-value'
certs = {None: cert_value}
cert_list = [cert_value]
message = object()
signature = object()

Expand All @@ -141,7 +141,7 @@ def test_failure(self):
Verifier.from_string = mock.MagicMock(name='from_string',
return_value=verifier)
self.assertRaises(crypt.AppIdentityError, crypt._verify_signature,
message, signature, certs)
message, signature, cert_list)

# Make sure our mocks were called as expected.
Verifier.from_string.assert_called_once_with(cert_value,
Expand Down Expand Up @@ -292,7 +292,10 @@ def test_jwt_payload_bad_json(self):
@mock.patch('oauth2client.crypt._verify_time_range')
@mock.patch('oauth2client.crypt._verify_signature')
def test_success(self, verify_sig, verify_time, check_aud):
certs = object()
certs = mock.MagicMock()
cert_list = object()
certs.values = mock.MagicMock(name='values',
return_value=cert_list)
audience = object()

header = b'header'
Expand All @@ -308,15 +311,7 @@ def test_success(self, verify_sig, verify_time, check_aud):

message_to_sign = header + b'.' + payload
verify_sig.assert_called_once_with(
message_to_sign, signature_bytes, certs)
message_to_sign, signature_bytes, cert_list)
verify_time.assert_called_once_with(payload_dict)
check_aud.assert_called_once_with(payload_dict, audience)


class _MockOrderedDict(object):

def __init__(self, *values):
self._values = values

def values(self):
return self._values
certs.values.assert_called_once_with()

0 comments on commit ef4d070

Please sign in to comment.