Revize 94e89bb1
Přidáno uživatelem Jan Pašek před téměř 4 roky(ů)
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
Re #8576 - calling CryptographyService from CrlService, passphrase support