Projekt

Obecné

Profil

« Předchozí | Další » 

Revize 94e89bb1

Přidáno uživatelem Jan Pašek před téměř 4 roky(ů)

Re #8576 - calling CryptographyService from CrlService, passphrase support

Zobrazit rozdíly:

src/constants.py
56 56
# available certificate states and revocation reasons
57 57
CERTIFICATE_STATES = {"valid", "revoked"}
58 58
CERTIFICATE_REVOCATION_REASONS = {"unspecified", "keyCompromise",
59
                                  "cACompromise", "affiliationChanged",
59
                                  "CACompromise", "affiliationChanged",
60 60
                                  "superseded", "cessationOfOperation",
61
                                  "certificateHold", "removeFromCRL",
62
                                  "privilegeWithdrawn", "aACompromise"}
61
                                  "certificateHold", "removeFromCRL"}
63 62

  
64 63

  
65 64
# Insert values into the template using % (index_file, serial_file)
src/exceptions/private_key_not_found_exception.py
1
class PrivateKeyNotFoundException(Exception):
2
    """
3
    Exception that denotes that the caller was trying to set
4
    work with non-existing private key
5
    """
6

  
7
    def __init__(self, id):
8
        self.id = id
9

  
10
    def __str__(self):
11
        return f"PrivateKey with id '{self.id}' does not exist."
src/services/crl/crl_service.py
3 3
from injector import inject
4 4

  
5 5
from src.dao.certificate_repository import CertificateRepository
6
from src.dao.private_key_repository import PrivateKeyRepository
6 7
from src.exceptions.certificate_not_found_exception import CertificateNotFoundException
8
from src.exceptions.private_key_not_found_exception import PrivateKeyNotFoundException
7 9
from src.services.crl.ca_index_file_line_generator import create_index_file_revoked_line
8 10
from src.services.cryptography import CryptographyService
9 11
from src.utils.temporary_file import TemporaryFile
......
13 15
    @inject
14 16
    def __init__(self,
15 17
                 certificate_repository: CertificateRepository,
18
                 key_repository: PrivateKeyRepository,
16 19
                 cryptography_service: CryptographyService
17 20
                 ):
21
        self.key_repository = key_repository
18 22
        self.certificate_repository = certificate_repository
19 23
        self.cryptography_service = cryptography_service
20 24

  
......
53 57
        :param ca_id: ID of a CA whose CRL shall be generated
54 58
        :return: CRL in PEM format
