Skip to content

Commit

Permalink
Facilitate testing with CLI config
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthiasValvekens committed May 15, 2023
1 parent bd09edf commit 35f4cb5
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 13 deletions.
45 changes: 45 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import os
import pathlib
import re
import shutil

import click
import pytest

from certomancer import crypto_utils
Expand All @@ -8,6 +14,9 @@
backends = ["backend:oscrypto"]


TEST_DATA_PATH = pathlib.Path("tests", "data").absolute()


@pytest.fixture(scope="session", autouse=True, params=backends)
def crypto_backend(request):
if 'oscrypto' in request.param:
Expand All @@ -21,3 +30,39 @@ def crypto_backend(request):
yield backend
finally:
crypto_utils.CRYPTO_BACKEND = orig_backend


def collect_files(path):
for cur, dirs, files in os.walk(str(path)):
for file in files:
yield os.path.relpath(os.path.join(cur, file), path)


def pytest_runtest_call(item):
for marker in item.iter_markers():
if marker.name == 'config_context':
config_file = marker.args[0]
for extra_config in (
"external-arch.yml",
"full-service-config.yml",
):
shutil.copyfile(
str(TEST_DATA_PATH / extra_config), extra_config
)
with (TEST_DATA_PATH / config_file).open('r') as inf:
with open("certomancer.yml", 'w') as outf:
pattern = re.compile(r"\s*path-prefix: keys-(.*)\n")
for line in inf:
m = pattern.fullmatch(line)
if m is not None:
keydir = pathlib.Path(f"keys-{m.group(1)}")
src_keydir = TEST_DATA_PATH / keydir
for keyfile in collect_files(src_keydir):
(keydir / keyfile).parent.mkdir(
parents=True, exist_ok=True
)
shutil.copyfile(
str(src_keydir / keyfile),
str(keydir / keyfile),
)
outf.write(line)
1 change: 1 addition & 0 deletions tests/test_animator.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ def test_zip():


@pytest.mark.parametrize('pw', [None, b'', b'secret'])
@pytest.mark.needcrypto
def test_pkcs12(pw):
data = {'cert': 'signer1'}
if pw is not None:
Expand Down
15 changes: 6 additions & 9 deletions tests/test_certs.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from certomancer.registry.issued.general import ExtensionSpec
from certomancer.registry.keys import KeySet
from certomancer.registry.plugin_api import CertProfilePluginRegistry
from tests.conftest import collect_files

importlib.import_module('certomancer.default_plugins')

Expand Down Expand Up @@ -580,16 +581,10 @@ def test_serial_order_indep(order):
assert arch.get_cert(CertLabel('signer1')).serial_number == 4097


def _collect_files(path):
for cur, dirs, files in os.walk(path):
for file in files:
yield os.path.relpath(os.path.join(cur, file), path)


def test_dump_no_pfx(tmp_path):
arch = CONFIG.get_pki_arch(ArchLabel('testing-ca'))
arch.dump_certs(str(tmp_path), include_pkcs12=False)
dumped = set(_collect_files(str(tmp_path)))
dumped = set(collect_files(str(tmp_path)))
assert dumped == {
'interm/signer1-long.cert.pem',
'interm/signer1.cert.pem',
Expand All @@ -602,10 +597,11 @@ def test_dump_no_pfx(tmp_path):
}


