test_ca.py 5.29 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
from OpenSSL import crypto
import unittest
import os

from autoca import ca
from autoca import certutil
from autoca.test import *


class CaTest(CaTestBase):

    def test_sanity_checks(self):
        self.assertTrue(os.path.exists(self.ca.storage.ca_key_path))
        self.assertTrue(os.path.exists(self.ca.storage.ca_crt_path))

        # Test subject attributes of the CA certificate.
        with open(self.ca.storage.ca_crt_path, 'r') as fd:
            cacrt = crypto.load_certificate(crypto.FILETYPE_PEM, fd.read())
        subj = cacrt.get_subject()
        self.assertEquals('Test CA', subj.CN)
        self.assertEquals('Test Corp.', subj.O)
        self.assertEquals('IE', subj.L)

        # Test fetching a non-existing certificate.
        self.assertEquals(None, self.ca.get_certificate('missing'))

    def test_reinit(self):
        ca2 = ca.CA(self.tmpdir, self.ca_subject, bits=1024)
        self.assertEquals(self.ca.public_ca_pem, ca2.public_ca_pem)

31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
    def test_get_ca(self):
        self.assertEquals(self.ca.public_ca_pem,
                          self.ca.get_ca())

    def test_get_crl_pem(self):
        crl_pem = self.ca.get_crl(format='pem')
        status, output = self._run_openssl(
            'crl -inform PEM -noout -text', crl_pem)
        self.assertEquals(0, status)
        self.assertTrue('No Revoked Certificates.' in output)

    def test_get_crl_der(self):
        crl_pem = self.ca.get_crl(format='der')
        status, output = self._run_openssl(
            'crl -inform DER -noout -text', crl_pem)
        self.assertEquals(0, status)
        self.assertTrue('No Revoked Certificates.' in output)

    def test_get_missing_certificate(self):
        result = self.ca.get_certificate('missing', raw=False)
        self.assertEquals(None, result)
        result = self.ca.get_certificate('missing', raw=True)
        self.assertEquals(None, result)

    def test_get_missing_serial(self):
        result = self.ca.get_serial('missing')
        self.assertEquals(None, result)

    def test_make_certificate(self):
        pkey, crt = self.ca.make_certificate({'CN': 'testcn'})
        self.assertEquals('testcn', crt.get_subject().CN)

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    def test_sign_certificate(self):
        pkey = certutil.create_rsa_key_pair()
        request = certutil.create_cert_request(pkey, CN='testcn')
        result = self.ca.sign_certificate(request)
        self.assertTrue(result is not None)
        self.assertEquals('testcn', result.get_subject().CN)

        # Check that the certificate is now stored in the CA db.
        result2 = self.ca.get_certificate('testcn')
        self.assertTrue(result2 is not None)
        
        # Check the serial number.
        serial_no = self.ca.get_serial('testcn')
        self.assertTrue(int(serial_no) > 1)

    def test_sign_certificate_twice(self):
        pkey = certutil.create_rsa_key_pair()
        request = certutil.create_cert_request(pkey, CN='testcn')
        result = self.ca.sign_certificate(request)
        self.assertTrue(result is not None)
        serial_no = int(result.get_serial_number())

        pkey2 = certutil.create_rsa_key_pair()
        request2 = certutil.create_cert_request(pkey2, CN='testcn')
        result2 = self.ca.sign_certificate(request)
        self.assertTrue(result2 is not None)
        serial_no2 = int(result2.get_serial_number())

        # Check that we have the same CN.
        self.assertEquals(result.get_subject().CN,
                          result2.get_subject().CN)

        # Check that the serial numbers are monotonically incrementing.
        self.assertNotEquals(serial_no, serial_no2)
        self.assertTrue(serial_no2 > serial_no)

        # Check that get_certificate() returns the latest cert.
        self.assertEquals(serial_no2,
                          self.ca.get_serial('testcn'))

        # Check that a CRL file has been generated.
        self.assertTrue(os.path.exists(self.ca.storage.crl_path))

    def test_revoke_certificate(self):
        pkey = certutil.create_rsa_key_pair()
        request = certutil.create_cert_request(pkey, CN='testcn')
        result = self.ca.sign_certificate(request)
        self.assertTrue(result is not None)
        self.assertEquals('testcn', result.get_subject().CN)
112
        serial = result.get_serial_number()
113 114 115 116 117 118 119 120 121 122

        # Check that the certificate is now stored in the CA db.
        result2 = self.ca.get_certificate('testcn')
        self.assertTrue(result2 is not None)
        
        self.ca.revoke_certificate('testcn')

        result3 = self.ca.get_certificate('testcn')
        self.assertEquals(None, result3)

123 124 125 126 127 128 129 130 131
        # Check that the serial appears in the revocation list.
        revoked = set(x[0] for x in self.ca.storage.get_revoked())
        self.assertTrue(serial in revoked)

        # Try to revoke it twice, expect no errors. Detect unexpected
        # calls to _update_crl and raise an exception.
        def unexpected(x):
            raise Exception('unexpected call')
        self.ca._update_crl = unexpected
132 133
        self.ca.revoke_certificate('testcn')

134 135 136 137 138 139 140
        # Examine the CRL and verify that it contains the serial.
        crl = self.ca.get_crl(format='pem')
        status, output = self._run_openssl(
            'crl -inform PEM -noout -text', crl)
        self.assertEquals(0, status)
        self.assertTrue(str(serial) in output)

141 142 143

if __name__ == '__main__':
    unittest.main()