From ad2fc50e952410c15baf9693e0c78b32502e29ec Mon Sep 17 00:00:00 2001 From: Danny Hermes Date: Thu, 2 Jul 2015 11:04:20 -0700 Subject: [PATCH] Casting message to bytes in PyCrypto verifier. Also - Removing bare `except:` statements in both the PyCrypto and OpenSSL verifiers (in the `verify` method). - Catching the only exception possible in the OpenSSL verifier (it is `OpenSSL.crypto.Error`). - Converting the signature to bytes (if not already) in the OpenSSL verifier. - Adding a test with both a unicode and bytes signature for each verifier. Fixes #201. --- oauth2client/crypt.py | 28 ++++++++++++++++------------ tests/test_jwt.py | 10 ++++++++-- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/oauth2client/crypt.py b/oauth2client/crypt.py index 9e3aede..1a25bec 100644 --- a/oauth2client/crypt.py +++ b/oauth2client/crypt.py @@ -85,20 +85,24 @@ try: """Verifies a message against a signature. Args: - message: string, The message to verify. - signature: string, The signature on the message. + message: string or bytes, The message to verify. If string, will be + encoded to bytes as utf-8. + signature: string or bytes, The signature on the message. If string, + will be encoded to bytes as utf-8. Returns: True if message was signed by the private key associated with the public key that this object was constructed with. """ from OpenSSL import crypto + if isinstance(message, six.text_type): + message = message.encode('utf-8') + if isinstance(signature, six.text_type): + signature = signature.encode('utf-8') try: - if isinstance(message, six.text_type): - message = message.encode('utf-8') crypto.verify(self._pubkey, signature, message, 'sha256') return True - except: + except crypto.Error: return False @staticmethod @@ -221,18 +225,18 @@ try: """Verifies a message against a signature. Args: - message: string, The message to verify. - signature: string, The signature on the message. + message: string or bytes, The message to verify. If string, will be + encoded to bytes as utf-8. + signature: string or bytes, The signature on the message. Returns: True if message was signed by the private key associated with the public key that this object was constructed with. """ - try: - return PKCS1_v1_5.new(self._pubkey).verify( - SHA256.new(message), signature) - except: - return False + if isinstance(message, six.text_type): + message = message.encode('utf-8') + return PKCS1_v1_5.new(self._pubkey).verify( + SHA256.new(message), signature) @staticmethod def from_string(key_pem, is_x509_cert): diff --git a/tests/test_jwt.py b/tests/test_jwt.py index f58a294..2b9db5a 100644 --- a/tests/test_jwt.py +++ b/tests/test_jwt.py @@ -59,7 +59,7 @@ class CryptTests(unittest.TestCase): self._check_sign_and_verify('privatekey.%s' % self.format) def test_sign_and_verify_from_converted_pkcs12(self): - """Tests that following instructions to convert from PKCS12 to PEM works.""" + # Tests that following instructions to convert from PKCS12 to PEM works. if self.format == 'pem': self._check_sign_and_verify('pem_from_pkcs12.pem') @@ -74,7 +74,8 @@ class CryptTests(unittest.TestCase): self.assertTrue(verifier.verify(b'foo', signature)) self.assertFalse(verifier.verify(b'bar', signature)) - self.assertFalse(verifier.verify(b'foo', 'bad signagure')) + self.assertFalse(verifier.verify(b'foo', b'bad signagure')) + self.assertFalse(verifier.verify(b'foo', u'bad signagure')) def _check_jwt_failure(self, jwt, expected_error): public_key = datafile('publickey.pem') @@ -189,6 +190,7 @@ class CryptTests(unittest.TestCase): class PEMCryptTestsPyCrypto(CryptTests): + def setUp(self): self.format = 'pem' self.signer = crypt.PyCryptoSigner @@ -196,6 +198,7 @@ class PEMCryptTestsPyCrypto(CryptTests): class PEMCryptTestsOpenSSL(CryptTests): + def setUp(self): self.format = 'pem' self.signer = crypt.OpenSSLSigner @@ -203,6 +206,7 @@ class PEMCryptTestsOpenSSL(CryptTests): class SignedJwtAssertionCredentialsTests(unittest.TestCase): + def setUp(self): self.format = 'p12' crypt.Signer = crypt.OpenSSLSigner @@ -281,6 +285,7 @@ class SignedJwtAssertionCredentialsTests(unittest.TestCase): class PEMSignedJwtAssertionCredentialsOpenSSLTests( SignedJwtAssertionCredentialsTests): + def setUp(self): self.format = 'pem' crypt.Signer = crypt.OpenSSLSigner @@ -288,6 +293,7 @@ class PEMSignedJwtAssertionCredentialsOpenSSLTests( class PEMSignedJwtAssertionCredentialsPyCryptoTests( SignedJwtAssertionCredentialsTests): + def setUp(self): self.format = 'pem' crypt.Signer = crypt.PyCryptoSigner