From c53f6c53758ffd2c464981890972fc9bcef8dcff Mon Sep 17 00:00:00 2001 From: javanlacerda Date: Fri, 16 Feb 2024 19:45:21 +0000 Subject: [PATCH 1/2] feat: checking that the client is allowd to run against staging Signed-off-by: javanlacerda --- README.md | 6 ++++++ docs/cli_protocol.md | 8 +++++++- test/client.py | 32 +++++++++++++++++--------------- test/conftest.py | 8 +++++++- test/test_bundle.py | 25 +++++++++++++++++++------ 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 1fd65b8..76e88ff 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,12 @@ Or if you are only checking verification use cases, (env) $ pytest test --skip-signing --entrypoint=SIGSTORE_CLIENT ``` +You can also run the tests against staging by adding `--staging` on the command, + +```sh +(env) $ pytest test --staging --entrypoint=SIGSTORE_CLIENT +``` + Using the [`gh` CLI](https://cli.github.com/) and noting SIGSTORE_CLIENT is the absolute path to a client implementing the [CLI specification](https://github.com/sigstore/sigstore-conformance/blob/main/docs/cli_protocol.md). ## Licensing diff --git a/docs/cli_protocol.md b/docs/cli_protocol.md index 42ba847..ceef090 100644 --- a/docs/cli_protocol.md +++ b/docs/cli_protocol.md @@ -24,10 +24,16 @@ client's native CLI accepts. This is the set of subcommands that the test CLI must support. Each subcommand has a provided syntax and list of descriptions for each argument. -To simplify argument parsing, all arguments are required and will **always** be +To simplify argument parsing, all arguments are required, except `--staging`, and will **always** be supplied by the conformance suite in the order that they are specified in the templates below. +All commands below are allowed to run against staging, adding the `--staging` in the command, for example: + +```console +${ENTRYPOINT} sign --identity-token TOKEN --signature FILE --certificate FILE FILE --staging +``` + ### Sign #### Signature and certificate flow diff --git a/test/client.py b/test/client.py index d8a61b5..b986fc5 100644 --- a/test/client.py +++ b/test/client.py @@ -111,7 +111,7 @@ class SigstoreClient: methods should not be called directly. """ - def __init__(self, entrypoint: str, identity_token: str) -> None: + def __init__(self, entrypoint: str, identity_token: str, staging: bool) -> None: """ Create a new `SigstoreClient`. @@ -120,15 +120,20 @@ def __init__(self, entrypoint: str, identity_token: str) -> None: self.entrypoint = entrypoint self.identity_token = identity_token self.completed_process: subprocess.CompletedProcess | None = None + self.staging = staging def run(self, *args) -> None: """ Execute a command against the Sigstore client. """ self.completed_process = None + full_command = [self.entrypoint, *args] + if self.staging: + full_command.append("--staging") + try: self.completed_process = subprocess.run( - [self.entrypoint, *args], + full_command, text=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, @@ -182,8 +187,7 @@ def _sign_for_sigcrt( This is an overload of `sign` for the signature/certificate flow and should not be called directly. """ - - self.run( + args = [ "sign", "--identity-token", self.identity_token, @@ -192,7 +196,9 @@ def _sign_for_sigcrt( "--certificate", materials.certificate, artifact, - ) + ] + + self.run(*args) @sign.register def _sign_for_bundle(self, materials: BundleMaterials, artifact: os.PathLike) -> None: @@ -202,21 +208,19 @@ def _sign_for_bundle(self, materials: BundleMaterials, artifact: os.PathLike) -> This is an overload of `sign` for the bundle flow and should not be called directly. """ - self.run( + args = [ "sign-bundle", "--identity-token", self.identity_token, "--bundle", materials.bundle, artifact, - ) + ] + + self.run(*args) @singledispatchmethod - def verify( - self, - materials: VerificationMaterials, - artifact: os.PathLike, - ) -> None: + def verify(self, materials: VerificationMaterials, artifact: os.PathLike) -> None: """ Verify an artifact with the Sigstore client. Dispatches to `_verify_for_sigcrt` when given `SignatureCertificateMaterials`, or `_verify_for_bundle` when given @@ -230,9 +234,7 @@ def verify( @verify.register def _verify_for_sigcrt( - self, - materials: SignatureCertificateMaterials, - artifact: os.PathLike, + self, materials: SignatureCertificateMaterials, artifact: os.PathLike ) -> None: """ Verify an artifact given a signature and certificate with the Sigstore client. diff --git a/test/conftest.py b/test/conftest.py index 6563d2d..05fba0e 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -63,6 +63,11 @@ def pytest_addoption(parser) -> None: action="store_true", help="skip tests that require signing functionality", ) + parser.addoption( + "--staging", + action="store_true", + help="run tests against staging", + ) def pytest_runtest_setup(item): @@ -162,7 +167,8 @@ def client(pytestconfig, identity_token): Parametrize each test with the client under test. """ entrypoint = pytestconfig.getoption("--entrypoint") - return SigstoreClient(entrypoint, identity_token) + staging = pytestconfig.getoption("--staging") + return SigstoreClient(entrypoint, identity_token, staging) @pytest.fixture diff --git a/test/test_bundle.py b/test/test_bundle.py index 3b64444..6912250 100644 --- a/test/test_bundle.py +++ b/test/test_bundle.py @@ -19,7 +19,9 @@ def test_verify(client: SigstoreClient, make_materials_by_type: _MakeMaterialsBy client.verify(materials, input_path) -def test_verify_dsse_bundle_with_trust_root(client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType) -> None: +def test_verify_dsse_bundle_with_trust_root( + client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType +) -> None: """ Test the happy path of verification for DSSE bundle w/ custom trust root """ @@ -170,7 +172,9 @@ def test_verify_rejects_different_materials( client.verify(materials, input_path) -def test_verify_rejects_expired_certificate(client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType) -> None: +def test_verify_rejects_expired_certificate( + client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType +) -> None: """ Check that the client rejects a bundle if the certificate was issued outside the validity window of the trusted root @@ -184,7 +188,9 @@ def test_verify_rejects_expired_certificate(client: SigstoreClient, make_materia client.verify(materials, input_path) -def test_verify_rejects_missing_inclusion_proof(client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType) -> None: +def test_verify_rejects_missing_inclusion_proof( + client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType +) -> None: """ Check that the client rejects a v0.2 bundle if the TLog entry does NOT contain an inclusion proof @@ -198,7 +204,9 @@ def test_verify_rejects_missing_inclusion_proof(client: SigstoreClient, make_mat client.verify(materials, input_path) -def test_verify_rejects_bad_tlog_timestamp(client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType) -> None: +def test_verify_rejects_bad_tlog_timestamp( + client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType +) -> None: """ Check that the client rejects a bundle if the TLog entry contains a timestamp that falls outside the validity window of the signing @@ -213,7 +221,9 @@ def test_verify_rejects_bad_tlog_timestamp(client: SigstoreClient, make_material client.verify(materials, input_path) -def test_verify_rejects_bad_tlog_entry(client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType) -> None: +def test_verify_rejects_bad_tlog_entry( + client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType +) -> None: """ Check that the client rejects a bundle if the body of the TLog entry does not match the signed artifact. @@ -226,7 +236,10 @@ def test_verify_rejects_bad_tlog_entry(client: SigstoreClient, make_materials_by with client.raises(): client.verify(materials, input_path) -def test_verify_rejects_bad_tsa_timestamp(client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType) -> None: + +def test_verify_rejects_bad_tsa_timestamp( + client: SigstoreClient, make_materials_by_type: _MakeMaterialsByType +) -> None: """ Check that the client rejects a bundle if the TSA timestamp falls outside the validity window of the signing certificate. From 9e771a94b79d0241eee57c009d9c11f8c9063b02 Mon Sep 17 00:00:00 2001 From: William Woodruff Date: Tue, 20 Feb 2024 11:56:09 -0500 Subject: [PATCH 2/2] Update docs/cli_protocol.md Signed-off-by: William Woodruff --- docs/cli_protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cli_protocol.md b/docs/cli_protocol.md index ceef090..b872aa8 100644 --- a/docs/cli_protocol.md +++ b/docs/cli_protocol.md @@ -28,7 +28,7 @@ To simplify argument parsing, all arguments are required, except `--staging`, an supplied by the conformance suite in the order that they are specified in the templates below. -All commands below are allowed to run against staging, adding the `--staging` in the command, for example: +All commands below are allowed to run against staging by appending the `--staging` in the command, for example: ```console ${ENTRYPOINT} sign --identity-token TOKEN --signature FILE --certificate FILE FILE --staging