@pytest.mark.needcrypto
def test_dump_with_pfx(tmp_path):
arch = CONFIG.get_pki_arch(ArchLabel('testing-ca'))
arch.dump_certs(str(tmp_path), include_pkcs12=True)
dumped = set(_collect_files(str(tmp_path)))
dumped = set(collect_files(str(tmp_path)))
assert dumped == {
'interm/signer1-long.cert.pem',
'interm/signer1-long.pfx',
Expand All @@ -629,7 +625,7 @@ def test_dump_with_pfx(tmp_path):
def test_dump_flat_no_pfx(tmp_path):
arch = CONFIG.get_pki_arch(ArchLabel('testing-ca'))
arch.dump_certs(str(tmp_path), include_pkcs12=False, flat=True)
dumped = set(_collect_files(str(tmp_path)))
dumped = set(collect_files(str(tmp_path)))
assert dumped == {
'signer1-long.cert.pem',
'signer1.cert.pem',
Expand Down Expand Up @@ -707,6 +703,7 @@ def test_pss_exclusive():


@pytest.mark.parametrize('pw', [None, b'', b'secret'])
@pytest.mark.needcrypto
def test_pkcs12(pw):
arch = CONFIG.get_pki_arch(ArchLabel('testing-ca'))
package = arch.package_pkcs12(CertLabel('signer1'), password=pw)
Expand Down
147 changes: 143 additions & 4 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from click.testing import CliRunner

from certomancer.cli import cli_root
from tests.conftest import TEST_DATA_PATH, collect_files


@pytest.fixture(scope="function", autouse=True)
Expand All @@ -15,9 +16,6 @@ def cli_runner():
yield runner


TEST_DATA_PATH = pathlib.Path("tests", "data").absolute()


def test_version(cli_runner):
result = cli_runner.invoke(
cli_root,
Expand All @@ -27,13 +25,14 @@ def test_version(cli_runner):
assert m is not None


def test_mass_summon(cli_runner):
def test_mass_summon_explicit_config(cli_runner):
result = cli_runner.invoke(
cli_root,
[
'--config',
str(TEST_DATA_PATH / "with-services.yml"),
'mass-summon',
'--no-pfx',
'testing-ca',
'outdir',
],
Expand All @@ -51,3 +50,143 @@ def test_mass_summon(cli_runner):
pem.unarmor(inf.read(), multiple=False)[2]
)
assert signer_cert.issuer == interm_cert.subject
dumped = set(collect_files(str(outdir)))
assert dumped == {
'interm/signer1-long.cert.pem',
'interm/signer1.cert.pem',
'interm/signer2.cert.pem',
'interm/interm-ocsp.cert.pem',
'root/interm.cert.pem',
'root/tsa.cert.pem',
'root/tsa2.cert.pem',
'root/root.cert.pem',
}


@pytest.mark.config_context("with-services.yml")
def test_mass_summon(cli_runner):
result = cli_runner.invoke(
cli_root,
[
'mass-summon',
'--no-pfx',
'testing-ca',
'outdir',
],
)
assert not result.exit_code, result.output
outdir = pathlib.Path('outdir')
dumped = set(collect_files(str(outdir)))
assert dumped == {
'interm/signer1-long.cert.pem',
'interm/signer1.cert.pem',
'interm/signer2.cert.pem',
'interm/interm-ocsp.cert.pem',
'root/interm.cert.pem',
'root/tsa.cert.pem',
'root/tsa2.cert.pem',
'root/root.cert.pem',
}


@pytest.mark.config_context("with-services.yml")
@pytest.mark.needcrypto
def test_mass_summon_with_pkcs12(cli_runner):
result = cli_runner.invoke(
cli_root,
[
'mass-summon',
'testing-ca',
'outdir',
],
)
assert not result.exit_code, result.output
outdir = pathlib.Path('outdir')
dumped = set(collect_files(str(outdir)))
assert dumped == {
'interm/signer1-long.cert.pem',
'interm/signer1-long.pfx',
'interm/signer1.cert.pem',
'interm/signer1.pfx',
'interm/signer2.cert.pem',
'interm/signer2.pfx',
'interm/interm-ocsp.cert.pem',
'interm/interm-ocsp.pfx',
'root/interm.cert.pem',
'root/interm.pfx',
'root/tsa.cert.pem',
'root/tsa.pfx',
'root/tsa2.cert.pem',
'root/tsa2.pfx',
'root/root.cert.pem',
'root/root.pfx',
}


@pytest.mark.config_context("with-services.yml")
def test_summon(cli_runner):
outdir = pathlib.Path('outdir')
outdir.mkdir()
result = cli_runner.invoke(
cli_root,
['summon', 'testing-ca', 'signer1', str(outdir / 'test.cert.pem')],
)
assert not result.exit_code, result.output
dumped = set(collect_files(str(outdir)))
assert dumped == {'test.cert.pem'}

with (outdir / 'test.cert.pem').open('rb') as inf:
cert = x509.Certificate.load(pem.unarmor(inf.read())[2])
assert 'Alice' in cert.subject.human_friendly


@pytest.mark.config_context("with-services.yml")
def test_summon_no_pem(cli_runner):
outdir = pathlib.Path('outdir')
outdir.mkdir()
result = cli_runner.invoke(
cli_root,
[
'summon',
'--no-pem',
'testing-ca',
'signer1',
str(outdir / 'test.crt'),
],
)
assert not result.exit_code, result.output
dumped = set(collect_files(str(outdir)))
assert dumped == {'test.crt'}

with (outdir / 'test.crt').open('rb') as inf:
cert = x509.Certificate.load(inf.read())
assert 'Alice' in cert.subject.human_friendly


@pytest.mark.config_context("with-services.yml")
def test_summon_stdout(cli_runner):
result = cli_runner.invoke(
cli_root,
[
'summon',
'testing-ca',
'signer1',
],
)
cert = x509.Certificate.load(pem.unarmor(result.output.encode('ascii'))[2])
assert 'Alice' in cert.subject.human_friendly


@pytest.mark.config_context("with-services.yml")
def test_summon_der_stdout(cli_runner):
result = cli_runner.invoke(
cli_root,
[
'summon',
'--no-pem',
'testing-ca',
'signer1',
],
)
cert = x509.Certificate.load(result.stdout_bytes)
assert 'Alice' in cert.subject.human_friendly

0 comments on commit 35f4cb5

Please sign in to comment.