55 59
        """
56
        # check if the requested CA exists and if not throw an exception
57
        if self.certificate_repository.read(ca_id) is None:
60
        # get cert and check if the requested CA exists and if not throw an exception
61
        cert = self.certificate_repository.read(ca_id)
62
        if cert is None:
58 63
            raise CertificateNotFoundException(ca_id)
59 64

  
65
        # get key and check if it exists
66
        key = self.key_repository.read(cert.private_key_id)
67
        if key is None:
68
            raise PrivateKeyNotFoundException(ca_id)
69

  
60 70
        # Create an index file and call cryptography service to generate CRL
61
        with TemporaryFile("crl.index", self.create_revoked_index(ca_id)) as index_path:
62
            crl_content = self.cryptography_service.generate_crl(index_path)
71
        with TemporaryFile("crl.index", f"{self.create_revoked_index(ca_id)}\n") as index_path:
72
            crl_content = self.cryptography_service.generate_crl(cert, key, index_path)
63 73

  
64 74
        return crl_content
src/services/cryptography.py
374 374
             TemporaryFile("private_key.pem", key.private_key) as key_file:
375 375

  
376 376
            args = ["ca", "-config", config_file, "-gencrl", "-keyfile", key_file, "-cert", cert_file, "-outdir", "."]
377

  
378
            if key.password is not None and key.password != "":
379
                args.extend(["-passin", f"pass:{key.password}"])
380

  
377 381
            return self.__run_for_output(args).decode("utf-8")
378 382

  
379 383

  
tests/integration_tests/services/conftest.py
79 79

  
80 80

  
81 81
@pytest.fixture
82
def crl_service_unique(certificate_repository_unique, cryptography_service):
83
    return CrlService(certificate_repository_unique, cryptography_service)
82
def crl_service_unique(certificate_repository_unique, private_key_repository_unique, cryptography_service):
83
    return CrlService(certificate_repository_unique, private_key_repository_unique, cryptography_service)
tests/integration_tests/services/crl_service_test.py
52 52
    certificate_service_unique.set_certificate_revocation_status(bar_ca.certificate_id, "revoked", "keyCompromise")
53 53
    # revoke the created end certificate (non-CA)
54 54
    certificate_service_unique.set_certificate_revocation_status(baz_cert.certificate_id, "revoked",
55
                                                                 "privilegeWithdrawn")
55
                                                                 "CACompromise")
56 56

  
57 57
    # create index of revoked certificates
58 58
    out = crl_service_unique.create_revoked_index(root_ca_cert.certificate_id)
......
80 80
    expected_lines = [
81 81
        f"R	{valid_to_dates[0]}	{revoked_dates[0]},unspecified	02	unknown	/CN=Foo CA/L=Brno",
82 82
        f"R	{valid_to_dates[1]}	{revoked_dates[1]},keyCompromise	03	unknown	/CN=Bar CA/C=CZ/L=Pilsen",
83
        f"R	{valid_to_dates[2]}	{revoked_dates[2]},privilegeWithdrawn	05	unknown	/CN=Baz CA/ST=ST"
83
        f"R	{valid_to_dates[2]}	{revoked_dates[2]},CACompromise	05	unknown	/CN=Baz CA/ST=ST"
84 84
    ]
85 85

  
86 86
    assert out == "\n".join(expected_lines)
87

  
88
def test_generate_crl_response(certificate_service_unique, private_key_service_unique, crl_service_unique,
89
                               cryptography_service):
90
    root_ca_private_key = private_key_service_unique.create_new_key(passphrase="foobar")
91
    inter_ca_private_key = private_key_service_unique.create_new_key(passphrase="barfoo")
92

  
93
    root_ca_cert = certificate_service_unique.create_root_ca(root_ca_private_key,
94
                                                             Subject(common_name="RootFoo",
95
                                                                     organization_unit="Department of Foo"))
96

  
97
    # create a CA
98
    foo_ca = certificate_service_unique.create_ca(inter_ca_private_key, Subject(common_name="Foo CA", locality="Brno"),
99
                                                  root_ca_cert,
100
                                                  root_ca_private_key)
101

  
102
    # create another CA
103
    bar_ca = certificate_service_unique.create_ca(inter_ca_private_key,
104
                                                  Subject(common_name="Bar CA", country="CZ", locality="Pilsen"),
105
                                                  root_ca_cert,
106
                                                  root_ca_private_key)
107

  
108
    # create another CA
109
    certificate_service_unique.create_ca(inter_ca_private_key, Subject(common_name="BarBaz CA"),
110
                                         root_ca_cert,
111
                                         root_ca_private_key)
112

  
113
    # create a certificate
114
    baz_cert = certificate_service_unique.create_end_cert(inter_ca_private_key,
115
                                                          Subject(common_name="Baz CA", state="ST"),
116
                                                          root_ca_cert,
117
                                                          root_ca_private_key)
118

  
119
    # revoke first created intermediate CA
120
    certificate_service_unique.set_certificate_revocation_status(foo_ca.certificate_id, "revoked", "unspecified")
121
    # revoke second created intermediate CA
122
    certificate_service_unique.set_certificate_revocation_status(bar_ca.certificate_id, "revoked", "keyCompromise")
123
    # revoke the created end certificate (non-CA)
124
    certificate_service_unique.set_certificate_revocation_status(baz_cert.certificate_id, "revoked",
125
                                                                 "CACompromise")
126

  
127
    crl = crl_service_unique.generate_crl_response(root_ca_cert.certificate_id)
128
    print(crl)

Také k dispozici: Unified diff