diff --git a/.github/workflows/check-outdated-trusted-root.yml b/.github/workflows/check-outdated-trusted-root.yml deleted file mode 100644 index 9575dcf3..00000000 --- a/.github/workflows/check-outdated-trusted-root.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: "Check for outdated trusted root certificates" - -on: - schedule: - - cron: "0 0 * * *" - -permissions: - contents: read - -jobs: - check: - runs-on: ubuntu-latest - permissions: - contents: read - issues: write # This permission is needed to create the issue - steps: - - uses: actions/checkout@v5 - - name: Pull new trusted root - run: gh attestation trusted-root > resources/new-trusted-root.jsonl - - name: Create an issue if different - env: - GH_TOKEN: ${{ github.token }} - run: | - diff resources/trusted-root.jsonl resources/new-trusted-root.jsonl \ - && echo "Trusted root cert has not changed, no action required." \ - || ( \ - (gh issue list --label "trusted-root-update" | grep -i "Trusted root needs updating") \ - && echo "Issue to update trusted root already exists, no action required." \ - || gh issue create --title "Trusted root needs updating" --body "The trusted root certificate file needs updating. Use the `diff -u <(jq < resources/trusted-root.jsonl) <(gh attestation trusted-root |jq)` command to view the differences, and the \`gh attestation trusted-root > resources/trusted-root.jsonl\` command to update it." --assignee "asgrim" --label "trusted-root-update" \ - ) diff --git a/composer.json b/composer.json index c49a0e14..25658a30 100644 --- a/composer.json +++ b/composer.json @@ -28,23 +28,24 @@ ], "require": { "php": "8.1.*||8.2.*||8.3.*||8.4.*||8.5.*", - "composer/composer": "^2.8.11", + "composer/composer": "^2.8.12", "composer/pcre": "^3.3.2", "composer/semver": "^3.4.4", "fidry/cpu-core-counter": "^1.3.0", - "illuminate/container": "^10.48.28", + "illuminate/container": "^10.49.0", "psr/container": "^2.0.2", - "symfony/console": "^6.4.25", - "symfony/event-dispatcher": "^6.4.24", - "symfony/process": "^6.4.25", + "symfony/console": "^6.4.26", + "symfony/event-dispatcher": "^6.4.25", + "symfony/process": "^6.4.26", + "thephpf/attestation": "^0.0.1", "webmozart/assert": "^1.11" }, "require-dev": { "ext-openssl": "*", - "behat/behat": "^3.23.0", + "behat/behat": "^3.24.1", "doctrine/coding-standard": "^13.0.1", - "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^10.5.48" + "phpstan/phpstan": "^2.1.29", + "phpunit/phpunit": "^10.5.58" }, "replace": { "symfony/polyfill-php81": "*", diff --git a/composer.lock b/composer.lock index 620fad3d..05f43d13 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fb078f5c73f463e113e0d38a71a8019c", + "content-hash": "0ac6f1ecff2f104985fd365f8a981ed8", "packages": [ { "name": "composer/ca-bundle", @@ -149,16 +149,16 @@ }, { "name": "composer/composer", - "version": "2.8.11", + "version": "2.8.12", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "00e1a3396eea67033775c4a49c772376f45acd73" + "reference": "3e38919bc9a2c3c026f2151b5e56d04084ce8f0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/00e1a3396eea67033775c4a49c772376f45acd73", - "reference": "00e1a3396eea67033775c4a49c772376f45acd73", + "url": "https://api.github.com/repos/composer/composer/zipball/3e38919bc9a2c3c026f2151b5e56d04084ce8f0b", + "reference": "3e38919bc9a2c3c026f2151b5e56d04084ce8f0b", "shasum": "" }, "require": { @@ -169,20 +169,20 @@ "composer/semver": "^3.3", "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", - "justinrainbow/json-schema": "^6.3.1", + "justinrainbow/json-schema": "^6.5.1", "php": "^7.2.5 || ^8.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "react/promise": "^2.11 || ^3.3", + "react/promise": "^3.3", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", "seld/signal-handler": "^2.0", - "symfony/console": "^5.4.35 || ^6.3.12 || ^7.0.3", - "symfony/filesystem": "^5.4.35 || ^6.3.12 || ^7.0.3", - "symfony/finder": "^5.4.35 || ^6.3.12 || ^7.0.3", + "symfony/console": "^5.4.47 || ^6.4.25 || ^7.1.10", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.1.10", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.1.10", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", "symfony/polyfill-php81": "^1.24", - "symfony/process": "^5.4.35 || ^6.3.12 || ^7.0.3" + "symfony/process": "^5.4.47 || ^6.4.25 || ^7.1.10" }, "require-dev": { "phpstan/phpstan": "^1.11.8", @@ -190,7 +190,7 @@ "phpstan/phpstan-phpunit": "^1.4.0", "phpstan/phpstan-strict-rules": "^1.6.0", "phpstan/phpstan-symfony": "^1.4.0", - "symfony/phpunit-bridge": "^6.4.3 || ^7.0.1" + "symfony/phpunit-bridge": "^6.4.25 || ^7.3.3" }, "suggest": { "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages", @@ -243,7 +243,7 @@ "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", "security": "https://github.com/composer/composer/security/policy", - "source": "https://github.com/composer/composer/tree/2.8.11" + "source": "https://github.com/composer/composer/tree/2.8.12" }, "funding": [ { @@ -255,7 +255,7 @@ "type": "github" } ], - "time": "2025-08-21T09:29:39+00:00" + "time": "2025-09-19T11:41:59+00:00" }, { "name": "composer/metadata-minifier", @@ -691,16 +691,16 @@ }, { "name": "illuminate/container", - "version": "v10.48.28", + "version": "v10.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", - "reference": "ed6253f7dd3a67d468b2cc7a69a657e1f14c7ba3" + "reference": "b4956de5de18524c21ef36221a8ffd7fa3b534db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/ed6253f7dd3a67d468b2cc7a69a657e1f14c7ba3", - "reference": "ed6253f7dd3a67d468b2cc7a69a657e1f14c7ba3", + "url": "https://api.github.com/repos/illuminate/container/zipball/b4956de5de18524c21ef36221a8ffd7fa3b534db", + "reference": "b4956de5de18524c21ef36221a8ffd7fa3b534db", "shasum": "" }, "require": { @@ -738,20 +738,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-11-21T14:02:44+00:00" + "time": "2025-03-24T11:47:24+00:00" }, { "name": "illuminate/contracts", - "version": "v10.48.28", + "version": "v10.49.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", - "reference": "f90663a69f926105a70b78060a31f3c64e2d1c74" + "reference": "2393ef579e020d88e24283913c815c3e2c143323" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/contracts/zipball/f90663a69f926105a70b78060a31f3c64e2d1c74", - "reference": "f90663a69f926105a70b78060a31f3c64e2d1c74", + "url": "https://api.github.com/repos/illuminate/contracts/zipball/2393ef579e020d88e24283913c815c3e2c143323", + "reference": "2393ef579e020d88e24283913c815c3e2c143323", "shasum": "" }, "require": { @@ -786,20 +786,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-11-21T14:02:44+00:00" + "time": "2025-03-24T11:47:24+00:00" }, { "name": "justinrainbow/json-schema", - "version": "6.5.1", + "version": "6.5.2", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "b5ab21e431594897e5bb86343c01f140ba862c26" + "reference": "ac0d369c09653cf7af561f6d91a705bc617a87b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/b5ab21e431594897e5bb86343c01f140ba862c26", - "reference": "b5ab21e431594897e5bb86343c01f140ba862c26", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/ac0d369c09653cf7af561f6d91a705bc617a87b8", + "reference": "ac0d369c09653cf7af561f6d91a705bc617a87b8", "shasum": "" }, "require": { @@ -859,22 +859,22 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/6.5.1" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.5.2" }, - "time": "2025-08-29T10:58:11+00:00" + "time": "2025-09-09T09:42:27+00:00" }, { "name": "marc-mabe/php-enum", - "version": "v4.7.1", + "version": "v4.7.2", "source": { "type": "git", "url": "https://github.com/marc-mabe/php-enum.git", - "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed" + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/7159809e5cfa041dca28e61f7f7ae58063aae8ed", - "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed", + "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/bb426fcdd65c60fb3638ef741e8782508fda7eef", + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef", "shasum": "" }, "require": { @@ -932,9 +932,9 @@ ], "support": { "issues": "https://github.com/marc-mabe/php-enum/issues", - "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.1" + "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.2" }, - "time": "2024-11-28T04:54:44+00:00" + "time": "2025-09-14T11:18:39+00:00" }, { "name": "psr/container", @@ -1388,16 +1388,16 @@ }, { "name": "symfony/console", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae" + "reference": "492de6dfd93910d7d7a729c5a04ddcd2b9e99c4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", - "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", + "url": "https://api.github.com/repos/symfony/console/zipball/492de6dfd93910d7d7a729c5a04ddcd2b9e99c4f", + "reference": "492de6dfd93910d7d7a729c5a04ddcd2b9e99c4f", "shasum": "" }, "require": { @@ -1462,7 +1462,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.25" + "source": "https://github.com/symfony/console/tree/v6.4.26" }, "funding": [ { @@ -1482,7 +1482,7 @@ "type": "tidelift" } ], - "time": "2025-08-22T10:21:53+00:00" + "time": "2025-09-26T12:13:46+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1553,16 +1553,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "307a09d8d7228d14a05e5e05b95fffdacab032b2" + "reference": "b0cf3162020603587363f0551cd3be43958611ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/307a09d8d7228d14a05e5e05b95fffdacab032b2", - "reference": "307a09d8d7228d14a05e5e05b95fffdacab032b2", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b0cf3162020603587363f0551cd3be43958611ff", + "reference": "b0cf3162020603587363f0551cd3be43958611ff", "shasum": "" }, "require": { @@ -1613,7 +1613,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.24" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.25" }, "funding": [ { @@ -1633,7 +1633,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:14:14+00:00" + "time": "2025-08-13T09:41:44+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -2186,16 +2186,16 @@ }, { "name": "symfony/process", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8" + "reference": "48bad913268c8cafabbf7034b39c8bb24fbc5ab8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8", - "reference": "6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8", + "url": "https://api.github.com/repos/symfony/process/zipball/48bad913268c8cafabbf7034b39c8bb24fbc5ab8", + "reference": "48bad913268c8cafabbf7034b39c8bb24fbc5ab8", "shasum": "" }, "require": { @@ -2227,7 +2227,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.25" + "source": "https://github.com/symfony/process/tree/v6.4.26" }, "funding": [ { @@ -2247,7 +2247,7 @@ "type": "tidelift" } ], - "time": "2025-08-14T06:23:17+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/service-contracts", @@ -2334,16 +2334,16 @@ }, { "name": "symfony/string", - "version": "v6.4.25", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1" + "reference": "5621f039a71a11c87c106c1c598bdcd04a19aeea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1", - "reference": "7cdec7edfaf2cdd9c18901e35bcf9653d6209ff1", + "url": "https://api.github.com/repos/symfony/string/zipball/5621f039a71a11c87c106c1c598bdcd04a19aeea", + "reference": "5621f039a71a11c87c106c1c598bdcd04a19aeea", "shasum": "" }, "require": { @@ -2357,7 +2357,6 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", "symfony/http-client": "^5.4|^6.0|^7.0", "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", @@ -2400,7 +2399,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.25" + "source": "https://github.com/symfony/string/tree/v6.4.26" }, "funding": [ { @@ -2420,7 +2419,68 @@ "type": "tidelift" } ], - "time": "2025-08-22T12:33:20+00:00" + "time": "2025-09-11T14:32:46+00:00" + }, + { + "name": "thephpf/attestation", + "version": "0.0.1", + "source": { + "type": "git", + "url": "https://github.com/ThePHPF/attestation.git", + "reference": "edefe3f071c5bf18849586165c991d08529505e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ThePHPF/attestation/zipball/edefe3f071c5bf18849586165c991d08529505e2", + "reference": "edefe3f071c5bf18849586165c991d08529505e2", + "shasum": "" + }, + "require": { + "composer/composer": "^2.2", + "ext-json": "*", + "php": "^7.4||^8.0", + "webmozart/assert": "^1.11" + }, + "require-dev": { + "doctrine/coding-standard": "^13.0", + "phpstan/phpstan": "^2.1", + "phpunit/phpunit": "^9.6.25" + }, + "suggest": { + "ext-openssl": "Needed to verify certificates using OpenSSL" + }, + "type": "library", + "autoload": { + "psr-4": { + "ThePhpFoundation\\Attestation\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "James Titcumb", + "email": "james@asgrim.com" + } + ], + "description": "A PHP library to aid in verifying artifact attestations", + "support": { + "issues": "https://github.com/ThePHPF/attestation/issues", + "source": "https://github.com/ThePHPF/attestation/tree/0.0.1" + }, + "funding": [ + { + "url": "https://github.com/ThePHPF", + "type": "github" + }, + { + "url": "https://opencollective.com/phpfoundation", + "type": "open_collective" + } + ], + "time": "2025-09-25T18:12:54+00:00" }, { "name": "webmozart/assert", @@ -2484,16 +2544,16 @@ "packages-dev": [ { "name": "behat/behat", - "version": "v3.23.0", + "version": "v3.24.1", "source": { "type": "git", "url": "https://github.com/Behat/Behat.git", - "reference": "c465af8756adaaa6d962c3176a0a6c594361809b" + "reference": "1b67565a55283b6c0d050a0e4c4e44025c791a67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Behat/zipball/c465af8756adaaa6d962c3176a0a6c594361809b", - "reference": "c465af8756adaaa6d962c3176a0a6c594361809b", + "url": "https://api.github.com/repos/Behat/Behat/zipball/1b67565a55283b6c0d050a0e4c4e44025c791a67", + "reference": "1b67565a55283b6c0d050a0e4c4e44025c791a67", "shasum": "" }, "require": { @@ -2515,8 +2575,9 @@ "friendsofphp/php-cs-fixer": "^3.68", "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^9.6", - "rector/rector": "^2.0", + "rector/rector": "2.1.4", "sebastian/diff": "^4.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", "symfony/polyfill-php84": "^1.31", "symfony/process": "^5.4 || ^6.4 || ^7.0" }, @@ -2571,9 +2632,9 @@ ], "support": { "issues": "https://github.com/Behat/Behat/issues", - "source": "https://github.com/Behat/Behat/tree/v3.23.0" + "source": "https://github.com/Behat/Behat/tree/v3.24.1" }, - "time": "2025-07-15T16:58:54+00:00" + "time": "2025-09-15T09:09:06+00:00" }, { "name": "behat/gherkin", @@ -3460,16 +3521,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.48", + "version": "10.5.58", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "6e0a2bc39f6fae7617989d690d76c48e6d2eb541" + "reference": "e24fb46da450d8e6a5788670513c1af1424f16ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/6e0a2bc39f6fae7617989d690d76c48e6d2eb541", - "reference": "6e0a2bc39f6fae7617989d690d76c48e6d2eb541", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e24fb46da450d8e6a5788670513c1af1424f16ca", + "reference": "e24fb46da450d8e6a5788670513c1af1424f16ca", "shasum": "" }, "require": { @@ -3479,7 +3540,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.3", + "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.1", @@ -3490,13 +3551,13 @@ "phpunit/php-timer": "^6.0.0", "sebastian/cli-parser": "^2.0.1", "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.3", + "sebastian/comparator": "^5.0.4", "sebastian/diff": "^5.1.1", "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.2", + "sebastian/exporter": "^5.1.4", "sebastian/global-state": "^6.0.2", "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.0", + "sebastian/recursion-context": "^5.0.1", "sebastian/type": "^4.0.0", "sebastian/version": "^4.0.1" }, @@ -3541,7 +3602,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.48" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.58" }, "funding": [ { @@ -3565,7 +3626,7 @@ "type": "tidelift" } ], - "time": "2025-07-11T04:07:17+00:00" + "time": "2025-09-28T12:04:46+00:00" }, { "name": "sebastian/cli-parser", @@ -3737,16 +3798,16 @@ }, { "name": "sebastian/comparator", - "version": "5.0.3", + "version": "5.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" + "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e8e53097718d2b53cfb2aa859b06a41abf58c62e", + "reference": "e8e53097718d2b53cfb2aa859b06a41abf58c62e", "shasum": "" }, "require": { @@ -3802,15 +3863,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2024-10-18T14:56:07+00:00" + "time": "2025-09-07T05:25:07+00:00" }, { "name": "sebastian/complexity", @@ -4003,16 +4076,16 @@ }, { "name": "sebastian/exporter", - "version": "5.1.2", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + "reference": "0735b90f4da94969541dac1da743446e276defa6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", + "reference": "0735b90f4da94969541dac1da743446e276defa6", "shasum": "" }, "require": { @@ -4021,7 +4094,7 @@ "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -4069,15 +4142,27 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" } ], - "time": "2024-03-02T07:17:12+00:00" + "time": "2025-09-24T06:09:11+00:00" }, { "name": "sebastian/global-state", @@ -4313,23 +4398,23 @@ }, { "name": "sebastian/recursion-context", - "version": "5.0.0", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", "shasum": "" }, "require": { "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -4364,15 +4449,28 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2023-02-03T07:05:40+00:00" + "time": "2025-08-10T07:50:56+00:00" }, { "name": "sebastian/type", @@ -4485,32 +4583,32 @@ }, { "name": "slevomat/coding-standard", - "version": "8.20.0", + "version": "8.22.1", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "b4f9f02edd4e6a586777f0cabe8d05574323f3eb" + "reference": "1dd80bf3b93692bedb21a6623c496887fad05fec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b4f9f02edd4e6a586777f0cabe8d05574323f3eb", - "reference": "b4f9f02edd4e6a586777f0cabe8d05574323f3eb", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/1dd80bf3b93692bedb21a6623c496887fad05fec", + "reference": "1dd80bf3b93692bedb21a6623c496887fad05fec", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.1.2", "php": "^7.4 || ^8.0", - "phpstan/phpdoc-parser": "^2.2.0", - "squizlabs/php_codesniffer": "^3.13.2" + "phpstan/phpdoc-parser": "^2.3.0", + "squizlabs/php_codesniffer": "^3.13.4" }, "require-dev": { "phing/phing": "3.0.1|3.1.0", "php-parallel-lint/php-parallel-lint": "1.4.0", - "phpstan/phpstan": "2.1.19", + "phpstan/phpstan": "2.1.24", "phpstan/phpstan-deprecation-rules": "2.0.3", "phpstan/phpstan-phpunit": "2.0.7", "phpstan/phpstan-strict-rules": "2.0.6", - "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.27|12.2.7" + "phpunit/phpunit": "9.6.8|10.5.48|11.4.4|11.5.36|12.3.10" }, "type": "phpcodesniffer-standard", "extra": { @@ -4534,7 +4632,7 @@ ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/8.20.0" + "source": "https://github.com/slevomat/coding-standard/tree/8.22.1" }, "funding": [ { @@ -4546,20 +4644,20 @@ "type": "tidelift" } ], - "time": "2025-07-26T15:35:10+00:00" + "time": "2025-09-13T08:53:30+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.13.2", + "version": "3.13.4", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" + "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", - "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/ad545ea9c1b7d270ce0fc9cbfb884161cd706119", + "reference": "ad545ea9c1b7d270ce0fc9cbfb884161cd706119", "shasum": "" }, "require": { @@ -4630,20 +4728,20 @@ "type": "thanks_dev" } ], - "time": "2025-06-17T22:17:01+00:00" + "time": "2025-09-05T05:47:09+00:00" }, { "name": "symfony/config", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "80e2cf005cf17138c97193be0434cdcfd1b2212e" + "reference": "f18dc5926cb203e125956987def795d052ee774e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/80e2cf005cf17138c97193be0434cdcfd1b2212e", - "reference": "80e2cf005cf17138c97193be0434cdcfd1b2212e", + "url": "https://api.github.com/repos/symfony/config/zipball/f18dc5926cb203e125956987def795d052ee774e", + "reference": "f18dc5926cb203e125956987def795d052ee774e", "shasum": "" }, "require": { @@ -4689,7 +4787,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.4.24" + "source": "https://github.com/symfony/config/tree/v6.4.26" }, "funding": [ { @@ -4709,20 +4807,20 @@ "type": "tidelift" } ], - "time": "2025-07-26T13:50:30+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "929ab73b93247a15166ee79e807ccee4f930322d" + "reference": "5f311eaf0b321f8ec640f6bae12da43a14026898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/929ab73b93247a15166ee79e807ccee4f930322d", - "reference": "929ab73b93247a15166ee79e807ccee4f930322d", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/5f311eaf0b321f8ec640f6bae12da43a14026898", + "reference": "5f311eaf0b321f8ec640f6bae12da43a14026898", "shasum": "" }, "require": { @@ -4774,7 +4872,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.24" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.26" }, "funding": [ { @@ -4794,20 +4892,20 @@ "type": "tidelift" } ], - "time": "2025-07-30T17:30:48+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/translation", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "300b72643e89de0734d99a9e3f8494a3ef6936e1" + "reference": "c8559fe25c7ee7aa9d28f228903a46db008156a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/300b72643e89de0734d99a9e3f8494a3ef6936e1", - "reference": "300b72643e89de0734d99a9e3f8494a3ef6936e1", + "url": "https://api.github.com/repos/symfony/translation/zipball/c8559fe25c7ee7aa9d28f228903a46db008156a4", + "reference": "c8559fe25c7ee7aa9d28f228903a46db008156a4", "shasum": "" }, "require": { @@ -4873,7 +4971,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v6.4.24" + "source": "https://github.com/symfony/translation/tree/v6.4.26" }, "funding": [ { @@ -4893,7 +4991,7 @@ "type": "tidelift" } ], - "time": "2025-07-30T17:30:48+00:00" + "time": "2025-09-05T18:17:25+00:00" }, { "name": "symfony/translation-contracts", @@ -4975,16 +5073,16 @@ }, { "name": "symfony/var-exporter", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "1e742d559fe5b19d0cdc281b1bf0b1fcc243bd35" + "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1e742d559fe5b19d0cdc281b1bf0b1fcc243bd35", - "reference": "1e742d559fe5b19d0cdc281b1bf0b1fcc243bd35", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/466fcac5fa2e871f83d31173f80e9c2684743bfc", + "reference": "466fcac5fa2e871f83d31173f80e9c2684743bfc", "shasum": "" }, "require": { @@ -5032,7 +5130,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v6.4.24" + "source": "https://github.com/symfony/var-exporter/tree/v6.4.26" }, "funding": [ { @@ -5052,20 +5150,20 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:14:14+00:00" + "time": "2025-09-11T09:57:09+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.24", + "version": "v6.4.26", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "742a8efc94027624b36b10ba58e23d402f961f51" + "reference": "0fc8b966fd0dcaab544ae59bfc3a433f048c17b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/742a8efc94027624b36b10ba58e23d402f961f51", - "reference": "742a8efc94027624b36b10ba58e23d402f961f51", + "url": "https://api.github.com/repos/symfony/yaml/zipball/0fc8b966fd0dcaab544ae59bfc3a433f048c17b0", + "reference": "0fc8b966fd0dcaab544ae59bfc3a433f048c17b0", "shasum": "" }, "require": { @@ -5108,7 +5206,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.24" + "source": "https://github.com/symfony/yaml/tree/v6.4.26" }, "funding": [ { @@ -5128,7 +5226,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:14:14+00:00" + "time": "2025-09-26T15:07:38+00:00" }, { "name": "theseer/tokenizer", diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index cf0c01ff..3374d5f5 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -438,48 +438,6 @@ parameters: count: 1 path: src/SelfManage/Update/FetchPieReleaseFromGitHub.php - - - message: '#^Cannot access offset ''extensions'' on array\|false\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php - - - - message: '#^Cannot access offset ''issuer'' on array\|false\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 2 - path: src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php - - - - message: '#^Cannot access offset ''subject'' on array\|false\.$#' - identifier: offsetAccess.nonOffsetAccessible - count: 1 - path: src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php - - - - message: '#^Parameter \#1 \$callback of function array_map expects \(callable\(mixed\)\: mixed\)\|null, Closure\(array\)\: Php\\Pie\\SelfManage\\Verify\\Attestation given\.$#' - identifier: argument.type - count: 1 - path: src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php - - - - message: '#^Parameter \#1 \$issuer of static method Php\\Pie\\SelfManage\\Verify\\FailedToVerifyRelease\:\:fromIssuerCertificateVerificationFailed\(\) expects array\\|string, mixed given\.$#' - identifier: argument.type - count: 1 - path: src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php - - - - message: '#^Parameter \#1 \$issuer of static method Php\\Pie\\SelfManage\\Verify\\FailedToVerifyRelease\:\:fromNoIssuerCertificateInTrustedRoot\(\) expects array\\|string, mixed given\.$#' - identifier: argument.type - count: 1 - path: src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php - - - - message: '#^Parameter \#1 \$string of function trim expects string, string\|false given\.$#' - identifier: argument.type - count: 1 - path: src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php - - message: '#^Dead catch \- Php\\Pie\\SelfManage\\Verify\\GithubCliNotAvailable is never thrown in the try block\.$#' identifier: catch.neverThrown diff --git a/resources/trusted-root.jsonl b/resources/trusted-root.jsonl deleted file mode 100644 index b102f34a..00000000 --- a/resources/trusted-root.jsonl +++ /dev/null @@ -1,2 +0,0 @@ -{"mediaType":"application/vnd.dev.sigstore.trustedroot+json;version=0.1","tlogs":[{"baseUrl":"https://rekor.sigstore.dev","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwrkBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2021-01-12T11:53:27Z"}},"logId":{"keyId":"wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="}}],"certificateAuthorities":[{"subject":{"organization":"sigstore.dev","commonName":"sigstore"},"uri":"https://fulcio.sigstore.dev","certChain":{"certificates":[{"rawBytes":"MIIB+DCCAX6gAwIBAgITNVkDZoCiofPDsy7dfm6geLbuhzAKBggqhkjOPQQDAzAqMRUwEwYDVQQKEwxzaWdzdG9yZS5kZXYxETAPBgNVBAMTCHNpZ3N0b3JlMB4XDTIxMDMwNzAzMjAyOVoXDTMxMDIyMzAzMjAyOVowKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLSyA7Ii5k+pNO8ZEWY0ylemWDowOkNa3kL+GZE5Z5GWehL9/A9bRNA3RbrsZ5i0JcastaRL7Sp5fp/jD5dxqc/UdTVnlvS16an+2Yfswe/QuLolRUCrcOE2+2iA5+tzd6NmMGQwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFMjFHQBBmiQpMlEk6w2uSu1KBtPsMB8GA1UdIwQYMBaAFMjFHQBBmiQpMlEk6w2uSu1KBtPsMAoGCCqGSM49BAMDA2gAMGUCMH8liWJfMui6vXXBhjDgY4MwslmN/TJxVe/83WrFomwmNf056y1X48F9c4m3a3ozXAIxAKjRay5/aj/jsKKGIkmQatjI8uupHr/+CxFvaJWmpYqNkLDGRU+9orzh5hI2RrcuaQ=="}]},"validFor":{"start":"2021-03-07T03:20:29Z","end":"2022-12-31T23:59:59.999Z"}},{"subject":{"organization":"sigstore.dev","commonName":"sigstore"},"uri":"https://fulcio.sigstore.dev","certChain":{"certificates":[{"rawBytes":"MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="},{"rawBytes":"MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"}]},"validFor":{"start":"2022-04-13T20:06:15Z"}}],"ctlogs":[{"baseUrl":"https://ctfe.sigstore.dev/test","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbfwR+RJudXscgRBRpKX1XFDy3PyudDxz/SfnRi1fT8ekpfBd2O1uoz7jr3Z8nKzxA69EUQ+eFCFI3zeubPWU7w==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2021-03-14T00:00:00Z","end":"2022-10-31T23:59:59.999Z"}},"logId":{"keyId":"CGCS8ChS/2hF0dFrJ4ScRWcYrBY9wzjSbea8IgY2b3I="}},{"baseUrl":"https://ctfe.sigstore.dev/2022","hashAlgorithm":"SHA2_256","publicKey":{"rawBytes":"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEiPSlFi0CmFTfEjCUqF9HuCEcYXNKAaYalIJmBZ8yyezPjTqhxrKBpMnaocVtLJBI1eM3uXnQzQGAJdJ4gs9Fyw==","keyDetails":"PKIX_ECDSA_P256_SHA_256","validFor":{"start":"2022-10-20T00:00:00Z"}},"logId":{"keyId":"3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4="}}],"timestampAuthorities":[{"subject":{"organization":"sigstore.dev","commonName":"sigstore-tsa-selfsigned"},"uri":"https://timestamp.sigstore.dev/api/v1/timestamp","certChain":{"certificates":[{"rawBytes":"MIICEDCCAZagAwIBAgIUOhNULwyQYe68wUMvy4qOiyojiwwwCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMC4xFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEVMBMGA1UEAxMMc2lnc3RvcmUtdHNhMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE4ra2Z8hKNig2T9kFjCAToGG30jky+WQv3BzL+mKvh1SKNR/UwuwsfNCg4sryoYAd8E6isovVA3M4aoNdm9QDi50Z8nTEyvqgfDPtTIwXItfiW/AFf1V7uwkbkAoj0xxco2owaDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFIn9eUOHz9BlRsMCRscsc1t9tOsDMB8GA1UdIwQYMBaAFJjsAe9/u1H/1JUeb4qImFMHic6/MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMAoGCCqGSM49BAMDA2gAMGUCMDtpsV/6KaO0qyF/UMsX2aSUXKQFdoGTptQGc0ftq1csulHPGG6dsmyMNd3JB+G3EQIxAOajvBcjpJmKb4Nv+2Taoj8Uc5+b6ih6FXCCKraSqupe07zqswMcXJTe1cExvHvvlw=="},{"rawBytes":"MIIB9zCCAXygAwIBAgIUV7f0GLDOoEzIh8LXSW80OJiUp14wCgYIKoZIzj0EAwMwOTEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MSAwHgYDVQQDExdzaWdzdG9yZS10c2Etc2VsZnNpZ25lZDAeFw0yNTA0MDgwNjU5NDNaFw0zNTA0MDYwNjU5NDNaMDkxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEgMB4GA1UEAxMXc2lnc3RvcmUtdHNhLXNlbGZzaWduZWQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQUQNtfRT/ou3YATa6wB/kKTe70cfJwyRIBovMnt8RcJph/COE82uyS6FmppLLL1VBPGcPfpQPYJNXzWwi8icwhKQ6W/Qe2h3oebBb2FHpwNJDqo+TMaC/tdfkv/ElJB72jRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSY7AHvf7tR/9SVHm+KiJhTB4nOvzAKBggqhkjOPQQDAwNpADBmAjEAwGEGrfGZR1cen1R8/DTVMI943LssZmJRtDp/i7SfGHmGRP6gRbuj9vOK3b67Z0QQAjEAuT2H673LQEaHTcyQSZrkp4mX7WwkmF+sVbkYY5mXN+RMH13KUEHHOqASaemYWK/E"}]},"validFor":{"start":"2025-07-04T00:00:00Z"}}]} -{"mediaType":"application/vnd.dev.sigstore.trustedroot+json;version=0.1","certificateAuthorities":[{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"fulcio.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICKjCCAbCgAwIBAgIUW3TJVeOvr+NSvJXdOw8nEEn7HhQwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMB4XDTIzMDkxMjE0MDY1NFoXDTI0MDkxMTE0MDY1NFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEsosodObhuHG6Pr5vp5y+pmnKawS1h2hwv3r3hBwqh3ZHJAw64mhDnDs9fw4jKkZEBYRSVyOHyZppz4day8hgpTIDwdj44Oan4RDb+wmj04jfhVLjLsQ4Q/X4K/ynRgNXo3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUm0vkDkQZ29hutYdayJobIRmf/iMwHwYDVR0jBBgwFoAUwOG4UqRLTz7eejgRBs9JjqFFmzMwCgYIKoZIzj0EAwMDaAAwZQIwIBl93E7vkWTvdeIm1WSIM4qNsj0ApE8LCj3k1vrY5x6/7yhAZs7QlO3/FBCoEeaZAjEAlJcNr37uZq9BYHODHBeO/gP+6EfbzsNaLV22ASBlhF/a9y83ESLuqCNN7IxGxmWT"},{"rawBytes":"MIICFTCCAZugAwIBAgIUD3Jlqt4qhrcZI4UnGfPGrEq/pjQwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDkxMTEyMDAwMFoXDTI4MDkwOTEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7X7nK0wC7uEmDjW+on0sXIX3FacL3hhcrhneA+M/kl1OtvQiPmFrH9lbUQqOj/AfspJ8uGY3jaq8WuSg6ghatzYfuuzLAJIK4nGpCBafncF8EynOssPq64/Dz+JUWXqlo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUwOG4UqRLTz7eejgRBs9JjqFFmzMwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAI8HWLrke7uzhOpwlD1cNixPmoX9XFKe7bEPozo0D+vKi0Gt6VlC7xPedFIw4/AypAIwQP+FGRWvfx0IAH5/n0aRiN7/LVpyFA5RkJASZOVOib2Y8pNuhXa9V3ZbWO6v6kW/"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2023-10-27T16:30:00Z","end":"2024-05-25T00:00:00Z"}},{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"fulcio.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICKzCCAbCgAwIBAgIUOpyw2HaZefsj/4SPXutGof8E2CkwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMB4XDTI0MDUxMzAwMDAwMFoXDTI1MDUxMzAwMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEJNJWvW8fckfk/oQmh+qCeIlFXl9YLEkKSjZCgcVB92Fi1HQnvmpCiyqpvP91SmT1/G6QbrmTGV7MmIQlDnBWHNUT+jwZ3elGu/yfr/v8U0uhZTIli/BMj5Y4ICHK/j4do3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUD0fF3cs+ldPyiWohHJ3JmO91V7gwHwYDVR0jBBgwFoAUwOG4UqRLTz7eejgRBs9JjqFFmzMwCgYIKoZIzj0EAwMDaQAwZgIxAO7BRC9i7oGUHjjlcHU/bfqk2NLy7t6wm3K5W+jBLFbAj6sVjYcY+rrYhop/OjclbQIxALafBKLPIPjoCI29BUHwLBFP6e92ZlyaoFtoqccceXAevRaDjXFvb5+M7wnD6AuAJw=="},{"rawBytes":"MIICFTCCAZugAwIBAgIUD3Jlqt4qhrcZI4UnGfPGrEq/pjQwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDkxMTEyMDAwMFoXDTI4MDkwOTEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7X7nK0wC7uEmDjW+on0sXIX3FacL3hhcrhneA+M/kl1OtvQiPmFrH9lbUQqOj/AfspJ8uGY3jaq8WuSg6ghatzYfuuzLAJIK4nGpCBafncF8EynOssPq64/Dz+JUWXqlo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUwOG4UqRLTz7eejgRBs9JjqFFmzMwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAI8HWLrke7uzhOpwlD1cNixPmoX9XFKe7bEPozo0D+vKi0Gt6VlC7xPedFIw4/AypAIwQP+FGRWvfx0IAH5/n0aRiN7/LVpyFA5RkJASZOVOib2Y8pNuhXa9V3ZbWO6v6kW/"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2024-05-13T00:00:00Z","end":"2024-10-25T00:00:00Z"}},{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"fulcio.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICKzCCAbCgAwIBAgIUQeyd9UH06yZ63pDuqjgUZ58CnpMwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMB4XDTI0MTAwMzEyMDAwMFoXDTI1MTAwMzEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEwvbET2w+j9j9j50iTInH1gb9GSXkpsCvWz5orX1zgme+/Qh/5gMkpfmgfOSLV2ZRgT1hzujYmnKQvP2mCxYnbwQELAkAf+VhEY/7Uw3zZvguGQSdF1cxzRHiMTOha5eFo3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUMib9z4ZYBcQANTVvVCa3KoTGbBUwHwYDVR0jBBgwFoAUwOG4UqRLTz7eejgRBs9JjqFFmzMwCgYIKoZIzj0EAwMDaQAwZgIxAPIU/zlJiJrxn6oTWNdEAD/YBSnhyxcvpq1D2DzFy8E8hbkEfMZPErYL7HyoL/BkdwIxAN9KDEKyktEUBrfHehfcLAzI2kERJx+8DSslXswOIbLaeqYfWsmrQAt5C0X/nOWxXA=="},{"rawBytes":"MIICFTCCAZugAwIBAgIUD3Jlqt4qhrcZI4UnGfPGrEq/pjQwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDkxMTEyMDAwMFoXDTI4MDkwOTEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7X7nK0wC7uEmDjW+on0sXIX3FacL3hhcrhneA+M/kl1OtvQiPmFrH9lbUQqOj/AfspJ8uGY3jaq8WuSg6ghatzYfuuzLAJIK4nGpCBafncF8EynOssPq64/Dz+JUWXqlo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUwOG4UqRLTz7eejgRBs9JjqFFmzMwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAI8HWLrke7uzhOpwlD1cNixPmoX9XFKe7bEPozo0D+vKi0Gt6VlC7xPedFIw4/AypAIwQP+FGRWvfx0IAH5/n0aRiN7/LVpyFA5RkJASZOVOib2Y8pNuhXa9V3ZbWO6v6kW/"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2024-10-07T00:00:00Z","end":"2025-06-19T00:00:00Z"}},{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"fulcio.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICKTCCAbCgAwIBAgIUU7Y2PESb8FK88XCRQvI2rKDB5skwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMB4XDTI1MDUyNzAwMDAwMFoXDTI2MDUyNzAwMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEevMuOTGccTTXLu65xinRJP4gxkOemyAPCmUXEvhXKtLd+aDgN87PI0QxutOmPuQD2dLZVfxQmt5lvwJpUDIVYkKpH3mDxYbF6MJPMbq+A/EhkMaOS2+mcJRJdY2uam0Vo3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU8tE1L3b7FV3qJKzSqy1w97vPt6AwHwYDVR0jBBgwFoAUwOG4UqRLTz7eejgRBs9JjqFFmzMwCgYIKoZIzj0EAwMDZwAwZAIwSIsnfcDIvp+9SGBe9Es4xLDgZ6/B3wtODu+jtNUznQFPw1/WHa3iBMp3vYPkIqZDAjBBD4AKu166Hg7tDd5E8ckSCNNDkXD0Q7Xdl4yujgqv0goVMeOgRA1pKDGszhunjAQ="},{"rawBytes":"MIICFTCCAZugAwIBAgIUD3Jlqt4qhrcZI4UnGfPGrEq/pjQwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDkxMTEyMDAwMFoXDTI4MDkwOTEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZGdWxjaW8gSW50ZXJtZWRpYXRlIGwxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE7X7nK0wC7uEmDjW+on0sXIX3FacL3hhcrhneA+M/kl1OtvQiPmFrH9lbUQqOj/AfspJ8uGY3jaq8WuSg6ghatzYfuuzLAJIK4nGpCBafncF8EynOssPq64/Dz+JUWXqlo2YwZDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQUwOG4UqRLTz7eejgRBs9JjqFFmzMwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAI8HWLrke7uzhOpwlD1cNixPmoX9XFKe7bEPozo0D+vKi0Gt6VlC7xPedFIw4/AypAIwQP+FGRWvfx0IAH5/n0aRiN7/LVpyFA5RkJASZOVOib2Y8pNuhXa9V3ZbWO6v6kW/"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2025-05-27T00:00:00Z"}}],"timestampAuthorities":[{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"timestamp.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICHDCCAaGgAwIBAgIUNDVlmtZuvoujn4KwiC/oxIr8hxAwCgYIKoZIzj0EAwMwMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMB4XDTIzMDgzMTEyMDAwMFoXDTI0MDgzMDEyMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgVGltZXN0YW1waW5nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEV/zJhNTdu0Fa9hGCUih/JvqEoE81tEWrAVwUXXhdRgIY9hIFErLhNo6sSOpV9d7Zuy0KWMHhcimCUr41a1732ByVRy3f+Z4QhqpsgFMh5b5J90HJLK7HOyUZjehAnvSno3gwdjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUGwE6T5ZIh6lY9wP6vt42UHyVMewwHwYDVR0jBBgwFoAUdh+GTP65aetHLVLs9hdhGgDIKIwwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDaQAwZgIxAJo48LtrSsn0UmLtqGiUKg2EUvso+aDN5EyjpvMmobZ/Oq9zjnR7Of369hoABW4/1gIxANg5ZW4FqijhsXnA3md6jM9yLrLCI9QL+KnuZnXq6WgAcNQaAN7PNNjVDKV3iJEklw=="},{"rawBytes":"MIICJDCCAaqgAwIBAgIUckXVHpiw7iJY1V/jY8LYLj5TgqAwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTI4MDgwNTEyMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEISv96hTQ58QroEzzu4K+o9p8YkwDCBia2U7Y+VBNbOG/w1mLRibve9hSeUE1FSyLBMkiFSSm6MexcsbjyqOoNtRxuMinyYt6DSEox+/It2s/bTPyNAN0QP0DCQQOpnTZo3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUdh+GTP65aetHLVLs9hdhGgDIKIwwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAIhf+2E5W2yOb/fCDAjhL/G/jerf74M0tG/zyo32U2keawxkzZosDdwnPaHaGLynAQIwa8nr3en4fZz1AdOZm6nK5hr1qK2F94nifgnAJ/WeT0fZnK/oHan0R28x363qYuYH"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2023-10-27T16:30:00Z","end":"2024-05-25T00:00:00Z"}},{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"timestamp.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICGzCCAaGgAwIBAgIUPPgn6ner1PU/75CQ+62fdBuazaAwCgYIKoZIzj0EAwMwMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMB4XDTI0MDUxMzAwMDAwMFoXDTI1MDUxMzAwMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgVGltZXN0YW1waW5nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEA0pG1mAC4qafk1JJuOoIvhnMME9XmBDxjGFreDLnyzaexIzRw+UHUFy8C2gE6Me+0tIGQt4Ftbu66NGmfvBkR6boPMYQSU2O5X5ykZBm/9LR/Aqz0lgmBy/OlXvTJjglo3gwdjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUDa4GVhd97Z2V8kiVl9DB0kC53CMwHwYDVR0jBBgwFoAUdh+GTP65aetHLVLs9hdhGgDIKIwwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDaAAwZQIwEQHd++b7IBAAuqT2/1i/wXf1WM2XrkFF6qd1c3kFcBVvdLQyJ5KoyNUHnfCCVJROAjEA+FoASOEcARlU6RqVcif9JthHwzh6nNwz0AfAHvO8xantN/7HjiLmFrFEGR/g0kN/"},{"rawBytes":"MIICJDCCAaqgAwIBAgIUckXVHpiw7iJY1V/jY8LYLj5TgqAwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTI4MDgwNTEyMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEISv96hTQ58QroEzzu4K+o9p8YkwDCBia2U7Y+VBNbOG/w1mLRibve9hSeUE1FSyLBMkiFSSm6MexcsbjyqOoNtRxuMinyYt6DSEox+/It2s/bTPyNAN0QP0DCQQOpnTZo3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUdh+GTP65aetHLVLs9hdhGgDIKIwwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAIhf+2E5W2yOb/fCDAjhL/G/jerf74M0tG/zyo32U2keawxkzZosDdwnPaHaGLynAQIwa8nr3en4fZz1AdOZm6nK5hr1qK2F94nifgnAJ/WeT0fZnK/oHan0R28x363qYuYH"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2024-05-13T00:00:00Z","end":"2024-10-25T00:00:00Z"}},{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"timestamp.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICGzCCAaGgAwIBAgIUH7swiMTn+svhcDh80OeZccDTj7AwCgYIKoZIzj0EAwMwMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMB4XDTI0MTAwNDEyMDAwMFoXDTI1MTAwNDEyMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgVGltZXN0YW1waW5nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEM7jdYNBTeD6hjym2/y73b50u2AFQsf8305Sr1NleOqamH9aWt6obhJQH3NoNUw9iFzHcDvafYWQFMu7SmOxS5n3aqwwfR8oJxKnEl36uCmGB+8TXS3B76SVTHEhG5rzOo3gwdjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUQvz9YbWX3S6a+jruBkhRBiE2RCkwHwYDVR0jBBgwFoAUdh+GTP65aetHLVLs9hdhGgDIKIwwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDaAAwZQIxAI4dhu5iyx/g+z1vKAAWvHtebl1ZwsC+Vwgjm6Ttlq5yLNHHvYEnJ/h15Qv2IuXvdgIwZ8H/iy4lXsFJdFYSsB1/zavl24EgxSzxK/pCpihXMetYYDA/lX3xMyquisMx45rN"},{"rawBytes":"MIICJDCCAaqgAwIBAgIUckXVHpiw7iJY1V/jY8LYLj5TgqAwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTI4MDgwNTEyMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEISv96hTQ58QroEzzu4K+o9p8YkwDCBia2U7Y+VBNbOG/w1mLRibve9hSeUE1FSyLBMkiFSSm6MexcsbjyqOoNtRxuMinyYt6DSEox+/It2s/bTPyNAN0QP0DCQQOpnTZo3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUdh+GTP65aetHLVLs9hdhGgDIKIwwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAIhf+2E5W2yOb/fCDAjhL/G/jerf74M0tG/zyo32U2keawxkzZosDdwnPaHaGLynAQIwa8nr3en4fZz1AdOZm6nK5hr1qK2F94nifgnAJ/WeT0fZnK/oHan0R28x363qYuYH"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2024-10-07T00:00:00Z","end":"2025-06-19T00:00:00Z"}},{"subject":{"organization":"GitHub, Inc.","commonName":"Internal Services Root"},"uri":"timestamp.githubapp.com","certChain":{"certificates":[{"rawBytes":"MIICGzCCAaGgAwIBAgIUaaAaeAO3NzYXR/muq5YMnGY34IUwCgYIKoZIzj0EAwMwMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMB4XDTI1MDUyNzAwMDAwMFoXDTI2MDUyNzAwMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgVGltZXN0YW1waW5nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEAjyAb+jWITMjkgbjWC02N05Zf5/kPs73ICf5/8lHSyHnoqqItP2z3fkMpWiRpelX8eIjzCjZ0Zht+DpGxtJUNh5jMa+fFv2qoDLGbnQ17DXKXCr9nWHF4vCMflHZK5JHo3gwdjAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUyvAcv8s1s37A/IWZAwdEptzjfWIwHwYDVR0jBBgwFoAUdh+GTP65aetHLVLs9hdhGgDIKIwwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwCgYIKoZIzj0EAwMDaAAwZQIwMnoHA4qDtR3eRohUIhvHGG70xT9XMfEnuj0kRvi9wu9VumL4pXqz1ktJgTBm6DrYAjEA5SYnRfUm2yAYmGEkJr9RvSCV9O7X+fL8KqfM4TOPrXJLMERQjhRXbWZ4DjxvifnF"},{"rawBytes":"MIICJDCCAaqgAwIBAgIUckXVHpiw7iJY1V/jY8LYLj5TgqAwCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTI4MDgwNTEyMDAwMFowMjEVMBMGA1UEChMMR2l0SHViLCBJbmMuMRkwFwYDVQQDExBUU0EgaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEISv96hTQ58QroEzzu4K+o9p8YkwDCBia2U7Y+VBNbOG/w1mLRibve9hSeUE1FSyLBMkiFSSm6MexcsbjyqOoNtRxuMinyYt6DSEox+/It2s/bTPyNAN0QP0DCQQOpnTZo3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUdh+GTP65aetHLVLs9hdhGgDIKIwwHwYDVR0jBBgwFoAUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaAAwZQIxAIhf+2E5W2yOb/fCDAjhL/G/jerf74M0tG/zyo32U2keawxkzZosDdwnPaHaGLynAQIwa8nr3en4fZz1AdOZm6nK5hr1qK2F94nifgnAJ/WeT0fZnK/oHan0R28x363qYuYH"},{"rawBytes":"MIIB9TCCAXqgAwIBAgIUNFryA06EHDIcd5EIbe8swbl9OY4wCgYIKoZIzj0EAwMwODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MB4XDTIzMDgwNzEyMDAwMFoXDTMzMDgwNDEyMDAwMFowODEVMBMGA1UEChMMR2l0SHViLCBJbmMuMR8wHQYDVQQDExZJbnRlcm5hbCBTZXJ2aWNlcyBSb290MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEXYaXx4H0oNuVP/2cfydA3oaafvvkkkgb5hbL8/j/BO25S7uTmDOCA5e4QLLWCKFuc+xp2j14tCH4WmHzMUDvf2tXtInVliY5wZgQMM9L6klo/IwA9x4omdcjnT+kKJAjo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUfFJ5/6rhfHEZPnXAhrQLhGkJJMwwCgYIKoZIzj0EAwMDaQAwZgIxAPzXsV+eokrqOHSQZH/XhhHE1slOscKy3DQpYpYJ1AWmJ2lJu/XOmubBX5s7apllUwIxALw2Ts8CDACiK42UymC8fk6sbNfoXUAWqdyKTVt2Lst+wNdkRniGvx7jT65BKTkcsQ=="}]},"validFor":{"start":"2025-05-27T00:00:00Z"}}]} diff --git a/src/Command/SelfUpdateCommand.php b/src/Command/SelfUpdateCommand.php index b60860fa..9a89148e 100644 --- a/src/Command/SelfUpdateCommand.php +++ b/src/Command/SelfUpdateCommand.php @@ -83,7 +83,7 @@ public function execute(InputInterface $input, OutputInterface $output): int $httpDownloader = new HttpDownloader($this->io, $composer->getConfig()); $authHelper = new AuthHelper($this->io, $composer->getConfig()); $fetchLatestPieRelease = new FetchPieReleaseFromGitHub($this->githubApiBaseUrl, $httpDownloader, $authHelper); - $verifyPiePhar = VerifyPieReleaseUsingAttestation::factory($this->githubApiBaseUrl, $httpDownloader, $authHelper); + $verifyPiePhar = VerifyPieReleaseUsingAttestation::factory(); if ($input->hasOption(self::OPTION_NIGHTLY_UPDATE) && $input->getOption(self::OPTION_NIGHTLY_UPDATE)) { $latestRelease = new ReleaseMetadata( diff --git a/src/Command/SelfVerifyCommand.php b/src/Command/SelfVerifyCommand.php index b5fd3dad..a024d0d6 100644 --- a/src/Command/SelfVerifyCommand.php +++ b/src/Command/SelfVerifyCommand.php @@ -4,11 +4,6 @@ namespace Php\Pie\Command; -use Composer\Util\AuthHelper; -use Composer\Util\HttpDownloader; -use Php\Pie\ComposerIntegration\PieComposerFactory; -use Php\Pie\ComposerIntegration\PieComposerRequest; -use Php\Pie\ComposerIntegration\QuieterConsoleIO; use Php\Pie\File\BinaryFile; use Php\Pie\File\FullPathToSelf; use Php\Pie\SelfManage\Update\ReleaseMetadata; @@ -16,7 +11,6 @@ use Php\Pie\SelfManage\Verify\VerifyPieReleaseUsingAttestation; use Php\Pie\Util\Emoji; use Php\Pie\Util\PieVersion; -use Psr\Container\ContainerInterface; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -30,11 +24,7 @@ )] final class SelfVerifyCommand extends Command { - /** @param non-empty-string $githubApiBaseUrl */ public function __construct( - private readonly string $githubApiBaseUrl, - private readonly QuieterConsoleIO $io, - private readonly ContainerInterface $container, private readonly FullPathToSelf $fullPathToSelf, ) { parent::__construct(); @@ -55,19 +45,9 @@ public function execute(InputInterface $input, OutputInterface $output): int return Command::FAILURE; } - $targetPlatform = CommandHelper::determineTargetPlatformFromInputs($input, $output); - $composer = PieComposerFactory::createPieComposer( - $this->container, - PieComposerRequest::noOperation( - $output, - $targetPlatform, - ), - ); - $httpDownloader = new HttpDownloader($this->io, $composer->getConfig()); - $authHelper = new AuthHelper($this->io, $composer->getConfig()); - $latestRelease = new ReleaseMetadata(PieVersion::get(), 'blah'); - $pharFilename = BinaryFile::fromFileWithSha256Checksum(($this->fullPathToSelf)()); - $verifyPiePhar = VerifyPieReleaseUsingAttestation::factory($this->githubApiBaseUrl, $httpDownloader, $authHelper); + $latestRelease = new ReleaseMetadata(PieVersion::get(), 'blah'); + $pharFilename = BinaryFile::fromFileWithSha256Checksum(($this->fullPathToSelf)()); + $verifyPiePhar = VerifyPieReleaseUsingAttestation::factory(); try { $verifyPiePhar->verify($latestRelease, $pharFilename, $output); diff --git a/src/SelfManage/Verify/FailedToVerifyRelease.php b/src/SelfManage/Verify/FailedToVerifyRelease.php index 3c8fd932..6ecaa67e 100644 --- a/src/SelfManage/Verify/FailedToVerifyRelease.php +++ b/src/SelfManage/Verify/FailedToVerifyRelease.php @@ -4,78 +4,19 @@ namespace Php\Pie\SelfManage\Verify; -use Php\Pie\File\BinaryFile; use Php\Pie\SelfManage\Update\ReleaseMetadata; use RuntimeException; use Symfony\Component\Process\Exception\ProcessFailedException; +use ThePhpFoundation\Attestation\Verification\Exception\FailedToVerifyArtifact; -use function implode; -use function is_array; use function sprintf; -use function strlen; use function trim; class FailedToVerifyRelease extends RuntimeException { - public static function fromInvalidSubjectDefinition(): self + public static function fromAttestationException(FailedToVerifyArtifact $failedToVerifyArtifact): self { - return new self('Unable to extract subject digest from the dsseEnvelope in the attestation.'); - } - - public static function fromMissingAttestation(ReleaseMetadata $releaseMetadata, BinaryFile $file): self - { - return new self(sprintf( - 'Attestation for %s (sha256:%s) was not found', - $releaseMetadata->tag, - $file->checksum, - )); - } - - public static function fromSignatureVerificationFailed(int $attestationIndex, ReleaseMetadata $releaseMetadata): self - { - return new self(sprintf( - 'Failed to verify DSSE Envelope payload signature for attestation %d for %s', - $attestationIndex, - $releaseMetadata->tag, - )); - } - - /** @param array|string $issuer */ - public static function fromIssuerCertificateVerificationFailed(array|string $issuer): self - { - return new self(sprintf( - 'Failed to verify the attestation certificate was issued by trusted root %s', - is_array($issuer) ? implode(',', $issuer) : $issuer, - )); - } - - /** @param array|string $issuer */ - public static function fromNoIssuerCertificateInTrustedRoot(array|string $issuer): self - { - return new self(sprintf( - 'Could not find a trusted root certificate for issuer %s', - is_array($issuer) ? implode(',', $issuer) : $issuer, - )); - } - - public static function fromInvalidDerEncodedStringLength(string $derEncodedString, int $expectedLength): self - { - return new self(sprintf( - 'DER encoded string length of "%s" was wrong; expected %d characters, was actually %d characters', - $derEncodedString, - $expectedLength, - strlen($derEncodedString), - )); - } - - public static function fromMismatchingExtensionValues(string $extension, string $expected, string $actual): self - { - return new self(sprintf( - 'Attestation certificate extension %s mismatch; expected "%s", was "%s"', - $extension, - $expected, - $actual, - )); + return new self($failedToVerifyArtifact->getMessage(), 0, $failedToVerifyArtifact); } public static function fromNoOpenssl(): self diff --git a/src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php b/src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php index e1691070..ff2af594 100644 --- a/src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php +++ b/src/SelfManage/Verify/FallbackVerificationUsingOpenSsl.php @@ -4,55 +4,33 @@ namespace Php\Pie\SelfManage\Verify; -use Composer\Downloader\TransportException; -use Composer\Util\AuthHelper; -use Composer\Util\HttpDownloader; -use OpenSSLAsymmetricKey; use Php\Pie\File\BinaryFile; use Php\Pie\SelfManage\Update\ReleaseMetadata; use Php\Pie\Util\Emoji; use Symfony\Component\Console\Output\OutputInterface; -use Webmozart\Assert\Assert; +use ThePhpFoundation\Attestation\FilenameWithChecksum; +use ThePhpFoundation\Attestation\FulcioSigstoreOidExtensions; +use ThePhpFoundation\Attestation\Verification\Exception\FailedToVerifyArtifact; +use ThePhpFoundation\Attestation\Verification\VerifyAttestation; -use function array_key_exists; -use function array_map; -use function count; -use function explode; -use function extension_loaded; -use function file_get_contents; -use function is_array; -use function is_string; -use function json_decode; -use function openssl_pkey_get_public; -use function openssl_verify; -use function openssl_x509_parse; -use function openssl_x509_verify; -use function ord; use function sprintf; -use function strlen; -use function substr; -use function trim; -use function wordwrap; - -use const OPENSSL_ALGO_SHA256; /** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */ final class FallbackVerificationUsingOpenSsl implements VerifyPiePhar { - public const TRUSTED_ROOT_FILE_PATH = __DIR__ . '/../../../resources/trusted-root.jsonl'; - /** @link https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#136141572641--fulcio */ private const ATTESTATION_CERTIFICATE_EXPECTED_EXTENSION_VALUES = [ - '1.3.6.1.4.1.57264.1.8' => 'https://token.actions.githubusercontent.com', - '1.3.6.1.4.1.57264.1.12' => 'https://github.com/php/pie', - '1.3.6.1.4.1.57264.1.16' => 'https://github.com/php', + FulcioSigstoreOidExtensions::ISSUER_V2 => 'https://token.actions.githubusercontent.com', + FulcioSigstoreOidExtensions::SOURCE_REPOSITORY_URI => 'https://github.com/php/pie', + FulcioSigstoreOidExtensions::SOURCE_REPOSITORY_OWNER_URI => 'https://github.com/php', ]; + private const ORGANISATION = 'php'; + + private const ARTIFACT_FILENAME = 'pie.phar'; + public function __construct( - private readonly string $trustedRootFilePath, - private readonly string $githubApiBaseUrl, - private readonly HttpDownloader $httpDownloader, - private readonly AuthHelper $authHelper, + private readonly VerifyAttestation $verifyAttestation, ) { } @@ -63,31 +41,16 @@ public function verify(ReleaseMetadata $releaseMetadata, BinaryFile $pharFilenam OutputInterface::VERBOSITY_VERBOSE, ); - $attestations = $this->downloadAttestations($releaseMetadata, $pharFilename); - - foreach ($attestations as $attestationIndex => $attestation) { - /** - * Useful references. Whilst we don't do the full verification that - * `gh attestation verify` would (since we don't want to re-invent - * the wheel), we can do some basic check of the DSSE Envelope. - * We'll check the payload digest matches our expectation, and - * verify the signature with the certificate. - * - * - https://github.com/cli/cli/blob/234d2effd545fb9d72ea77aa648caa499aecaa6e/pkg/cmd/attestation/verify/verify.go#L225-L256 - * - https://docs.sigstore.dev/logging/verify-release/ - * - https://github.com/secure-systems-lab/dsse/blob/master/protocol.md#protocol - */ - $this->assertCertificateSignedByTrustedRoot($attestation); - $output->writeln('#' . $attestationIndex . ': Certificate was signed by a trusted root.', OutputInterface::VERBOSITY_VERBOSE); - - $this->assertCertificateExtensionClaims($attestation); - $output->writeln('#' . $attestationIndex . ': Certificate extension claims match.', OutputInterface::VERBOSITY_VERBOSE); - - $this->assertDigestFromAttestationMatchesActual($pharFilename, $attestation); - $output->writeln('#' . $attestationIndex . ': Payload digest matches downloaded file.', OutputInterface::VERBOSITY_VERBOSE); - - $this->verifyDsseEnvelopeSignature($releaseMetadata, $attestationIndex, $attestation); - $output->writeln('#' . $attestationIndex . ': DSSE payload signature verified with certificate.', OutputInterface::VERBOSITY_VERBOSE); + try { + /** @psalm-suppress InvalidArgument */ + $this->verifyAttestation->verify( + FilenameWithChecksum::fromFilenameAndChecksum($pharFilename->filePath, $pharFilename->checksum), + self::ORGANISATION, + self::ARTIFACT_FILENAME, + self::ATTESTATION_CERTIFICATE_EXPECTED_EXTENSION_VALUES, + ); + } catch (FailedToVerifyArtifact $failedToVerifyArtifact) { + throw FailedToVerifyRelease::fromAttestationException($failedToVerifyArtifact); } $output->writeln(sprintf( @@ -95,220 +58,4 @@ public function verify(ReleaseMetadata $releaseMetadata, BinaryFile $pharFilenam Emoji::GREEN_CHECKMARK, )); } - - private function assertCertificateSignedByTrustedRoot(Attestation $attestation): void - { - $attestationCertificateInfo = openssl_x509_parse($attestation->certificate); - - $trustedRootJsonLines = explode("\n", trim(file_get_contents($this->trustedRootFilePath))); - - /** - * Now go through our trusted root certificates and attempt to verify that the certificate was signed by an - * in-date trusted root certificate. The root certificates should be periodically and frequently updated using: - * - * gh attestation trusted-root > resources/trusted-root.jsonl - * - * And verifying the contents afterwards to ensure they have not been compromised. This list of JSON blobs may - * have multiple certificates (e.g. root certificates, intermediate certificates, expired certificates, etc.) - * so we should loop over to find the correct certificate used to sign the attestation certificate. - */ - foreach ($trustedRootJsonLines as $jsonLine) { - /** @var mixed $decoded */ - $decoded = json_decode($jsonLine, true); - - // No certificate authorities defined in this JSON line, skip it... - if ( - ! is_array($decoded) - || ! array_key_exists('certificateAuthorities', $decoded) - || ! is_array($decoded['certificateAuthorities']) - ) { - continue; - } - - /** @var mixed $certificateAuthority */ - foreach ($decoded['certificateAuthorities'] as $certificateAuthority) { - // We don't have a certificate chain defined, skip it... - if ( - ! is_array($certificateAuthority) - || ! array_key_exists('certChain', $certificateAuthority) - || ! is_array($certificateAuthority['certChain']) - || ! array_key_exists('certificates', $certificateAuthority['certChain']) - || ! is_array($certificateAuthority['certChain']['certificates']) - ) { - continue; - } - - /** @var mixed $caCertificateWrapper */ - foreach ($certificateAuthority['certChain']['certificates'] as $caCertificateWrapper) { - // Certificate is not in the expected format, i.e. no rawBytes key, skip it... - if ( - ! is_array($caCertificateWrapper) - || ! array_key_exists('rawBytes', $caCertificateWrapper) - || ! is_string($caCertificateWrapper['rawBytes']) - || $caCertificateWrapper['rawBytes'] === '' - ) { - continue; - } - - // Embed the base64-encoded DER into a PEM envelope for consumption by OpenSSL. - $caCertificateString = sprintf( - <<<'EOT' - -----BEGIN CERTIFICATE----- - %s - -----END CERTIFICATE----- - EOT, - wordwrap($caCertificateWrapper['rawBytes'], 67, "\n", true), - ); - - $caCertificateInfo = openssl_x509_parse($caCertificateString); - - // If the CA certificate subject is not the issuer of the attestation certificate, - // this was not the cert we were looking for, skip it... - if ($caCertificateInfo['subject'] !== $attestationCertificateInfo['issuer']) { - continue; - } - - // Finally, verify that the located CA cert was used to sign the attestation certificate - if (openssl_x509_verify($attestation->certificate, $caCertificateString) !== 1) { - throw FailedToVerifyRelease::fromIssuerCertificateVerificationFailed($attestationCertificateInfo['issuer']); - } - - return; - } - } - } - - /** - * If we got here, we skipped all the certificates in the trusted root collection for various reasons; so we - * therefore cannot trust the attestation certificate. - */ - throw FailedToVerifyRelease::fromNoIssuerCertificateInTrustedRoot($attestationCertificateInfo['issuer']); - } - - private function assertCertificateExtensionClaims(Attestation $attestation): void - { - $attestationCertificateInfo = openssl_x509_parse($attestation->certificate); - Assert::isArray($attestationCertificateInfo['extensions']); - - /** - * See {@link https://github.com/sigstore/fulcio/blob/main/docs/oid-info.md#136141572641--fulcio} for details - * on the Fulcio extension keys; note the values are DER-encoded strings; the ASN.1 tag is UTF8String (0x0C). - * - * Check the extension values are what we expect; these are hard-coded, as we don't expect them - * to change unless the namespace/repo name change, etc. - */ - foreach (self::ATTESTATION_CERTIFICATE_EXPECTED_EXTENSION_VALUES as $extension => $expectedValue) { - Assert::keyExists($attestationCertificateInfo['extensions'], $extension); - Assert::stringNotEmpty($attestationCertificateInfo['extensions'][$extension]); - $actualValue = $attestationCertificateInfo['extensions'][$extension]; - - // First character (the ASN.1 tag) is expected to be UTF8String (0x0C) - if (ord($actualValue[0]) !== 0x0C) { - throw FailedToVerifyRelease::fromMismatchingExtensionValues($extension, $expectedValue, $actualValue); - } - - /** - * Second character is expected to be the length of the actual value - * as long as they are less than 127 bytes (short form) - * - * @link https://www.oss.com/asn1/resources/asn1-made-simple/asn1-quick-reference/basic-encoding-rules.html#Lengths - */ - $expectedValueLength = ord($actualValue[1]); - if (strlen($actualValue) !== 2 + $expectedValueLength) { - throw FailedToVerifyRelease::fromInvalidDerEncodedStringLength($actualValue, 2 + $expectedValueLength); - } - - $derDecodedValue = substr($actualValue, 2, $expectedValueLength); - if ($derDecodedValue !== $expectedValue) { - throw FailedToVerifyRelease::fromMismatchingExtensionValues($extension, $expectedValue, $derDecodedValue); - } - } - } - - private function verifyDsseEnvelopeSignature(ReleaseMetadata $releaseMetadata, int $attestationIndex, Attestation $attestation): void - { - if (! extension_loaded('openssl')) { - throw FailedToVerifyRelease::fromNoOpenssl(); - } - - $publicKey = openssl_pkey_get_public($attestation->certificate); - Assert::isInstanceOf($publicKey, OpenSSLAsymmetricKey::class); - - $preAuthenticationEncoding = sprintf( - 'DSSEv1 %d %s %d %s', - strlen($attestation->dsseEnvelopePayloadType), - $attestation->dsseEnvelopePayloadType, - strlen($attestation->dsseEnvelopePayload), - $attestation->dsseEnvelopePayload, - ); - - if (openssl_verify($preAuthenticationEncoding, $attestation->dsseEnvelopeSignature, $publicKey, OPENSSL_ALGO_SHA256) !== 1) { - throw FailedToVerifyRelease::fromSignatureVerificationFailed($attestationIndex, $releaseMetadata); - } - } - - private function assertDigestFromAttestationMatchesActual(BinaryFile $pharFilename, Attestation $attestation): void - { - /** @var mixed $decodedPayload */ - $decodedPayload = json_decode($attestation->dsseEnvelopePayload, true); - - if ( - ! is_array($decodedPayload) - || ! array_key_exists('subject', $decodedPayload) - || ! is_array($decodedPayload['subject']) - || count($decodedPayload['subject']) !== 1 - || ! array_key_exists(0, $decodedPayload['subject']) - || ! is_array($decodedPayload['subject'][0]) - || ! array_key_exists('name', $decodedPayload['subject'][0]) - || $decodedPayload['subject'][0]['name'] !== 'pie.phar' - || ! array_key_exists('digest', $decodedPayload['subject'][0]) - || ! is_array($decodedPayload['subject'][0]['digest']) - || ! array_key_exists('sha256', $decodedPayload['subject'][0]['digest']) - || ! is_string($decodedPayload['subject'][0]['digest']['sha256']) - || $decodedPayload['subject'][0]['digest']['sha256'] === '' - ) { - throw FailedToVerifyRelease::fromInvalidSubjectDefinition(); - } - - $pharFilename->verifyAgainstOther(new BinaryFile( - $pharFilename->filePath, - $decodedPayload['subject'][0]['digest']['sha256'], - )); - } - - /** @return non-empty-list */ - private function downloadAttestations(ReleaseMetadata $releaseMetadata, BinaryFile $pharFilename): array - { - $attestationUrl = $this->githubApiBaseUrl . '/orgs/php/attestations/sha256:' . $pharFilename->checksum; - - try { - $decodedJson = $this->httpDownloader->get( - $attestationUrl, - [ - 'retry-auth-failure' => true, - 'http' => [ - 'method' => 'GET', - 'header' => $this->authHelper->addAuthenticationHeader([], $this->githubApiBaseUrl, $attestationUrl), - ], - ], - )->decodeJson(); - - Assert::isArray($decodedJson); - Assert::keyExists($decodedJson, 'attestations'); - Assert::isNonEmptyList($decodedJson['attestations']); - - return array_map( - static function (array $attestation): Attestation { - return Attestation::fromAttestationBundleWithDsseEnvelope($attestation); - }, - $decodedJson['attestations'], - ); - } catch (TransportException $transportException) { - if ($transportException->getStatusCode() === 404) { - throw FailedToVerifyRelease::fromMissingAttestation($releaseMetadata, $pharFilename); - } - - throw $transportException; - } - } } diff --git a/src/SelfManage/Verify/VerifyPieReleaseUsingAttestation.php b/src/SelfManage/Verify/VerifyPieReleaseUsingAttestation.php index 186d4f74..fbf3f24a 100644 --- a/src/SelfManage/Verify/VerifyPieReleaseUsingAttestation.php +++ b/src/SelfManage/Verify/VerifyPieReleaseUsingAttestation.php @@ -4,12 +4,11 @@ namespace Php\Pie\SelfManage\Verify; -use Composer\Util\AuthHelper; -use Composer\Util\HttpDownloader; use Php\Pie\File\BinaryFile; use Php\Pie\SelfManage\Update\ReleaseMetadata; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Process\ExecutableFinder; +use ThePhpFoundation\Attestation\Verification\VerifyAttestationWithOpenSsl; use function extension_loaded; @@ -22,15 +21,11 @@ public function __construct( ) { } - /** @param non-empty-string $githubApiBaseUrl */ - public static function factory( - string $githubApiBaseUrl, - HttpDownloader $httpDownloader, - AuthHelper $authHelper, - ): self { + public static function factory(): self + { return new VerifyPieReleaseUsingAttestation( new GithubCliAttestationVerification(new ExecutableFinder()), - new FallbackVerificationUsingOpenSsl(FallbackVerificationUsingOpenSsl::TRUSTED_ROOT_FILE_PATH, $githubApiBaseUrl, $httpDownloader, $authHelper), + new FallbackVerificationUsingOpenSsl(VerifyAttestationWithOpenSsl::factory()), ); } diff --git a/test/unit/SelfManage/Verify/FallbackVerificationUsingOpenSslTest.php b/test/unit/SelfManage/Verify/FallbackVerificationUsingOpenSslTest.php index cf820c18..7122661b 100644 --- a/test/unit/SelfManage/Verify/FallbackVerificationUsingOpenSslTest.php +++ b/test/unit/SelfManage/Verify/FallbackVerificationUsingOpenSslTest.php @@ -9,7 +9,6 @@ use Composer\Util\Http\Response; use Composer\Util\HttpDownloader; use Php\Pie\File\BinaryFile; -use Php\Pie\File\BinaryFileFailedVerification; use Php\Pie\SelfManage\Update\ReleaseMetadata; use Php\Pie\SelfManage\Verify\FailedToVerifyRelease; use Php\Pie\SelfManage\Verify\FallbackVerificationUsingOpenSsl; @@ -17,10 +16,13 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Output\BufferedOutput; +use ThePhpFoundation\Attestation\Verification\VerifyAttestationWithOpenSsl; +use function assert; use function base64_encode; use function extension_loaded; use function file_put_contents; +use function is_string; use function json_encode; use function openssl_csr_new; use function openssl_csr_sign; @@ -48,6 +50,7 @@ final class FallbackVerificationUsingOpenSslTest extends TestCase private AuthHelper&MockObject $authHelper; private BufferedOutput $output; private FallbackVerificationUsingOpenSsl $verifier; + /** @var non-empty-string */ private string $trustedRootFilePath; public function setUp(): void @@ -61,9 +64,11 @@ public function setUp(): void $this->authHelper = $this->createMock(AuthHelper::class); $this->output = new BufferedOutput(); - $this->trustedRootFilePath = tempnam(sys_get_temp_dir(), 'pie_test_trusted_root_file_path'); + $trustedRootFilePath = tempnam(sys_get_temp_dir(), 'pie_test_trusted_root_file_path'); + assert(is_string($trustedRootFilePath)); + $this->trustedRootFilePath = $trustedRootFilePath; - $this->verifier = new FallbackVerificationUsingOpenSsl($this->trustedRootFilePath, self::TEST_GITHUB_URL, $this->httpDownloader, $this->authHelper); + $this->verifier = new FallbackVerificationUsingOpenSsl(new VerifyAttestationWithOpenSsl($this->trustedRootFilePath, self::TEST_GITHUB_URL, $this->httpDownloader, $this->authHelper)); } /** @return array{0: string, 1: string} */ @@ -217,7 +222,7 @@ public function testFailedToVerifyBecauseDigestMismatch(): void $this->mockAttestationResponse($this->downloadedPhar->checksum, $dsseEnvelopePayload, $signature, $pemCertificate); - $this->expectException(BinaryFileFailedVerification::class); + $this->expectException(FailedToVerifyRelease::class); $this->verifier->verify($this->release, $this->downloadedPhar, $this->output); }