Skip to content

Commit

Permalink
feat: checking that the client is allowd to run against staging
Browse files Browse the repository at this point in the history
Signed-off-by: javanlacerda <javanlacerda@google.com>
  • Loading branch information
javanlacerda committed Feb 16, 2024
1 parent 7375951 commit 0b6004c
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 21 deletions.
49 changes: 34 additions & 15 deletions test/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,13 @@ def raises(self):
)
raise ClientUnexpectedSuccess(msg)

def set_staging(self, args):
args.append("--staging")

@singledispatchmethod
def sign(self, materials: VerificationMaterials, artifact: os.PathLike) -> None:
def sign(
self, materials: VerificationMaterials, artifact: os.PathLike, staging: bool = False
) -> None:
"""
Sign an artifact with the Sigstore client. Dispatches to `_sign_for_sigcrt`
when given `SignatureCertificateMaterials`, or `_sign_for_bundle` when given
Expand All @@ -174,16 +179,15 @@ def sign(self, materials: VerificationMaterials, artifact: os.PathLike) -> None:

@sign.register
def _sign_for_sigcrt(
self, materials: SignatureCertificateMaterials, artifact: os.PathLike
self, materials: SignatureCertificateMaterials, artifact: os.PathLike, staging: bool = False
) -> None:
"""
Sign an artifact with the Sigstore client, producing a signature and certificate.
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,
Expand All @@ -192,30 +196,39 @@ def _sign_for_sigcrt(
"--certificate",
materials.certificate,
artifact,
)
]

if staging:
self.set_staging(args)
self.run(*args)

@sign.register
def _sign_for_bundle(self, materials: BundleMaterials, artifact: os.PathLike) -> None:
def _sign_for_bundle(
self, materials: BundleMaterials, artifact: os.PathLike, staging: bool = False
) -> None:
"""
Sign an artifact with the Sigstore client, producing a bundle.
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,
)
]

if staging:
self.set_staging(args)

self.run(*args)

@singledispatchmethod
def verify(
self,
materials: VerificationMaterials,
artifact: os.PathLike,
self, materials: VerificationMaterials, artifact: os.PathLike, staging: bool = False
) -> None:
"""
Verify an artifact with the Sigstore client. Dispatches to `_verify_for_sigcrt`
Expand All @@ -230,9 +243,7 @@ def verify(

@verify.register
def _verify_for_sigcrt(
self,
materials: SignatureCertificateMaterials,
artifact: os.PathLike,
self, materials: SignatureCertificateMaterials, artifact: os.PathLike, staging: bool = False
) -> None:
"""
Verify an artifact given a signature and certificate with the Sigstore client.
Expand All @@ -256,12 +267,17 @@ def _verify_for_sigcrt(
if getattr(materials, "trusted_root", None) is not None:
args.extend(["--trusted-root", materials.trusted_root])

if staging:
args.append("--staging")

# The identity and OIDC issuer cannot be specified by the test since they remain constant
# across the GitHub Actions job.
self.run(*args, artifact)

@verify.register
def _verify_for_bundle(self, materials: BundleMaterials, artifact: os.PathLike) -> None:
def _verify_for_bundle(
self, materials: BundleMaterials, artifact: os.PathLike, staging: bool = False
) -> None:
"""
Verify an artifact given a bundle with the Sigstore client.
Expand All @@ -282,4 +298,7 @@ def _verify_for_bundle(self, materials: BundleMaterials, artifact: os.PathLike)
if getattr(materials, "trusted_root", None) is not None:
args.extend(["--trusted-root", materials.trusted_root])

if staging:
args.append("--staging")

self.run(*args, artifact)
25 changes: 19 additions & 6 deletions test/test_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
"""
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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.
Expand Down
24 changes: 24 additions & 0 deletions test/test_simple_staging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from test.conftest import _MakeMaterials

import pytest # type: ignore

from .client import SigstoreClient


@pytest.mark.signing_staging
def test_simple_staging(client: SigstoreClient, make_materials: _MakeMaterials) -> None:
"""
A simple test that signs and verifies an artifact for a given Sigstore
client against staging.
"""

staging = True
input_path, materials = make_materials("b.txt")
assert not materials.exists()

# Sign the artifact.
client.sign(materials, input_path, staging)
assert materials.exists()

# Verify the artifact signature.
client.verify(materials, input_path, staging)

0 comments on commit 0b6004c

Please sign in to comment.