From 61aa29d28cfa9d53c15a63c94dbcabc427164571 Mon Sep 17 00:00:00 2001 From: Jakub Warmuz Date: Sun, 5 Jul 2015 20:34:45 +0000 Subject: [PATCH] Drop PyCrypto. --- letsencrypt/crypto_util.py | 9 +++---- .../plugins/standalone/authenticator.py | 2 -- .../standalone/tests/authenticator_test.py | 11 +++----- letsencrypt/revoker.py | 26 +++++++++++-------- letsencrypt/tests/revoker_test.py | 20 +++++++++----- setup.py | 2 -- 6 files changed, 35 insertions(+), 35 deletions(-) diff --git a/letsencrypt/crypto_util.py b/letsencrypt/crypto_util.py index 82b1b4867..3abe2d130 100644 --- a/letsencrypt/crypto_util.py +++ b/letsencrypt/crypto_util.py @@ -8,10 +8,6 @@ import logging import os import time -import Crypto.Hash.SHA256 -import Crypto.PublicKey.RSA -import Crypto.Signature.PKCS1_v1_5 - import M2Crypto import OpenSSL @@ -169,7 +165,10 @@ def make_key(bits): :rtype: str """ - return Crypto.PublicKey.RSA.generate(bits).exportKey(format="PEM") + assert bits >= 1024 # XXX + key = OpenSSL.crypto.PKey() + key.generate_key(OpenSSL.crypto.TYPE_RSA, bits) + return OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, key) def valid_privkey(privkey): diff --git a/letsencrypt/plugins/standalone/authenticator.py b/letsencrypt/plugins/standalone/authenticator.py index 971f90266..a90c02281 100644 --- a/letsencrypt/plugins/standalone/authenticator.py +++ b/letsencrypt/plugins/standalone/authenticator.py @@ -6,7 +6,6 @@ import socket import sys import time -import Crypto.Random import OpenSSL.crypto import OpenSSL.SSL import zope.component @@ -267,7 +266,6 @@ class StandaloneAuthenticator(common.Plugin): sys.stdout.flush() fork_result = os.fork() - Crypto.Random.atfork() if fork_result: # PARENT process (still the Let's Encrypt client process) self.child_pid = fork_result diff --git a/letsencrypt/plugins/standalone/tests/authenticator_test.py b/letsencrypt/plugins/standalone/tests/authenticator_test.py index 1794ff65c..b61482990 100644 --- a/letsencrypt/plugins/standalone/tests/authenticator_test.py +++ b/letsencrypt/plugins/standalone/tests/authenticator_test.py @@ -374,10 +374,8 @@ class StartListenerTest(unittest.TestCase): StandaloneAuthenticator self.authenticator = StandaloneAuthenticator(config=CONFIG, name=None) - @mock.patch("letsencrypt.plugins.standalone.authenticator." - "Crypto.Random.atfork") @mock.patch("letsencrypt.plugins.standalone.authenticator.os.fork") - def test_start_listener_fork_parent(self, mock_fork, mock_atfork): + def test_start_listener_fork_parent(self, mock_fork): self.authenticator.do_parent_process = mock.Mock() self.authenticator.do_parent_process.return_value = True mock_fork.return_value = 22222 @@ -387,12 +385,9 @@ class StartListenerTest(unittest.TestCase): self.assertTrue(result) self.assertEqual(self.authenticator.child_pid, 22222) self.authenticator.do_parent_process.assert_called_once_with(1717) - mock_atfork.assert_called_once_with() - @mock.patch("letsencrypt.plugins.standalone.authenticator." - "Crypto.Random.atfork") @mock.patch("letsencrypt.plugins.standalone.authenticator.os.fork") - def test_start_listener_fork_child(self, mock_fork, mock_atfork): + def test_start_listener_fork_child(self, mock_fork): self.authenticator.do_parent_process = mock.Mock() self.authenticator.do_child_process = mock.Mock() mock_fork.return_value = 0 @@ -400,7 +395,7 @@ class StartListenerTest(unittest.TestCase): self.assertEqual(self.authenticator.child_pid, os.getpid()) self.authenticator.do_child_process.assert_called_once_with( 1717, "key") - mock_atfork.assert_called_once_with() + class DoParentProcessTest(unittest.TestCase): """Tests for do_parent_process() method.""" diff --git a/letsencrypt/revoker.py b/letsencrypt/revoker.py index 9faf9339c..d8bec5fff 100644 --- a/letsencrypt/revoker.py +++ b/letsencrypt/revoker.py @@ -13,8 +13,8 @@ import os import shutil import tempfile -import Crypto.PublicKey.RSA import M2Crypto +import OpenSSL from acme.jose import util as jose_util @@ -70,10 +70,11 @@ class Revoker(object): """ certs = [] try: - clean_pem = Crypto.PublicKey.RSA.importKey( - authkey.pem).exportKey("PEM") - # https://www.dlitz.net/software/pycrypto/api/current/Crypto.PublicKey.RSA-module.html - except (IndexError, ValueError, TypeError): + clean_pem = OpenSSL.crypto.dump_privatekey( + OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.load_privatekey( + OpenSSL.crypto.FILETYPE_PEM, authkey.pem)) + except OpenSSL.crypto.Error as error: + logger.debug(error, exc_info=True) raise errors.RevokerError( "Invalid key file specified to revoke_from_key") @@ -86,9 +87,11 @@ class Revoker(object): # certificate. _, b_k = self._row_to_backup(row) try: - test_pem = Crypto.PublicKey.RSA.importKey( - open(b_k).read()).exportKey("PEM") - except (IndexError, ValueError, TypeError): + test_pem = OpenSSL.crypto.dump_privatekey( + OpenSSL.crypto.FILETYPE_PEM, OpenSSL.crypto.load_privatekey( + OpenSSL.crypto.FILETYPE_PEM, open(b_k).read())) + except OpenSSL.crypto.Error as error: + logger.debug(error, exc_info=True) # This should never happen given the assumptions of the # module. If it does, it is probably best to delete the # the offending key/cert. For now... just raise an exception @@ -248,10 +251,11 @@ class Revoker(object): certificate = jose_util.ComparableX509(cert._cert) try: with open(cert.backup_key_path, "rU") as backup_key_file: - key = Crypto.PublicKey.RSA.importKey(backup_key_file.read()) - + key = OpenSSL.crypto.load_privatekey( + OpenSSL.crypto.FILETYPE_PEM, backup_key_file.read()) # If the key file doesn't exist... or is corrupted - except (IndexError, ValueError, TypeError): + except OpenSSL.crypto.Error as error: + logger.debug(error, exc_info=True) raise errors.RevokerError( "Corrupted backup key file: %s" % cert.backup_key_path) diff --git a/letsencrypt/tests/revoker_test.py b/letsencrypt/tests/revoker_test.py index 893865ce9..ae4eaa900 100644 --- a/letsencrypt/tests/revoker_test.py +++ b/letsencrypt/tests/revoker_test.py @@ -7,12 +7,18 @@ import tempfile import unittest import mock +import OpenSSL from letsencrypt import errors from letsencrypt import le_util from letsencrypt.display import util as display_util +KEY = OpenSSL.crypto.load_privatekey( + OpenSSL.crypto.FILETYPE_PEM, pkg_resources.resource_string( + __name__, os.path.join("testdata", "rsa512_key.pem"))) + + class RevokerBase(unittest.TestCase): # pylint: disable=too-few-public-methods """Base Class for Revoker Tests.""" def setUp(self): @@ -77,13 +83,13 @@ class RevokerTest(RevokerBase): self.assertEqual(mock_net.call_count, 2) - @mock.patch("letsencrypt.revoker.Crypto.PublicKey.RSA.importKey") - def test_revoke_by_invalid_keys(self, mock_import): - mock_import.side_effect = ValueError + @mock.patch("letsencrypt.revoker.OpenSSL.crypto.load_privatekey") + def test_revoke_by_invalid_keys(self, mock_load_privatekey): + mock_load_privatekey.side_effect = OpenSSL.crypto.Error self.assertRaises( errors.RevokerError, self.revoker.revoke_from_key, self.key) - mock_import.side_effect = [mock.Mock(), IndexError] + mock_load_privatekey.side_effect = [KEY, OpenSSL.crypto.Error] self.assertRaises( errors.RevokerError, self.revoker.revoke_from_key, self.key) @@ -192,10 +198,10 @@ class RevokerTest(RevokerBase): self.revoker._safe_revoke(self.certs) self.assertTrue(mock_log.error.called) - @mock.patch("letsencrypt.revoker.Crypto.PublicKey.RSA.importKey") - def test_acme_revoke_failure(self, mock_crypto): + @mock.patch("letsencrypt.revoker.OpenSSL.crypto.load_privatekey") + def test_acme_revoke_failure(self, mock_load_privatekey): # pylint: disable=protected-access - mock_crypto.side_effect = ValueError + mock_load_privatekey.side_effect = OpenSSL.crypto.Error self.assertRaises( errors.Error, self.revoker._acme_revoke, self.certs[0]) diff --git a/setup.py b/setup.py index 7b4cc5068..b80983f24 100644 --- a/setup.py +++ b/setup.py @@ -57,7 +57,6 @@ letsencrypt_install_requires = [ 'mock', 'parsedatetime', 'psutil>=2.1.0', # net_connections introduced in 2.1.0 - 'pycrypto', # https://pyopenssl.readthedocs.org/en/latest/api/crypto.html#OpenSSL.crypto.X509Req.get_extensions 'PyOpenSSL>=0.15', 'pyrfc3339', @@ -93,7 +92,6 @@ install_requires = [ 'parsedatetime', 'psutil>=2.1.0', # net_connections introduced in 2.1.0 'pyasn1', # urllib3 InsecurePlatformWarning (#304) - 'pycrypto', # https://pyopenssl.readthedocs.org/en/latest/api/crypto.html#OpenSSL.crypto.X509Req.get_extensions 'PyOpenSSL>=0.15', 'pyparsing>=1.5.5', # Python3 support; perhaps unnecessary?