Deferring OpenSSL import until usage.
This is to speed up import times. In OpenSSL 0.14 the import takes 0.5 seconds due to cffi on-demand build of extensions in the cryptography library. For classes and functions which are conditionally defined based on the existence of OpenSSL.crypto, we check that the module exists (but don't import it) using imp.find_module.
This commit is contained in:
@@ -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,9 @@ 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')
|
||||
|
||||
class OpenSSLVerifier(object):
|
||||
"""Verifies the signature on a message."""
|
||||
@@ -61,6 +65,7 @@ try:
|
||||
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 +89,7 @@ try:
|
||||
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 +117,7 @@ try:
|
||||
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 +136,7 @@ try:
|
||||
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 +157,7 @@ try:
|
||||
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')
|
||||
|
||||
@@ -58,17 +58,19 @@ class Test_pkcs12_key_as_pem(unittest.TestCase):
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user