diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d392b8cf..485dc9e3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,11 +20,11 @@ All versions prior to 0.9.0 are untracked. * TSA: Changed the Timestamp Authority requests to explicitly use sha256 for message digests. [#1373](https://github.com/sigstore/sigstore-python/pull/1373) -* Fixed the certificate calidity period check for Timestamp Authorities (TSA). - Certificates need not have and end date, while still requiring a start date. +* Fixed the certificate validity period check for Timestamp Authorities (TSA). + Certificates need not have an end date, while still requiring a start date. [#1368](https://github.com/sigstore/sigstore-python/pull/1368) -* API: Make Rekor APIs compatible with Rekor v2 by removing trailing slashes +* Made Rekor client more compatible with Rekor v2 by removing trailing slashes from endpoints ([#1366](https://github.com/sigstore/sigstore-python/pull/1366)) * Verify: verify that all established times (timestamps or the log integration time) @@ -38,8 +38,25 @@ All versions prior to 0.9.0 are untracked. ### Changed +* API: + * ClientTrustConfig now provides methods `production()`, `staging()`and `from_tuf()` + to get access to current client configuration (trusted keys & certificates, + URLs and their validity periods). [#1363](https://github.com/sigstore/sigstore-python/pull/1363) * `--trust-config` now requires a file with SigningConfig v0.2, and is able to fully configure the used Sigstore instance [#1358]/(https://github.com/sigstore/sigstore-python/pull/1358) +* By default (when `--trust-config` is not used) the whole trust configuration now + comes from the TUF repository [#1363](https://github.com/sigstore/sigstore-python/pull/1363) + +### Removed + * API: + * `Issuer.production()` and `Issuer.staging()` have been removed: Use + `Issuer()` instead with relevant URL. The current public good production and + staging URLs are available via the `ClientTrustConfig` object. + [#1363](https://github.com/sigstore/sigstore-python/pull/1363) + * `SigningContext.production()` and `SigningContext.staging()` have been removed: + Use `SigningContext.from_trust_config()` instead. + [#1363](https://github.com/sigstore/sigstore-python/pull/1363) + ## [3.6.2] diff --git a/Makefile b/Makefile index 23ddb2cec..c7945f307 100644 --- a/Makefile +++ b/Makefile @@ -177,6 +177,6 @@ update-embedded-root: $(VENV)/pyvenv.cfg . $(VENV_BIN)/activate && \ python -m sigstore plumbing update-trust-root cp ~/.local/share/sigstore-python/tuf/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/root.json \ - sigstore/_store/prod/root.json + sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/root.json cp ~/.cache/sigstore-python/tuf/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/trusted_root.json \ - sigstore/_store/prod/trusted_root.json + sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/trusted_root.json diff --git a/README.md b/README.md index 048502c5f..b77e8c282 100644 --- a/README.md +++ b/README.md @@ -121,8 +121,7 @@ OpenID Connect options: --oidc-disable-ambient-providers Disable ambient OpenID Connect credential detection (e.g. on GitHub Actions) (default: False) - --oidc-issuer URL The OpenID Connect issuer to use (conflicts with - --staging) (default: https://oauth2.sigstore.dev/auth) + --oidc-issuer URL The OpenID Connect issuer to use (default: None) --oauth-force-oob Force an out-of-band OAuth flow and do not automatically start the default web browser (default: False) @@ -185,8 +184,7 @@ OpenID Connect options: --oidc-disable-ambient-providers Disable ambient OpenID Connect credential detection (e.g. on GitHub Actions) (default: False) - --oidc-issuer URL The OpenID Connect issuer to use (conflicts with - --staging) (default: https://oauth2.sigstore.dev/auth) + --oidc-issuer URL The OpenID Connect issuer to use (default: None) --oauth-force-oob Force an out-of-band OAuth flow and do not automatically start the default web browser (default: False) diff --git a/sigstore/_cli.py b/sigstore/_cli.py index 480512e63..5846fe753 100644 --- a/sigstore/_cli.py +++ b/sigstore/_cli.py @@ -39,7 +39,7 @@ from sigstore._internal.fulcio.client import ExpiredCertificate from sigstore._internal.rekor import _hashedrekord_from_parts from sigstore._internal.rekor.client import RekorClient -from sigstore._internal.trust import ClientTrustConfig, TrustedRoot +from sigstore._internal.trust import ClientTrustConfig from sigstore._utils import sha256_digest from sigstore.dsse import StatementBuilder, Subject from sigstore.dsse._predicate import ( @@ -51,7 +51,6 @@ from sigstore.hashes import Hashed from sigstore.models import Bundle, InvalidBundle from sigstore.oidc import ( - DEFAULT_OAUTH_ISSUER_URL, ExpiredIdentity, IdentityToken, Issuer, @@ -229,8 +228,8 @@ def _add_shared_oidc_options( "--oidc-issuer", metavar="URL", type=str, - default=os.getenv("SIGSTORE_OIDC_ISSUER", DEFAULT_OAUTH_ISSUER_URL), - help="The OpenID Connect issuer to use (conflicts with --staging)", + default=os.getenv("SIGSTORE_OIDC_ISSUER", None), + help="The OpenID Connect issuer to use", ) group.add_argument( "--oauth-force-oob", @@ -614,11 +613,7 @@ def main(args: list[str] | None = None) -> None: elif args.verify_subcommand == "github": _verify_github(args) elif args.subcommand == "get-identity-token": - identity = _get_identity(args) - if identity: - print(identity) - else: - _invalid_arguments(args, "No identity token supplied or detected!") + _get_identity_token(args) elif args.subcommand == "plumbing": if args.plumbing_subcommand == "fix-bundle": _fix_bundle(args) @@ -630,6 +625,17 @@ def main(args: list[str] | None = None) -> None: e.log_and_exit(_logger, args.verbose >= 1) +def _get_identity_token(args: argparse.Namespace) -> None: + """ + Output the OIDC authentication token + """ + identity = _get_identity(args, _get_trust_config(args)) + if identity: + print(identity) + else: + _invalid_arguments(args, "No identity token supplied or detected!") + + def _sign_common( args: argparse.Namespace, output_map: OutputMap, predicate: dict[str, Any] | None ) -> None: @@ -643,17 +649,8 @@ def _sign_common( not, it will use a hashedrekord. """ # Select the signing context to use. - if args.staging: - _logger.debug("sign: staging instances requested") - signing_ctx = SigningContext.staging() - elif args.trust_config: - trust_config = ClientTrustConfig.from_json(args.trust_config.read_text()) - signing_ctx = SigningContext._from_trust_config(trust_config) - else: - # If the user didn't request the staging instance or pass in an - # explicit client trust config, we're using the public good (i.e. - # production) instance. - signing_ctx = SigningContext.production() + trust_config = _get_trust_config(args) + signing_ctx = SigningContext.from_trust_config(trust_config) # The order of precedence for identities is as follows: # @@ -664,7 +661,7 @@ def _sign_common( if args.identity_token: identity = IdentityToken(args.identity_token) else: - identity = _get_identity(args) + identity = _get_identity(args, trust_config) if not identity: _invalid_arguments(args, "No identity token supplied or detected!") @@ -1009,14 +1006,8 @@ def _collect_verification_state( f"Missing verification materials for {(hashed)}: {', '.join(missing)}", ) - if args.staging: - _logger.debug("verify: staging instances requested") - verifier = Verifier.staging(offline=args.offline) - elif args.trust_config: - trust_config = ClientTrustConfig.from_json(args.trust_config.read_text()) - verifier = Verifier._from_trust_config(trust_config) - else: - verifier = Verifier.production(offline=args.offline) + trust_config = _get_trust_config(args) + verifier = Verifier(trusted_root=trust_config.trusted_root) all_materials = [] for file_or_hashed, materials in input_map.items(): @@ -1167,7 +1158,27 @@ def _verify_common( return None -def _get_identity(args: argparse.Namespace) -> Optional[IdentityToken]: +def _get_trust_config(args: argparse.Namespace) -> ClientTrustConfig: + """ + Return the client trust configuration (Sigstore service URLs, key material and lifetimes) + + The configuration may come from explicit argument (--trust-config) or from the TUF + repository of the used Sigstore instance. + """ + # Not all commands provide --offline + offline = getattr(args, "offline", False) + + if args.trust_config: + return ClientTrustConfig.from_json(args.trust_config.read_text()) + elif args.staging: + return ClientTrustConfig.staging(offline=offline) + else: + return ClientTrustConfig.production(offline=offline) + + +def _get_identity( + args: argparse.Namespace, trust_config: ClientTrustConfig +) -> Optional[IdentityToken]: token = None if not args.oidc_disable_ambient_providers: token = detect_credential() @@ -1176,12 +1187,10 @@ def _get_identity(args: argparse.Namespace) -> Optional[IdentityToken]: if token: return IdentityToken(token) - if args.staging: - issuer = Issuer.staging() - elif args.oidc_issuer == DEFAULT_OAUTH_ISSUER_URL: - issuer = Issuer.production() - else: + if args.oidc_issuer is not None: issuer = Issuer(args.oidc_issuer) + else: + issuer = Issuer(trust_config.signing_config.get_oidc_url()) if args.oidc_client_secret is None: args.oidc_client_secret = "" # nosec: B105 @@ -1198,6 +1207,7 @@ def _get_identity(args: argparse.Namespace) -> Optional[IdentityToken]: def _fix_bundle(args: argparse.Namespace) -> None: # NOTE: We could support `--trusted-root` here in the future, # for custom Rekor instances. + rekor = RekorClient.staging() if args.staging else RekorClient.production() raw_bundle = RawBundle.from_dict(json.loads(args.bundle.read_bytes())) @@ -1234,13 +1244,10 @@ def _fix_bundle(args: argparse.Namespace) -> None: def _update_trust_root(args: argparse.Namespace) -> None: - # Simply creating the TrustedRoot in online mode is enough to perform + # Simply creating the TrustConfig in online mode is enough to perform # a metadata update. - if args.staging: - trusted_root = TrustedRoot.staging(offline=False) - else: - trusted_root = TrustedRoot.production(offline=False) + config = _get_trust_config(args) _console.print( - f"Trust root updated: {len(trusted_root.get_fulcio_certs())} Fulcio certificates" + f"Trust root & signing config updated: {len(config.trusted_root.get_fulcio_certs())} Fulcio certificates" ) diff --git a/sigstore/_internal/fulcio/client.py b/sigstore/_internal/fulcio/client.py index 0552628d1..75da5114f 100644 --- a/sigstore/_internal/fulcio/client.py +++ b/sigstore/_internal/fulcio/client.py @@ -39,8 +39,6 @@ _logger = logging.getLogger(__name__) -DEFAULT_FULCIO_URL = "https://fulcio.sigstore.dev" -STAGING_FULCIO_URL = "https://fulcio.sigstage.dev" SIGNING_CERT_ENDPOINT = "/api/v2/signingCert" TRUST_BUNDLE_ENDPOINT = "/api/v2/trustBundle" @@ -163,7 +161,7 @@ def get(self) -> FulcioTrustBundleResponse: class FulcioClient: """The internal Fulcio client""" - def __init__(self, url: str = DEFAULT_FULCIO_URL) -> None: + def __init__(self, url: str) -> None: """Initialize the client""" _logger.debug(f"Fulcio client using URL: {url}") self.url = url @@ -180,20 +178,6 @@ def __del__(self) -> None: """ self.session.close() - @classmethod - def production(cls) -> FulcioClient: - """ - Returns a `FulcioClient` for the Sigstore production instance of Fulcio. - """ - return cls(DEFAULT_FULCIO_URL) - - @classmethod - def staging(cls) -> FulcioClient: - """ - Returns a `FulcioClient` for the Sigstore staging instance of Fulcio. - """ - return cls(STAGING_FULCIO_URL) - @property def signing_cert(self) -> FulcioSigningCert: """ diff --git a/sigstore/_internal/trust.py b/sigstore/_internal/trust.py index ae104e071..f77181ef0 100644 --- a/sigstore/_internal/trust.py +++ b/sigstore/_internal/trust.py @@ -62,8 +62,9 @@ PublicKey, key_id, load_der_public_key, + read_embedded, ) -from sigstore.errors import Error, MetadataError, VerificationError +from sigstore.errors import Error, MetadataError, TUFError, VerificationError def _is_timerange_valid(period: TimeRange | None, *, allow_expired: bool) -> bool: @@ -402,9 +403,7 @@ def get_tsa_urls(self) -> list[str]: but may return more in future. """ url = self._get_valid_service_url(self._inner.tsa_urls) - if not url: - raise Error("No valid Timestamp Authority found in signing config") - return [url] + return [] if url is None else [url] class TrustedRoot: @@ -453,44 +452,6 @@ def from_file( inner = _TrustedRoot().from_json(Path(path).read_bytes()) return cls(inner) - @classmethod - def from_tuf( - cls, - url: str, - offline: bool = False, - ) -> TrustedRoot: - """Create a new trust root from a TUF repository. - - If `offline`, will use trust root in local TUF cache. Otherwise will - update the trust root from remote TUF repository. - """ - path = TrustUpdater(url, offline).get_trusted_root_path() - return cls.from_file(path) - - @classmethod - def production( - cls, - offline: bool = False, - ) -> TrustedRoot: - """Create new trust root from Sigstore production TUF repository. - - If `offline`, will use trust root in local TUF cache. Otherwise will - update the trust root from remote TUF repository. - """ - return cls.from_tuf(DEFAULT_TUF_URL, offline) - - @classmethod - def staging( - cls, - offline: bool = False, - ) -> TrustedRoot: - """Create new trust root from Sigstore staging TUF repository. - - If `offline`, will use trust root in local TUF cache. Otherwise will - update the trust root from remote TUF repository. - """ - return cls.from_tuf(STAGING_TUF_URL, offline) - def _get_tlog_keys( self, tlogs: list[TransparencyLogInstance], purpose: KeyringPurpose ) -> Iterable[_PublicKey]: @@ -575,6 +536,66 @@ def from_json(cls, raw: str) -> ClientTrustConfig: inner = _ClientTrustConfig().from_json(raw) return cls(inner) + @classmethod + def production( + cls, + offline: bool = False, + ) -> ClientTrustConfig: + """Create new trust config from Sigstore production TUF repository. + + If `offline`, will use data in local TUF cache. Otherwise will + update the data from remote TUF repository. + """ + return cls.from_tuf(DEFAULT_TUF_URL, offline) + + @classmethod + def staging( + cls, + offline: bool = False, + ) -> ClientTrustConfig: + """Create new trust config from Sigstore staging TUF repository. + + If `offline`, will use data in local TUF cache. Otherwise will + update the data from remote TUF repository. + """ + return cls.from_tuf(STAGING_TUF_URL, offline) + + @classmethod + def from_tuf( + cls, + url: str, + offline: bool = False, + ) -> ClientTrustConfig: + """Create a new trust config from a TUF repository. + + If `offline`, will use data in local TUF cache. Otherwise will + update the trust config from remote TUF repository. + """ + updater = TrustUpdater(url, offline) + + tr_path = updater.get_trusted_root_path() + inner_tr = _TrustedRoot().from_json(Path(tr_path).read_bytes()) + + try: + sc_path = updater.get_signing_config_path() + inner_sc = _SigningConfig().from_json(Path(sc_path).read_bytes()) + except TUFError as e: + # TUF repo may not have signing config yet: hard code values for prod: + # https://github.com/sigstore/sigstore-python/issues/1388 + if url == DEFAULT_TUF_URL: + embedded = read_embedded("signing_config.v0.2.json", url) + inner_sc = _SigningConfig().from_json(embedded) + else: + raise e + + return cls( + _ClientTrustConfig( + ClientTrustConfig.ClientTrustConfigType.CONFIG_0_1, + inner_tr, + inner_sc, + ) + ) + def __init__(self, inner: _ClientTrustConfig) -> None: """ @api private diff --git a/sigstore/_internal/tuf.py b/sigstore/_internal/tuf.py index 265be87a0..c38becb61 100644 --- a/sigstore/_internal/tuf.py +++ b/sigstore/_internal/tuf.py @@ -29,7 +29,7 @@ from sigstore import __version__ from sigstore._utils import read_embedded -from sigstore.errors import RootError, TUFError +from sigstore.errors import TUFError _logger = logging.getLogger(__name__) @@ -70,8 +70,9 @@ def __init__(self, url: str, offline: bool = False) -> None: """ Create a new `TrustUpdater`, pulling from the given `url`. - The URL is expected to match one of `sigstore-python`'s known TUF - roots, i.e. for the production or staging Sigstore TUF repos. + TrustUpdater expects that either embedded data contains + a root.json for this url or that local data has been initialized + already. If not `offline`, TrustUpdater will update the TUF metadata from the remote repository. @@ -79,25 +80,17 @@ def __init__(self, url: str, offline: bool = False) -> None: self._repo_url = url self._metadata_dir, self._targets_dir = _get_dirs(url) - rsrc_prefix: str - if self._repo_url == DEFAULT_TUF_URL: - rsrc_prefix = "prod" - elif self._repo_url == STAGING_TUF_URL: - rsrc_prefix = "staging" - else: - raise RootError - - # Initialize targets cache dir + # Populate targets cache so we don't have to download these versions self._targets_dir.mkdir(parents=True, exist_ok=True) - trusted_root_target = self._targets_dir / "trusted_root.json" - - if not trusted_root_target.exists(): - try: - trusted_root_json = read_embedded("trusted_root.json", rsrc_prefix) - except FileNotFoundError as e: - raise RootError from e - trusted_root_target.write_bytes(trusted_root_json) + for artifact in ["trusted_root.json", "signing_config.v0.2.json"]: + artifact_path = self._targets_dir / artifact + if not artifact_path.exists(): + try: + data = read_embedded(artifact, url) + artifact_path.write_bytes(data) + except FileNotFoundError: + pass # this is ok: e.g. signing_config is not in prod repository yet _logger.debug(f"TUF metadata: {self._metadata_dir}") _logger.debug(f"TUF targets cache: {self._targets_dir}") @@ -110,9 +103,12 @@ def __init__(self, url: str, offline: bool = False) -> None: else: # Initialize and update the toplevel TUF metadata try: - root_json = read_embedded("root.json", rsrc_prefix) - except FileNotFoundError as e: - raise RootError from e + root_json = read_embedded("root.json", url) + except FileNotFoundError: + # embedded root not found: we can still initialize _if_ the local metadata + # exists already + root_json = None + self._updater = Updater( metadata_dir=str(self._metadata_dir), metadata_base_url=self._repo_url, @@ -121,6 +117,7 @@ def __init__(self, url: str, offline: bool = False) -> None: config=UpdaterConfig(app_user_agent=f"sigstore-python/{__version__}"), bootstrap=root_json, ) + try: self._updater.refresh() except Exception as e: @@ -148,3 +145,26 @@ def get_trusted_root_path(self) -> str: _logger.debug("Found and verified trusted root") return path + + @lru_cache() + def get_signing_config_path(self) -> str: + """Return local path to currently valid signing config file""" + if not self._updater: + _logger.debug("Using unverified signing config from cache") + return str(self._targets_dir / "signing_config.v0.2.json") + + root_info = self._updater.get_targetinfo("signing_config.v0.2.json") + if root_info is None: + raise TUFError("Unsupported TUF configuration: no signing config") + path = self._updater.find_cached_target(root_info) + if path is None: + try: + path = self._updater.download_target(root_info) + except ( + TUFExceptions.DownloadError, + TUFExceptions.RepositoryError, + ) as e: + raise TUFError("Failed to download signing config") from e + + _logger.debug("Found and verified signing config") + return path diff --git a/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/root.json b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/root.json new file mode 100644 index 000000000..9206f75be --- /dev/null +++ b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/root.json @@ -0,0 +1,107 @@ +{ + "signatures": [ + { + "keyid": "aa61e09f6af7662ac686cf0c6364079f63d3e7a86836684eeced93eace3acd81", + "sig": "3044022064ac6af7f922e3bc8ac095d1fb59c5e65b52c8b378d3777b9223fc63b65c1f05022022a3722f464b3cfb985cdd76b76790533c5ac81613dade8f3a1136d4473dc466" + }, + { + "keyid": "61f9609d2655b346fcebccd66b509d5828168d5e447110e261f0bcc8553624bc", + "sig": "3046022100ef742d08c803a87e4eabbefbad528e40bdbe7aa9dcdcdcc024aa256315c8bcf202210089e444aebb431f743fad85cecbb16a3cfd62b624dbd37a9bfdce21135659bd8b" + }, + { + "keyid": "9471fbda95411d10109e467ad526082d15f14a38de54ea2ada9687ab39d8e237", + "sig": "" + }, + { + "keyid": "0374a9e18a20a2103736cb4277e2fdd7f8453642c7d9eaf4ad8aee9cf2d47bb5", + "sig": "" + } + ], + "signed": { + "_type": "root", + "consistent_snapshot": true, + "expires": "2025-08-01T13:24:50Z", + "keys": { + "0374a9e18a20a2103736cb4277e2fdd7f8453642c7d9eaf4ad8aee9cf2d47bb5": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEoxkvDOmtGEknB3M+ZkPts8joDM0X\nIH5JZwPlgC2CXs/eqOuNF8AcEWwGYRiDhV/IMlQw5bg8PLICQcgsbrDiKg==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@mnm678" + }, + "61f9609d2655b346fcebccd66b509d5828168d5e447110e261f0bcc8553624bc": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE++Wv+DcLRk+mfkmlpCwl1GUi9EMh\npBUTz8K0fH7bE4mQuViGSyWA/eyMc0HvzZi6Xr0diHw0/lUPBvok214YQw==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@kommendorkapten" + }, + "9471fbda95411d10109e467ad526082d15f14a38de54ea2ada9687ab39d8e237": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFHDb85JH+JYR1LQmxiz4UMokVMnP\nxKoWpaEnFCKXH8W4Fc/DfIxMnkpjCuvWUBdJXkO0aDIxwsij8TOFh2R7dw==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@joshuagl" + }, + "aa61e09f6af7662ac686cf0c6364079f63d3e7a86836684eeced93eace3acd81": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEohqIdE+yTl4OxpX8ZxNUPrg3SL9H\nBDnhZuceKkxy2oMhUOxhWweZeG3bfM1T4ZLnJimC6CAYVU5+F5jZCoftRw==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-keyowner": "@jku" + }, + "c3479007e861445ce5dc109d9661ed77b35bbc0e3f161852c46114266fc2daa4": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExxmEtmhF5U+i+v/6he4BcSLzCgMx\n/0qSrvDg6bUWwUrkSKS2vDpcJrhGy5fmmhRrGawjPp1ALpC3y1kqFTpXDg==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-online-uri": "gcpkms:projects/projectsigstore-staging/locations/global/keyRings/tuf-keyring/cryptoKeys/tuf-key/cryptoKeyVersions/2" + } + }, + "roles": { + "root": { + "keyids": [ + "aa61e09f6af7662ac686cf0c6364079f63d3e7a86836684eeced93eace3acd81", + "61f9609d2655b346fcebccd66b509d5828168d5e447110e261f0bcc8553624bc", + "9471fbda95411d10109e467ad526082d15f14a38de54ea2ada9687ab39d8e237", + "0374a9e18a20a2103736cb4277e2fdd7f8453642c7d9eaf4ad8aee9cf2d47bb5" + ], + "threshold": 2 + }, + "snapshot": { + "keyids": [ + "c3479007e861445ce5dc109d9661ed77b35bbc0e3f161852c46114266fc2daa4" + ], + "threshold": 1, + "x-tuf-on-ci-expiry-period": 3650, + "x-tuf-on-ci-signing-period": 365 + }, + "targets": { + "keyids": [ + "aa61e09f6af7662ac686cf0c6364079f63d3e7a86836684eeced93eace3acd81", + "61f9609d2655b346fcebccd66b509d5828168d5e447110e261f0bcc8553624bc", + "9471fbda95411d10109e467ad526082d15f14a38de54ea2ada9687ab39d8e237", + "0374a9e18a20a2103736cb4277e2fdd7f8453642c7d9eaf4ad8aee9cf2d47bb5" + ], + "threshold": 1 + }, + "timestamp": { + "keyids": [ + "c3479007e861445ce5dc109d9661ed77b35bbc0e3f161852c46114266fc2daa4" + ], + "threshold": 1, + "x-tuf-on-ci-expiry-period": 7, + "x-tuf-on-ci-signing-period": 6 + } + }, + "spec_version": "1.0", + "version": 11, + "x-tuf-on-ci-expiry-period": 182, + "x-tuf-on-ci-signing-period": 35 + } +} \ No newline at end of file diff --git a/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/signing_config.v0.2.json b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/signing_config.v0.2.json new file mode 100644 index 000000000..fe66ad97b --- /dev/null +++ b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/signing_config.v0.2.json @@ -0,0 +1,45 @@ +{ + "mediaType": "application/vnd.dev.sigstore.signingconfig.v0.2+json", + "caUrls": [ + { + "url": "https://fulcio.sigstage.dev", + "majorApiVersion": 1, + "validFor": { + "start": "2022-04-14T21:38:40Z" + } + } + ], + "oidcUrls": [ + { + "url": "https://oauth2.sigstage.dev/auth", + "majorApiVersion": 1, + "validFor": { + "start": "2025-04-16T00:00:00Z" + } + } + ], + "rekorTlogUrls": [ + { + "url": "https://rekor.sigstage.dev", + "majorApiVersion": 1, + "validFor": { + "start": "2021-01-12T11:53:27Z" + } + } + ], + "tsaUrls": [ + { + "url": "https://timestamp.sigstage.dev/api/v1/timestamp", + "majorApiVersion": 1, + "validFor": { + "start": "2025-04-09T00:00:00Z" + } + } + ], + "rekorTlogConfig": { + "selector": "ANY" + }, + "tsaConfig": { + "selector": "ANY" + } +} \ No newline at end of file diff --git a/sigstore/_store/staging/trusted_root.json b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/trusted_root.json similarity index 61% rename from sigstore/_store/staging/trusted_root.json rename to sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/trusted_root.json index f5b8853e7..8691ef5d3 100644 --- a/sigstore/_store/staging/trusted_root.json +++ b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstage.dev/trusted_root.json @@ -8,7 +8,7 @@ "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDODRU688UYGuy54mNUlaEBiQdTE9nYLr0lg6RXowI/QV/RE1azBn4Eg5/2uTOMbhB1/gfcHzijzFi9Tk+g1Prg==", "keyDetails": "PKIX_ECDSA_P256_SHA_256", "validFor": { - "start": "2021-01-12T11:53:27.000Z" + "start": "2021-01-12T11:53:27Z" } }, "logId": { @@ -34,7 +34,7 @@ ] }, "validFor": { - "start": "2022-04-14T21:38:40.000Z" + "start": "2022-04-14T21:38:40Z" } } ], @@ -46,8 +46,8 @@ "rawBytes": "MIICCgKCAgEA27A2MPQXm0I0v7/Ly5BIauDjRZF5Jor9vU+QheoE2UIIsZHcyYq3slHzSSHy2lLj1ZD2d91CtJ492ZXqnBmsr4TwZ9jQ05tW2mGIRI8u2DqN8LpuNYZGz/f9SZrjhQQmUttqWmtu3UoLfKz6NbNXUnoo+NhZFcFRLXJ8VporVhuiAmL7zqT53cXR3yQfFPCUDeGnRksnlhVIAJc3AHZZSHQJ8DEXMhh35TVv2nYhTI3rID7GwjXXw4ocz7RGDD37ky6p39Tl5NB71gT1eSqhZhGHEYHIPXraEBd5+3w9qIuLWlp5Ej/K6Mu4ELioXKCUimCbwy+Cs8UhHFlqcyg4AysOHJwIadXIa8LsY51jnVSGrGOEBZevopmQPNPtyfFY3dmXSS+6Z3RD2Gd6oDnNGJzpSyEk410Ag5uvNDfYzJLCWX9tU8lIxNwdFYmIwpd89HijyRyoGnoJ3entd63cvKfuuix5r+GHyKp1Xm1L5j5AWM6P+z0xigwkiXnt+adexAl1J9wdDxv/pUFEESRF4DG8DFGVtbdH6aR1A5/vD4krO4tC1QYUSeyL5Mvsw8WRqIFHcXtgybtxylljvNcGMV1KXQC8UFDmpGZVDSHx6v3e/BHMrZ7gjoCCfVMZ/cFcQi0W2AIHPYEMH/C95J2r4XbHMRdYXpovpOoT5Ca78gsCAwEAAQ==", "keyDetails": "PKCS1_RSA_PKCS1V5", "validFor": { - "start": "2021-03-14T00:00:00.000Z", - "end": "2022-07-31T00:00:00.000Z" + "start": "2021-03-14T00:00:00Z", + "end": "2022-07-31T00:00:00Z" } }, "logId": { @@ -61,8 +61,8 @@ "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh99xuRi6slBFd8VUJoK/rLigy4bYeSYWO/fE6Br7r0D8NpMI94+A63LR/WvLxpUUGBpY8IJA3iU2telag5CRpA==", "keyDetails": "PKIX_ECDSA_P256_SHA_256", "validFor": { - "start": "2022-07-01T00:00:00.000Z", - "end": "2022-07-31T00:00:00.000Z" + "start": "2022-07-01T00:00:00Z", + "end": "2022-07-31T00:00:00Z" } }, "logId": { @@ -76,7 +76,7 @@ "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8gEDKNme8AnXuPBgHjrtXdS6miHqc24CRblNEOFpiJRngeq8Ko73Y+K18yRYVf1DXD4AVLwvKyzdNdl5n0jUSQ==", "keyDetails": "PKIX_ECDSA_P256_SHA_256", "validFor": { - "start": "2022-07-01T00:00:00.000Z" + "start": "2022-07-01T00:00:00Z" } }, "logId": { @@ -87,25 +87,22 @@ "timestampAuthorities": [ { "subject": { - "organization": "GitHub, Inc.", - "commonName": "Internal Services Root - staging" + "organization": "sigstore.dev", + "commonName": "sigstore-tsa-selfsigned" }, - "uri": "tsa.github.internal", + "uri": "https://timestamp.sigstage.dev/api/v1/timestamp", "certChain": { "certificates": [ { - "rawBytes": "MIICEzCCAZigAwIBAgIUMpRykCcZaSOBipYce6r2DlnM7vUwCgYIKoZIzj0EAwMwPDEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSMwIQYDVQQDExpUU0EgaW50ZXJtZWRpYXRlIC0gc3RhZ2luZzAeFw0yMzA2MTQxMjAwMDBaFw0yNDA2MTMxMjAwMDBaMDwxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEjMCEGA1UEAxMaVFNBIFRpbWVzdGFtcGluZyAtIHN0YWdpbmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWAMg1BEHAzb03PHUKJiRJZdXcKIL0K/ks3Ylq5F5YDRIxUN4o8yeIaCWXa6i16zi8nXMFsa+3XrYM8mUyi9F6o3gwdjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUr+RZdcTNo31p3FuR0pajelcnr40wHwYDVR0jBBgwFoAUCmpQzrB6hAnlizGx37LrhKEzsT4wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDaQAwZgIxAIPUlZB2/p5rpCM3HCn1R8G5TIIW6aZPKtfPWDkNQY0bpFu6e8Dkm2TV3jfgYExuBgIxAOA+vTlDDJoz/qTMMs8VSpw3AMgktlMEhd8V0E+aLW5OizfphuiidkqkqkbCwRSW1w==" - }, - { - "rawBytes": "MIICNzCCAb6gAwIBAgIUUXRsBKgGXjrJbdJCQPJMsjfyJcYwCgYIKoZIzj0EAwMwQjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSkwJwYDVQQDEyBJbnRlcm5hbCBTZXJ2aWNlcyBSb290IC0gc3RhZ2luZzAeFw0yMzA2MTQwMDAwMDBaFw0yODA2MTIwMDAwMDBaMDwxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEjMCEGA1UEAxMaVFNBIGludGVybWVkaWF0ZSAtIHN0YWdpbmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAS/upihrvu/9+w1Ybfog3B1a8KfQa1bn7DLcJz2iumo+oCfg2bcbyRWygu8zRmrzJKp4HgQHC4LZJEEWm/MNIN1o6wVVmiDTZw01tk4aInmRVF13VKMscdzW5Ho4sYaeOejezB5MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDCDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQKalDOsHqECeWLMbHfsuuEoTOxPjAfBgNVHSMEGDAWgBR04GYtT79vaQmAEPPEte8q+W1KRTAKBggqhkjOPQQDAwNnADBkAjBOTWZP1QYnmHpFqL73eSzhmSLiHs9pXsQghK0p8pvlAg0R9bxAyXGIZ8qx+k2iIGcCMDRQIScz0gu2Xef3++p2vFYouBsIKbqxv0raJuIlmGiYEvb22MDpAitevKAgqNVMEg==" + "rawBytes": "MIICDzCCAZagAwIBAgIUCjWhBmHV4kFzxomWp/J98n4DfKcwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTAzMjgwOTE0MDZaFw0zNTAzMjYwODE0MDZaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEx1v5F3HpD9egHuknpBFlRz7QBRDJu4aeVzt9zJLRY0lvmx1lF7WBM2c9AN8ZGPQsmDqHlJN2R/7+RxLkvlLzkc19IOx38t7mGGEcB7agUDdCF/Ky3RTLSK0Xo/0AgHQdo2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFKj8ZPYo3i7mO3NPVIxSxOGc3VOlMB8GA1UdIwQYMBaAFDsgRlletTJNRzDObmPuc3RH8gR9MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2cAMGQCMESvVS6GGtF33+J19TfwENWJXjRv4i0/HQFwLUSkX6TfV7g0nG8VnqNHJLvEpAtOjQIwUD3uywTXorQP1DgbV09rF9Yen+CEqs/iEpieJWPst280SSOZ5Na+dyPVk9/8SFk6" }, { - "rawBytes": "MIICCDCCAY6gAwIBAgIULHHP/UhbXJbdyZfT6gHgTzIYF4EwCgYIKoZIzj0EAwMwQjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSkwJwYDVQQDEyBJbnRlcm5hbCBTZXJ2aWNlcyBSb290IC0gc3RhZ2luZzAeFw0yMzA2MTQwMDAwMDBaFw0zMzA2MTEwMDAwMDBaMEIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEpMCcGA1UEAxMgSW50ZXJuYWwgU2VydmljZXMgUm9vdCAtIHN0YWdpbmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASocByKBUdzgtqRXcpe/AE5oPoDMWTQqz1/jUQOA8qoEjYBXg9gfGU5KHK/UdwQc4lxbZEA9nJS9vUQAMVV5Es9B4thNHThKR4hFmCL8kKIEoMzXx282Qr6x4ZHYk4tQsCjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1UdDgQWBBR04GYtT79vaQmAEPPEte8q+W1KRTAKBggqhkjOPQQDAwNoADBlAjBBOu3RtlH1FLvfHPhyoWJHgm+PSNrsWQLRkmWQgAfNPYsfO5fWyhAebMV3FpKVPBICMQCVaie4NAsGi+AHLDhGnPn4Qptz0LBH2So6AVJS24ICeDUDQxKeUTNkUsy6Qgg97/4=" + "rawBytes": "MIIB9zCCAXygAwIBAgIUCPExEFKiQh0dP4sp5ltmSYSSkFUwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTAzMjgwOTE0MDZaFw0zNTAzMjYwODE0MDZaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATt0tIDWyo4ARfL9BaSo0W5bJQEbKJTU/u7llvdjSI5aTkOAJa8tixn2+LEfPG4dMFdsMPtsIuU1qn2OqFiuMk6vHv/c+az25RQVY1oo50iMb0jIL3N4FgwhPFpZnCbQPOjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQ7IEZZXrUyTUcwzm5j7nN0R/IEfTAKBggqhkjOPQQDAwNpADBmAjEA2MI1VXgbf3dUOSc95hSRypBKOab18eh2xzQtxUsHvWeY+1iFgyMluUuNR6taoSmFAjEA31m2czguZhKYX+4JSKu5pRYhBTXAd8KKQ3xdPRX/qCaLvT2qJAEQ1YQM3EJRrtI7" } ] }, "validFor": { - "start": "2023-06-15T00:00:00Z" + "start": "2025-04-09T00:00:00Z" } } ] diff --git a/sigstore/_store/prod/root.json b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/root.json similarity index 100% rename from sigstore/_store/prod/root.json rename to sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/root.json diff --git a/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/signing_config.v0.2.json b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/signing_config.v0.2.json new file mode 100644 index 000000000..5a7b47cfb --- /dev/null +++ b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/signing_config.v0.2.json @@ -0,0 +1,39 @@ +{ + "comment": "Place holder for use until prod actually has a signing config: see ClientTrustConfig.from_tuf()", + "mediaType": "application/vnd.dev.sigstore.signingconfig.v0.2+json", + "caUrls": [ + { + "url": "https://fulcio.sigstore.dev", + "majorApiVersion": 1, + "validFor": { + "start": "2022-04-13T20:06:15.000Z" + } + } + ], + "oidcUrls": [ + { + "url": "https://oauth2.sigstore.dev/auth", + "majorApiVersion": 1, + "validFor": { + "start": "2025-04-30T00:00:00Z" + } + } + ], + "rekorTlogUrls": [ + { + "url": "https://rekor.sigstore.dev", + "majorApiVersion": 1, + "validFor": { + "start": "2021-01-12T11:53:27.000Z" + } + } + ], + "tsaUrls": [ + ], + "rekorTlogConfig": { + "selector": "ANY" + }, + "tsaConfig": { + "selector": "ANY" + } +} \ No newline at end of file diff --git a/sigstore/_store/prod/trusted_root.json b/sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/trusted_root.json similarity index 100% rename from sigstore/_store/prod/trusted_root.json rename to sigstore/_store/https%3A%2F%2Ftuf-repo-cdn.sigstore.dev/trusted_root.json diff --git a/sigstore/_store/staging/root.json b/sigstore/_store/staging/root.json deleted file mode 100644 index e506177b8..000000000 --- a/sigstore/_store/staging/root.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "signed": { - "_type": "root", - "spec_version": "1.0", - "version": 4, - "expires": "2029-03-05T22:50:21Z", - "keys": { - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600": { - "keytype": "ecdsa-sha2-nistp256", - "scheme": "ecdsa-sha2-nistp256", - "keyid_hash_algorithms": [ - "sha256", - "sha512" - ], - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXMZ7rD8tWDE4lK/+naJN7INMxNC7\nbMMANDqTQE7WpzyzffWOg59hc/MwbvJtvuxhO9mEu3GD3Cn0HffFlmVRiA==\n-----END PUBLIC KEY-----\n" - } - }, - "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda": { - "keytype": "ecdsa-sha2-nistp256", - "scheme": "ecdsa-sha2-nistp256", - "keyid_hash_algorithms": [ - "sha256", - "sha512" - ], - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEL3vL/VeaH6nBbo4rekyO4cc/QthS\n+nlyJXCXSnyIMAtLmVTa8Pf0qG6YIVaR0TmLkyk9YoSVsZakxuMTuaEwrg==\n-----END PUBLIC KEY-----\n" - } - } - }, - "roles": { - "root": { - "keyids": [ - "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda" - ], - "threshold": 1 - }, - "snapshot": { - "keyids": [ - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600" - ], - "threshold": 1 - }, - "targets": { - "keyids": [ - "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda" - ], - "threshold": 1 - }, - "timestamp": { - "keyids": [ - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600" - ], - "threshold": 1 - } - }, - "consistent_snapshot": true - }, - "signatures": [ - { - "keyid": "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda", - "sig": "3044022006fe8fff51d18753aeff141f81a962b8ac33f49831bbbec1334b2733ea96890002206e6f343c9c7b98a2ebd1f0b51aa5286ed3a4d48e271c77d88ea77499231bff5c" - } - ] -} \ No newline at end of file diff --git a/sigstore/_utils.py b/sigstore/_utils.py index 26c1c6b92..6c42cc67c 100644 --- a/sigstore/_utils.py +++ b/sigstore/_utils.py @@ -22,6 +22,7 @@ import hashlib import sys from typing import IO, NewType, Union +from urllib import parse from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import ec, ed25519, rsa @@ -207,12 +208,13 @@ def _sha256_streaming(io: IO[bytes]) -> bytes: return sha256.digest() -def read_embedded(name: str, prefix: str) -> bytes: +def read_embedded(name: str, url: str) -> bytes: """ - Read a resource embedded in this distribution of sigstore-python, - returning its contents as bytes. + Read a resource for a given TUF repository embedded in this distribution + of sigstore-python, returning its contents as bytes. """ - b: bytes = resources.files("sigstore._store").joinpath(prefix, name).read_bytes() + embed_dir = parse.quote(url, safe="") + b: bytes = resources.files("sigstore._store").joinpath(embed_dir, name).read_bytes() return b diff --git a/sigstore/oidc.py b/sigstore/oidc.py index c401dff59..414bf715b 100644 --- a/sigstore/oidc.py +++ b/sigstore/oidc.py @@ -34,9 +34,6 @@ from sigstore._internal import USER_AGENT from sigstore.errors import Error, NetworkError -DEFAULT_OAUTH_ISSUER_URL = "https://oauth2.sigstore.dev/auth" -STAGING_OAUTH_ISSUER_URL = "https://oauth2.sigstage.dev/auth" - # See: https://github.com/sigstore/fulcio/blob/b2186c0/pkg/config/config.go#L182-L201 _KNOWN_OIDC_ISSUERS = { "https://accounts.google.com": "email", @@ -271,20 +268,6 @@ def __init__(self, base_url: str) -> None: except ValueError as exc: raise IssuerError(f"OIDC issuer returned invalid configuration: {exc}") - @classmethod - def production(cls) -> Issuer: - """ - Returns an `Issuer` configured against Sigstore's production-level services. - """ - return cls(DEFAULT_OAUTH_ISSUER_URL) - - @classmethod - def staging(cls) -> Issuer: - """ - Returns an `Issuer` configured against Sigstore's staging-level services. - """ - return cls(STAGING_OAUTH_ISSUER_URL) - def identity_token( # nosec: B107 self, client_id: str = "sigstore", diff --git a/sigstore/sign.py b/sigstore/sign.py index ffe6fbdb1..643cc7960 100644 --- a/sigstore/sign.py +++ b/sigstore/sign.py @@ -324,29 +324,7 @@ def __init__( self._tsa_clients = tsa_clients or [] @classmethod - def production(cls) -> SigningContext: - """ - Return a `SigningContext` instance configured against Sigstore's production-level services. - """ - return cls( - fulcio=FulcioClient.production(), - rekor=RekorClient.production(), - trusted_root=TrustedRoot.production(), - ) - - @classmethod - def staging(cls) -> SigningContext: - """ - Return a `SignerContext` instance configured against Sigstore's staging-level services. - """ - return cls( - fulcio=FulcioClient.staging(), - rekor=RekorClient.staging(), - trusted_root=TrustedRoot.staging(), - ) - - @classmethod - def _from_trust_config(cls, trust_config: ClientTrustConfig) -> SigningContext: + def from_trust_config(cls, trust_config: ClientTrustConfig) -> SigningContext: """ Create a `SigningContext` from the given `ClientTrustConfig`. diff --git a/sigstore/verify/verifier.py b/sigstore/verify/verifier.py index 471b5e1f4..e05a3d7c7 100644 --- a/sigstore/verify/verifier.py +++ b/sigstore/verify/verifier.py @@ -96,8 +96,9 @@ def production(cls, *, offline: bool = False) -> Verifier: the verifier uses the Trusted Root in the local TUF cache. If `False`, a TUF repository refresh is attempted. """ + config = ClientTrustConfig.production(offline=offline) return cls( - trusted_root=TrustedRoot.production(offline=offline), + trusted_root=config.trusted_root, ) @classmethod @@ -109,19 +110,9 @@ def staging(cls, *, offline: bool = False) -> Verifier: the verifier uses the Trusted Root in the local TUF cache. If `False`, a TUF repository refresh is attempted. """ + config = ClientTrustConfig.staging(offline=offline) return cls( - trusted_root=TrustedRoot.staging(offline=offline), - ) - - @classmethod - def _from_trust_config(cls, trust_config: ClientTrustConfig) -> Verifier: - """ - Create a `Verifier` from the given `ClientTrustConfig`. - - @api private - """ - return cls( - trusted_root=trust_config.trusted_root, + trusted_root=config.trusted_root, ) def _verify_signed_timestamp( diff --git a/test/assets/staging-tuf/13.snapshot.json b/test/assets/staging-tuf/13.snapshot.json new file mode 100644 index 000000000..1eb631496 --- /dev/null +++ b/test/assets/staging-tuf/13.snapshot.json @@ -0,0 +1,22 @@ +{ + "signatures": [ + { + "keyid": "c3479007e861445ce5dc109d9661ed77b35bbc0e3f161852c46114266fc2daa4", + "sig": "3046022100c36bf62c4b5f72f8e3defc1af05148518a282394b304f0e0a154c10feeaee9a1022100ed8bb83508e1fcd3906bdf71af0da30f066a048db0f8da589db7dfe5f1458537" + } + ], + "signed": { + "_type": "snapshot", + "expires": "2035-04-30T07:17:48Z", + "meta": { + "registry.npmjs.org.json": { + "version": 5 + }, + "targets.json": { + "version": 13 + } + }, + "spec_version": "1.0", + "version": 13 + } +} \ No newline at end of file diff --git a/test/assets/staging-tuf/13.targets.json b/test/assets/staging-tuf/13.targets.json new file mode 100644 index 000000000..e95d33949 --- /dev/null +++ b/test/assets/staging-tuf/13.targets.json @@ -0,0 +1,151 @@ +{ + "signatures": [ + { + "keyid": "aa61e09f6af7662ac686cf0c6364079f63d3e7a86836684eeced93eace3acd81", + "sig": "3046022100c1968b55a40906590168f9b9ecd2251ef4056f79e9067fb80374ad4bc1a770a102210085d17acfcd779f8d004b54e0c5170e9e4629487603859bf85f4519d46ef3a994" + }, + { + "keyid": "61f9609d2655b346fcebccd66b509d5828168d5e447110e261f0bcc8553624bc", + "sig": "3046022100fc18a5d048d94be077f240866f344bc679098dde898f4d61ed44ba1cd37f86ec022100cc3b9d06b15ea56f953afbd3917a53c674b86e94ee5d3ffb160f3f465c2fee70" + }, + { + "keyid": "9471fbda95411d10109e467ad526082d15f14a38de54ea2ada9687ab39d8e237", + "sig": "" + }, + { + "keyid": "0374a9e18a20a2103736cb4277e2fdd7f8453642c7d9eaf4ad8aee9cf2d47bb5", + "sig": "" + } + ], + "signed": { + "_type": "targets", + "delegations": { + "keys": { + "5e3a4021b11a425fd0a444f1670457ce5b15bbe036144f2417426f7f4b9721da": { + "keytype": "ecdsa", + "keyval": { + "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEVfei1dXQRVeArCMcTDgxJtYg+Fs7\nV87DjhQbGlRJPyC7SW5TbNNkmvpmi4LeTv6moLVZ7T2nVqiRZbSkD+cf8w==\n-----END PUBLIC KEY-----\n" + }, + "scheme": "ecdsa-sha2-nistp256", + "x-tuf-on-ci-online-uri": "azurekms://npm-tuf-delegate.vault.azure.net/keys/npm-tuf-delegate-2024-08/e2772c1d01ca400da571096889f1660e" + } + }, + "roles": [ + { + "keyids": [ + "5e3a4021b11a425fd0a444f1670457ce5b15bbe036144f2417426f7f4b9721da" + ], + "name": "registry.npmjs.org", + "paths": [ + "registry.npmjs.org/*" + ], + "terminating": true, + "threshold": 1 + } + ] + }, + "expires": "2035-04-27T13:57:15Z", + "spec_version": "1.0", + "targets": { + "ctfe.pub": { + "custom": { + "sigstore": { + "status": "Active", + "uri": "https://ctfe.sigstage.dev/test", + "usage": "CTFE" + } + }, + "hashes": { + "sha256": "bd7a6812a1f239dfddbbb19d36c7423d21510da56d466ba5018401959cd66037" + }, + "length": 775 + }, + "ctfe_2022.pub": { + "custom": { + "sigstore": { + "status": "Active", + "uri": "https://ctfe.sigstage.dev/2022", + "usage": "CTFE" + } + }, + "hashes": { + "sha256": "910d899c7763563095a0fe684c8477573fedc19a78586de6ecfbfd8f289f5423" + }, + "length": 178 + }, + "ctfe_2022_2.pub": { + "custom": { + "sigstore": { + "status": "Active", + "uri": "https://ctfe.sigstage.dev/2022-2", + "usage": "CTFE" + } + }, + "hashes": { + "sha256": "7054b4f15f969daca1c242bb9e77527abaf0b9acf9818a2a35144e4b32b20dc6" + }, + "length": 178 + }, + "fulcio.crt.pem": { + "custom": { + "sigstore": { + "status": "Active", + "uri": "https://fulcio.sigstage.dev", + "usage": "Fulcio" + } + }, + "hashes": { + "sha256": "0e6b0442485ad552bea5f62f11c29e2acfda35307d7538430b4cc1dbef49bff1" + }, + "length": 741 + }, + "fulcio_intermediate.crt.pem": { + "custom": { + "sigstore": { + "status": "Active", + "uri": "https://fulcio.sigstage.dev", + "usage": "Fulcio" + } + }, + "hashes": { + "sha256": "782868913fe13c385105ddf33e827191386f58da40a931f2075a7e27b1b6ac7b" + }, + "length": 790 + }, + "rekor.pub": { + "custom": { + "sigstore": { + "status": "Active", + "uri": "https://rekor.sigstage.dev", + "usage": "Rekor" + } + }, + "hashes": { + "sha256": "1d80b8f72505a43e65e6e125247cd508f61b459dc457c1d1bcb78d96e1760959" + }, + "length": 178 + }, + "signing_config.json": { + "hashes": { + "sha256": "bf52f4aa7dc05849a6c8c760f5ae2ea4047b03b59505d9280efe02a1ec63c6e8" + }, + "length": 220 + }, + "signing_config.v0.2.json": { + "hashes": { + "sha256": "cb9a48c332a0d515db7760ad6972a09a0f4ed721fe5e839b70371e0d0802abe2" + }, + "length": 885 + }, + "trusted_root.json": { + "hashes": { + "sha256": "3f8ab41b9311910106caf66cb5e4117b1bee0d1871def4e816c6c60cee69d421" + }, + "length": 6399 + } + }, + "version": 13, + "x-tuf-on-ci-expiry-period": 3650, + "x-tuf-on-ci-signing-period": 365 + } +} \ No newline at end of file diff --git a/test/assets/staging-tuf/2.registry.npmjs.org.json b/test/assets/staging-tuf/2.registry.npmjs.org.json deleted file mode 100644 index d53f15267..000000000 --- a/test/assets/staging-tuf/2.registry.npmjs.org.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "signed": { - "_type": "targets", - "spec_version": "1.0", - "version": 2, - "expires": "2028-09-29T21:10:55Z", - "targets": { - "registry.npmjs.org/keys.json": { - "length": 1017, - "hashes": { - "sha256": "7a8ec9678ad824cdccaa7a6dc0961caf8f8df61bc7274189122c123446248426", - "sha512": "881a853ee92d8cf513b07c164fea36b22a7305c256125bdfffdc5c65a4205c4c3fc2b5bcc98964349167ea68d40b8cd02551fcaa870a30d4601ba1caf6f63699" - } - } - } - }, - "signatures": [ - { - "keyid": "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600", - "sig": "3045022057b9fc8afd9feaf45cf3173d3420fdcd6b68c22e4ef7b47e80a6887e1f20246c0221009f39c42fac630ab354c5197288c9a82ab6d46a59b423f81fff719da57cff16ab" - } - ] -} \ No newline at end of file diff --git a/test/assets/staging-tuf/4.root.json b/test/assets/staging-tuf/4.root.json deleted file mode 100644 index e506177b8..000000000 --- a/test/assets/staging-tuf/4.root.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "signed": { - "_type": "root", - "spec_version": "1.0", - "version": 4, - "expires": "2029-03-05T22:50:21Z", - "keys": { - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600": { - "keytype": "ecdsa-sha2-nistp256", - "scheme": "ecdsa-sha2-nistp256", - "keyid_hash_algorithms": [ - "sha256", - "sha512" - ], - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXMZ7rD8tWDE4lK/+naJN7INMxNC7\nbMMANDqTQE7WpzyzffWOg59hc/MwbvJtvuxhO9mEu3GD3Cn0HffFlmVRiA==\n-----END PUBLIC KEY-----\n" - } - }, - "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda": { - "keytype": "ecdsa-sha2-nistp256", - "scheme": "ecdsa-sha2-nistp256", - "keyid_hash_algorithms": [ - "sha256", - "sha512" - ], - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEL3vL/VeaH6nBbo4rekyO4cc/QthS\n+nlyJXCXSnyIMAtLmVTa8Pf0qG6YIVaR0TmLkyk9YoSVsZakxuMTuaEwrg==\n-----END PUBLIC KEY-----\n" - } - } - }, - "roles": { - "root": { - "keyids": [ - "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda" - ], - "threshold": 1 - }, - "snapshot": { - "keyids": [ - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600" - ], - "threshold": 1 - }, - "targets": { - "keyids": [ - "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda" - ], - "threshold": 1 - }, - "timestamp": { - "keyids": [ - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600" - ], - "threshold": 1 - } - }, - "consistent_snapshot": true - }, - "signatures": [ - { - "keyid": "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda", - "sig": "3044022006fe8fff51d18753aeff141f81a962b8ac33f49831bbbec1334b2733ea96890002206e6f343c9c7b98a2ebd1f0b51aa5286ed3a4d48e271c77d88ea77499231bff5c" - } - ] -} \ No newline at end of file diff --git a/test/assets/staging-tuf/4.snapshot.json b/test/assets/staging-tuf/4.snapshot.json deleted file mode 100644 index 013e76b16..000000000 --- a/test/assets/staging-tuf/4.snapshot.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "signed": { - "_type": "snapshot", - "spec_version": "1.0", - "version": 4, - "expires": "2028-09-26T22:52:19Z", - "meta": { - "registry.npmjs.org.json": { - "length": 715, - "hashes": { - "sha256": "4dc55b2b468b0d1c9629c457c5cfce2cc1c330c59c5a7cf71cb7549f1ef76f1d", - "sha512": "278f4b6112db9d4bd9366e1717cf710ad7eacf44605fd4f894c3374fc5dff850a1a03c24c4a885d050a4ac1a86fa6929537fae12d8c2864c8e0c239b382d5556" - }, - "version": 2 - }, - "targets.json": { - "length": 4120, - "hashes": { - "sha256": "83107aa29ad45bf40c198d370b299272df612e5f03db2c06c7f90fca1fb1af5e", - "sha512": "b32a2ce40ec74aa453c34a6458a06abd5a0d28ded1114db9b8d49cb26eb6cce81790c9d019d5c9d88359ac78bddafe335225285485fa5443283351217da73e5d" - }, - "version": 4 - } - } - }, - "signatures": [ - { - "keyid": "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600", - "sig": "3046022100be9bafe7c1ce4efb9d39082a164eca2205103e701164512b6c9286909e4515e6022100caab046152056039b0e72a2246ce4e9af2576fff0c56272d76a9653bdb7e502e" - } - ] -} \ No newline at end of file diff --git a/test/assets/staging-tuf/4.targets.json b/test/assets/staging-tuf/4.targets.json deleted file mode 100644 index 7aec6c837..000000000 --- a/test/assets/staging-tuf/4.targets.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "signed": { - "_type": "targets", - "spec_version": "1.0", - "version": 4, - "expires": "2029-03-05T22:50:21Z", - "targets": { - "ctfe.pub": { - "length": 775, - "hashes": { - "sha256": "bd7a6812a1f239dfddbbb19d36c7423d21510da56d466ba5018401959cd66037", - "sha512": "b861189e48df51186a39612230fba6b02af951f7b35ad9375e8ca182d0e085d470e26d69f7cd4d7450a0f223991e8e5a4ddf8f1968caa15255de8e37035af43a" - }, - "custom": { - "sigstore": { - "status": "Active", - "uri": "https://ctfe.sigstage.dev/test", - "usage": "CTFE" - } - } - }, - "ctfe_2022.pub": { - "length": 178, - "hashes": { - "sha256": "910d899c7763563095a0fe684c8477573fedc19a78586de6ecfbfd8f289f5423", - "sha512": "ab975a75600fc366a837536d0dcba841b755552d21bb114498ff8ac9d2403f76643f5b91269bce5d124a365514719a3edee9dcc2b046cb173f51af659911fcd3" - }, - "custom": { - "sigstore": { - "status": "Active", - "uri": "https://ctfe.sigstage.dev/2022", - "usage": "CTFE" - } - } - }, - "ctfe_2022_2.pub": { - "length": 178, - "hashes": { - "sha256": "7054b4f15f969daca1c242bb9e77527abaf0b9acf9818a2a35144e4b32b20dc6", - "sha512": "3d035f94e1b14ac84627a28afdbed9a34861fb84239f76d73aa1a99f52262bfd95c4fa0ee71f1fd7e3bfb998d89cd5e0f0eafcff9fa7fa87c6e23484fc1e0cec" - }, - "custom": { - "sigstore": { - "status": "Active", - "uri": "https://ctfe.sigstage.dev/2022-2", - "usage": "CTFE" - } - } - }, - "fulcio.crt.pem": { - "length": 741, - "hashes": { - "sha256": "0e6b0442485ad552bea5f62f11c29e2acfda35307d7538430b4cc1dbef49bff1", - "sha512": "c69ae618883a0c89c282c0943a1ad0c16b0a7788f74e47a1adefc631dac48a0c4449d8c3de7455ae7d772e43c4a87e341f180b0614a46a86006969f8a7b84532" - }, - "custom": { - "sigstore": { - "status": "Active", - "uri": "https://fulcio.sigstage.dev", - "usage": "Fulcio" - } - } - }, - "fulcio_intermediate.crt.pem": { - "length": 790, - "hashes": { - "sha256": "782868913fe13c385105ddf33e827191386f58da40a931f2075a7e27b1b6ac7b", - "sha512": "90659875a02f73d1026055427c6d857c556e410e23748ff88aeb493227610fd2f5fbdd95ef2a21565f91438dfb3e073f50c4c9dd06f9a601b5d9b064d5cb60b4" - }, - "custom": { - "sigstore": { - "status": "Active", - "uri": "https://fulcio.sigstage.dev", - "usage": "Fulcio" - } - } - }, - "rekor.pub": { - "length": 178, - "hashes": { - "sha256": "1d80b8f72505a43e65e6e125247cd508f61b459dc457c1d1bcb78d96e1760959", - "sha512": "09ab08698a67354a95d3b8897d9ce7eaef05f06f5ed5f0202d79c228579858ecc5816b7e1b7cc6786abe7d6aaa758e1fcb05900cb749235186c3bf9522d6d7ce" - }, - "custom": { - "sigstore": { - "status": "Active", - "uri": "https://rekor.sigstage.dev", - "usage": "Rekor" - } - } - }, - "trusted_root.json": { - "length": 7256, - "hashes": { - "sha256": "99f4f7728a889fa7db2fec893c387714a64aaf032fbe3035909fc8445effb857", - "sha512": "acf0438a71de70bbf1813c908545281e0c4a1e3aafa2ce36b82c1cc24a9cce5169e9dcfe85c31bb4f662e94fdd9a686fa54fbbfccff1888e51ebd73924c12495" - } - } - }, - "delegations": { - "keys": { - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600": { - "keytype": "ecdsa-sha2-nistp256", - "scheme": "ecdsa-sha2-nistp256", - "keyid_hash_algorithms": [ - "sha256", - "sha512" - ], - "keyval": { - "public": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEXMZ7rD8tWDE4lK/+naJN7INMxNC7\nbMMANDqTQE7WpzyzffWOg59hc/MwbvJtvuxhO9mEu3GD3Cn0HffFlmVRiA==\n-----END PUBLIC KEY-----\n" - } - } - }, - "roles": [ - { - "name": "registry.npmjs.org", - "keyids": [ - "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600" - ], - "threshold": 1, - "terminating": true, - "paths": [ - "registry.npmjs.org/*" - ] - } - ] - } - }, - "signatures": [ - { - "keyid": "c8e09a68b5821b75462ae0df52151c81deb7f1838246dc1da8c34cc91ec12bda", - "sig": "3045022100f96ad83711dcf8766cea141c0726c48ebdd982116eb5e8a29447ae956d93cc050220315ac2124fb8a66e2bbea4810bd857da8ba1abca1360f9b287d16647bdfcd066" - } - ] -} \ No newline at end of file diff --git a/test/assets/staging-tuf/targets/09ab08698a67354a95d3b8897d9ce7eaef05f06f5ed5f0202d79c228579858ecc5816b7e1b7cc6786abe7d6aaa758e1fcb05900cb749235186c3bf9522d6d7ce.rekor.pub b/test/assets/staging-tuf/targets/09ab08698a67354a95d3b8897d9ce7eaef05f06f5ed5f0202d79c228579858ecc5816b7e1b7cc6786abe7d6aaa758e1fcb05900cb749235186c3bf9522d6d7ce.rekor.pub deleted file mode 100644 index 4234e16c3..000000000 --- a/test/assets/staging-tuf/targets/09ab08698a67354a95d3b8897d9ce7eaef05f06f5ed5f0202d79c228579858ecc5816b7e1b7cc6786abe7d6aaa758e1fcb05900cb749235186c3bf9522d6d7ce.rekor.pub +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDODRU688UYGuy54mNUlaEBiQdTE9 -nYLr0lg6RXowI/QV/RE1azBn4Eg5/2uTOMbhB1/gfcHzijzFi9Tk+g1Prg== ------END PUBLIC KEY----- diff --git a/test/assets/staging-tuf/targets/3d035f94e1b14ac84627a28afdbed9a34861fb84239f76d73aa1a99f52262bfd95c4fa0ee71f1fd7e3bfb998d89cd5e0f0eafcff9fa7fa87c6e23484fc1e0cec.ctfe_2022_2.pub b/test/assets/staging-tuf/targets/3d035f94e1b14ac84627a28afdbed9a34861fb84239f76d73aa1a99f52262bfd95c4fa0ee71f1fd7e3bfb998d89cd5e0f0eafcff9fa7fa87c6e23484fc1e0cec.ctfe_2022_2.pub deleted file mode 100644 index 0f5eb8637..000000000 --- a/test/assets/staging-tuf/targets/3d035f94e1b14ac84627a28afdbed9a34861fb84239f76d73aa1a99f52262bfd95c4fa0ee71f1fd7e3bfb998d89cd5e0f0eafcff9fa7fa87c6e23484fc1e0cec.ctfe_2022_2.pub +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8gEDKNme8AnXuPBgHjrtXdS6miHq -c24CRblNEOFpiJRngeq8Ko73Y+K18yRYVf1DXD4AVLwvKyzdNdl5n0jUSQ== ------END PUBLIC KEY----- diff --git a/test/assets/staging-tuf/targets/99f4f7728a889fa7db2fec893c387714a64aaf032fbe3035909fc8445effb857.trusted_root.json b/test/assets/staging-tuf/targets/3f8ab41b9311910106caf66cb5e4117b1bee0d1871def4e816c6c60cee69d421.trusted_root.json similarity index 61% rename from test/assets/staging-tuf/targets/99f4f7728a889fa7db2fec893c387714a64aaf032fbe3035909fc8445effb857.trusted_root.json rename to test/assets/staging-tuf/targets/3f8ab41b9311910106caf66cb5e4117b1bee0d1871def4e816c6c60cee69d421.trusted_root.json index f5b8853e7..8691ef5d3 100644 --- a/test/assets/staging-tuf/targets/99f4f7728a889fa7db2fec893c387714a64aaf032fbe3035909fc8445effb857.trusted_root.json +++ b/test/assets/staging-tuf/targets/3f8ab41b9311910106caf66cb5e4117b1bee0d1871def4e816c6c60cee69d421.trusted_root.json @@ -8,7 +8,7 @@ "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDODRU688UYGuy54mNUlaEBiQdTE9nYLr0lg6RXowI/QV/RE1azBn4Eg5/2uTOMbhB1/gfcHzijzFi9Tk+g1Prg==", "keyDetails": "PKIX_ECDSA_P256_SHA_256", "validFor": { - "start": "2021-01-12T11:53:27.000Z" + "start": "2021-01-12T11:53:27Z" } }, "logId": { @@ -34,7 +34,7 @@ ] }, "validFor": { - "start": "2022-04-14T21:38:40.000Z" + "start": "2022-04-14T21:38:40Z" } } ], @@ -46,8 +46,8 @@ "rawBytes": "MIICCgKCAgEA27A2MPQXm0I0v7/Ly5BIauDjRZF5Jor9vU+QheoE2UIIsZHcyYq3slHzSSHy2lLj1ZD2d91CtJ492ZXqnBmsr4TwZ9jQ05tW2mGIRI8u2DqN8LpuNYZGz/f9SZrjhQQmUttqWmtu3UoLfKz6NbNXUnoo+NhZFcFRLXJ8VporVhuiAmL7zqT53cXR3yQfFPCUDeGnRksnlhVIAJc3AHZZSHQJ8DEXMhh35TVv2nYhTI3rID7GwjXXw4ocz7RGDD37ky6p39Tl5NB71gT1eSqhZhGHEYHIPXraEBd5+3w9qIuLWlp5Ej/K6Mu4ELioXKCUimCbwy+Cs8UhHFlqcyg4AysOHJwIadXIa8LsY51jnVSGrGOEBZevopmQPNPtyfFY3dmXSS+6Z3RD2Gd6oDnNGJzpSyEk410Ag5uvNDfYzJLCWX9tU8lIxNwdFYmIwpd89HijyRyoGnoJ3entd63cvKfuuix5r+GHyKp1Xm1L5j5AWM6P+z0xigwkiXnt+adexAl1J9wdDxv/pUFEESRF4DG8DFGVtbdH6aR1A5/vD4krO4tC1QYUSeyL5Mvsw8WRqIFHcXtgybtxylljvNcGMV1KXQC8UFDmpGZVDSHx6v3e/BHMrZ7gjoCCfVMZ/cFcQi0W2AIHPYEMH/C95J2r4XbHMRdYXpovpOoT5Ca78gsCAwEAAQ==", "keyDetails": "PKCS1_RSA_PKCS1V5", "validFor": { - "start": "2021-03-14T00:00:00.000Z", - "end": "2022-07-31T00:00:00.000Z" + "start": "2021-03-14T00:00:00Z", + "end": "2022-07-31T00:00:00Z" } }, "logId": { @@ -61,8 +61,8 @@ "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh99xuRi6slBFd8VUJoK/rLigy4bYeSYWO/fE6Br7r0D8NpMI94+A63LR/WvLxpUUGBpY8IJA3iU2telag5CRpA==", "keyDetails": "PKIX_ECDSA_P256_SHA_256", "validFor": { - "start": "2022-07-01T00:00:00.000Z", - "end": "2022-07-31T00:00:00.000Z" + "start": "2022-07-01T00:00:00Z", + "end": "2022-07-31T00:00:00Z" } }, "logId": { @@ -76,7 +76,7 @@ "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8gEDKNme8AnXuPBgHjrtXdS6miHqc24CRblNEOFpiJRngeq8Ko73Y+K18yRYVf1DXD4AVLwvKyzdNdl5n0jUSQ==", "keyDetails": "PKIX_ECDSA_P256_SHA_256", "validFor": { - "start": "2022-07-01T00:00:00.000Z" + "start": "2022-07-01T00:00:00Z" } }, "logId": { @@ -87,25 +87,22 @@ "timestampAuthorities": [ { "subject": { - "organization": "GitHub, Inc.", - "commonName": "Internal Services Root - staging" + "organization": "sigstore.dev", + "commonName": "sigstore-tsa-selfsigned" }, - "uri": "tsa.github.internal", + "uri": "https://timestamp.sigstage.dev/api/v1/timestamp", "certChain": { "certificates": [ { - "rawBytes": "MIICEzCCAZigAwIBAgIUMpRykCcZaSOBipYce6r2DlnM7vUwCgYIKoZIzj0EAwMwPDEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSMwIQYDVQQDExpUU0EgaW50ZXJtZWRpYXRlIC0gc3RhZ2luZzAeFw0yMzA2MTQxMjAwMDBaFw0yNDA2MTMxMjAwMDBaMDwxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEjMCEGA1UEAxMaVFNBIFRpbWVzdGFtcGluZyAtIHN0YWdpbmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWAMg1BEHAzb03PHUKJiRJZdXcKIL0K/ks3Ylq5F5YDRIxUN4o8yeIaCWXa6i16zi8nXMFsa+3XrYM8mUyi9F6o3gwdjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUr+RZdcTNo31p3FuR0pajelcnr40wHwYDVR0jBBgwFoAUCmpQzrB6hAnlizGx37LrhKEzsT4wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDaQAwZgIxAIPUlZB2/p5rpCM3HCn1R8G5TIIW6aZPKtfPWDkNQY0bpFu6e8Dkm2TV3jfgYExuBgIxAOA+vTlDDJoz/qTMMs8VSpw3AMgktlMEhd8V0E+aLW5OizfphuiidkqkqkbCwRSW1w==" - }, - { - "rawBytes": "MIICNzCCAb6gAwIBAgIUUXRsBKgGXjrJbdJCQPJMsjfyJcYwCgYIKoZIzj0EAwMwQjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSkwJwYDVQQDEyBJbnRlcm5hbCBTZXJ2aWNlcyBSb290IC0gc3RhZ2luZzAeFw0yMzA2MTQwMDAwMDBaFw0yODA2MTIwMDAwMDBaMDwxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEjMCEGA1UEAxMaVFNBIGludGVybWVkaWF0ZSAtIHN0YWdpbmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAS/upihrvu/9+w1Ybfog3B1a8KfQa1bn7DLcJz2iumo+oCfg2bcbyRWygu8zRmrzJKp4HgQHC4LZJEEWm/MNIN1o6wVVmiDTZw01tk4aInmRVF13VKMscdzW5Ho4sYaeOejezB5MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDCDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQKalDOsHqECeWLMbHfsuuEoTOxPjAfBgNVHSMEGDAWgBR04GYtT79vaQmAEPPEte8q+W1KRTAKBggqhkjOPQQDAwNnADBkAjBOTWZP1QYnmHpFqL73eSzhmSLiHs9pXsQghK0p8pvlAg0R9bxAyXGIZ8qx+k2iIGcCMDRQIScz0gu2Xef3++p2vFYouBsIKbqxv0raJuIlmGiYEvb22MDpAitevKAgqNVMEg==" + "rawBytes": "MIICDzCCAZagAwIBAgIUCjWhBmHV4kFzxomWp/J98n4DfKcwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTAzMjgwOTE0MDZaFw0zNTAzMjYwODE0MDZaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEx1v5F3HpD9egHuknpBFlRz7QBRDJu4aeVzt9zJLRY0lvmx1lF7WBM2c9AN8ZGPQsmDqHlJN2R/7+RxLkvlLzkc19IOx38t7mGGEcB7agUDdCF/Ky3RTLSK0Xo/0AgHQdo2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFKj8ZPYo3i7mO3NPVIxSxOGc3VOlMB8GA1UdIwQYMBaAFDsgRlletTJNRzDObmPuc3RH8gR9MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2cAMGQCMESvVS6GGtF33+J19TfwENWJXjRv4i0/HQFwLUSkX6TfV7g0nG8VnqNHJLvEpAtOjQIwUD3uywTXorQP1DgbV09rF9Yen+CEqs/iEpieJWPst280SSOZ5Na+dyPVk9/8SFk6" }, { - "rawBytes": "MIICCDCCAY6gAwIBAgIULHHP/UhbXJbdyZfT6gHgTzIYF4EwCgYIKoZIzj0EAwMwQjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSkwJwYDVQQDEyBJbnRlcm5hbCBTZXJ2aWNlcyBSb290IC0gc3RhZ2luZzAeFw0yMzA2MTQwMDAwMDBaFw0zMzA2MTEwMDAwMDBaMEIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEpMCcGA1UEAxMgSW50ZXJuYWwgU2VydmljZXMgUm9vdCAtIHN0YWdpbmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASocByKBUdzgtqRXcpe/AE5oPoDMWTQqz1/jUQOA8qoEjYBXg9gfGU5KHK/UdwQc4lxbZEA9nJS9vUQAMVV5Es9B4thNHThKR4hFmCL8kKIEoMzXx282Qr6x4ZHYk4tQsCjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1UdDgQWBBR04GYtT79vaQmAEPPEte8q+W1KRTAKBggqhkjOPQQDAwNoADBlAjBBOu3RtlH1FLvfHPhyoWJHgm+PSNrsWQLRkmWQgAfNPYsfO5fWyhAebMV3FpKVPBICMQCVaie4NAsGi+AHLDhGnPn4Qptz0LBH2So6AVJS24ICeDUDQxKeUTNkUsy6Qgg97/4=" + "rawBytes": "MIIB9zCCAXygAwIBAgIUCPExEFKiQh0dP4sp5ltmSYSSkFUwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTAzMjgwOTE0MDZaFw0zNTAzMjYwODE0MDZaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATt0tIDWyo4ARfL9BaSo0W5bJQEbKJTU/u7llvdjSI5aTkOAJa8tixn2+LEfPG4dMFdsMPtsIuU1qn2OqFiuMk6vHv/c+az25RQVY1oo50iMb0jIL3N4FgwhPFpZnCbQPOjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQ7IEZZXrUyTUcwzm5j7nN0R/IEfTAKBggqhkjOPQQDAwNpADBmAjEA2MI1VXgbf3dUOSc95hSRypBKOab18eh2xzQtxUsHvWeY+1iFgyMluUuNR6taoSmFAjEA31m2czguZhKYX+4JSKu5pRYhBTXAd8KKQ3xdPRX/qCaLvT2qJAEQ1YQM3EJRrtI7" } ] }, "validFor": { - "start": "2023-06-15T00:00:00Z" + "start": "2025-04-09T00:00:00Z" } } ] diff --git a/test/assets/staging-tuf/targets/90659875a02f73d1026055427c6d857c556e410e23748ff88aeb493227610fd2f5fbdd95ef2a21565f91438dfb3e073f50c4c9dd06f9a601b5d9b064d5cb60b4.fulcio_intermediate.crt.pem b/test/assets/staging-tuf/targets/90659875a02f73d1026055427c6d857c556e410e23748ff88aeb493227610fd2f5fbdd95ef2a21565f91438dfb3e073f50c4c9dd06f9a601b5d9b064d5cb60b4.fulcio_intermediate.crt.pem deleted file mode 100644 index d94a2aa40..000000000 --- a/test/assets/staging-tuf/targets/90659875a02f73d1026055427c6d857c556e410e23748ff88aeb493227610fd2f5fbdd95ef2a21565f91438dfb3e073f50c4c9dd06f9a601b5d9b064d5cb60b4.fulcio_intermediate.crt.pem +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICGTCCAaCgAwIBAgITJta/okfgHvjabGm1BOzuhrwA1TAKBggqhkjOPQQDAzAq -MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIy -MDQxNDIxMzg0MFoXDTMyMDMyMjE2NTA0NVowNzEVMBMGA1UEChMMc2lnc3RvcmUu -ZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwdjAQBgcqhkjOPQIB -BgUrgQQAIgNiAASosAySWJQ/tK5r8T5aHqavk0oI+BKQbnLLdmOMRXHQF/4Hx9Kt -NfpcdjH9hNKQSBxSlLFFN3tvFCco0qFBzWYwZtsYsBe1l91qYn/9VHFTaEVwYQWI -JEEvrs0fvPuAqjajezB5MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEF -BQcDAzASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRxhjCmFHxib/n31vQF -Gn9f/+tvrDAfBgNVHSMEGDAWgBT/QjK6aH2rOnCv3AzUGuI+h49mZTAKBggqhkjO -PQQDAwNnADBkAjAM1lbKkcqQlE/UspMTbWNo1y2TaJ44tx3l/FJFceTSdDZ+0W1O -HHeU4twie/lq8XgCMHQxgEv26xNNiAGyPXbkYgrDPvbOqp0UeWX4mJnLSrBr3aN/ -KX1SBrKQu220FmVL0Q== ------END CERTIFICATE----- diff --git a/test/assets/staging-tuf/targets/910d899c7763563095a0fe684c8477573fedc19a78586de6ecfbfd8f289f5423.ctfe_2022.pub b/test/assets/staging-tuf/targets/910d899c7763563095a0fe684c8477573fedc19a78586de6ecfbfd8f289f5423.ctfe_2022.pub deleted file mode 100644 index 3023b8618..000000000 --- a/test/assets/staging-tuf/targets/910d899c7763563095a0fe684c8477573fedc19a78586de6ecfbfd8f289f5423.ctfe_2022.pub +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh99xuRi6slBFd8VUJoK/rLigy4bY -eSYWO/fE6Br7r0D8NpMI94+A63LR/WvLxpUUGBpY8IJA3iU2telag5CRpA== ------END PUBLIC KEY----- diff --git a/test/assets/staging-tuf/targets/ab975a75600fc366a837536d0dcba841b755552d21bb114498ff8ac9d2403f76643f5b91269bce5d124a365514719a3edee9dcc2b046cb173f51af659911fcd3.ctfe_2022.pub b/test/assets/staging-tuf/targets/ab975a75600fc366a837536d0dcba841b755552d21bb114498ff8ac9d2403f76643f5b91269bce5d124a365514719a3edee9dcc2b046cb173f51af659911fcd3.ctfe_2022.pub deleted file mode 100644 index 3023b8618..000000000 --- a/test/assets/staging-tuf/targets/ab975a75600fc366a837536d0dcba841b755552d21bb114498ff8ac9d2403f76643f5b91269bce5d124a365514719a3edee9dcc2b046cb173f51af659911fcd3.ctfe_2022.pub +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh99xuRi6slBFd8VUJoK/rLigy4bY -eSYWO/fE6Br7r0D8NpMI94+A63LR/WvLxpUUGBpY8IJA3iU2telag5CRpA== ------END PUBLIC KEY----- diff --git a/test/assets/staging-tuf/targets/acf0438a71de70bbf1813c908545281e0c4a1e3aafa2ce36b82c1cc24a9cce5169e9dcfe85c31bb4f662e94fdd9a686fa54fbbfccff1888e51ebd73924c12495.trusted_root.json b/test/assets/staging-tuf/targets/acf0438a71de70bbf1813c908545281e0c4a1e3aafa2ce36b82c1cc24a9cce5169e9dcfe85c31bb4f662e94fdd9a686fa54fbbfccff1888e51ebd73924c12495.trusted_root.json deleted file mode 100644 index f5b8853e7..000000000 --- a/test/assets/staging-tuf/targets/acf0438a71de70bbf1813c908545281e0c4a1e3aafa2ce36b82c1cc24a9cce5169e9dcfe85c31bb4f662e94fdd9a686fa54fbbfccff1888e51ebd73924c12495.trusted_root.json +++ /dev/null @@ -1,112 +0,0 @@ -{ - "mediaType": "application/vnd.dev.sigstore.trustedroot+json;version=0.1", - "tlogs": [ - { - "baseUrl": "https://rekor.sigstage.dev", - "hashAlgorithm": "SHA2_256", - "publicKey": { - "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDODRU688UYGuy54mNUlaEBiQdTE9nYLr0lg6RXowI/QV/RE1azBn4Eg5/2uTOMbhB1/gfcHzijzFi9Tk+g1Prg==", - "keyDetails": "PKIX_ECDSA_P256_SHA_256", - "validFor": { - "start": "2021-01-12T11:53:27.000Z" - } - }, - "logId": { - "keyId": "0y8wo8MtY5wrdiIFohx7sHeI5oKDpK5vQhGHI6G+pJY=" - } - } - ], - "certificateAuthorities": [ - { - "subject": { - "organization": "sigstore.dev", - "commonName": "sigstore" - }, - "uri": "https://fulcio.sigstage.dev", - "certChain": { - "certificates": [ - { - "rawBytes": "MIICGTCCAaCgAwIBAgITJta/okfgHvjabGm1BOzuhrwA1TAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIyMDQxNDIxMzg0MFoXDTMyMDMyMjE2NTA0NVowNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASosAySWJQ/tK5r8T5aHqavk0oI+BKQbnLLdmOMRXHQF/4Hx9KtNfpcdjH9hNKQSBxSlLFFN3tvFCco0qFBzWYwZtsYsBe1l91qYn/9VHFTaEVwYQWIJEEvrs0fvPuAqjajezB5MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDAzASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRxhjCmFHxib/n31vQFGn9f/+tvrDAfBgNVHSMEGDAWgBT/QjK6aH2rOnCv3AzUGuI+h49mZTAKBggqhkjOPQQDAwNnADBkAjAM1lbKkcqQlE/UspMTbWNo1y2TaJ44tx3l/FJFceTSdDZ+0W1OHHeU4twie/lq8XgCMHQxgEv26xNNiAGyPXbkYgrDPvbOqp0UeWX4mJnLSrBr3aN/KX1SBrKQu220FmVL0Q==" - }, - { - "rawBytes": "MIIB9jCCAXugAwIBAgITDdEJvluliE0AzYaIE4jTMdnFTzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIyMDMyNTE2NTA0NloXDTMyMDMyMjE2NTA0NVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMo9BUNk9QIYisYysC24+2OytoV72YiLonYcqR3yeVnYziPt7Xv++CYE8yoCTiwedUECCWKOcvQKRCJZb9ht4Hzy+VvBx36hK+C6sECCSR0x6pPSiz+cTk1f788ZjBlUZaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP9CMrpofas6cK/cDNQa4j6Hj2ZlMB8GA1UdIwQYMBaAFP9CMrpofas6cK/cDNQa4j6Hj2ZlMAoGCCqGSM49BAMDA2kAMGYCMQD+kojuzMwztNay9Ibzjuk//ZL5m6T2OCsm45l1lY004pcb984L926BowodoirFMcMCMQDIJtFHhP/1D3a+M3dAGomOb6O4CmTry3TTPbPsAFnv22YA0Y+P21NVoxKDjdu0tkw=" - } - ] - }, - "validFor": { - "start": "2022-04-14T21:38:40.000Z" - } - } - ], - "ctlogs": [ - { - "baseUrl": "https://ctfe.sigstage.dev/test", - "hashAlgorithm": "SHA2_256", - "publicKey": { - "rawBytes": "MIICCgKCAgEA27A2MPQXm0I0v7/Ly5BIauDjRZF5Jor9vU+QheoE2UIIsZHcyYq3slHzSSHy2lLj1ZD2d91CtJ492ZXqnBmsr4TwZ9jQ05tW2mGIRI8u2DqN8LpuNYZGz/f9SZrjhQQmUttqWmtu3UoLfKz6NbNXUnoo+NhZFcFRLXJ8VporVhuiAmL7zqT53cXR3yQfFPCUDeGnRksnlhVIAJc3AHZZSHQJ8DEXMhh35TVv2nYhTI3rID7GwjXXw4ocz7RGDD37ky6p39Tl5NB71gT1eSqhZhGHEYHIPXraEBd5+3w9qIuLWlp5Ej/K6Mu4ELioXKCUimCbwy+Cs8UhHFlqcyg4AysOHJwIadXIa8LsY51jnVSGrGOEBZevopmQPNPtyfFY3dmXSS+6Z3RD2Gd6oDnNGJzpSyEk410Ag5uvNDfYzJLCWX9tU8lIxNwdFYmIwpd89HijyRyoGnoJ3entd63cvKfuuix5r+GHyKp1Xm1L5j5AWM6P+z0xigwkiXnt+adexAl1J9wdDxv/pUFEESRF4DG8DFGVtbdH6aR1A5/vD4krO4tC1QYUSeyL5Mvsw8WRqIFHcXtgybtxylljvNcGMV1KXQC8UFDmpGZVDSHx6v3e/BHMrZ7gjoCCfVMZ/cFcQi0W2AIHPYEMH/C95J2r4XbHMRdYXpovpOoT5Ca78gsCAwEAAQ==", - "keyDetails": "PKCS1_RSA_PKCS1V5", - "validFor": { - "start": "2021-03-14T00:00:00.000Z", - "end": "2022-07-31T00:00:00.000Z" - } - }, - "logId": { - "keyId": "G3wUKk6ZK6ffHh/FdCRUE2wVekyzHEEIpSG4savnv0w=" - } - }, - { - "baseUrl": "https://ctfe.sigstage.dev/2022", - "hashAlgorithm": "SHA2_256", - "publicKey": { - "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEh99xuRi6slBFd8VUJoK/rLigy4bYeSYWO/fE6Br7r0D8NpMI94+A63LR/WvLxpUUGBpY8IJA3iU2telag5CRpA==", - "keyDetails": "PKIX_ECDSA_P256_SHA_256", - "validFor": { - "start": "2022-07-01T00:00:00.000Z", - "end": "2022-07-31T00:00:00.000Z" - } - }, - "logId": { - "keyId": "++JKOMQt7SJ3ynUHnCfnDhcKP8/58J4TueMqXuk3HmA=" - } - }, - { - "baseUrl": "https://ctfe.sigstage.dev/2022-2", - "hashAlgorithm": "SHA2_256", - "publicKey": { - "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE8gEDKNme8AnXuPBgHjrtXdS6miHqc24CRblNEOFpiJRngeq8Ko73Y+K18yRYVf1DXD4AVLwvKyzdNdl5n0jUSQ==", - "keyDetails": "PKIX_ECDSA_P256_SHA_256", - "validFor": { - "start": "2022-07-01T00:00:00.000Z" - } - }, - "logId": { - "keyId": "KzC83GiIyeLh2CYpXnQfSDkxlgLynDPLXkNA/rKshno=" - } - } - ], - "timestampAuthorities": [ - { - "subject": { - "organization": "GitHub, Inc.", - "commonName": "Internal Services Root - staging" - }, - "uri": "tsa.github.internal", - "certChain": { - "certificates": [ - { - "rawBytes": "MIICEzCCAZigAwIBAgIUMpRykCcZaSOBipYce6r2DlnM7vUwCgYIKoZIzj0EAwMwPDEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSMwIQYDVQQDExpUU0EgaW50ZXJtZWRpYXRlIC0gc3RhZ2luZzAeFw0yMzA2MTQxMjAwMDBaFw0yNDA2MTMxMjAwMDBaMDwxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEjMCEGA1UEAxMaVFNBIFRpbWVzdGFtcGluZyAtIHN0YWdpbmcwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATWAMg1BEHAzb03PHUKJiRJZdXcKIL0K/ks3Ylq5F5YDRIxUN4o8yeIaCWXa6i16zi8nXMFsa+3XrYM8mUyi9F6o3gwdjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUr+RZdcTNo31p3FuR0pajelcnr40wHwYDVR0jBBgwFoAUCmpQzrB6hAnlizGx37LrhKEzsT4wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDaQAwZgIxAIPUlZB2/p5rpCM3HCn1R8G5TIIW6aZPKtfPWDkNQY0bpFu6e8Dkm2TV3jfgYExuBgIxAOA+vTlDDJoz/qTMMs8VSpw3AMgktlMEhd8V0E+aLW5OizfphuiidkqkqkbCwRSW1w==" - }, - { - "rawBytes": "MIICNzCCAb6gAwIBAgIUUXRsBKgGXjrJbdJCQPJMsjfyJcYwCgYIKoZIzj0EAwMwQjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSkwJwYDVQQDEyBJbnRlcm5hbCBTZXJ2aWNlcyBSb290IC0gc3RhZ2luZzAeFw0yMzA2MTQwMDAwMDBaFw0yODA2MTIwMDAwMDBaMDwxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEjMCEGA1UEAxMaVFNBIGludGVybWVkaWF0ZSAtIHN0YWdpbmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAS/upihrvu/9+w1Ybfog3B1a8KfQa1bn7DLcJz2iumo+oCfg2bcbyRWygu8zRmrzJKp4HgQHC4LZJEEWm/MNIN1o6wVVmiDTZw01tk4aInmRVF13VKMscdzW5Ho4sYaeOejezB5MA4GA1UdDwEB/wQEAwIBBjATBgNVHSUEDDAKBggrBgEFBQcDCDASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBQKalDOsHqECeWLMbHfsuuEoTOxPjAfBgNVHSMEGDAWgBR04GYtT79vaQmAEPPEte8q+W1KRTAKBggqhkjOPQQDAwNnADBkAjBOTWZP1QYnmHpFqL73eSzhmSLiHs9pXsQghK0p8pvlAg0R9bxAyXGIZ8qx+k2iIGcCMDRQIScz0gu2Xef3++p2vFYouBsIKbqxv0raJuIlmGiYEvb22MDpAitevKAgqNVMEg==" - }, - { - "rawBytes": "MIICCDCCAY6gAwIBAgIULHHP/UhbXJbdyZfT6gHgTzIYF4EwCgYIKoZIzj0EAwMwQjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMSkwJwYDVQQDEyBJbnRlcm5hbCBTZXJ2aWNlcyBSb290IC0gc3RhZ2luZzAeFw0yMzA2MTQwMDAwMDBaFw0zMzA2MTEwMDAwMDBaMEIxFTATBgNVBAoTDEdpdEh1YiwgSW5jLjEpMCcGA1UEAxMgSW50ZXJuYWwgU2VydmljZXMgUm9vdCAtIHN0YWdpbmcwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASocByKBUdzgtqRXcpe/AE5oPoDMWTQqz1/jUQOA8qoEjYBXg9gfGU5KHK/UdwQc4lxbZEA9nJS9vUQAMVV5Es9B4thNHThKR4hFmCL8kKIEoMzXx282Qr6x4ZHYk4tQsCjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgECMB0GA1UdDgQWBBR04GYtT79vaQmAEPPEte8q+W1KRTAKBggqhkjOPQQDAwNoADBlAjBBOu3RtlH1FLvfHPhyoWJHgm+PSNrsWQLRkmWQgAfNPYsfO5fWyhAebMV3FpKVPBICMQCVaie4NAsGi+AHLDhGnPn4Qptz0LBH2So6AVJS24ICeDUDQxKeUTNkUsy6Qgg97/4=" - } - ] - }, - "validFor": { - "start": "2023-06-15T00:00:00Z" - } - } - ] -} diff --git a/test/assets/staging-tuf/targets/b861189e48df51186a39612230fba6b02af951f7b35ad9375e8ca182d0e085d470e26d69f7cd4d7450a0f223991e8e5a4ddf8f1968caa15255de8e37035af43a.ctfe.pub b/test/assets/staging-tuf/targets/b861189e48df51186a39612230fba6b02af951f7b35ad9375e8ca182d0e085d470e26d69f7cd4d7450a0f223991e8e5a4ddf8f1968caa15255de8e37035af43a.ctfe.pub deleted file mode 100644 index 39512c214..000000000 --- a/test/assets/staging-tuf/targets/b861189e48df51186a39612230fba6b02af951f7b35ad9375e8ca182d0e085d470e26d69f7cd4d7450a0f223991e8e5a4ddf8f1968caa15255de8e37035af43a.ctfe.pub +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN RSA PUBLIC KEY----- -MIICCgKCAgEA27A2MPQXm0I0v7/Ly5BIauDjRZF5Jor9vU+QheoE2UIIsZHcyYq3 -slHzSSHy2lLj1ZD2d91CtJ492ZXqnBmsr4TwZ9jQ05tW2mGIRI8u2DqN8LpuNYZG -z/f9SZrjhQQmUttqWmtu3UoLfKz6NbNXUnoo+NhZFcFRLXJ8VporVhuiAmL7zqT5 -3cXR3yQfFPCUDeGnRksnlhVIAJc3AHZZSHQJ8DEXMhh35TVv2nYhTI3rID7GwjXX -w4ocz7RGDD37ky6p39Tl5NB71gT1eSqhZhGHEYHIPXraEBd5+3w9qIuLWlp5Ej/K -6Mu4ELioXKCUimCbwy+Cs8UhHFlqcyg4AysOHJwIadXIa8LsY51jnVSGrGOEBZev -opmQPNPtyfFY3dmXSS+6Z3RD2Gd6oDnNGJzpSyEk410Ag5uvNDfYzJLCWX9tU8lI -xNwdFYmIwpd89HijyRyoGnoJ3entd63cvKfuuix5r+GHyKp1Xm1L5j5AWM6P+z0x -igwkiXnt+adexAl1J9wdDxv/pUFEESRF4DG8DFGVtbdH6aR1A5/vD4krO4tC1QYU -SeyL5Mvsw8WRqIFHcXtgybtxylljvNcGMV1KXQC8UFDmpGZVDSHx6v3e/BHMrZ7g -joCCfVMZ/cFcQi0W2AIHPYEMH/C95J2r4XbHMRdYXpovpOoT5Ca78gsCAwEAAQ== ------END RSA PUBLIC KEY----- diff --git a/test/assets/staging-tuf/targets/bd7a6812a1f239dfddbbb19d36c7423d21510da56d466ba5018401959cd66037.ctfe.pub b/test/assets/staging-tuf/targets/bd7a6812a1f239dfddbbb19d36c7423d21510da56d466ba5018401959cd66037.ctfe.pub deleted file mode 100644 index 39512c214..000000000 --- a/test/assets/staging-tuf/targets/bd7a6812a1f239dfddbbb19d36c7423d21510da56d466ba5018401959cd66037.ctfe.pub +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN RSA PUBLIC KEY----- -MIICCgKCAgEA27A2MPQXm0I0v7/Ly5BIauDjRZF5Jor9vU+QheoE2UIIsZHcyYq3 -slHzSSHy2lLj1ZD2d91CtJ492ZXqnBmsr4TwZ9jQ05tW2mGIRI8u2DqN8LpuNYZG -z/f9SZrjhQQmUttqWmtu3UoLfKz6NbNXUnoo+NhZFcFRLXJ8VporVhuiAmL7zqT5 -3cXR3yQfFPCUDeGnRksnlhVIAJc3AHZZSHQJ8DEXMhh35TVv2nYhTI3rID7GwjXX -w4ocz7RGDD37ky6p39Tl5NB71gT1eSqhZhGHEYHIPXraEBd5+3w9qIuLWlp5Ej/K -6Mu4ELioXKCUimCbwy+Cs8UhHFlqcyg4AysOHJwIadXIa8LsY51jnVSGrGOEBZev -opmQPNPtyfFY3dmXSS+6Z3RD2Gd6oDnNGJzpSyEk410Ag5uvNDfYzJLCWX9tU8lI -xNwdFYmIwpd89HijyRyoGnoJ3entd63cvKfuuix5r+GHyKp1Xm1L5j5AWM6P+z0x -igwkiXnt+adexAl1J9wdDxv/pUFEESRF4DG8DFGVtbdH6aR1A5/vD4krO4tC1QYU -SeyL5Mvsw8WRqIFHcXtgybtxylljvNcGMV1KXQC8UFDmpGZVDSHx6v3e/BHMrZ7g -joCCfVMZ/cFcQi0W2AIHPYEMH/C95J2r4XbHMRdYXpovpOoT5Ca78gsCAwEAAQ== ------END RSA PUBLIC KEY----- diff --git a/test/assets/staging-tuf/targets/c69ae618883a0c89c282c0943a1ad0c16b0a7788f74e47a1adefc631dac48a0c4449d8c3de7455ae7d772e43c4a87e341f180b0614a46a86006969f8a7b84532.fulcio.crt.pem b/test/assets/staging-tuf/targets/c69ae618883a0c89c282c0943a1ad0c16b0a7788f74e47a1adefc631dac48a0c4449d8c3de7455ae7d772e43c4a87e341f180b0614a46a86006969f8a7b84532.fulcio.crt.pem deleted file mode 100644 index 47a5becff..000000000 --- a/test/assets/staging-tuf/targets/c69ae618883a0c89c282c0943a1ad0c16b0a7788f74e47a1adefc631dac48a0c4449d8c3de7455ae7d772e43c4a87e341f180b0614a46a86006969f8a7b84532.fulcio.crt.pem +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIB9jCCAXugAwIBAgITDdEJvluliE0AzYaIE4jTMdnFTzAKBggqhkjOPQQDAzAq -MRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIy -MDMyNTE2NTA0NloXDTMyMDMyMjE2NTA0NVowKjEVMBMGA1UEChMMc2lnc3RvcmUu -ZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMo9 -BUNk9QIYisYysC24+2OytoV72YiLonYcqR3yeVnYziPt7Xv++CYE8yoCTiwedUEC -CWKOcvQKRCJZb9ht4Hzy+VvBx36hK+C6sECCSR0x6pPSiz+cTk1f788ZjBlUZaNj -MGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP9C -Mrpofas6cK/cDNQa4j6Hj2ZlMB8GA1UdIwQYMBaAFP9CMrpofas6cK/cDNQa4j6H -j2ZlMAoGCCqGSM49BAMDA2kAMGYCMQD+kojuzMwztNay9Ibzjuk//ZL5m6T2OCsm -45l1lY004pcb984L926BowodoirFMcMCMQDIJtFHhP/1D3a+M3dAGomOb6O4CmTr -y3TTPbPsAFnv22YA0Y+P21NVoxKDjdu0tkw= ------END CERTIFICATE----- diff --git a/test/assets/staging-tuf/targets/cb9a48c332a0d515db7760ad6972a09a0f4ed721fe5e839b70371e0d0802abe2.signing_config.v0.2.json b/test/assets/staging-tuf/targets/cb9a48c332a0d515db7760ad6972a09a0f4ed721fe5e839b70371e0d0802abe2.signing_config.v0.2.json new file mode 100644 index 000000000..fe66ad97b --- /dev/null +++ b/test/assets/staging-tuf/targets/cb9a48c332a0d515db7760ad6972a09a0f4ed721fe5e839b70371e0d0802abe2.signing_config.v0.2.json @@ -0,0 +1,45 @@ +{ + "mediaType": "application/vnd.dev.sigstore.signingconfig.v0.2+json", + "caUrls": [ + { + "url": "https://fulcio.sigstage.dev", + "majorApiVersion": 1, + "validFor": { + "start": "2022-04-14T21:38:40Z" + } + } + ], + "oidcUrls": [ + { + "url": "https://oauth2.sigstage.dev/auth", + "majorApiVersion": 1, + "validFor": { + "start": "2025-04-16T00:00:00Z" + } + } + ], + "rekorTlogUrls": [ + { + "url": "https://rekor.sigstage.dev", + "majorApiVersion": 1, + "validFor": { + "start": "2021-01-12T11:53:27Z" + } + } + ], + "tsaUrls": [ + { + "url": "https://timestamp.sigstage.dev/api/v1/timestamp", + "majorApiVersion": 1, + "validFor": { + "start": "2025-04-09T00:00:00Z" + } + } + ], + "rekorTlogConfig": { + "selector": "ANY" + }, + "tsaConfig": { + "selector": "ANY" + } +} \ No newline at end of file diff --git a/test/assets/staging-tuf/targets/registry.npmjs.org/7a8ec9678ad824cdccaa7a6dc0961caf8f8df61bc7274189122c123446248426.keys.json b/test/assets/staging-tuf/targets/registry.npmjs.org/7a8ec9678ad824cdccaa7a6dc0961caf8f8df61bc7274189122c123446248426.keys.json deleted file mode 100644 index f5667a5f0..000000000 --- a/test/assets/staging-tuf/targets/registry.npmjs.org/7a8ec9678ad824cdccaa7a6dc0961caf8f8df61bc7274189122c123446248426.keys.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "keys": [ - { - "keyId": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", - "keyUsage": "npm:signatures", - "publicKey": { - "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==", - "keyDetails": "PKIX_ECDSA_P256_SHA_256", - "validFor": { - "start": "1999-01-01T00:00:00.000Z" - } - } - }, - { - "keyId": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", - "keyUsage": "npm:attestations", - "publicKey": { - "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==", - "keyDetails": "PKIX_ECDSA_P256_SHA_256", - "validFor": { - "start": "2022-12-01T00:00:00.000Z" - } - } - } - ] -} diff --git a/test/assets/staging-tuf/targets/registry.npmjs.org/881a853ee92d8cf513b07c164fea36b22a7305c256125bdfffdc5c65a4205c4c3fc2b5bcc98964349167ea68d40b8cd02551fcaa870a30d4601ba1caf6f63699.keys.json b/test/assets/staging-tuf/targets/registry.npmjs.org/881a853ee92d8cf513b07c164fea36b22a7305c256125bdfffdc5c65a4205c4c3fc2b5bcc98964349167ea68d40b8cd02551fcaa870a30d4601ba1caf6f63699.keys.json deleted file mode 100644 index f5667a5f0..000000000 --- a/test/assets/staging-tuf/targets/registry.npmjs.org/881a853ee92d8cf513b07c164fea36b22a7305c256125bdfffdc5c65a4205c4c3fc2b5bcc98964349167ea68d40b8cd02551fcaa870a30d4601ba1caf6f63699.keys.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "keys": [ - { - "keyId": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", - "keyUsage": "npm:signatures", - "publicKey": { - "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==", - "keyDetails": "PKIX_ECDSA_P256_SHA_256", - "validFor": { - "start": "1999-01-01T00:00:00.000Z" - } - } - }, - { - "keyId": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", - "keyUsage": "npm:attestations", - "publicKey": { - "rawBytes": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1Olb3zMAFFxXKHiIkQO5cJ3Yhl5i6UPp+IhuteBJbuHcA5UogKo0EWtlWwW6KSaKoTNEYL7JlCQiVnkhBktUgg==", - "keyDetails": "PKIX_ECDSA_P256_SHA_256", - "validFor": { - "start": "2022-12-01T00:00:00.000Z" - } - } - } - ] -} diff --git a/test/assets/staging-tuf/timestamp.json b/test/assets/staging-tuf/timestamp.json index 5aa16c8e3..8feb575b0 100644 --- a/test/assets/staging-tuf/timestamp.json +++ b/test/assets/staging-tuf/timestamp.json @@ -1,24 +1,19 @@ { - "signed": { - "_type": "timestamp", - "spec_version": "1.0", - "version": 4, - "expires": "2028-09-19T22:52:25Z", - "meta": { - "snapshot.json": { - "length": 1043, - "hashes": { - "sha256": "30eee4304ab6d1d9545f8510953d5e2f2d877307216bcd60b7ce27302c4e3d02", - "sha512": "9149780f6daf49b70e3afef83ff1a158095f539c01d474ca9e97f8c8bd9d451b266b1444223b15f15fe8d5db09d3b0da94f1f6d6bbac9c3c0e7bc62c2905003d" - }, - "version": 4 - } - } - }, - "signatures": [ - { - "keyid": "314ae73abd3012fc73bfcc3783e31d03852716597642b891d6a33155c4baf600", - "sig": "3046022100cc12bcab1c1f9776f0b98232a12567822816de0acbe9cc7026ec9370619f30f8022100ef0f6d0bb55f4fba134a8a6c50739a6d90d8d09cfe54e51d1adf158d65aa1870" - } - ] + "signatures": [ + { + "keyid": "c3479007e861445ce5dc109d9661ed77b35bbc0e3f161852c46114266fc2daa4", + "sig": "30450220665b03b09118979b8c8d93b55077279e0424ae5802a0f59e14fdccef49b0c420022100f2fd10223ca19ee7e0671839e69508e8fd4a5ea875cf7e19fe6d0d77acd604a3" + } + ], + "signed": { + "_type": "timestamp", + "expires": "2025-05-09T07:17:49Z", + "meta": { + "snapshot.json": { + "version": 13 + } + }, + "spec_version": "1.0", + "version": 280 + } } \ No newline at end of file diff --git a/test/unit/conftest.py b/test/unit/conftest.py index e495557f4..44adac273 100644 --- a/test/unit/conftest.py +++ b/test/unit/conftest.py @@ -15,6 +15,7 @@ from __future__ import annotations import base64 +import datetime import os import re from collections import defaultdict @@ -158,6 +159,16 @@ def _fetch(self, url: str) -> Iterator[bytes]: monkeypatch.setattr(updater, "Urllib3Fetcher", lambda app_user_agent: MockFetcher()) + # Using the staging TUF assets is a nice way to test but staging tuf assets expire in + # 3 days so faking now() becomes necessary. This correctly affects checks in + # _internal/trust.py as well + class mydatetime(datetime.datetime): + @classmethod + def now(cls, tz=None): + return datetime.datetime(2025, 5, 6, 0, 0, 0, 0, datetime.timezone.utc) + + monkeypatch.setattr(datetime, "datetime", mydatetime) + return success, failure diff --git a/test/unit/internal/oidc/test_issuer.py b/test/unit/internal/oidc/test_issuer.py index 5241c4171..629071f11 100644 --- a/test/unit/internal/oidc/test_issuer.py +++ b/test/unit/internal/oidc/test_issuer.py @@ -30,7 +30,7 @@ def test_init_url(): @pytest.mark.online def test_get_identity_token_bad_code(monkeypatch): + # Send token request to oauth2.sigstage.dev but provide a bogus authorization code monkeypatch.setattr("builtins.input", lambda _: "hunter2") - with pytest.raises(IdentityError, match=r"^Token request failed with .+$"): - Issuer.staging().identity_token(force_oob=True) + Issuer("https://oauth2.sigstage.dev/auth").identity_token(force_oob=True) diff --git a/test/unit/internal/test_trust.py b/test/unit/internal/test_trust.py index a2bf3c6a3..71f29af7b 100644 --- a/test/unit/internal/test_trust.py +++ b/test/unit/internal/test_trust.py @@ -30,7 +30,7 @@ _is_timerange_valid, ) from sigstore._utils import load_pem_public_key -from sigstore.errors import Error, RootError +from sigstore.errors import Error class TestCertificateAuthority: @@ -110,7 +110,7 @@ def test_trust_root_tuf_caches_and_requests(mock_staging_tuf, tuf_dirs): # keep track of requests the TrustUpdater invoked by TrustedRoot makes reqs, fail_reqs = mock_staging_tuf - trust_root = TrustedRoot.staging() + trust_config = ClientTrustConfig.staging() # metadata was "downloaded" from staging expected = [ "root.json", @@ -125,31 +125,31 @@ def test_trust_root_tuf_caches_and_requests(mock_staging_tuf, tuf_dirs): # Don't expect trusted_root.json request as it's cached already expected_requests = { "timestamp.json": 1, - "4.snapshot.json": 1, - "4.targets.json": 1, + "13.snapshot.json": 1, + "13.targets.json": 1, } - expected_fail_reqs = {"5.root.json": 1} + expected_fail_reqs = {"12.root.json": 1} assert reqs == expected_requests assert fail_reqs == expected_fail_reqs - trust_root.ct_keyring(KeyringPurpose.VERIFY) - trust_root.rekor_keyring(KeyringPurpose.VERIFY) + trust_config.trusted_root.ct_keyring(KeyringPurpose.VERIFY) + trust_config.trusted_root.rekor_keyring(KeyringPurpose.VERIFY) # no new requests assert reqs == expected_requests assert fail_reqs == expected_fail_reqs # New trust root (and TrustUpdater instance), same cache dirs - trust_root = TrustedRoot.staging() + trust_config = ClientTrustConfig.staging() # Expect new timestamp and root requests expected_requests["timestamp.json"] += 1 - expected_fail_reqs["5.root.json"] += 1 + expected_fail_reqs["12.root.json"] += 1 assert reqs == expected_requests assert fail_reqs == expected_fail_reqs - trust_root.ct_keyring(purpose=KeyringPurpose.VERIFY) - trust_root.rekor_keyring(purpose=KeyringPurpose.VERIFY) + trust_config.trusted_root.ct_keyring(purpose=KeyringPurpose.VERIFY) + trust_config.trusted_root.rekor_keyring(purpose=KeyringPurpose.VERIFY) # Expect no requests assert reqs == expected_requests assert fail_reqs == expected_fail_reqs @@ -162,15 +162,15 @@ def test_trust_root_tuf_offline(mock_staging_tuf, tuf_dirs): # keep track of requests the TrustUpdater invoked by TrustedRoot makes reqs, fail_reqs = mock_staging_tuf - trust_root = TrustedRoot.staging(offline=True) + trust_config = ClientTrustConfig.staging(offline=True) # local TUF metadata is not initialized, nothing is downloaded assert not os.path.exists(data_dir) assert reqs == {} assert fail_reqs == {} - trust_root.ct_keyring(purpose=KeyringPurpose.VERIFY) - trust_root.rekor_keyring(purpose=KeyringPurpose.VERIFY) + trust_config.trusted_root.ct_keyring(purpose=KeyringPurpose.VERIFY) + trust_config.trusted_root.rekor_keyring(purpose=KeyringPurpose.VERIFY) # Still no requests assert reqs == {} @@ -231,7 +231,7 @@ def _pem_keys(keys): ] # Assert that trust root from TUF contains the expected keys/certs - trust_root = TrustedRoot.staging() + trust_root = ClientTrustConfig.staging().trusted_root assert ctfe_keys[0] in get_public_bytes( [ k.key @@ -254,7 +254,7 @@ def _pem_keys(keys): assert trust_root.get_fulcio_certs() == fulcio_certs # Assert that trust root from offline TUF contains the expected keys/certs - trust_root = TrustedRoot.staging(offline=True) + trust_root = ClientTrustConfig.staging(offline=True).trusted_root assert ctfe_keys[0] in get_public_bytes( [ k.key @@ -302,19 +302,21 @@ def _pem_keys(keys): def test_trust_root_tuf_instance_error(): - with pytest.raises(RootError): - TrustedRoot.from_tuf("foo.bar") + # Expect file not found since embedded root.json is not found and + # no local metadata is found + with pytest.raises(FileNotFoundError): + ClientTrustConfig.from_tuf("foo.bar") def test_trust_root_tuf_ctfe_keys_error(monkeypatch): - trust_root = TrustedRoot.staging(offline=True) + trust_root = ClientTrustConfig.staging(offline=True).trusted_root monkeypatch.setattr(trust_root._inner, "ctlogs", []) with pytest.raises(Exception, match="CTFE keys not found in trusted root"): trust_root.ct_keyring(purpose=KeyringPurpose.VERIFY) def test_trust_root_fulcio_certs_error(tuf_asset, monkeypatch): - trust_root = TrustedRoot.staging(offline=True) + trust_root = ClientTrustConfig.staging(offline=True).trusted_root monkeypatch.setattr(trust_root._inner, "certificate_authorities", []) with pytest.raises( Exception, match="Fulcio certificates not found in trusted root" diff --git a/test/unit/test_sign.py b/test/unit/test_sign.py index 756748bc0..04a5be75d 100644 --- a/test/unit/test_sign.py +++ b/test/unit/test_sign.py @@ -29,15 +29,6 @@ from sigstore.verify.policy import UnsafeNoOp -class TestSigningContext: - @pytest.mark.production - def test_production(self): - assert SigningContext.production() is not None - - def test_staging(self, mock_staging_tuf): - assert SigningContext.staging() is not None - - @pytest.mark.parametrize("env", ["staging", "production"]) @pytest.mark.ambient_oidc def test_sign_rekor_entry_consistent(sign_ctx_and_ident_for_env): @@ -185,7 +176,7 @@ def sig_ctx(self, asset, tsa_url) -> SigningContext: trust_config._inner.signing_config.tsa_urls[0] = tsa_url - return SigningContext._from_trust_config(trust_config) + return SigningContext.from_trust_config(trust_config) @pytest.fixture def identity(self, staging): diff --git a/test/unit/test_store.py b/test/unit/test_store.py index 7e546f9bd..50551154f 100644 --- a/test/unit/test_store.py +++ b/test/unit/test_store.py @@ -19,13 +19,25 @@ from sigstore._utils import read_embedded -@pytest.mark.parametrize("env", ["prod", "staging"]) +@pytest.mark.parametrize( + "env", + [ + "https://tuf-repo-cdn.sigstore.dev", + "https://tuf-repo-cdn.sigstage.dev", + ], +) def test_store_reads_root_json(env): root_json = read_embedded("root.json", env) assert json.loads(root_json) -@pytest.mark.parametrize("env", ["prod", "staging"]) +@pytest.mark.parametrize( + "env", + [ + "https://tuf-repo-cdn.sigstore.dev", + "https://tuf-repo-cdn.sigstage.dev", + ], +) def test_store_reads_targets_json(env): trusted_root_json = read_embedded("trusted_root.json", env) assert json.loads(trusted_root_json)