|
26 | 26 | from cryptography.x509 import load_pem_x509_certificate
|
27 | 27 | from rich.logging import RichHandler
|
28 | 28 |
|
29 |
| -from sigstore import __version__ |
| 29 | +from sigstore import __version__, dsse |
30 | 30 | from sigstore._internal.fulcio.client import (
|
31 | 31 | DEFAULT_FULCIO_URL,
|
32 | 32 | ExpiredCertificate,
|
@@ -813,11 +813,31 @@ def _verify_identity(args: argparse.Namespace) -> None:
|
813 | 813 | )
|
814 | 814 |
|
815 | 815 | try:
|
816 |
| - verifier.verify_artifact( |
817 |
| - input_=hashed, |
818 |
| - bundle=bundle, |
819 |
| - policy=policy_, |
820 |
| - ) |
| 816 | + # If the bundle specifies a DSSE envelope, perform DSSE verification |
| 817 | + # and assert that the inner payload is an in-toto statement bound |
| 818 | + # to a subject matching the input's digest. |
| 819 | + if bundle._dsse_envelope: |
| 820 | + with file.open(mode="rb", buffering=0) as io: |
| 821 | + digest = sha256_digest(io) |
| 822 | + |
| 823 | + type_, payload = verifier.verify_dsse(bundle=bundle, policy=policy_) |
| 824 | + if type_ != dsse.Envelope._TYPE: |
| 825 | + raise VerificationError( |
| 826 | + f"expected JSON payload for DSSE, got {type_}" |
| 827 | + ) |
| 828 | + |
| 829 | + stmt = dsse.Statement(payload) |
| 830 | + if not stmt._matches_digest(digest): |
| 831 | + raise VerificationError( |
| 832 | + f"in-toto statement has no subject for digest {digest.digest.hex()}" |
| 833 | + ) |
| 834 | + else: |
| 835 | + verifier.verify_artifact( |
| 836 | + input_=hashed, |
| 837 | + bundle=bundle, |
| 838 | + policy=policy_, |
| 839 | + ) |
| 840 | + |
821 | 841 | print(f"OK: {file}")
|
822 | 842 | except VerificationError as exc:
|
823 | 843 | _logger.error(f"FAIL: {file}")
|
@@ -851,7 +871,30 @@ def _verify_github(args: argparse.Namespace) -> None:
|
851 | 871 | verifier, materials = _collect_verification_state(args)
|
852 | 872 | for file, hashed, bundle in materials:
|
853 | 873 | try:
|
854 |
| - verifier.verify_artifact(input_=hashed, bundle=bundle, policy=policy_) |
| 874 | + # If the bundle specifies a DSSE envelope, perform DSSE verification |
| 875 | + # and assert that the inner payload is an in-toto statement bound |
| 876 | + # to a subject matching the input's digest. |
| 877 | + if bundle._dsse_envelope: |
| 878 | + with file.open(mode="rb", buffering=0) as io: |
| 879 | + digest = sha256_digest(io) |
| 880 | + |
| 881 | + type_, payload = verifier.verify_dsse(bundle=bundle, policy=policy_) |
| 882 | + if type_ != dsse.Envelope._TYPE: |
| 883 | + raise VerificationError( |
| 884 | + f"expected JSON payload for DSSE, got {type_}" |
| 885 | + ) |
| 886 | + |
| 887 | + stmt = dsse.Statement(payload) |
| 888 | + if not stmt._matches_digest(digest): |
| 889 | + raise VerificationError( |
| 890 | + f"in-toto statement has no subject for digest {digest.digest.hex()}" |
| 891 | + ) |
| 892 | + else: |
| 893 | + verifier.verify_artifact( |
| 894 | + input_=hashed, |
| 895 | + bundle=bundle, |
| 896 | + policy=policy_, |
| 897 | + ) |
855 | 898 | print(f"OK: {file}")
|
856 | 899 | except VerificationError as exc:
|
857 | 900 | _logger.error(f"FAIL: {file}")
|
|
0 commit comments