diff --git a/oauth2client/crypt.py b/oauth2client/crypt.py index 381f389e4..660adb754 100644 --- a/oauth2client/crypt.py +++ b/oauth2client/crypt.py @@ -16,8 +16,10 @@ """Crypto-related routines for oauth2client.""" import base64 +import imp import json import logging +import os import sys import time @@ -37,7 +39,10 @@ class AppIdentityError(Exception): try: - from OpenSSL import crypto + _, package_dir, _ = imp.find_module('OpenSSL') + if not os.path.isfile(os.path.join(package_dir, 'crypto.py')): + raise ImportError('No module named OpenSSL') + del package_dir class OpenSSLVerifier(object): """Verifies the signature on a message.""" @@ -61,6 +66,7 @@ def verify(self, message, signature): True if message was signed by the private key associated with the public key that this object was constructed with. """ + from OpenSSL import crypto try: if isinstance(message, six.text_type): message = message.encode('utf-8') @@ -84,6 +90,7 @@ def from_string(key_pem, is_x509_cert): Raises: OpenSSL.crypto.Error if the key_pem can't be parsed. """ + from OpenSSL import crypto if is_x509_cert: pubkey = crypto.load_certificate(crypto.FILETYPE_PEM, key_pem) else: @@ -111,6 +118,7 @@ def sign(self, message): Returns: string, The signature of the message for the given key. """ + from OpenSSL import crypto if isinstance(message, six.text_type): message = message.encode('utf-8') return crypto.sign(self._key, message, 'sha256') @@ -129,6 +137,7 @@ def from_string(key, password=b'notasecret'): Raises: OpenSSL.crypto.Error if the key can't be parsed. """ + from OpenSSL import crypto parsed_pem_key = _parse_pem_key(key) if parsed_pem_key: pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, parsed_pem_key) @@ -149,6 +158,7 @@ def pkcs12_key_as_pem(private_key_text, private_key_password): Returns: String. PEM contents of ``private_key_text``. """ + from OpenSSL import crypto decoded_body = base64.b64decode(private_key_text) if isinstance(private_key_password, six.string_types): private_key_password = private_key_password.encode('ascii') diff --git a/tests/test_crypt.py b/tests/test_crypt.py index 73e66b2a2..f471b5f04 100644 --- a/tests/test_crypt.py +++ b/tests/test_crypt.py @@ -58,17 +58,19 @@ def test_succeeds(self): self.assertTrue(pem_contents in [pkcs12_key_as_pem, alternate_pem]) def test_without_openssl(self): - openssl_mod = sys.modules['OpenSSL'] + import os + path_isfile = os.path.isfile try: - sys.modules['OpenSSL'] = None + os.path.isfile = lambda value: False reload(crypt) self.assertRaises(NotImplementedError, crypt.pkcs12_key_as_pem, 'FOO', 'BAR') finally: - sys.modules['OpenSSL'] = openssl_mod + os.path.isfile = path_isfile reload(crypt) def test_with_nonsense_key(self): + from OpenSSL import crypto credentials = self._make_signed_jwt_creds(private_key=b'NOT_A_KEY') - self.assertRaises(crypt.crypto.Error, crypt.pkcs12_key_as_pem, + self.assertRaises(crypto.Error, crypt.pkcs12_key_as_pem, credentials.private_key, credentials.private_key_password)