Revize e39e138f
Přidáno uživatelem Stanislav Král před asi 4 roky(ů)
src/db/init_queries.py | ||
---|---|---|
1 |
SCHEMA_SQL = """ |
|
2 |
/* ---------------------------------------------------- */ |
|
3 |
/* Generated by Enterprise Architect Version 13.5 */ |
|
4 |
/* Created On : 01-dub-2021 15:16:53 */ |
|
5 |
/* DBMS : SQLite */ |
|
6 |
/* ---------------------------------------------------- */ |
|
7 |
|
|
8 |
/* Drop Tables */ |
|
9 |
|
|
10 |
DROP TABLE IF EXISTS 'PrivateKeys' |
|
11 |
; |
|
12 |
|
|
13 |
DROP TABLE IF EXISTS 'CertificateTypes' |
|
14 |
; |
|
15 |
|
|
16 |
DROP TABLE IF EXISTS 'UsageTypes' |
|
17 |
; |
|
18 |
|
|
19 |
DROP TABLE IF EXISTS 'Certificates' |
|
20 |
; |
|
21 |
|
|
22 |
DROP TABLE IF EXISTS 'CertificateUsages' |
|
23 |
; |
|
24 |
|
|
25 |
/* Create Tables with Primary and Foreign Keys, Check and Unique Constraints */ |
|
26 |
|
|
27 |
CREATE TABLE 'PrivateKeys' |
|
28 |
( |
|
29 |
'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, |
|
30 |
'private_key' TEXT NOT NULL, |
|
31 |
'password' TEXT NULL |
|
32 |
) |
|
33 |
; |
|
34 |
|
|
35 |
CREATE TABLE 'CertificateTypes' |
|
36 |
( |
|
37 |
'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, |
|
38 |
'certificate_type' TEXT NOT NULL |
|
39 |
) |
|
40 |
; |
|
41 |
|
|
42 |
CREATE TABLE 'UsageTypes' |
|
43 |
( |
|
44 |
'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, |
|
45 |
'usage_type' TEXT NOT NULL |
|
46 |
) |
|
47 |
; |
|
48 |
|
|
49 |
CREATE TABLE 'Certificates' |
|
50 |
( |
|
51 |
'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, |
|
52 |
'common_name' TEXT NOT NULL, |
|
53 |
'valid_from' TEXT NOT NULL, |
|
54 |
'valid_to' TEXT NOT NULL, |
|
55 |
'pem_data' TEXT NOT NULL, |
|
56 |
'private_key_id' INTEGER NOT NULL, |
|
57 |
'certificate_type_id' INTEGER NOT NULL, |
|
58 |
'parent_certificate_id' INTEGER NOT NULL, |
|
59 |
CONSTRAINT 'FK_Certificates' FOREIGN KEY ('parent_certificate_id') REFERENCES 'Certificates' ('id') ON DELETE No Action ON UPDATE No Action, |
|
60 |
CONSTRAINT 'FK_CertificateTypes' FOREIGN KEY ('certificate_type_id') REFERENCES 'CertificateTypes' ('id') ON DELETE No Action ON UPDATE No Action, |
|
61 |
CONSTRAINT 'FK_PrivateKeys' FOREIGN KEY ('private_key_id') REFERENCES 'PrivateKeys' ('id') ON DELETE No Action ON UPDATE No Action |
|
62 |
) |
|
63 |
; |
|
64 |
|
|
65 |
CREATE TABLE 'CertificateUsages' |
|
66 |
( |
|
67 |
'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, |
|
68 |
'certificate_id' INTEGER NOT NULL, |
|
69 |
'usage_type_id' INTEGER NOT NULL, |
|
70 |
CONSTRAINT 'FK_Certificates' FOREIGN KEY ('certificate_id') REFERENCES 'Certificates' ('id') ON DELETE Cascade ON UPDATE No Action, |
|
71 |
CONSTRAINT 'FK_UsageTypes' FOREIGN KEY ('usage_type_id') REFERENCES 'UsageTypes' ('id') ON DELETE No Action ON UPDATE No Action |
|
72 |
) |
|
73 |
; |
|
74 |
|
|
75 |
""" |
|
76 |
|
|
77 |
DEFAULT_VALUES_SQL = """ |
|
78 |
/* ---------------------------------------------------- */ |
|
79 |
/* Generated by Enterprise Architect Version 13.5 */ |
|
80 |
/* Created On : 26-bře-2021 13:33:05 */ |
|
81 |
/* DBMS : SQLite */ |
|
82 |
/* ---------------------------------------------------- */ |
|
83 |
|
|
84 |
/* Insert default values */ |
|
85 |
|
|
86 |
INSERT INTO CertificateTypes(certificate_type) VALUES('ROOT_CA'); |
|
87 |
INSERT INTO CertificateTypes(certificate_type) VALUES('INTERMEDIATE_CA'); |
|
88 |
INSERT INTO CertificateTypes(certificate_type) VALUES('CERTIFICATE'); |
|
89 |
|
|
90 |
INSERT INTO UsageTypes(usage_type) VALUES('CA'); |
|
91 |
INSERT INTO UsageTypes(usage_type) VALUES('SSL'); |
|
92 |
INSERT INTO UsageTypes(usage_type) VALUES('SIGNATURE'); |
|
93 |
INSERT INTO UsageTypes(usage_type) VALUES('AUTHENTICATION'); |
|
94 |
|
|
95 |
""" |
tests/dao/certificate_repository/conftest.py | ||
---|---|---|
1 |
import pytest |
|
2 |
import sqlite3 |
|
3 |
from sqlite3 import Connection, Cursor |
|
4 |
|
|
5 |
from src.dao.certificate_repository import CertificateRepository |
|
6 |
from src.constants import DATABASE_FILE |
|
7 |
|
|
8 |
|
|
9 |
@pytest.fixture |
|
10 |
def repository(): |
|
11 |
connection: Connection = sqlite3.connect("../../../" + DATABASE_FILE) |
|
12 |
cursor: Cursor = connection.cursor() |
|
13 |
return CertificateRepository(connection, cursor) |
tests/dao/certificate_repository/create_certificate.py | ||
---|---|---|
1 |
import pytest |
|
2 |
from src.constants import * |
|
3 |
|
|
4 |
|
|
5 |
def test_connection(repository): |
|
6 |
sql = f"SELECT * FROM {TAB_CERTIFICATE_TYPES}" |
|
7 |
repository.cursor.execute(sql) |
|
8 |
selected_rows = repository.cursor.fetchall() |
|
9 |
|
|
10 |
assert len(selected_rows) > 1 |
|
11 |
assert selected_rows[ROOT_CA_ID - 1][1] == "ROOT_CA" |
|
12 |
assert selected_rows[INTERMEDIATE_CA_ID - 1][1] == "INTERMEDIATE_CA" |
|
13 |
assert selected_rows[CERTIFICATE_ID - 1][1] == "CERTIFICATE" |
tests/integration_tests/dao/certificate_repository/conftest.py | ||
---|---|---|
1 |
import pytest |
|
2 |
import sqlite3 |
|
3 |
from sqlite3 import Connection, Cursor |
|
4 |
|
|
5 |
from src.dao.certificate_repository import CertificateRepository |
|
6 |
from src.constants import DATABASE_FILE |
|
7 |
|
|
8 |
|
|
9 |
@pytest.fixture |
|
10 |
def repository(): |
|
11 |
connection: Connection = sqlite3.connect("../../../" + DATABASE_FILE) |
|
12 |
cursor: Cursor = connection.cursor() |
|
13 |
return CertificateRepository(connection, cursor) |
tests/integration_tests/dao/certificate_repository/create_certificate.py | ||
---|---|---|
1 |
import pytest |
|
2 |
from src.constants import * |
|
3 |
|
|
4 |
|
|
5 |
def test_connection(repository): |
|
6 |
sql = f"SELECT * FROM {TAB_CERTIFICATE_TYPES}" |
|
7 |
repository.cursor.execute(sql) |
|
8 |
selected_rows = repository.cursor.fetchall() |
|
9 |
|
|
10 |
assert len(selected_rows) > 1 |
|
11 |
assert selected_rows[ROOT_CA_ID - 1][1] == "ROOT_CA" |
|
12 |
assert selected_rows[INTERMEDIATE_CA_ID - 1][1] == "INTERMEDIATE_CA" |
|
13 |
assert selected_rows[CERTIFICATE_ID - 1][1] == "CERTIFICATE" |
tests/integration_tests/services/certificate_key_service_test.py | ||
---|---|---|
1 |
from src.model.subject import Subject |
|
2 |
|
|
3 |
|
|
4 |
def test_connection(private_key_service, certificate_service): |
|
5 |
private_key = private_key_service.create_new_key(passphrase="foobar") |
|
6 |
|
|
7 |
cert = certificate_service.create_root_ca(private_key, |
|
8 |
Subject(common_name="FooName", organization_unit="Department of Foo")) |
|
9 |
|
|
10 |
|
|
11 |
def test_connection_2(private_key_service, certificate_service): |
|
12 |
private_key = private_key_service.create_new_key(passphrase="foobarbaz") |
|
13 |
|
|
14 |
certificate_service.create_root_ca(private_key, |
|
15 |
Subject(common_name="FooNameD", organization_unit="Department of Foo")) |
tests/integration_tests/services/conftest.py | ||
---|---|---|
1 |
import os |
|
2 |
import sqlite3 |
|
3 |
from sqlite3 import Connection |
|
4 |
|
|
5 |
import pytest |
|
6 |
|
|
7 |
from src.dao.certificate_repository import CertificateRepository |
|
8 |
from src.dao.private_key_repository import PrivateKeyRepository |
|
9 |
from src.db.init_queries import SCHEMA_SQL, DEFAULT_VALUES_SQL |
|
10 |
from src.services.certificate_service import CertificateService |
|
11 |
from src.services.cryptography import CryptographyService |
|
12 |
from src.services.key_service import KeyService |
|
13 |
|
|
14 |
|
|
15 |
# scope="module" means that this fixture is run once per module |
|
16 |
@pytest.fixture(scope="module") |
|
17 |
def connection(): |
|
18 |
print("Creating a new SQLITE connection to the test DB") |
|
19 |
test_db_file = "test.sqlite" |
|
20 |
connection: Connection = sqlite3.connect(test_db_file) |
|
21 |
|
|
22 |
# yield the created connection |
|
23 |
yield connection |
|
24 |
|
|
25 |
# after tests have finished delete the created db file |
|
26 |
try: |
|
27 |
print("Deleting the test DB") |
|
28 |
os.unlink(test_db_file) |
|
29 |
except FileNotFoundError: |
|
30 |
print(f"Could not delete {test_db_file} file containing the test DB") |
|
31 |
pass |
|
32 |
|
|
33 |
|
|
34 |
@pytest.fixture(scope="module") |
|
35 |
def cursor(connection): |
|
36 |
cursor = connection.cursor() |
|
37 |
|
|
38 |
# execute db initialisation script |
|
39 |
cursor.executescript(SCHEMA_SQL) |
|
40 |
|
|
41 |
# insert default values |
|
42 |
cursor.executescript(DEFAULT_VALUES_SQL) |
|
43 |
|
|
44 |
return cursor |
|
45 |
|
|
46 |
|
|
47 |
# scope defaults to "function" which means that the fixture is run once per test (function) |
|
48 |
@pytest.fixture |
|
49 |
def certificate_repository(connection, cursor): |
|
50 |
return CertificateRepository(connection, cursor) |
|
51 |
|
|
52 |
|
|
53 |
@pytest.fixture |
|
54 |
def private_key_repository(connection, cursor): |
|
55 |
return PrivateKeyRepository(connection, cursor) |
|
56 |
|
|
57 |
|
|
58 |
@pytest.fixture |
|
59 |
def cryptography_service(): |
|
60 |
return CryptographyService() |
|
61 |
|
|
62 |
|
|
63 |
@pytest.fixture |
|
64 |
def private_key_service(private_key_repository, cryptography_service): |
|
65 |
return KeyService(cryptography_service, private_key_repository) |
|
66 |
|
|
67 |
|
|
68 |
@pytest.fixture |
|
69 |
def certificate_service(certificate_repository, cryptography_service): |
|
70 |
return CertificateService(cryptography_service, certificate_repository) |
tests/services/certificate/conftest.py | ||
---|---|---|
1 |
import pytest |
|
2 |
import sqlite3 |
|
3 |
import os |
|
4 |
from sqlite3 import Connection, Cursor |
|
5 |
|
|
6 |
from src.dao.certificate_repository import CertificateRepository |
|
7 |
from src.dao.private_key_repository import PrivateKeyRepository |
|
8 |
from src.services.certificate_service import CertificateService |
|
9 |
from src.services.cryptography import CryptographyService |
|
10 |
from src.services.key_service import KeyService |
|
11 |
|
|
12 |
|
|
13 |
@pytest.fixture |
|
14 |
def connection(): |
|
15 |
try: |
|
16 |
os.remove("../../../test.sqlite") |
|
17 |
except FileNotFoundError: |
|
18 |
pass |
|
19 |
connection: Connection = sqlite3.connect("../../../" + "test.sqlite") |
|
20 |
return connection |
|
21 |
|
|
22 |
|
|
23 |
@pytest.fixture |
|
24 |
def cursor(connection): |
|
25 |
cursor = connection.cursor() |
|
26 |
|
|
27 |
# execute db initialisation script |
|
28 |
with open('../../../SQLite_database.sql', 'r') as sql_file: |
|
29 |
sql_script = sql_file.read() |
|
30 |
cursor.executescript(sql_script) |
|
31 |
|
|
32 |
# insert default values |
|
33 |
with open('../../../SQLite_default_values.sql', 'r') as sql_file: |
|
34 |
sql_script = sql_file.read() |
|
35 |
cursor.executescript(sql_script) |
|
36 |
|
|
37 |
return cursor |
|
38 |
|
|
39 |
|
|
40 |
@pytest.fixture |
|
41 |
def certificate_repository(connection, cursor): |
|
42 |
return CertificateRepository(connection, cursor) |
|
43 |
|
|
44 |
|
|
45 |
@pytest.fixture |
|
46 |
def private_key_repository(connection, cursor): |
|
47 |
return PrivateKeyRepository(connection, cursor) |
|
48 |
|
|
49 |
|
|
50 |
@pytest.fixture |
|
51 |
def cryptography_service(): |
|
52 |
return CryptographyService() |
|
53 |
|
|
54 |
|
|
55 |
@pytest.fixture |
|
56 |
def private_key_service(private_key_repository, cryptography_service): |
|
57 |
return KeyService(cryptography_service, private_key_repository) |
|
58 |
|
|
59 |
|
|
60 |
@pytest.fixture |
|
61 |
def certificate_service(certificate_repository, cryptography_service): |
|
62 |
return CertificateService(cryptography_service, certificate_repository) |
tests/services/certificate/integration_test.py | ||
---|---|---|
1 |
from src.model.subject import Subject |
|
2 |
|
|
3 |
|
|
4 |
def test_connection(private_key_service, certificate_service): |
|
5 |
private_key = private_key_service.create_new_key(passphrase="foobar") |
|
6 |
|
|
7 |
certificate_service.create_root_ca(private_key, |
|
8 |
Subject(common_name="FooName", organization_unit="Department of Foo")) |
tests/services/cryptography/conftest.py | ||
---|---|---|
1 |
import pytest |
|
2 |
|
|
3 |
from src.services.cryptography import CryptographyService |
|
4 |
|
|
5 |
|
|
6 |
@pytest.fixture |
|
7 |
def service(): |
|
8 |
# provide a CryptographyService fixture |
|
9 |
return CryptographyService() |
tests/services/cryptography/create_crt_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
import pytest |
|
4 |
|
|
5 |
from src.model.subject import Subject |
|
6 |
from src.services.cryptography import CryptographyException |
|
7 |
|
|
8 |
|
|
9 |
def export_crt(crt): |
|
10 |
return subprocess.check_output(["openssl", "x509", "-noout", "-text", "-in", "-"], |
|
11 |
input=bytes(crt, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
12 |
|
|
13 |
|
|
14 |
def test_sign_cst(service): |
|
15 |
# create root CA |
|
16 |
root_key = service.create_private_key() |
|
17 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key) |
|
18 |
|
|
19 |
# create a private key to be used to make a CSR for the intermediate CA |
|
20 |
inter_key = service.create_private_key() |
|
21 |
|
|
22 |
# create a CA using the root CA |
|
23 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key) |
|
24 |
|
|
25 |
inter_ca_printed = export_crt(inter_ca) |
|
26 |
|
|
27 |
# assert fields |
|
28 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
29 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
30 |
|
|
31 |
|
|
32 |
def test_sign_crt_passphrase(service): |
|
33 |
# create root CA and encrypt the private key of the root CA |
|
34 |
root_key_passphrase = "barbaz" |
|
35 |
root_key = service.create_private_key(passphrase=root_key_passphrase) |
|
36 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key, key_pass=root_key_passphrase) |
|
37 |
|
|
38 |
# create a private key to be used to make a CSR for the intermediate CA |
|
39 |
inter_key_passphrase = "foobazbar" |
|
40 |
inter_key = service.create_private_key(passphrase=inter_key_passphrase) |
|
41 |
|
|
42 |
# create a CA using the root CA |
|
43 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key, |
|
44 |
subject_key_pass=inter_key_passphrase, issuer_key_pass=root_key_passphrase) |
|
45 |
|
|
46 |
inter_ca_printed = export_crt(inter_ca) |
|
47 |
|
|
48 |
# assert fields |
|
49 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
50 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
51 |
|
|
52 |
# some basic incorrect passphrase combinations |
|
53 |
passphrases = [ |
|
54 |
(inter_key, None), |
|
55 |
(inter_key, "foofoobarbar"), |
|
56 |
(None, root_key), |
|
57 |
("foofoobarbar", root_key), |
|
58 |
("foofoobarbar", "foofoobarbar"), |
|
59 |
(None, None) |
|
60 |
] |
|
61 |
|
|
62 |
for (key_pass, issuer_key_pass) in passphrases: |
|
63 |
# try to create it using a wrong issuer passphrase |
|
64 |
with pytest.raises(CryptographyException) as e: |
|
65 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key, |
|
66 |
subject_key_pass=key_pass, issuer_key_pass=issuer_key_pass) |
|
67 |
assert "bad decrypt" in e.value.message |
|
68 |
|
|
69 |
|
|
70 |
def test_sign_crt_extensions(service): |
|
71 |
# create root CA and encrypt the private key of the root CA |
|
72 |
root_key_passphrase = "barbaz" |
|
73 |
root_key = service.create_private_key(passphrase=root_key_passphrase) |
|
74 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key, key_pass=root_key_passphrase) |
|
75 |
|
|
76 |
# create a private key to be used to make a CSR for the intermediate CA |
|
77 |
inter_key_passphrase = "foofoo" |
|
78 |
inter_key = service.create_private_key() |
|
79 |
|
|
80 |
# create a CA using the root CA |
|
81 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key, |
|
82 |
subject_key_pass=inter_key_passphrase, issuer_key_pass=root_key_passphrase, |
|
83 |
extensions="authorityInfoAccess = caIssuers;URI:bar.cz/baz/cert\nbasicConstraints=critical,CA:TRUE") |
|
84 |
|
|
85 |
inter_ca_printed = export_crt(inter_ca) |
|
86 |
|
|
87 |
# assert fields |
|
88 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
89 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
90 |
|
|
91 |
# assert extensions |
|
92 |
expected_extensions = """ X509v3 extensions: |
|
93 |
Authority Information Access: |
|
94 |
CA Issuers - URI:bar.cz/baz/cert |
|
95 |
|
|
96 |
X509v3 Basic Constraints: critical |
|
97 |
CA:TRUE""" |
|
98 |
assert expected_extensions in inter_ca_printed |
tests/services/cryptography/create_csr_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
from src.model.subject import Subject |
|
4 |
|
|
5 |
|
|
6 |
def get_csr_pem(csr): |
|
7 |
return subprocess.check_output(["openssl", "req", "-noout", "-text", "-verify", "-in", "-"], |
|
8 |
input=bytes(csr, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
9 |
|
|
10 |
|
|
11 |
def test_make_csr(service): |
|
12 |
private_key = service.create_private_key() |
|
13 |
|
|
14 |
subject = Subject(common_name="foo", country="CZ") |
|
15 |
csr = service._CryptographyService__create_csr(subject, private_key) |
|
16 |
|
|
17 |
assert "Subject: CN = foo, C = CZ" in get_csr_pem(csr) |
|
18 |
|
|
19 |
|
|
20 |
def test_make_csr_pkey_passphrase(service): |
|
21 |
private_key = service.create_private_key(passphrase="foobar") |
|
22 |
|
|
23 |
subject = Subject(common_name="foo", country="CZ", organization_unit="Mysterious Unit") |
|
24 |
csr = service._CryptographyService__create_csr(subject, private_key, key_pass="foobar") |
|
25 |
|
|
26 |
assert "Subject: CN = foo, C = CZ, OU = Mysterious Unit" in get_csr_pem(csr) |
tests/services/cryptography/parse_cert_pem_test.py | ||
---|---|---|
1 |
from src.model.subject import Subject |
|
2 |
|
|
3 |
|
|
4 |
def test_parse_cert_pem(service): |
|
5 |
cert_pem = """ |
|
6 |
-----BEGIN CERTIFICATE----- |
|
7 |
|
|
8 |
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 |
|
41 |
-----END CERTIFICATE----- |
|
42 |
""" |
|
43 |
|
|
44 |
# parse a certificate supplied in a PEM format |
|
45 |
subj, n_before, n_after = service.parse_cert_pem(cert_pem) |
|
46 |
|
|
47 |
assert 3 == n_before.tm_mon |
|
48 |
assert 21 == n_before.tm_mday |
|
49 |
assert 10 == n_before.tm_hour |
|
50 |
assert 1 == n_before.tm_min |
|
51 |
assert 52 == n_before.tm_sec |
|
52 |
assert 2021 == n_before.tm_year |
|
53 |
|
|
54 |
assert 3 == n_after.tm_mon |
|
55 |
assert 21 == n_after.tm_mday |
|
56 |
assert 10 == n_after.tm_hour |
|
57 |
assert 1 == n_after.tm_min |
|
58 |
assert 52 == n_after.tm_sec |
|
59 |
assert 2026 == n_after.tm_year |
|
60 |
|
|
61 |
assert "CZ" == subj.country |
|
62 |
assert "Pilsen Region" == subj.state |
|
63 |
assert "Pilsen" == subj.locality |
|
64 |
assert "Rooting Roots" == subj.organization |
|
65 |
assert "Department of ROots" == subj.organization_unit |
|
66 |
assert "Main Rooter" == subj.common_name |
|
67 |
assert "root@root.cz" == subj.email_address |
|
68 |
|
|
69 |
|
|
70 |
def test_parse_cert_pen_2(service): |
|
71 |
cert_pem = """ |
|
72 |
-----BEGIN CERTIFICATE----- |
|
73 |
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 |
|
103 |
-----END CERTIFICATE----- |
|
104 |
""" |
|
105 |
|
|
106 |
# parse a certificate supplied in a PEM format |
|
107 |
subj, n_before, n_after = service.parse_cert_pem(cert_pem) |
|
108 |
|
|
109 |
assert 3 == n_before.tm_mon |
|
110 |
assert 23 == n_before.tm_mday |
|
111 |
assert 21 == n_before.tm_hour |
|
112 |
assert 32 == n_before.tm_min |
|
113 |
assert 59 == n_before.tm_sec |
|
114 |
assert 2021 == n_before.tm_year |
|
115 |
|
|
116 |
assert 3 == n_after.tm_mon |
|
117 |
assert 23 == n_after.tm_mday |
|
118 |
assert 21 == n_after.tm_hour |
|
119 |
assert 32 == n_after.tm_min |
|
120 |
assert 59 == n_after.tm_sec |
|
121 |
assert 2024 == n_after.tm_year |
|
122 |
|
|
123 |
assert "AU" == subj.country |
|
124 |
assert "Some-State" == subj.state |
|
125 |
assert "Internet Widgits Pty Ltd" == subj.organization |
|
126 |
assert "NCHILD_2" == subj.common_name |
|
127 |
assert None is subj.locality |
|
128 |
assert None is subj.organization_unit |
|
129 |
assert None is subj.email_address |
|
130 |
|
|
131 |
|
|
132 |
def test_parse_cert_pen_empty(service): |
|
133 |
cert_pem = """ |
|
134 |
-----BEGIN CERTIFICATE----- |
|
135 |
MIIDczCCAlugAwIBAgIUPM++Jj33iag4uaOMIzED4/rMTB4wDQYJKoZIhvcNAQEL |
|
136 |
BQAwSTELMAkGA1UEBhMCICAxCzAJBgNVBAgMAiAgMQowCAYDVQQKDAEgMQswCQYD |
|
137 |
VQQDDAIgIDEUMBIGCSqGSIb3DQEJARYFIGZvbyAwHhcNMjEwNDAzMjMzMDEwWhcN |
|
138 |
MjEwNTAzMjMzMDEwWjBJMQswCQYDVQQGEwIgIDELMAkGA1UECAwCICAxCjAIBgNV |
|
139 |
BAoMASAxCzAJBgNVBAMMAiAgMRQwEgYJKoZIhvcNAQkBFgUgZm9vIDCCASIwDQYJ |
|
140 |
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALI9Ksw85aFLBw2wAeRUoxMQarXkWWbw |
|
141 |
FyvGCb426EcdKYEiax4BYsK+VLxJpJsIo4DnSM1c0EKNJmN4w+l93CBVhHvmA+qo |
|
142 |
3LYShf/DgNeKZD7KJgAWwPHBnA1eOA/8kUX0YT9Z76JpJN46KFfqaY9Scb9GBU/m |
|
143 |
Kr/Lm2Rkg/LehMObPfNQm3XGOvcRjHON9VoB7hZW8zt2lvWTkhia9t46p/kY90eg |
|
144 |
3iw5JRR/MeYBiYeikjT4g5pMZDkymWUp7eahOsoR4kGYGLkpdXVN66evWzTikUKV |
|
145 |
QSHdzUZOiTJ7GFJ70qqh+gAEMCf/Lx8EDbDcuz7ZH40Lr6knY2+9xe8CAwEAAaNT |
|
146 |
MFEwHQYDVR0OBBYEFChHMZUZ2fyOrclVGjtopKn7f/mSMB8GA1UdIwQYMBaAFChH |
|
147 |
MZUZ2fyOrclVGjtopKn7f/mSMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL |
|
148 |
BQADggEBAETfyBYSS6drAyGY1/+z7fWKV3aS1Ocd8c/7oj1seFZ8AH+b0zktTynv |
|
149 |
khprZhxRGRR6cHhyVmMexSWucWb7zlJZNcO9F0/FIgoqcKODtdNczTJyrC9raeuf |
|
150 |
8pAqhaxXcNXXUSB8vNQKHLRtRnPCB3nZE7xSl5RRmSPyPGZyyAYygxRnLjMFgJEU |
|
151 |
4c1FOpvRcfRS5yWviOS6dFv+cGA8hoUMXkpIW88GfwgdO6nMSQB1wUdqKoPnaIFc |
|
152 |
3vjtLMWkuVZFYqvp3NN6GtyI5pw1O0FzjkLZsAeuHZyIkwpKkMsnGlGW8lz1svZ+ |
|
153 |
7AQMsDl5rA4ZVlnLXSQlq3YXVuXZlAI= |
|
154 |
-----END CERTIFICATE----- |
|
155 |
""" |
|
156 |
|
|
157 |
# parse a certificate supplied in a PEM format |
|
158 |
subj, n_before, n_after = service.parse_cert_pem(cert_pem) |
|
159 |
|
|
160 |
assert 4 == n_before.tm_mon |
|
161 |
assert 3 == n_before.tm_mday |
|
162 |
assert 23 == n_before.tm_hour |
|
163 |
assert 30 == n_before.tm_min |
|
164 |
assert 10 == n_before.tm_sec |
|
165 |
assert 2021 == n_before.tm_year |
|
166 |
|
|
167 |
assert 5 == n_after.tm_mon |
|
168 |
assert 3 == n_after.tm_mday |
|
169 |
assert 23 == n_after.tm_hour |
|
170 |
assert 30 == n_after.tm_min |
|
171 |
assert 10 == n_after.tm_sec |
|
172 |
assert 2021 == n_after.tm_year |
|
173 |
|
|
174 |
# TODO improve parsing of fields within quotes |
|
175 |
assert "\" \"" == subj.country |
|
176 |
assert "\" \"" == subj.state |
|
177 |
assert "\" \"" == subj.organization |
|
178 |
assert "\" \"" == subj.common_name |
|
179 |
assert None is subj.locality |
|
180 |
assert None is subj.organization_unit |
|
181 |
assert "\" foo \"" == subj.email_address |
|
182 |
|
|
183 |
|
|
184 |
def test_create_and_parse_cert(service): |
|
185 |
# create a private key |
|
186 |
key = service.create_private_key(passphrase="foobar") |
|
187 |
|
|
188 |
# create a certificate |
|
189 |
cert = service.create_sscrt(Subject(common_name="Foo CN", email_address="foo@bar.cz"), key, key_pass="foobar") |
|
190 |
|
|
191 |
# parse the subject |
|
192 |
parsed_subj, n_before, n_after = service.parse_cert_pem(cert) |
|
193 |
|
|
194 |
assert "Foo CN" == parsed_subj.common_name |
|
195 |
assert "foo@bar.cz" == parsed_subj.email_address |
tests/services/cryptography/private_keys_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
import pytest |
|
4 |
|
|
5 |
|
|
6 |
def test_private_key(service): |
|
7 |
private_key = service.create_private_key() |
|
8 |
|
|
9 |
# verify the private key |
|
10 |
subprocess.check_output(["openssl", "rsa", "-in", "-", "-check"], input=bytes(private_key, encoding="utf-8"), |
|
11 |
stderr=subprocess.STDOUT) |
|
12 |
|
|
13 |
|
|
14 |
def test_encrypted_private_key(service): |
|
15 |
private_key = service.create_private_key(passphrase="foobar") |
|
16 |
|
|
17 |
# verify the private key providing a correct passphrase |
|
18 |
subprocess.check_output(["openssl", "rsa", "-in", "-", "-passin", "pass:foobar", "-check"], |
|
19 |
input=bytes(private_key, encoding="utf-8"), stderr=subprocess.STDOUT) |
|
20 |
|
|
21 |
|
|
22 |
def test_encrypted_private_key_incorrect_pass(service): |
|
23 |
private_key = service.create_private_key(passphrase="foobar") |
|
24 |
|
|
25 |
# incorrect passphrase provided |
|
26 |
with pytest.raises(subprocess.CalledProcessError): |
|
27 |
subprocess.check_output(["openssl", "rsa", "-in", "-", "-passin", "pass:bazbaz", "-check"], |
|
28 |
input=bytes(private_key, encoding="utf-8"), stderr=subprocess.STDOUT) |
tests/services/cryptography/run_for_output_test.py | ||
---|---|---|
1 |
import pytest |
|
2 |
|
|
3 |
from src.services.cryptography import CryptographyException |
|
4 |
|
|
5 |
|
|
6 |
def test_simple_exec(service): |
|
7 |
out = service._CryptographyService__run_for_output(["version"]) |
|
8 |
assert "OpenSSL" in out.decode() |
|
9 |
|
|
10 |
|
|
11 |
def test_simple_exec_without_parameters(service): |
|
12 |
out = service._CryptographyService__run_for_output() |
|
13 |
assert "OpenSSL>" in out.decode() |
|
14 |
|
|
15 |
|
|
16 |
def test_nonexistent_executable(service): |
|
17 |
with pytest.raises(CryptographyException) as e: |
|
18 |
service._CryptographyService__run_for_output(executable="nonexistent_executable#") |
|
19 |
assert """"nonexistent_executable#" not found in the current PATH.""" in e.value.message |
|
20 |
|
|
21 |
|
|
22 |
def test_exception_str(service): |
|
23 |
with pytest.raises(CryptographyException) as e: |
|
24 |
service._CryptographyService__run_for_output(executable="nonexistent_executable") |
|
25 |
assert """EXECUTABLE: nonexistent_executable |
|
26 |
ARGS: ('nonexistent_executable',) |
|
27 |
MESSAGE: "nonexistent_executable" not found in the current PATH.""" in e.value.__str__() |
tests/services/cryptography/self_signed_cert_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
import pytest |
|
4 |
|
|
5 |
from src.model.subject import Subject |
|
6 |
from src.services.cryptography import CryptographyException |
|
7 |
|
|
8 |
|
|
9 |
def test_create_sscrt(service): |
|
10 |
# create a self signed certificate using configuration and extensions |
|
11 |
private_key = service.create_private_key(passphrase="foobar") |
|
12 |
|
|
13 |
# distinguished_name is always required |
|
14 |
config = """ |
|
15 |
# Simple Root CA |
|
16 |
|
|
17 |
[ req ] |
|
18 |
distinguished_name = ca_dn # DN section |
|
19 |
|
|
20 |
[ ca_dn ] |
|
21 |
|
|
22 |
[ root_ca_ext ] |
|
23 |
keyUsage = critical,keyCertSign,cRLSign |
|
24 |
basicConstraints = critical,CA:true |
|
25 |
subjectKeyIdentifier = hash |
|
26 |
authorityKeyIdentifier = keyid:always |
|
27 |
""" |
|
28 |
|
|
29 |
cert = service.create_sscrt(Subject(common_name="Topnax", |
|
30 |
country="CZ", |
|
31 |
locality="My Locality", |
|
32 |
state="My state", |
|
33 |
organization="Mysterious Org.", |
|
34 |
organization_unit="Department of Mysteries", |
|
35 |
email_address="mysterious@box.cz"), private_key, config=config, |
|
36 |
extensions="root_ca_ext", key_pass="foobar") |
|
37 |
|
|
38 |
cert_printed = subprocess.check_output(["openssl", "x509", "-noout", "-text", "-in", "-"], |
|
39 |
input=bytes(cert, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
40 |
|
|
41 |
assert "Certificate Sign, CRL Sign" in cert_printed |
|
42 |
assert "X509v3 Key Usage: critical" in cert_printed |
|
43 |
assert "CA:TRUE" in cert_printed |
|
44 |
|
|
45 |
assert "Issuer: CN = Topnax, C = CZ, L = My Locality, ST = My state, O = Mysterious Org., OU = Department of Mysteries, emailAddress = mysterious@box.cz" in cert_printed |
|
46 |
assert "Subject: CN = Topnax, C = CZ, L = My Locality, ST = My state, O = Mysterious Org., OU = Department of Mysteries, emailAddress = mysterious@box.cz" in cert_printed |
|
47 |
|
|
48 |
|
|
49 |
def test_create_sscrt_config_without_extensions(service): |
|
50 |
# create a self signed certificate without specifying extensions |
|
51 |
private_key = service.create_private_key() |
|
52 |
|
|
53 |
config = """ |
|
54 |
# Simple Root CA |
|
55 |
|
|
56 |
[ req ] |
|
57 |
distinguished_name = ca_dn # DN section |
|
58 |
|
|
59 |
[ ca_dn ] |
|
60 |
|
|
61 |
""" |
|
62 |
|
|
63 |
cert = service.create_sscrt(Subject(common_name="Topnax", country="CZ"), private_key, config=config) |
|
64 |
|
|
65 |
cert_printed = subprocess.check_output(["openssl", "x509", "-noout", "-text", "-in", "-"], |
|
66 |
input=bytes(cert, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
67 |
|
|
68 |
# TODO pass something in the configuration that can be asserted |
|
69 |
assert "Issuer: CN = Topnax, C = CZ" in cert_printed |
|
70 |
assert "Subject: CN = Topnax, C = CZ" in cert_printed |
|
71 |
|
|
72 |
|
|
73 |
def test_create_sscrt_plain(service): |
|
74 |
# create a self signed certificate without configuration |
|
75 |
private_key = service.create_private_key() |
|
76 |
|
|
77 |
cert = service.create_sscrt(Subject(common_name="Topnax", country="CZ"), private_key) |
|
78 |
|
|
79 |
cert_printed = subprocess.check_output(["openssl", "x509", "-noout", "-text", "-in", "-"], |
|
80 |
input=bytes(cert, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
81 |
|
|
82 |
assert "Issuer: CN = Topnax, C = CZ" in cert_printed |
|
83 |
assert "Subject: CN = Topnax, C = CZ" in cert_printed |
|
84 |
|
|
85 |
|
|
86 |
def test_create_sscrt_passphrase(service): |
|
87 |
# create a self signed certificate with a PK that is protected by a passphrase |
|
88 |
private_key = service.create_private_key(passphrase="foobar") |
|
89 |
|
|
90 |
cert = service.create_sscrt(Subject(common_name="Topnax", country="CZ"), private_key, key_pass="foobar") |
|
91 |
|
|
92 |
cert_printed = subprocess.check_output(["openssl", "x509", "-noout", "-text", "-in", "-"], |
|
93 |
input=bytes(cert, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
94 |
|
|
95 |
assert "Issuer: CN = Topnax, C = CZ" in cert_printed |
|
96 |
assert "Subject: CN = Topnax, C = CZ" in cert_printed |
|
97 |
|
|
98 |
|
|
99 |
def test_create_sscrt_incorrect_passphrase(service): |
|
100 |
# make an attempt to create a self signed certificate using a private key with specifying wrong key passphrase or |
|
101 |
# no passphrase at all |
|
102 |
private_key = service.create_private_key(passphrase="foobar") |
|
103 |
|
|
104 |
# incorrect passphrase provided when using a protected private key |
|
105 |
with pytest.raises(CryptographyException) as e: |
|
106 |
service.create_sscrt(Subject(common_name="Topnax", country="CZ"), private_key, key_pass="bazfoo") |
|
107 |
assert "bad decrypt" in e.value.message |
|
108 |
|
|
109 |
# no passphrase provided when using a protected private key |
|
110 |
with pytest.raises(CryptographyException) as e: |
|
111 |
service.create_sscrt(Subject(common_name="Topnax", country="CZ"), private_key) |
|
112 |
assert "bad decrypt" in e.value.message |
tests/services/cryptography/sign_csr_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
import pytest |
|
4 |
|
|
5 |
from src.model.subject import Subject |
|
6 |
from src.services.cryptography import CryptographyException |
|
7 |
|
|
8 |
|
|
9 |
def export_crt(csr): |
|
10 |
return subprocess.check_output(["openssl", "x509", "-noout", "-text", "-in", "-"], |
|
11 |
input=bytes(csr, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
12 |
|
|
13 |
|
|
14 |
def test_sign_csr(service): |
|
15 |
# create root CA |
|
16 |
root_key = service.create_private_key() |
|
17 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key) |
|
18 |
|
|
19 |
# create a private key to be used to make a CSR for the intermediate CA |
|
20 |
inter_key = service.create_private_key() |
|
21 |
csr = service._CryptographyService__create_csr(Subject(common_name="bar", country="CZ"), inter_key) |
|
22 |
|
|
23 |
# sign the created CSR with root CA |
|
24 |
inter_ca = service._CryptographyService__sign_csr(csr, root_ca, root_key) |
|
25 |
|
|
26 |
inter_ca_printed = export_crt(inter_ca) |
|
27 |
|
|
28 |
# assert fields |
|
29 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
30 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
31 |
|
|
32 |
|
|
33 |
def test_sign_csr_passphrase(service): |
|
34 |
# create root CA and encrypt the private key of the root CA |
|
35 |
root_key_passphrase = "barbaz" |
|
36 |
root_key = service.create_private_key(passphrase=root_key_passphrase) |
|
37 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key, key_pass=root_key_passphrase) |
|
38 |
|
|
39 |
# create a private key to be used to make a CSR for the intermediate CA |
|
40 |
inter_key = service.create_private_key() |
|
41 |
csr = service._CryptographyService__create_csr(Subject(common_name="bar", country="CZ"), inter_key) |
|
42 |
|
|
43 |
# sign the created CSR with root CA and specify root key passphrase |
|
44 |
inter_ca = service._CryptographyService__sign_csr(csr, root_ca, root_key, issuer_key_pass=root_key_passphrase) |
|
45 |
|
|
46 |
inter_ca_printed = export_crt(inter_ca) |
|
47 |
|
|
48 |
# assert fields |
|
49 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
50 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
51 |
|
|
52 |
# try to sign it using a wrong passphrase |
|
53 |
with pytest.raises(CryptographyException) as e: |
|
54 |
service._CryptographyService__sign_csr(csr, root_ca, root_key, |
|
55 |
extensions="authorityInfoAccess = caIssuers;URI:bar.cz/baz.cert", |
|
56 |
issuer_key_pass="bazbaz") |
|
57 |
assert "bad decrypt" in e.value.message |
|
58 |
|
|
59 |
# try to sign it without specifying a passphrase |
|
60 |
with pytest.raises(CryptographyException) as e: |
|
61 |
service._CryptographyService__sign_csr(csr, root_ca, root_key, |
|
62 |
extensions="authorityInfoAccess = caIssuers;URI:bar.cz/baz.cert") |
|
63 |
assert "bad decrypt" in e.value.message |
|
64 |
|
|
65 |
|
|
66 |
def test_sign_csr_extensions(service): |
|
67 |
# create root CA and encrypt the private key of the root CA |
|
68 |
root_key_passphrase = "barbaz" |
|
69 |
root_key = service.create_private_key(passphrase=root_key_passphrase) |
|
70 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key, key_pass=root_key_passphrase) |
|
71 |
|
|
72 |
# create a private key to be used to make a CSR for the intermediate CA |
|
73 |
inter_key = service.create_private_key() |
|
74 |
csr = service._CryptographyService__create_csr(Subject(common_name="bar", country="CZ"), inter_key) |
|
75 |
|
|
76 |
# sign the created CSR with root CA and specify root key passphrase and specify extensions (AIA and CA) |
|
77 |
inter_ca = service._CryptographyService__sign_csr(csr, root_ca, root_key, |
|
78 |
extensions="authorityInfoAccess = caIssuers;URI:bar.cz/baz/cert\nbasicConstraints=critical,CA:TRUE", |
|
79 |
issuer_key_pass=root_key_passphrase) |
|
80 |
|
|
81 |
inter_ca_printed = export_crt(inter_ca) |
|
82 |
|
|
83 |
# assert fields |
|
84 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
85 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
86 |
|
|
87 |
# assert extensions |
|
88 |
expected_extensions = """ X509v3 extensions: |
|
89 |
Authority Information Access: |
|
90 |
CA Issuers - URI:bar.cz/baz/cert |
|
91 |
|
|
92 |
X509v3 Basic Constraints: critical |
|
93 |
CA:TRUE""" |
|
94 |
assert expected_extensions in inter_ca_printed |
tests/services/cryptography/verify_ca_test.py | ||
---|---|---|
1 |
import pytest |
|
2 |
|
|
3 |
from src.model.subject import Subject |
|
4 |
from src.services.cryptography import CryptographyException |
|
5 |
|
|
6 |
|
|
7 |
def test_verify_valid_ca(service): |
|
8 |
# verify validation of valid certificates |
|
9 |
private_key = service.create_private_key() |
|
10 |
root_cert = service.create_sscrt(Subject(common_name="foo"), private_key) |
|
11 |
child_cert = service.create_crt(Subject(common_name="Expired Foo"), private_key, root_cert, private_key, days=1) |
|
12 |
|
|
13 |
assert service.verify_cert(root_cert) |
|
14 |
assert service.verify_cert(child_cert) |
|
15 |
|
|
16 |
|
|
17 |
def test_verify_invalid_ca(service): |
|
18 |
# test whether expired certificate will fail to get verified |
|
19 |
private_key = service.create_private_key() |
|
20 |
root_cert = service.create_sscrt(Subject(common_name="foo"), private_key) |
|
21 |
|
|
22 |
expired_cert = service.create_crt(Subject(common_name="Expired Foo"), private_key, root_cert, private_key, days=0) |
|
23 |
|
|
24 |
assert not service.verify_cert(expired_cert) |
|
25 |
|
|
26 |
|
|
27 |
def test_verify_invalid_cert_format(service): |
|
28 |
# verify that certificate in invalid format raises <CryptographyException> |
|
29 |
|
|
30 |
with pytest.raises(CryptographyException): |
|
31 |
service.verify_cert("invalid cert") |
tests/unit_tests/services/cryptography/conftest.py | ||
---|---|---|
1 |
import pytest |
|
2 |
|
|
3 |
from src.services.cryptography import CryptographyService |
|
4 |
|
|
5 |
|
|
6 |
@pytest.fixture |
|
7 |
def service(): |
|
8 |
# provide a CryptographyService fixture |
|
9 |
return CryptographyService() |
tests/unit_tests/services/cryptography/create_crt_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
import pytest |
|
4 |
|
|
5 |
from src.model.subject import Subject |
|
6 |
from src.services.cryptography import CryptographyException |
|
7 |
|
|
8 |
|
|
9 |
def export_crt(crt): |
|
10 |
return subprocess.check_output(["openssl", "x509", "-noout", "-text", "-in", "-"], |
|
11 |
input=bytes(crt, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
12 |
|
|
13 |
|
|
14 |
def test_sign_cst(service): |
|
15 |
# create root CA |
|
16 |
root_key = service.create_private_key() |
|
17 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key) |
|
18 |
|
|
19 |
# create a private key to be used to make a CSR for the intermediate CA |
|
20 |
inter_key = service.create_private_key() |
|
21 |
|
|
22 |
# create a CA using the root CA |
|
23 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key) |
|
24 |
|
|
25 |
inter_ca_printed = export_crt(inter_ca) |
|
26 |
|
|
27 |
# assert fields |
|
28 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
29 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
30 |
|
|
31 |
|
|
32 |
def test_sign_crt_passphrase(service): |
|
33 |
# create root CA and encrypt the private key of the root CA |
|
34 |
root_key_passphrase = "barbaz" |
|
35 |
root_key = service.create_private_key(passphrase=root_key_passphrase) |
|
36 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key, key_pass=root_key_passphrase) |
|
37 |
|
|
38 |
# create a private key to be used to make a CSR for the intermediate CA |
|
39 |
inter_key_passphrase = "foobazbar" |
|
40 |
inter_key = service.create_private_key(passphrase=inter_key_passphrase) |
|
41 |
|
|
42 |
# create a CA using the root CA |
|
43 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key, |
|
44 |
subject_key_pass=inter_key_passphrase, issuer_key_pass=root_key_passphrase) |
|
45 |
|
|
46 |
inter_ca_printed = export_crt(inter_ca) |
|
47 |
|
|
48 |
# assert fields |
|
49 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
50 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
51 |
|
|
52 |
# some basic incorrect passphrase combinations |
|
53 |
passphrases = [ |
|
54 |
(inter_key, None), |
|
55 |
(inter_key, "foofoobarbar"), |
|
56 |
(None, root_key), |
|
57 |
("foofoobarbar", root_key), |
|
58 |
("foofoobarbar", "foofoobarbar"), |
|
59 |
(None, None) |
|
60 |
] |
|
61 |
|
|
62 |
for (key_pass, issuer_key_pass) in passphrases: |
|
63 |
# try to create it using a wrong issuer passphrase |
|
64 |
with pytest.raises(CryptographyException) as e: |
|
65 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key, |
|
66 |
subject_key_pass=key_pass, issuer_key_pass=issuer_key_pass) |
|
67 |
assert "bad decrypt" in e.value.message |
|
68 |
|
|
69 |
|
|
70 |
def test_sign_crt_extensions(service): |
|
71 |
# create root CA and encrypt the private key of the root CA |
|
72 |
root_key_passphrase = "barbaz" |
|
73 |
root_key = service.create_private_key(passphrase=root_key_passphrase) |
|
74 |
root_ca = service.create_sscrt(Subject(common_name="foo"), root_key, key_pass=root_key_passphrase) |
|
75 |
|
|
76 |
# create a private key to be used to make a CSR for the intermediate CA |
|
77 |
inter_key_passphrase = "foofoo" |
|
78 |
inter_key = service.create_private_key() |
|
79 |
|
|
80 |
# create a CA using the root CA |
|
81 |
inter_ca = service.create_crt(Subject(common_name="bar", country="CZ"), inter_key, root_ca, root_key, |
|
82 |
subject_key_pass=inter_key_passphrase, issuer_key_pass=root_key_passphrase, |
|
83 |
extensions="authorityInfoAccess = caIssuers;URI:bar.cz/baz/cert\nbasicConstraints=critical,CA:TRUE") |
|
84 |
|
|
85 |
inter_ca_printed = export_crt(inter_ca) |
|
86 |
|
|
87 |
# assert fields |
|
88 |
assert "Issuer: CN = foo" in inter_ca_printed |
|
89 |
assert "Subject: CN = bar, C = CZ" in inter_ca_printed |
|
90 |
|
|
91 |
# assert extensions |
|
92 |
expected_extensions = """ X509v3 extensions: |
|
93 |
Authority Information Access: |
|
94 |
CA Issuers - URI:bar.cz/baz/cert |
|
95 |
|
|
96 |
X509v3 Basic Constraints: critical |
|
97 |
CA:TRUE""" |
|
98 |
assert expected_extensions in inter_ca_printed |
tests/unit_tests/services/cryptography/create_csr_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
from src.model.subject import Subject |
|
4 |
|
|
5 |
|
|
6 |
def get_csr_pem(csr): |
|
7 |
return subprocess.check_output(["openssl", "req", "-noout", "-text", "-verify", "-in", "-"], |
|
8 |
input=bytes(csr, encoding="utf-8"), stderr=subprocess.STDOUT).decode() |
|
9 |
|
|
10 |
|
|
11 |
def test_make_csr(service): |
|
12 |
private_key = service.create_private_key() |
|
13 |
|
|
14 |
subject = Subject(common_name="foo", country="CZ") |
|
15 |
csr = service._CryptographyService__create_csr(subject, private_key) |
|
16 |
|
|
17 |
assert "Subject: CN = foo, C = CZ" in get_csr_pem(csr) |
|
18 |
|
|
19 |
|
|
20 |
def test_make_csr_pkey_passphrase(service): |
|
21 |
private_key = service.create_private_key(passphrase="foobar") |
|
22 |
|
|
23 |
subject = Subject(common_name="foo", country="CZ", organization_unit="Mysterious Unit") |
|
24 |
csr = service._CryptographyService__create_csr(subject, private_key, key_pass="foobar") |
|
25 |
|
|
26 |
assert "Subject: CN = foo, C = CZ, OU = Mysterious Unit" in get_csr_pem(csr) |
tests/unit_tests/services/cryptography/parse_cert_pem_test.py | ||
---|---|---|
1 |
from src.model.subject import Subject |
|
2 |
|
|
3 |
|
|
4 |
def test_parse_cert_pem(service): |
|
5 |
cert_pem = """ |
|
6 |
-----BEGIN CERTIFICATE----- |
|
7 |
|
|
8 |
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 |
|
41 |
-----END CERTIFICATE----- |
|
42 |
""" |
|
43 |
|
|
44 |
# parse a certificate supplied in a PEM format |
|
45 |
subj, n_before, n_after = service.parse_cert_pem(cert_pem) |
|
46 |
|
|
47 |
assert 3 == n_before.tm_mon |
|
48 |
assert 21 == n_before.tm_mday |
|
49 |
assert 10 == n_before.tm_hour |
|
50 |
assert 1 == n_before.tm_min |
|
51 |
assert 52 == n_before.tm_sec |
|
52 |
assert 2021 == n_before.tm_year |
|
53 |
|
|
54 |
assert 3 == n_after.tm_mon |
|
55 |
assert 21 == n_after.tm_mday |
|
56 |
assert 10 == n_after.tm_hour |
|
57 |
assert 1 == n_after.tm_min |
|
58 |
assert 52 == n_after.tm_sec |
|
59 |
assert 2026 == n_after.tm_year |
|
60 |
|
|
61 |
assert "CZ" == subj.country |
|
62 |
assert "Pilsen Region" == subj.state |
|
63 |
assert "Pilsen" == subj.locality |
|
64 |
assert "Rooting Roots" == subj.organization |
|
65 |
assert "Department of ROots" == subj.organization_unit |
|
66 |
assert "Main Rooter" == subj.common_name |
|
67 |
assert "root@root.cz" == subj.email_address |
|
68 |
|
|
69 |
|
|
70 |
def test_parse_cert_pen_2(service): |
|
71 |
cert_pem = """ |
|
72 |
-----BEGIN CERTIFICATE----- |
|
73 |
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 |
|
103 |
-----END CERTIFICATE----- |
|
104 |
""" |
|
105 |
|
|
106 |
# parse a certificate supplied in a PEM format |
|
107 |
subj, n_before, n_after = service.parse_cert_pem(cert_pem) |
|
108 |
|
|
109 |
assert 3 == n_before.tm_mon |
|
110 |
assert 23 == n_before.tm_mday |
|
111 |
assert 21 == n_before.tm_hour |
|
112 |
assert 32 == n_before.tm_min |
|
113 |
assert 59 == n_before.tm_sec |
|
114 |
assert 2021 == n_before.tm_year |
|
115 |
|
|
116 |
assert 3 == n_after.tm_mon |
|
117 |
assert 23 == n_after.tm_mday |
|
118 |
assert 21 == n_after.tm_hour |
|
119 |
assert 32 == n_after.tm_min |
|
120 |
assert 59 == n_after.tm_sec |
|
121 |
assert 2024 == n_after.tm_year |
|
122 |
|
|
123 |
assert "AU" == subj.country |
|
124 |
assert "Some-State" == subj.state |
|
125 |
assert "Internet Widgits Pty Ltd" == subj.organization |
|
126 |
assert "NCHILD_2" == subj.common_name |
|
127 |
assert None is subj.locality |
|
128 |
assert None is subj.organization_unit |
|
129 |
assert None is subj.email_address |
|
130 |
|
|
131 |
|
|
132 |
def test_parse_cert_pen_empty(service): |
|
133 |
cert_pem = """ |
|
134 |
-----BEGIN CERTIFICATE----- |
|
135 |
MIIDczCCAlugAwIBAgIUPM++Jj33iag4uaOMIzED4/rMTB4wDQYJKoZIhvcNAQEL |
|
136 |
BQAwSTELMAkGA1UEBhMCICAxCzAJBgNVBAgMAiAgMQowCAYDVQQKDAEgMQswCQYD |
|
137 |
VQQDDAIgIDEUMBIGCSqGSIb3DQEJARYFIGZvbyAwHhcNMjEwNDAzMjMzMDEwWhcN |
|
138 |
MjEwNTAzMjMzMDEwWjBJMQswCQYDVQQGEwIgIDELMAkGA1UECAwCICAxCjAIBgNV |
|
139 |
BAoMASAxCzAJBgNVBAMMAiAgMRQwEgYJKoZIhvcNAQkBFgUgZm9vIDCCASIwDQYJ |
|
140 |
KoZIhvcNAQEBBQADggEPADCCAQoCggEBALI9Ksw85aFLBw2wAeRUoxMQarXkWWbw |
|
141 |
FyvGCb426EcdKYEiax4BYsK+VLxJpJsIo4DnSM1c0EKNJmN4w+l93CBVhHvmA+qo |
|
142 |
3LYShf/DgNeKZD7KJgAWwPHBnA1eOA/8kUX0YT9Z76JpJN46KFfqaY9Scb9GBU/m |
|
143 |
Kr/Lm2Rkg/LehMObPfNQm3XGOvcRjHON9VoB7hZW8zt2lvWTkhia9t46p/kY90eg |
|
144 |
3iw5JRR/MeYBiYeikjT4g5pMZDkymWUp7eahOsoR4kGYGLkpdXVN66evWzTikUKV |
|
145 |
QSHdzUZOiTJ7GFJ70qqh+gAEMCf/Lx8EDbDcuz7ZH40Lr6knY2+9xe8CAwEAAaNT |
|
146 |
MFEwHQYDVR0OBBYEFChHMZUZ2fyOrclVGjtopKn7f/mSMB8GA1UdIwQYMBaAFChH |
|
147 |
MZUZ2fyOrclVGjtopKn7f/mSMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL |
|
148 |
BQADggEBAETfyBYSS6drAyGY1/+z7fWKV3aS1Ocd8c/7oj1seFZ8AH+b0zktTynv |
|
149 |
khprZhxRGRR6cHhyVmMexSWucWb7zlJZNcO9F0/FIgoqcKODtdNczTJyrC9raeuf |
|
150 |
8pAqhaxXcNXXUSB8vNQKHLRtRnPCB3nZE7xSl5RRmSPyPGZyyAYygxRnLjMFgJEU |
|
151 |
4c1FOpvRcfRS5yWviOS6dFv+cGA8hoUMXkpIW88GfwgdO6nMSQB1wUdqKoPnaIFc |
|
152 |
3vjtLMWkuVZFYqvp3NN6GtyI5pw1O0FzjkLZsAeuHZyIkwpKkMsnGlGW8lz1svZ+ |
|
153 |
7AQMsDl5rA4ZVlnLXSQlq3YXVuXZlAI= |
|
154 |
-----END CERTIFICATE----- |
|
155 |
""" |
|
156 |
|
|
157 |
# parse a certificate supplied in a PEM format |
|
158 |
subj, n_before, n_after = service.parse_cert_pem(cert_pem) |
|
159 |
|
|
160 |
assert 4 == n_before.tm_mon |
|
161 |
assert 3 == n_before.tm_mday |
|
162 |
assert 23 == n_before.tm_hour |
|
163 |
assert 30 == n_before.tm_min |
|
164 |
assert 10 == n_before.tm_sec |
|
165 |
assert 2021 == n_before.tm_year |
|
166 |
|
|
167 |
assert 5 == n_after.tm_mon |
|
168 |
assert 3 == n_after.tm_mday |
|
169 |
assert 23 == n_after.tm_hour |
|
170 |
assert 30 == n_after.tm_min |
|
171 |
assert 10 == n_after.tm_sec |
|
172 |
assert 2021 == n_after.tm_year |
|
173 |
|
|
174 |
# TODO improve parsing of fields within quotes |
|
175 |
assert "\" \"" == subj.country |
|
176 |
assert "\" \"" == subj.state |
|
177 |
assert "\" \"" == subj.organization |
|
178 |
assert "\" \"" == subj.common_name |
|
179 |
assert None is subj.locality |
|
180 |
assert None is subj.organization_unit |
|
181 |
assert "\" foo \"" == subj.email_address |
|
182 |
|
|
183 |
|
|
184 |
def test_create_and_parse_cert(service): |
|
185 |
# create a private key |
|
186 |
key = service.create_private_key(passphrase="foobar") |
|
187 |
|
|
188 |
# create a certificate |
|
189 |
cert = service.create_sscrt(Subject(common_name="Foo CN", email_address="foo@bar.cz"), key, key_pass="foobar") |
|
190 |
|
|
191 |
# parse the subject |
|
192 |
parsed_subj, n_before, n_after = service.parse_cert_pem(cert) |
|
193 |
|
|
194 |
assert "Foo CN" == parsed_subj.common_name |
|
195 |
assert "foo@bar.cz" == parsed_subj.email_address |
tests/unit_tests/services/cryptography/private_keys_test.py | ||
---|---|---|
1 |
import subprocess |
|
2 |
|
|
3 |
import pytest |
|
4 |
|
|
5 |
|
|
6 |
def test_private_key(service): |
|
7 |
private_key = service.create_private_key() |
|
8 |
|
|
9 |
# verify the private key |
|
10 |
subprocess.check_output(["openssl", "rsa", "-in", "-", "-check"], input=bytes(private_key, encoding="utf-8"), |
|
11 |
stderr=subprocess.STDOUT) |
|
12 |
|
|
13 |
|
|
14 |
def test_encrypted_private_key(service): |
|
15 |
private_key = service.create_private_key(passphrase="foobar") |
|
16 |
|
|
17 |
# verify the private key providing a correct passphrase |
|
18 |
subprocess.check_output(["openssl", "rsa", "-in", "-", "-passin", "pass:foobar", "-check"], |
|
19 |
input=bytes(private_key, encoding="utf-8"), stderr=subprocess.STDOUT) |
|
20 |
|
|
21 |
|
|
22 |
def test_encrypted_private_key_incorrect_pass(service): |
|
23 |
private_key = service.create_private_key(passphrase="foobar") |
|
24 |
|
|
25 |
# incorrect passphrase provided |
|
26 |
with pytest.raises(subprocess.CalledProcessError): |
|
27 |
subprocess.check_output(["openssl", "rsa", "-in", "-", "-passin", "pass:bazbaz", "-check"], |
|
28 |
input=bytes(private_key, encoding="utf-8"), stderr=subprocess.STDOUT) |
tests/unit_tests/services/cryptography/run_for_output_test.py | ||
---|---|---|
1 |
import pytest |
|
2 |
|
|
3 |
from src.services.cryptography import CryptographyException |
|
4 |
|
|
5 |
|
|
6 |
def test_simple_exec(service): |
|
7 |
out = service._CryptographyService__run_for_output(["version"]) |
|
8 |
assert "OpenSSL" in out.decode() |
|
9 |
|
|
10 |
|
|
11 |
def test_simple_exec_without_parameters(service): |
|
12 |
out = service._CryptographyService__run_for_output() |
|
13 |
assert "OpenSSL>" in out.decode() |
|
14 |
|
|
15 |
|
|
16 |
def test_nonexistent_executable(service): |
|
17 |
with pytest.raises(CryptographyException) as e: |
|
18 |
service._CryptographyService__run_for_output(executable="nonexistent_executable#") |
|
19 |
assert """"nonexistent_executable#" not found in the current PATH.""" in e.value.message |
|
20 |
|
|
21 |
|
|
22 |
def test_exception_str(service): |
|
23 |
with pytest.raises(CryptographyException) as e: |
|
24 |
service._CryptographyService__run_for_output(executable="nonexistent_executable") |
|
25 |
assert """EXECUTABLE: nonexistent_executable |
|
26 |
ARGS: ('nonexistent_executable',) |
|
27 |
MESSAGE: "nonexistent_executable" not found in the current PATH.""" in e.value.__str__() |
Také k dispozici: Unified diff
Re #8472 - Improved SQL connection/cursor fixtures in such way that connection to DB happens only once per test module