Viewing file: crypto_util_test.py (13.56 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
"""Tests for certbot.crypto_util.""" import logging import os import unittest
import OpenSSL import mock import zope.component
from certbot import errors from certbot import interfaces from certbot import util import certbot.tests.util as test_util
RSA256_KEY = test_util.load_vector('rsa256_key.pem') RSA256_KEY_PATH = test_util.vector_path('rsa256_key.pem') RSA512_KEY = test_util.load_vector('rsa512_key.pem') RSA2048_KEY_PATH = test_util.vector_path('rsa2048_key.pem') CERT_PATH = test_util.vector_path('cert_512.pem') CERT = test_util.load_vector('cert_512.pem') SS_CERT_PATH = test_util.vector_path('cert_2048.pem') SS_CERT = test_util.load_vector('cert_2048.pem') P256_KEY = test_util.load_vector('nistp256_key.pem') P256_CERT_PATH = test_util.vector_path('cert-nosans_nistp256.pem') P256_CERT = test_util.load_vector('cert-nosans_nistp256.pem')
class InitSaveKeyTest(test_util.TempDirTestCase): """Tests for certbot.crypto_util.init_save_key.""" def setUp(self): super(InitSaveKeyTest, self).setUp()
logging.disable(logging.CRITICAL) zope.component.provideUtility( mock.Mock(strict_permissions=True), interfaces.IConfig)
def tearDown(self): super(InitSaveKeyTest, self).tearDown()
logging.disable(logging.NOTSET)
@classmethod def _call(cls, key_size, key_dir): from certbot.crypto_util import init_save_key return init_save_key(key_size, key_dir, 'key-certbot.pem')
@mock.patch('certbot.crypto_util.make_key') def test_success(self, mock_make): mock_make.return_value = b'key_pem' key = self._call(1024, self.tempdir) self.assertEqual(key.pem, b'key_pem') self.assertTrue('key-certbot.pem' in key.file) self.assertTrue(os.path.exists(os.path.join(self.tempdir, key.file)))
@mock.patch('certbot.crypto_util.make_key') def test_key_failure(self, mock_make): mock_make.side_effect = ValueError self.assertRaises(ValueError, self._call, 431, self.tempdir)
class InitSaveCSRTest(test_util.TempDirTestCase): """Tests for certbot.crypto_util.init_save_csr."""
def setUp(self): super(InitSaveCSRTest, self).setUp()
zope.component.provideUtility( mock.Mock(strict_permissions=True), interfaces.IConfig)
@mock.patch('acme.crypto_util.make_csr') @mock.patch('certbot.crypto_util.util.make_or_verify_dir') def test_it(self, unused_mock_verify, mock_csr): from certbot.crypto_util import init_save_csr
mock_csr.return_value = b'csr_pem'
csr = init_save_csr( mock.Mock(pem='dummy_key'), 'example.com', self.tempdir)
self.assertEqual(csr.data, b'csr_pem') self.assertTrue('csr-certbot.pem' in csr.file)
class ValidCSRTest(unittest.TestCase): """Tests for certbot.crypto_util.valid_csr."""
@classmethod def _call(cls, csr): from certbot.crypto_util import valid_csr return valid_csr(csr)
def test_valid_pem_true(self): self.assertTrue(self._call(test_util.load_vector('csr_512.pem')))
def test_valid_pem_san_true(self): self.assertTrue(self._call(test_util.load_vector('csr-san_512.pem')))
def test_valid_der_false(self): self.assertFalse(self._call(test_util.load_vector('csr_512.der')))
def test_empty_false(self): self.assertFalse(self._call(''))
def test_random_false(self): self.assertFalse(self._call('foo bar'))
class CSRMatchesPubkeyTest(unittest.TestCase): """Tests for certbot.crypto_util.csr_matches_pubkey."""
@classmethod def _call(cls, *args, **kwargs): from certbot.crypto_util import csr_matches_pubkey return csr_matches_pubkey(*args, **kwargs)
def test_valid_true(self): self.assertTrue(self._call( test_util.load_vector('csr_512.pem'), RSA512_KEY))
def test_invalid_false(self): self.assertFalse(self._call( test_util.load_vector('csr_512.pem'), RSA256_KEY))
class ImportCSRFileTest(unittest.TestCase): """Tests for certbot.certbot_util.import_csr_file."""
@classmethod def _call(cls, *args, **kwargs): from certbot.crypto_util import import_csr_file return import_csr_file(*args, **kwargs)
def test_der_csr(self): csrfile = test_util.vector_path('csr_512.der') data = test_util.load_vector('csr_512.der') data_pem = test_util.load_vector('csr_512.pem')
self.assertEqual( (OpenSSL.crypto.FILETYPE_PEM, util.CSR(file=csrfile, data=data_pem, form="pem"), ["Example.com"]), self._call(csrfile, data))
def test_pem_csr(self): csrfile = test_util.vector_path('csr_512.pem') data = test_util.load_vector('csr_512.pem')
self.assertEqual( (OpenSSL.crypto.FILETYPE_PEM, util.CSR(file=csrfile, data=data, form="pem"), ["Example.com"],), self._call(csrfile, data))
def test_bad_csr(self): self.assertRaises(errors.Error, self._call, test_util.vector_path('cert_512.pem'), test_util.load_vector('cert_512.pem'))
class MakeKeyTest(unittest.TestCase): # pylint: disable=too-few-public-methods """Tests for certbot.crypto_util.make_key."""
def test_it(self): # pylint: disable=no-self-use from certbot.crypto_util import make_key # Do not test larger keys as it takes too long. OpenSSL.crypto.load_privatekey( OpenSSL.crypto.FILETYPE_PEM, make_key(1024))
class VerifyCertSetup(unittest.TestCase): """Refactoring for verification tests."""
def setUp(self): super(VerifyCertSetup, self).setUp()
self.renewable_cert = mock.MagicMock() self.renewable_cert.cert = SS_CERT_PATH self.renewable_cert.chain = SS_CERT_PATH self.renewable_cert.privkey = RSA2048_KEY_PATH self.renewable_cert.fullchain = test_util.vector_path('cert_fullchain_2048.pem')
self.bad_renewable_cert = mock.MagicMock() self.bad_renewable_cert.chain = SS_CERT_PATH self.bad_renewable_cert.cert = SS_CERT_PATH self.bad_renewable_cert.fullchain = SS_CERT_PATH
class VerifyRenewableCertTest(VerifyCertSetup): """Tests for certbot.crypto_util.verify_renewable_cert."""
def setUp(self): super(VerifyRenewableCertTest, self).setUp()
def _call(self, renewable_cert): from certbot.crypto_util import verify_renewable_cert return verify_renewable_cert(renewable_cert)
def test_verify_renewable_cert(self): self.assertEqual(None, self._call(self.renewable_cert))
@mock.patch('certbot.crypto_util.verify_renewable_cert_sig', side_effect=errors.Error("")) def test_verify_renewable_cert_failure(self, unused_verify_renewable_cert_sign): self.assertRaises(errors.Error, self._call, self.bad_renewable_cert)
class VerifyRenewableCertSigTest(VerifyCertSetup): """Tests for certbot.crypto_util.verify_renewable_cert."""
def setUp(self): super(VerifyRenewableCertSigTest, self).setUp()
def _call(self, renewable_cert): from certbot.crypto_util import verify_renewable_cert_sig return verify_renewable_cert_sig(renewable_cert)
def test_cert_sig_match(self): self.assertEqual(None, self._call(self.renewable_cert))
def test_cert_sig_match_ec(self): renewable_cert = mock.MagicMock() renewable_cert.cert = P256_CERT_PATH renewable_cert.chain = P256_CERT_PATH renewable_cert.privkey = P256_KEY self.assertEqual(None, self._call(renewable_cert))
def test_cert_sig_mismatch(self): self.bad_renewable_cert.cert = test_util.vector_path('cert_512_bad.pem') self.assertRaises(errors.Error, self._call, self.bad_renewable_cert)
class VerifyFullchainTest(VerifyCertSetup): """Tests for certbot.crypto_util.verify_fullchain."""
def setUp(self): super(VerifyFullchainTest, self).setUp()
def _call(self, renewable_cert): from certbot.crypto_util import verify_fullchain return verify_fullchain(renewable_cert)
def test_fullchain_matches(self): self.assertEqual(None, self._call(self.renewable_cert))
def test_fullchain_mismatch(self): self.assertRaises(errors.Error, self._call, self.bad_renewable_cert)
def test_fullchain_ioerror(self): self.bad_renewable_cert.chain = "dog" self.assertRaises(errors.Error, self._call, self.bad_renewable_cert)
class VerifyCertMatchesPrivKeyTest(VerifyCertSetup): """Tests for certbot.crypto_util.verify_cert_matches_priv_key."""
def setUp(self): super(VerifyCertMatchesPrivKeyTest, self).setUp()
def _call(self, renewable_cert): from certbot.crypto_util import verify_cert_matches_priv_key return verify_cert_matches_priv_key(renewable_cert.cert, renewable_cert.privkey)
def test_cert_priv_key_match(self): self.renewable_cert.cert = SS_CERT_PATH self.renewable_cert.privkey = RSA2048_KEY_PATH self.assertEqual(None, self._call(self.renewable_cert))
def test_cert_priv_key_mismatch(self): self.bad_renewable_cert.privkey = RSA256_KEY_PATH self.bad_renewable_cert.cert = SS_CERT_PATH
self.assertRaises(errors.Error, self._call, self.bad_renewable_cert)
class ValidPrivkeyTest(unittest.TestCase): """Tests for certbot.crypto_util.valid_privkey."""
@classmethod def _call(cls, privkey): from certbot.crypto_util import valid_privkey return valid_privkey(privkey)
def test_valid_true(self): self.assertTrue(self._call(RSA512_KEY))
def test_empty_false(self): self.assertFalse(self._call(''))
def test_random_false(self): self.assertFalse(self._call('foo bar'))
class GetSANsFromCertTest(unittest.TestCase): """Tests for certbot.crypto_util.get_sans_from_cert."""
@classmethod def _call(cls, *args, **kwargs): from certbot.crypto_util import get_sans_from_cert return get_sans_from_cert(*args, **kwargs)
def test_single(self): self.assertEqual([], self._call(test_util.load_vector('cert_512.pem')))
def test_san(self): self.assertEqual( ['example.com', 'www.example.com'], self._call(test_util.load_vector('cert-san_512.pem')))
class GetNamesFromCertTest(unittest.TestCase): """Tests for certbot.crypto_util.get_names_from_cert."""
@classmethod def _call(cls, *args, **kwargs): from certbot.crypto_util import get_names_from_cert return get_names_from_cert(*args, **kwargs)
def test_single(self): self.assertEqual( ['example.com'], self._call(test_util.load_vector('cert_512.pem')))
def test_san(self): self.assertEqual( ['example.com', 'www.example.com'], self._call(test_util.load_vector('cert-san_512.pem')))
def test_common_name_sans_order(self): # Tests that the common name comes first # followed by the SANS in alphabetical order self.assertEqual( ['example.com'] + ['{0}.example.com'.format(c) for c in 'abcd'], self._call(test_util.load_vector('cert-5sans_512.pem')))
def test_parse_non_cert(self): self.assertRaises(OpenSSL.crypto.Error, self._call, "hello there")
class CertLoaderTest(unittest.TestCase): """Tests for certbot.crypto_util.pyopenssl_load_certificate"""
def test_load_valid_cert(self): from certbot.crypto_util import pyopenssl_load_certificate
cert, file_type = pyopenssl_load_certificate(CERT) self.assertEqual(cert.digest('sha256'), OpenSSL.crypto.load_certificate(file_type, CERT).digest('sha256'))
def test_load_invalid_cert(self): from certbot.crypto_util import pyopenssl_load_certificate bad_cert_data = CERT.replace(b"BEGIN CERTIFICATE", b"ASDFASDFASDF!!!") self.assertRaises( errors.Error, pyopenssl_load_certificate, bad_cert_data)
class NotBeforeTest(unittest.TestCase): """Tests for certbot.crypto_util.notBefore"""
def test_notBefore(self): from certbot.crypto_util import notBefore self.assertEqual(notBefore(CERT_PATH).isoformat(), '2014-12-11T22:34:45+00:00')
class NotAfterTest(unittest.TestCase): """Tests for certbot.crypto_util.notAfter"""
def test_notAfter(self): from certbot.crypto_util import notAfter self.assertEqual(notAfter(CERT_PATH).isoformat(), '2014-12-18T22:34:45+00:00')
class Sha256sumTest(unittest.TestCase): """Tests for certbot.crypto_util.notAfter""" def test_sha256sum(self): from certbot.crypto_util import sha256sum self.assertEqual(sha256sum(CERT_PATH), '914ffed8daf9e2c99d90ac95c77d54f32cbd556672facac380f0c063498df84e')
class CertAndChainFromFullchainTest(unittest.TestCase): """Tests for certbot.crypto_util.cert_and_chain_from_fullchain"""
def test_cert_and_chain_from_fullchain(self): cert_pem = CERT.decode() chain_pem = cert_pem + SS_CERT.decode() fullchain_pem = cert_pem + chain_pem spacey_fullchain_pem = cert_pem + u'\n' + chain_pem from certbot.crypto_util import cert_and_chain_from_fullchain for fullchain in (fullchain_pem, spacey_fullchain_pem): cert_out, chain_out = cert_and_chain_from_fullchain(fullchain) self.assertEqual(cert_out, cert_pem) self.assertEqual(chain_out, chain_pem)
if __name__ == '__main__': unittest.main() # pragma: no cover
|