Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions sigstore/verify/verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,18 @@ def _verify_signed_timestamp(
for certificate_authority in cert_authorities:
certificates = certificate_authority.certificates(allow_expired=True)

builder = VerifierBuilder()
for certificate in certificates:
builder.add_root_certificate(certificate)
# We expect at least a signing cert and a root cert but there may be intermediates
if len(certificates) < 2:
_logger.debug("Unable to verify Timestamp: cert chain is incomplete")
continue

builder = (
VerifierBuilder()
.tsa_certificate(certificates[0])
.add_root_certificate(certificates[-1])
)
for certificate in certificates[1:-1]:
builder = builder.add_intermediate_certificate(certificate)
Comment on lines +141 to +142
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flagging, nonblocking: we could add these with add_root_certificate instead, since they're semantically root certs ("root" meaning "in the root program," not "is a self-signed certificate"). That would be slightly faster, since our verification would then be one-hop (TSR -> TSA -> TSA-CA) rather than having to chain TSA-CA up to its "root."

In practice that's probably a marginal performance benefit, however.


verifier = builder.build()
try:
Expand Down
Binary file added test/assets/tsa/issue1482-message
Binary file not shown.
Binary file added test/assets/tsa/issue1482-timestamp-with-no-cert
Binary file not shown.
15 changes: 15 additions & 0 deletions test/unit/verify/test_verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,18 @@ def test_verifier_not_enough_timestamp(
Bundle.from_json(asset("tsa/bundle.txt.sigstore").read_bytes()),
null_policy,
)

def test_verify_signed_timestamp_regression(self, asset):
"""
Ensure we correctly verify a timestamp with no embedded certs.

This is a regression test for # 1482
"""
verifier = Verifier.staging(offline=True)
ts = rfc3161_client.decode_timestamp_response(
asset("tsa/issue1482-timestamp-with-no-cert").read_bytes()
)
res = verifier._verify_signed_timestamp(
ts, asset("tsa/issue1482-message").read_bytes()
)
assert res is not None
Loading