diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 9584ab7a..00000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,76 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ "*.*.x" ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ "4.6.x", "4.7.x" ] - schedule: - - cron: '37 10 * * 4' - -jobs: - analyze: - name: Analyze - runs-on: ${{ 'ubuntu-latest' }} - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'javascript' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Use only 'java' to analyze code written in Java, Kotlin or both - # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both - # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - - # Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v3 - - # ℹī¸ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - # If the Autobuild fails above, remove it and uncomment the following three lines. - # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. - - # - run: | - # echo "Run, Build Application using script" - # ./location_of_script_within_repo/buildscript.sh - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 0d4a0136..b9d6d20f 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -1,9 +1,3 @@ -# Dependency Review Action -# -# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. -# -# Source repository: https://github.com/actions/dependency-review-action -# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement name: 'Dependency Review' on: [pull_request] diff --git a/.github/workflows/infection.yml b/.github/workflows/infection.yml index 84a4ce7f..2f87de72 100644 --- a/.github/workflows/infection.yml +++ b/.github/workflows/infection.yml @@ -1,5 +1,3 @@ -# yaml-language-server: $schema=https://json.schemastore.org/github-workflow - name: "Integrate" on: diff --git a/.github/workflows/integrate.yml b/.github/workflows/integrate.yml index 47cd0538..c9d830d9 100644 --- a/.github/workflows/integrate.yml +++ b/.github/workflows/integrate.yml @@ -1,5 +1,3 @@ -# yaml-language-server: $schema=https://json.schemastore.org/github-workflow - name: "Integrate" on: @@ -32,7 +30,7 @@ jobs: - name: "Set up PHP" uses: "shivammathur/setup-php@v2" with: - php-version: "8.2" + php-version: "8.3" coverage: "none" - name: "Checkout code" @@ -56,8 +54,6 @@ jobs: operating-system: - "ubuntu-latest" php-version: - - "8.1" - - "8.2" - "8.3" dependencies: - "lowest" @@ -98,7 +94,7 @@ jobs: operating-system: - "ubuntu-latest" php-version: - - "8.2" + - "8.3" runs-on: ${{ matrix.operating-system }} steps: - name: "Set up PHP" @@ -132,7 +128,7 @@ jobs: - name: "Set up PHP" uses: "shivammathur/setup-php@v2" with: - php-version: "8.2" + php-version: "8.3" extensions: "ctype, curl, dom, json, libxml, mbstring, openssl, phar, simplexml, sodium, tokenizer, xml, xmlwriter, zlib" coverage: "none" @@ -164,13 +160,16 @@ jobs: - name: "Set up PHP" uses: "shivammathur/setup-php@v2" with: - php-version: "8.2" + php-version: "8.3" extensions: "ctype, curl, dom, json, libxml, mbstring, openssl, phar, simplexml, sodium, tokenizer, xml, xmlwriter, zlib" coverage: "none" - name: "Checkout code" uses: "actions/checkout@v4" + - name: "Get tags" + run: git fetch --tags origin + - name: "Check adherence to EditorConfig" uses: "greut/eclint-action@v0" @@ -197,7 +196,7 @@ jobs: - name: "Set up PHP" uses: "shivammathur/setup-php@v2" with: - php-version: "8.2" + php-version: "8.3" extensions: "ctype, curl, dom, json, libxml, mbstring, openssl, phar, simplexml, sodium, tokenizer, xml, xmlwriter, zlib" coverage: "xdebug" diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml index c2b017b9..fedb91dd 100644 --- a/.github/workflows/lock-closed-issues.yml +++ b/.github/workflows/lock-closed-issues.yml @@ -2,7 +2,7 @@ name: 'Lock Issues' on: schedule: - - cron: '0 0 * * *' + - cron: '12 6 * * *' jobs: lock: diff --git a/.github/workflows/release-on-milestone-closed.yml b/.github/workflows/release-on-milestone-closed.yml index b9986a89..00f73474 100644 --- a/.github/workflows/release-on-milestone-closed.yml +++ b/.github/workflows/release-on-milestone-closed.yml @@ -1,5 +1,3 @@ -# https://help.github.com/en/categories/automating-your-workflow-with-github-actions - name: "Automatic Releases" on: diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index a686ee38..a6379abe 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -1,12 +1,11 @@ name: Scorecards supply-chain security on: - # Only the default branch is supported. - branch_protection_rule: schedule: - cron: '34 4 * * 6' push: - branches: [ "4.6.x", "4.7.x" ] + branches: + - "*.*.x" # Declare default permissions as read only. permissions: read-all diff --git a/composer.json b/composer.json index 38147912..6fc48e04 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,6 @@ "symfony-ux", "bundle" ], - "minimum-stability": "dev", "homepage": "https://github.com/web-auth/webauthn-framework", "authors": [ { @@ -43,35 +42,28 @@ } }, "require": { - "php": ">=8.1", + "php": ">=8.3", "ext-json": "*", "ext-mbstring": "*", "ext-openssl": "*", - "lcobucci/clock": "^2.2|^3.0", - "nyholm/psr7": "^1.5", "paragonie/constant_time_encoding": "^2.6|^3.0", - "phpdocumentor/reflection-docblock": "^5.3", "psr/clock": "^1.0", "psr/event-dispatcher": "^1.0", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "spomky-labs/cbor-php": "^3.0", "spomky-labs/pki-framework": "^1.0", - "symfony/config": "^6.1|^7.0", - "symfony/dependency-injection": "^6.1|^7.0", + "symfony/config": "^7.0", + "symfony/dependency-injection": "^7.0", "symfony/deprecation-contracts": "^3.2", - "symfony/framework-bundle": "^6.1|^7.0", - "symfony/http-client": "^6.1|^7.0", - "symfony/psr-http-message-bridge": "^2.1|^6.1|^7.0", - "symfony/property-access": "^6.1|^7.0", - "symfony/property-info": "^6.1|^7.0", - "symfony/security-bundle": "^6.1|^7.0", - "symfony/security-core": "^6.1|^7.0", - "symfony/security-http": "^6.1|^7.0", - "symfony/serializer": "^6.1|^7.0", - "symfony/uid": "^6.1|^7.0", - "symfony/validator": "^6.1|^7.0", + "symfony/clock": "^7.0", + "symfony/framework-bundle": "^7.0", + "symfony/http-client": "^7.0", + "symfony/security-bundle": "^7.0", + "symfony/security-core": "^7.0", + "symfony/security-http": "^7.0", + "symfony/serializer": "^7.0", + "symfony/uid": "^7.0", + "symfony/validator": "^7.0", "web-auth/cose-lib": "^4.2.3", "web-token/jwt-library": "^3.3|^4.0" }, @@ -90,7 +82,6 @@ } }, "suggest": { - "psr/clock-implementation": "As of 4.5.x, the PSR Clock implementation will replace lcobucci/clock", "psr/log-implementation": "Recommended to receive logs from the library", "symfony/security-bundle": "Symfony firewall using a JSON API (perfect for script applications)" }, @@ -100,20 +91,20 @@ "doctrine/orm": "^2.14|^3.0", "doctrine/persistence": "^3.1", "ekino/phpstan-banned-code": "^1.0", - "infection/infection": "^0.27 || ^0.29", - "matthiasnoback/symfony-dependency-injection-test": "^4.3|^5.0", - "php-http/curl-client": "^2.2", - "php-http/mock-client": "^1.5", + "infection/infection": "^0.29", + "matthiasnoback/symfony-dependency-injection-test": "^5.1", "php-parallel-lint/php-parallel-lint": "^1.3", + "phpdocumentor/reflection-docblock": "^5.3", "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": "^10.1", - "qossmic/deptrac-shim": "^1.0", + "phpunit/phpunit": "^10.1|^11.0", + "qossmic/deptrac": "^2.0", "rector/rector": "^1.0", "roave/security-advisories": "dev-latest", + "staabm/phpstan-todo-by": "^0.1.25", "symfony/asset": "^6.4|^7.0", "symfony/asset-mapper": "^6.4|^7.0", "symfony/browser-kit": "^6.4|^7.0", diff --git a/deptrac.yaml b/deptrac.yaml index 68b46154..a9ad05f4 100644 --- a/deptrac.yaml +++ b/deptrac.yaml @@ -1,35 +1,35 @@ -parameters: +deptrac: paths: - './src' layers: - name: 'Webauthn' collectors: - type: 'directory' - regex: 'src/webauthn/.*' + value: 'src/webauthn/.*' - name: 'UX' collectors: - type: 'directory' - regex: 'src/stimulus/.*' + value: 'src/stimulus/.*' - name: 'SymfonyBundle' collectors: - type: 'directory' - regex: 'src/symfony/.*' + value: 'src/symfony/.*' - name: 'MetadataService' collectors: - type: 'directory' - regex: 'src/metadata-service/.*' + value: 'src/metadata-service/.*' - name: 'Vendors' collectors: - - { type: className, regex: '^Cose\\' } - - { type: className, regex: '^Symfony\\' } - - { type: className, regex: '^Jose\\' } - - { type: className, regex: '^Psr\\' } - - { type: className, regex: '^SpomkyLabs\\Pki\\' } - - { type: className, regex: '^CBOR\\' } - - { type: className, regex: '^Lcobucci\\' } - - { type: className, regex: '^ParagonIE\\' } - - { type: className, regex: '^Safe\\' } - - { type: className, regex: '^Doctrine\\' } + - { type: classLike, value: '^Cose\\' } + - { type: classLike, value: '^Symfony\\' } + - { type: classLike, value: '^Jose\\' } + - { type: classLike, value: '^Psr\\' } + - { type: classLike, value: '^SpomkyLabs\\Pki\\' } + - { type: classLike, value: '^CBOR\\' } + - { type: classLike, value: '^Lcobucci\\' } + - { type: classLike, value: '^ParagonIE\\' } + - { type: classLike, value: '^Safe\\' } + - { type: classLike, value: '^Doctrine\\' } ruleset: MetadataService: - 'Vendors' diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ac93686a..5ddc7b2c 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,868 +1,53 @@ parameters: ignoreErrors: - - message: "#^Parameter \\#2 \\$array of function array_map expects array, iterable\\ given\\.$#" - count: 1 - path: src/metadata-service/src/CertificateChain/CertificateToolbox.php - - - - message: "#^Call to an undefined method Psr\\\\Http\\\\Client\\\\ClientInterface\\|Symfony\\\\Contracts\\\\HttpClient\\\\HttpClientInterface\\:\\:sendRequest\\(\\)\\.$#" - count: 1 - path: src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php - - - - message: "#^Cannot call method createRequest\\(\\) on Psr\\\\Http\\\\Message\\\\RequestFactoryInterface\\|null\\.$#" - count: 1 - path: src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php - - - - message: "#^Parameter \\#1 \\$untrustedCertificates of static method Webauthn\\\\MetadataService\\\\Exception\\\\CertificateChainException\\:\\:create\\(\\) expects array\\, array\\ given\\.$#" - count: 2 - path: src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php - - - - message: "#^Parameter \\#2 \\$trustedCertificates of static method Webauthn\\\\MetadataService\\\\Exception\\\\CertificateChainException\\:\\:create\\(\\) expects array\\, array\\ given\\.$#" - count: 2 - path: src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Denormalizer\\\\ExtensionDescriptorDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Denormalizer\\\\ExtensionDescriptorDenormalizer\\:\\:supportsDenormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php - - - - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php - - - - message: "#^Strict comparison using \\=\\=\\= between Symfony\\\\Component\\\\Serializer\\\\Normalizer\\\\DenormalizerInterface and null will always evaluate to false\\.$#" - count: 1 - path: src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Psr18HttpClient\\:\\:request\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Psr18HttpClient.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Psr18HttpClient\\:\\:withOptions\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Psr18HttpClient.php - - - - message: "#^Property Webauthn\\\\MetadataService\\\\Psr18HttpClient\\:\\:\\$options type has no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Psr18HttpClient.php - - - - message: "#^Call to an undefined method Psr\\\\Http\\\\Client\\\\ClientInterface\\|Symfony\\\\Contracts\\\\HttpClient\\\\HttpClientInterface\\:\\:request\\(\\)\\.$#" - count: 1 - path: src/metadata-service/src/Service/DistantResourceMetadataService.php - - - - message: "#^Call to an undefined method Psr\\\\Http\\\\Client\\\\ClientInterface\\|Symfony\\\\Contracts\\\\HttpClient\\\\HttpClientInterface\\:\\:sendRequest\\(\\)\\.$#" - count: 1 - path: src/metadata-service/src/Service/DistantResourceMetadataService.php - - - - message: """ - #^Call to deprecated method createFromString\\(\\) of class Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\: - since 4\\.7\\.0\\. Please use the symfony/serializer for converting the object\\.$# - """ - count: 1 - path: src/metadata-service/src/Service/DistantResourceMetadataService.php - - - - message: "#^Cannot call method createRequest\\(\\) on Psr\\\\Http\\\\Message\\\\RequestFactoryInterface\\|null\\.$#" - count: 1 - path: src/metadata-service/src/Service/DistantResourceMetadataService.php - - - - message: "#^Parameter \\#5 \\$additionalHeaderParameters of class Webauthn\\\\MetadataService\\\\Service\\\\DistantResourceMetadataService constructor expects array\\, array\\ given\\.$#" - count: 1 - path: src/metadata-service/src/Service/DistantResourceMetadataService.php - - - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Call to an undefined method Psr\\\\Http\\\\Client\\\\ClientInterface\\|Symfony\\\\Contracts\\\\HttpClient\\\\HttpClientInterface\\:\\:request\\(\\)\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Call to an undefined method Psr\\\\Http\\\\Client\\\\ClientInterface\\|Symfony\\\\Contracts\\\\HttpClient\\\\HttpClientInterface\\:\\:sendRequest\\(\\)\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: """ - #^Call to deprecated method createFromArray\\(\\) of class Webauthn\\\\MetadataService\\\\Service\\\\MetadataBLOBPayloadEntry\\: - since 4\\.7\\.0\\. Please use the symfony/serializer for converting the object\\.$# - """ - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Cannot access offset 'entries' on mixed\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Cannot call method createRequest\\(\\) on Psr\\\\Http\\\\Message\\\\RequestFactoryInterface\\|null\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\Service\\\\MetadataBLOBPayloadEntry\\:\\:createFromArray\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Parameter \\#2 \\$headerParameters of method Webauthn\\\\MetadataService\\\\Service\\\\FidoAllianceCompliantMetadataService\\:\\:sendPsrRequest\\(\\) expects array\\, array\\ given\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Parameter \\#2 \\$headerParameters of method Webauthn\\\\MetadataService\\\\Service\\\\FidoAllianceCompliantMetadataService\\:\\:sendSymfonyRequest\\(\\) expects array\\, array\\ given\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: "#^Parameter &\\$rootCertificates by\\-ref type of method Webauthn\\\\MetadataService\\\\Service\\\\FidoAllianceCompliantMetadataService\\:\\:getJwsPayload\\(\\) expects array\\, array given\\.$#" - count: 1 - path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - - - message: """ - #^Call to deprecated method createFromString\\(\\) of class Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\: - since 4\\.7\\.0\\. Please use the symfony/serializer for converting the object\\.$# - """ - count: 1 - path: src/metadata-service/src/Service/FolderResourceMetadataService.php - - - - message: "#^Parameter \\#1 \\$string of function trim expects string, string\\|false given\\.$#" - count: 1 - path: src/metadata-service/src/Service/FolderResourceMetadataService.php - - - - message: """ - #^Call to deprecated method createFromString\\(\\) of class Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\: - since 4\\.7\\.0\\. Please use the symfony/serializer for converting the object\\.$# - """ - count: 1 - path: src/metadata-service/src/Service/JsonMetadataService.php - - - - message: """ - #^Call to deprecated method createFromString\\(\\) of class Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\: - since 4\\.7\\.0\\. Please use the symfony/serializer for converting the object\\.$# - """ - count: 1 - path: src/metadata-service/src/Service/LocalResourceMetadataService.php - - - - message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decode\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: src/metadata-service/src/Service/LocalResourceMetadataService.php - - - - message: "#^Parameter \\#1 \\$statement of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:createFromString\\(\\) expects string, string\\|false given\\.$#" - count: 1 - path: src/metadata-service/src/Service/LocalResourceMetadataService.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\Service\\\\MetadataBLOBPayloadEntry\\:\\:createFromArray\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Service/MetadataBLOBPayload.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: Webauthn\\\\MetadataService\\\\Statement\\\\StatusReport given\\.$#" - count: 1 - path: src/metadata-service/src/Service/MetadataBLOBPayloadEntry.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\AuthenticatorGetInfo\\:\\:jsonSerialize\\(\\) should return array\\ but returns array\\\\.$#" - count: 1 - path: src/metadata-service/src/Statement/AuthenticatorGetInfo.php - - - - message: "#^Parameter \\#1 \\$selfAttestedFRR of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricAccuracyDescriptor\\:\\:create\\(\\) expects float\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php - - - - message: "#^Parameter \\#2 \\$selfAttestedFAR of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricAccuracyDescriptor\\:\\:create\\(\\) expects float\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php - - - - message: "#^Parameter \\#3 \\$maxTemplates of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricAccuracyDescriptor\\:\\:create\\(\\) expects float\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php - - - - message: "#^Parameter \\#4 \\$maxRetries of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricAccuracyDescriptor\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php - - - - message: "#^Parameter \\#5 \\$blockSlowdown of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricAccuracyDescriptor\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php - - - - message: "#^Parameter \\#1 \\$certLevel of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricStatusReport\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricStatusReport.php - - - - message: "#^Parameter \\#2 \\$modality of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricStatusReport\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricStatusReport.php - - - - message: "#^Parameter \\#3 \\$effectiveDate of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricStatusReport\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricStatusReport.php - - - - message: "#^Parameter \\#4 \\$certificationDescriptor of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricStatusReport\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricStatusReport.php - - - - message: "#^Parameter \\#5 \\$certificateNumber of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricStatusReport\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricStatusReport.php - - - - message: "#^Parameter \\#6 \\$certificationPolicyVersion of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricStatusReport\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricStatusReport.php - - - - message: "#^Parameter \\#7 \\$certificationRequirementsVersion of static method Webauthn\\\\MetadataService\\\\Statement\\\\BiometricStatusReport\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/BiometricStatusReport.php - - - - message: "#^Parameter \\#1 \\$base of static method Webauthn\\\\MetadataService\\\\Statement\\\\CodeAccuracyDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/CodeAccuracyDescriptor.php - - - - message: "#^Parameter \\#2 \\$minLength of static method Webauthn\\\\MetadataService\\\\Statement\\\\CodeAccuracyDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/CodeAccuracyDescriptor.php - - - - message: "#^Parameter \\#3 \\$maxRetries of static method Webauthn\\\\MetadataService\\\\Statement\\\\CodeAccuracyDescriptor\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/CodeAccuracyDescriptor.php - - - - message: "#^Parameter \\#4 \\$blockSlowdown of static method Webauthn\\\\MetadataService\\\\Statement\\\\CodeAccuracyDescriptor\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/CodeAccuracyDescriptor.php - - - - message: "#^@readonly property Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:\\$plte is assigned outside of the constructor\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: Webauthn\\\\MetadataService\\\\Statement\\\\RgbPaletteEntry given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#1 \\$width of static method Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#2 \\$height of static method Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#3 \\$bitDepth of static method Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#4 \\$colorType of static method Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#5 \\$compression of static method Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#6 \\$filter of static method Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Parameter \\#7 \\$interlace of static method Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\EcdaaTrustAnchor\\:\\:jsonSerialize\\(\\) should return array\\ but returns array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/EcdaaTrustAnchor.php - - - - message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" - count: 5 - path: src/metadata-service/src/Statement/EcdaaTrustAnchor.php - - - - message: "#^Parameter \\#6 \\$G1Curve of class Webauthn\\\\MetadataService\\\\Statement\\\\EcdaaTrustAnchor constructor expects string, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/EcdaaTrustAnchor.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:__construct\\(\\) has parameter \\$tcDisplayPNGCharacteristics with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$alternativeDescriptions with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$attachmentHint with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$attestationCertificateKeyIdentifiers with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$attestationRootCertificates with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$attestationTypes with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$authenticationAlgorithms with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$ecdaaTrustAnchors with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$keyProtection with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$matcherProtection with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$publicKeyAlgAndEncodings with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$supportedExtensions with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$tcDisplay with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$tcDisplayPNGCharacteristics with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$upv with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) has parameter \\$userVerificationDetails with no value type specified in iterable type array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: Webauthn\\\\MetadataService\\\\Statement\\\\DisplayPNGCharacteristicsDescriptor given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:fixPEMStructures\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\Statement\\\\ExtensionDescriptor\\:\\:createFromArray\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:createFromArray\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\Statement\\\\VerificationMethodANDCombinations\\:\\:createFromArray\\(\\) expects array\\, array given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\Statement\\\\Version\\:\\:createFromArray\\(\\) expects array\\, array given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$description of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#1 \\$info of static method Webauthn\\\\MetadataService\\\\Statement\\\\AuthenticatorGetInfo\\:\\:create\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#10 \\$matcherProtection of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#11 \\$tcDisplay of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#13 \\$alternativeDescriptions of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#14 \\$legalHeader of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#15 \\$aaid of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#16 \\$aaguid of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#17 \\$attestationCertificateKeyIdentifiers of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#18 \\$keyProtection of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#19 \\$isKeyRestricted of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#2 \\$array of function array_map expects array, mixed given\\.$#" - count: 4 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#2 \\$authenticatorVersion of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#20 \\$isFreshUserVerificationRequired of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#21 \\$cryptoStrength of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#22 \\$attachmentHint of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#23 \\$tcDisplayContentType of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#25 \\$ecdaaTrustAnchors of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#26 \\$icon of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#3 \\$protocolFamily of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#4 \\$schema of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#6 \\$authenticationAlgorithms of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#7 \\$publicKeyAlgAndEncodings of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Parameter \\#8 \\$attestationTypes of static method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: """ - #^Parameter \\$ecdaaTrustAnchors of method Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\MetadataService\\\\Statement\\\\EcdaaTrustAnchor\\: - since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$# - """ - count: 1 - path: src/metadata-service/src/Statement/MetadataStatement.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\PatternAccuracyDescriptor\\:\\:jsonSerialize\\(\\) should return array\\ but returns array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/PatternAccuracyDescriptor.php - - - - message: "#^Parameter \\#1 \\$r of static method Webauthn\\\\MetadataService\\\\Statement\\\\RgbPaletteEntry\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/RgbPaletteEntry.php - - - - message: "#^Parameter \\#2 \\$g of static method Webauthn\\\\MetadataService\\\\Statement\\\\RgbPaletteEntry\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/RgbPaletteEntry.php - - - - message: "#^Parameter \\#3 \\$b of static method Webauthn\\\\MetadataService\\\\Statement\\\\RgbPaletteEntry\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/RgbPaletteEntry.php - - - - message: "#^Strict comparison using \\=\\=\\= between mixed and null will always evaluate to false\\.$#" - count: 1 - path: src/metadata-service/src/Statement/StatusReport.php - - - - message: "#^@readonly property Webauthn\\\\MetadataService\\\\Statement\\\\VerificationMethodANDCombinations\\:\\:\\$verificationMethods is assigned outside of the constructor\\.$#" - count: 1 - path: src/metadata-service/src/Statement/VerificationMethodANDCombinations.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: Webauthn\\\\MetadataService\\\\Statement\\\\VerificationMethodDescriptor given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/VerificationMethodANDCombinations.php - - - - message: "#^Method Webauthn\\\\MetadataService\\\\Statement\\\\Version\\:\\:jsonSerialize\\(\\) should return array\\ but returns array\\.$#" - count: 1 - path: src/metadata-service/src/Statement/Version.php - - - - message: "#^Parameter \\#1 \\$major of static method Webauthn\\\\MetadataService\\\\Statement\\\\Version\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/Version.php - - - - message: "#^Parameter \\#2 \\$minor of static method Webauthn\\\\MetadataService\\\\Statement\\\\Version\\:\\:create\\(\\) expects int\\|null, mixed given\\.$#" - count: 1 - path: src/metadata-service/src/Statement/Version.php - - - - message: "#^Cannot access offset 'FrameworkBundle' on array\\|bool\\|float\\|int\\|string\\|UnitEnum\\.$#" - count: 1 - path: src/stimulus/src/DependencyInjection/WebauthnStimulusExtension.php - - - - message: "#^Method Webauthn\\\\Stimulus\\\\WebauthnStimulusBundle\\:\\:getContainerExtension\\(\\) never returns null so it can be removed from the return type\\.$#" - count: 1 - path: src/stimulus/src/WebauthnStimulusBundle.php - - - - message: "#^Parameter \\#8 \\$publicKeyCredentialSourceRepository of class Webauthn\\\\Bundle\\\\Controller\\\\AssertionResponseController constructor expects Webauthn\\\\Bundle\\\\Repository\\\\PublicKeyCredentialSourceRepositoryInterface\\|null, Webauthn\\\\Bundle\\\\Repository\\\\PublicKeyCredentialSourceRepositoryInterface\\|Webauthn\\\\PublicKeyCredentialSourceRepository given\\.$#" - count: 1 - path: src/symfony/src/Controller/AssertionControllerFactory.php - - - - message: """ - #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AssertionControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: - since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# - """ - count: 1 - path: src/symfony/src/Controller/AssertionControllerFactory.php - - - - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\Bundle\\\\Controller\\\\AssertionControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/Controller/AssertionControllerFactory.php - - - - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Request\\:\\:getContentType\\(\\)\\.$#" - count: 1 - path: src/symfony/src/Controller/AssertionResponseController.php - - - - message: "#^Call to function method_exists\\(\\) with Symfony\\\\Component\\\\HttpFoundation\\\\Request and 'getContentTypeFormat' will always evaluate to true\\.$#" - count: 1 - path: src/symfony/src/Controller/AssertionResponseController.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Security\\\\Storage\\\\OptionsStorage\\:\\:get\\(\\) invoked with 1 parameter, 0 required\\.$#" - count: 1 - path: src/symfony/src/Controller/AssertionResponseController.php - - - - message: """ - #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AssertionResponseController\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: - since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# - """ - count: 1 - path: src/symfony/src/Controller/AssertionResponseController.php - - - - message: """ - #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AttestationControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: - since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# - """ - count: 1 - path: src/symfony/src/Controller/AttestationControllerFactory.php - - - - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\Bundle\\\\Controller\\\\AttestationControllerFactory\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationControllerFactory.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\CredentialOptionsBuilder\\\\PublicKeyCredentialCreationOptionsBuilder\\:\\:getFromRequest\\(\\) invoked with 3 parameters, 2 required\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationRequestController.php - - - - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Request\\:\\:getContentType\\(\\)\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationResponseController.php - - - - message: "#^Call to function method_exists\\(\\) with Symfony\\\\Component\\\\HttpFoundation\\\\Request and 'getContentTypeFormat' will always evaluate to true\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationResponseController.php - - - - message: "#^Fetching class constant class of deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationResponseController.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Security\\\\Storage\\\\OptionsStorage\\:\\:get\\(\\) invoked with 1 parameter, 0 required\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationResponseController.php - - - - message: "#^Parameter \\#2 \\$exception of method Symfony\\\\Component\\\\Security\\\\Http\\\\Authentication\\\\AuthenticationFailureHandlerInterface\\:\\:onAuthenticationFailure\\(\\) expects Symfony\\\\Component\\\\Security\\\\Core\\\\Exception\\\\AuthenticationException, Symfony\\\\Component\\\\Security\\\\Core\\\\Exception\\\\AuthenticationException\\|Webauthn\\\\Bundle\\\\Exception\\\\HttpNotImplementedException given\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationResponseController.php - - - - message: "#^Parameter \\$credentialSourceRepository of method Webauthn\\\\Bundle\\\\Controller\\\\AttestationResponseController\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/Controller/AttestationResponseController.php - - - - message: """ - #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Controller\\\\AttestationResponseController\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: - since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# - """ - count: 1 - path: src/symfony/src/Controller/AttestationResponseController.php - - - - message: """ - #^Access to deprecated property \\$authenticatorSelection of class Webauthn\\\\Bundle\\\\Dto\\\\PublicKeyCredentialCreationOptionsRequest\\: - Use \\$userVerification, \\$residentKey and \\$authenticatorAttachment$# - """ - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php - - - - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Request\\:\\:getContentType\\(\\)\\.$#" - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php - - - - message: """ - #^Call to deprecated method createFromArray\\(\\) of class Webauthn\\\\AuthenticatorSelectionCriteria\\: - since 4\\.8\\.0\\. Please use \\{Webauthn\\\\Denormalizer\\\\WebauthnSerializerFactory\\} for converting the object\\.$# - """ - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php - - - - message: "#^Call to function method_exists\\(\\) with Symfony\\\\Component\\\\HttpFoundation\\\\Request and 'getContentTypeFormat' will always evaluate to true\\.$#" - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php - - - - message: """ - #^Call to method create\\(\\) of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php - - - - message: "#^Fetching class constant class of deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php - - - - message: "#^Parameter \\$credentialSourceRepository of method Webauthn\\\\Bundle\\\\CredentialOptionsBuilder\\\\ProfileBasedCreationOptionsBuilder\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php - - - - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Request\\:\\:getContentType\\(\\)\\.$#" - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php - - - - message: "#^Call to function method_exists\\(\\) with Symfony\\\\Component\\\\HttpFoundation\\\\Request and 'getContentTypeFormat' will always evaluate to true\\.$#" - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php - - - - message: """ - #^Call to method create\\(\\) of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php - - - - message: "#^Fetching class constant class of deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" + message: "#^Method Webauthn\\\\MetadataService\\\\Denormalizer\\\\ExtensionDescriptorDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php + path: src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php - - message: "#^Parameter \\#1 \\$userEntity of method Webauthn\\\\Bundle\\\\CredentialOptionsBuilder\\\\ProfileBasedRequestOptionsBuilder\\:\\:getCredentials\\(\\) expects Webauthn\\\\PublicKeyCredentialUserEntity, Webauthn\\\\PublicKeyCredentialUserEntity\\|null given\\.$#" + message: "#^Method Webauthn\\\\MetadataService\\\\Denormalizer\\\\ExtensionDescriptorDenormalizer\\:\\:supportsDenormalization\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php + path: src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php - - message: "#^Parameter \\$credentialSourceRepository of method Webauthn\\\\Bundle\\\\CredentialOptionsBuilder\\\\ProfileBasedRequestOptionsBuilder\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" + message: "#^Method Webauthn\\\\MetadataService\\\\Psr18HttpClient\\:\\:request\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 - path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php + path: src/metadata-service/src/Psr18HttpClient.php - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\Bundle\\\\Event\\\\AuthenticatorAssertionResponseValidationFailedEvent\\: - since 4\\.3\\.0, use \\{@link \\\\Webauthn\\\\Event\\\\AuthenticatorAssertionResponseValidationFailedEvent\\} instead\\.$# - """ + message: "#^Method Webauthn\\\\MetadataService\\\\Psr18HttpClient\\:\\:withOptions\\(\\) has parameter \\$options with no value type specified in iterable type array\\.$#" count: 1 - path: src/symfony/src/DataCollector/WebauthnCollector.php + path: src/metadata-service/src/Psr18HttpClient.php - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\Bundle\\\\Event\\\\AuthenticatorAssertionResponseValidationSucceededEvent\\: - since 4\\.3\\.0, use \\{@link \\\\Webauthn\\\\Event\\\\AuthenticatorAssertionResponseValidationSucceededEvent\\} instead\\.$# - """ + message: "#^Property Webauthn\\\\MetadataService\\\\Psr18HttpClient\\:\\:\\$options type has no value type specified in iterable type array\\.$#" count: 1 - path: src/symfony/src/DataCollector/WebauthnCollector.php + path: src/metadata-service/src/Psr18HttpClient.php - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\Bundle\\\\Event\\\\AuthenticatorAttestationResponseValidationSucceededEvent\\: - since 4\\.3\\.0, use \\{@link \\\\Webauthn\\\\Event\\\\AuthenticatorAttestationResponseValidationSucceededEvent\\} instead\\.$# - """ + message: "#^Parameter &\\$rootCertificates by\\-ref type of method Webauthn\\\\MetadataService\\\\Service\\\\FidoAllianceCompliantMetadataService\\:\\:getJwsPayload\\(\\) expects array\\, array given\\.$#" count: 1 - path: src/symfony/src/DataCollector/WebauthnCollector.php + path: src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php - - message: """ - #^Parameter \\$event of method Webauthn\\\\Bundle\\\\DataCollector\\\\WebauthnCollector\\:\\:addAuthenticatorAssertionResponseValidationFailed\\(\\) has typehint with deprecated class Webauthn\\\\Bundle\\\\Event\\\\AuthenticatorAssertionResponseValidationFailedEvent\\: - since 4\\.3\\.0, use \\{@link \\\\Webauthn\\\\Event\\\\AuthenticatorAssertionResponseValidationFailedEvent\\} instead\\.$# - """ + message: "#^Cannot access offset 'FrameworkBundle' on array\\|bool\\|float\\|int\\|string\\|UnitEnum\\.$#" count: 1 - path: src/symfony/src/DataCollector/WebauthnCollector.php + path: src/stimulus/src/DependencyInjection/WebauthnStimulusExtension.php - - message: """ - #^Parameter \\$event of method Webauthn\\\\Bundle\\\\DataCollector\\\\WebauthnCollector\\:\\:addAuthenticatorAssertionResponseValidationSucceeded\\(\\) has typehint with deprecated class Webauthn\\\\Bundle\\\\Event\\\\AuthenticatorAssertionResponseValidationSucceededEvent\\: - since 4\\.3\\.0, use \\{@link \\\\Webauthn\\\\Event\\\\AuthenticatorAssertionResponseValidationSucceededEvent\\} instead\\.$# - """ + message: "#^Method Webauthn\\\\Bundle\\\\CredentialOptionsBuilder\\\\PublicKeyCredentialCreationOptionsBuilder\\:\\:getFromRequest\\(\\) invoked with 3 parameters, 2 required\\.$#" count: 1 - path: src/symfony/src/DataCollector/WebauthnCollector.php + path: src/symfony/src/Controller/AttestationRequestController.php - - message: """ - #^Parameter \\$event of method Webauthn\\\\Bundle\\\\DataCollector\\\\WebauthnCollector\\:\\:addAuthenticatorAttestationResponseValidationSucceeded\\(\\) has typehint with deprecated class Webauthn\\\\Bundle\\\\Event\\\\AuthenticatorAttestationResponseValidationSucceededEvent\\: - since 4\\.3\\.0, use \\{@link \\\\Webauthn\\\\Event\\\\AuthenticatorAttestationResponseValidationSucceededEvent\\} instead\\.$# - """ + message: "#^Parameter \\#1 \\$userEntity of method Webauthn\\\\Bundle\\\\CredentialOptionsBuilder\\\\ProfileBasedRequestOptionsBuilder\\:\\:getCredentials\\(\\) expects Webauthn\\\\PublicKeyCredentialUserEntity, Webauthn\\\\PublicKeyCredentialUserEntity\\|null given\\.$#" count: 1 - path: src/symfony/src/DataCollector/WebauthnCollector.php + path: src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php - message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface\\:\\:integerNode\\(\\)\\.$#" - count: 2 + count: 1 path: src/symfony/src/DependencyInjection/Configuration.php - @@ -870,14 +55,6 @@ parameters: count: 4 path: src/symfony/src/DependencyInjection/Configuration.php - - - message: """ - #^Call to deprecated method addAndroidSafetynetConfig\\(\\) of class Webauthn\\\\Bundle\\\\DependencyInjection\\\\Configuration\\: - since 4\\.9\\.0 and will be removed in 5\\.0\\.0\\. Android SafetyNet is now deprecated\\.$# - """ - count: 1 - path: src/symfony/src/DependencyInjection/Configuration.php - - message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeParentInterface\\:\\:scalarNode\\(\\)\\.$#" count: 1 @@ -923,21 +100,6 @@ parameters: count: 12 path: src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php - - - message: "#^Method Webauthn\\\\Bundle\\\\DependencyInjection\\\\Factory\\\\Security\\\\WebauthnFactory\\:\\:createAuthenticator\\(\\) never returns array\\ so it can be removed from the return type\\.$#" - count: 1 - path: src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\DependencyInjection\\\\Factory\\\\Security\\\\WebauthnFactory\\:\\:getAssertionOptionsBuilderId\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" - count: 1 - path: src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\DependencyInjection\\\\Factory\\\\Security\\\\WebauthnFactory\\:\\:getAttestationOptionsBuilderId\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" - count: 1 - path: src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php - - message: "#^Parameter \\#3 \\$config of method Webauthn\\\\Bundle\\\\DependencyInjection\\\\Factory\\\\Security\\\\WebauthnFactory\\:\\:getAssertionOptionsBuilderId\\(\\) expects array, mixed given\\.$#" count: 1 @@ -1048,14 +210,6 @@ parameters: count: 1 path: src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php - - - message: """ - #^Call to deprecated method loadAndroidSafetyNet\\(\\) of class Webauthn\\\\Bundle\\\\DependencyInjection\\\\WebauthnExtension\\: - since 4\\.9\\.0 and will be removed in 5\\.0\\.0\\. Android SafetyNet is now deprecated\\.$# - """ - count: 1 - path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - message: "#^Cannot access offset 'failure_handler' on mixed\\.$#" count: 4 @@ -1126,27 +280,6 @@ parameters: count: 1 path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - - message: """ - #^Fetching class constant class of deprecated interface Webauthn\\\\Bundle\\\\Repository\\\\PublicKeyCredentialUserEntityRepository\\: - since 4\\.6\\.0, to be removed in 5\\.0\\.0\\. Use \\{@link PublicKeyCredentialUserEntityRepositoryInterface\\} and \\{@link CanRegisterUserEntity\\} instead\\.$# - """ - count: 1 - path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - - - message: "#^Fetching class constant class of deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - - - message: """ - #^Fetching class constant class of deprecated interface Webauthn\\\\TokenBinding\\\\TokenBindingHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - message: "#^Method Webauthn\\\\Bundle\\\\DependencyInjection\\\\WebauthnExtension\\:\\:getConfiguration\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#" count: 1 @@ -1167,174 +300,11 @@ parameters: count: 15 path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - - message: "#^Parameter \\#2 \\$id of method Symfony\\\\Component\\\\DependencyInjection\\\\ContainerBuilder\\:\\:setAlias\\(\\) expects string\\|Symfony\\\\Component\\\\DependencyInjection\\\\Alias, mixed given\\.$#" - count: 1 - path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - - - message: "#^Parameter \\#2 \\$value of method Symfony\\\\Component\\\\DependencyInjection\\\\Container\\:\\:setParameter\\(\\) expects array\\|bool\\|float\\|int\\|string\\|UnitEnum\\|null, mixed given\\.$#" - count: 3 - path: src/symfony/src/DependencyInjection/WebauthnExtension.php - - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/AAGUIDDataType.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Doctrine\\\\Type\\\\AAGUIDDataType\\:\\:convertToDatabaseValue\\(\\) should return string\\|null but returns mixed\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/AAGUIDDataType.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Doctrine\\\\Type\\\\AAGUIDDataType\\:\\:convertToPHPValue\\(\\) should return Symfony\\\\Component\\\\Uid\\\\Uuid\\|null but returns mixed\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/AAGUIDDataType.php - - - - message: "#^Parameter \\#1 \\$uuid of static method Symfony\\\\Component\\\\Uid\\\\Uuid\\:\\:fromString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/AAGUIDDataType.php - - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/AttestedCredentialDataType.php - - - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\AttestedCredentialData\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/AttestedCredentialDataType.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Doctrine\\\\Type\\\\Base64BinaryDataType\\:\\:convertToDatabaseValue\\(\\) should return string\\|null but returns mixed\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/Base64BinaryDataType.php - - - - message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decode\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/Base64BinaryDataType.php - - - - message: "#^@readonly property Webauthn\\\\Bundle\\\\Doctrine\\\\Type\\\\PublicKeyCredentialDescriptorCollection\\:\\:\\$publicKeyCredentialDescriptors is already assigned\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^@readonly property Webauthn\\\\Bundle\\\\Doctrine\\\\Type\\\\PublicKeyCredentialDescriptorCollection\\:\\:\\$publicKeyCredentialDescriptors is assigned outside of the constructor\\.$#" - count: 2 - path: src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Doctrine\\\\Type\\\\PublicKeyCredentialDescriptorCollection\\:\\:jsonSerialize\\(\\) should return array\\\\> but returns array\\\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: Webauthn\\\\PublicKeyCredentialDescriptor given\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\Bundle\\\\Doctrine\\\\Type\\\\PublicKeyCredentialDescriptorCollection\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php - - message: "#^Parameter \\#2 \\$mode of function count expects 0\\|1, int given\\.$#" count: 1 path: src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\PublicKeyCredentialDescriptor\\:\\:createFromString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorType.php - - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/TrustPathDataType.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\TrustPath\\\\TrustPathLoader\\:\\:loadTrustPath\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/symfony/src/Doctrine/Type/TrustPathDataType.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Repository\\\\DoctrineCredentialSourceRepository\\:\\:findAllForUserEntity\\(\\) should return array\\ but returns mixed\\.$#" - count: 1 - path: src/symfony/src/Repository/DoctrineCredentialSourceRepository.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\Repository\\\\DoctrineCredentialSourceRepository\\:\\:findOneByCredentialId\\(\\) should return Webauthn\\\\PublicKeyCredentialSource\\|null but returns mixed\\.$#" - count: 1 - path: src/symfony/src/Repository/DoctrineCredentialSourceRepository.php - - - - message: "#^Class Webauthn\\\\Bundle\\\\Repository\\\\PublicKeyCredentialSourceRepository extends generic class Webauthn\\\\Bundle\\\\Repository\\\\DoctrineCredentialSourceRepository but does not specify its types\\: T$#" - count: 1 - path: src/symfony/src/Repository/PublicKeyCredentialSourceRepository.php - - - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\AttestationStatement\\\\AndroidSafetyNetAttestationStatementSupport\\: - since 4\\.9\\.0 and will be removed in 5\\.0\\.0\\. Android SafetyNet is now deprecated\\.$# - """ - count: 1 - path: src/symfony/src/Resources/config/android_safetynet.php - - - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: - since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# - """ - count: 1 - path: src/symfony/src/Resources/config/services.php - - - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\TokenBinding\\\\IgnoreTokenBindingHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/symfony/src/Resources/config/services.php - - - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\TokenBinding\\\\SecTokenBindingHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/symfony/src/Resources/config/services.php - - - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\TokenBinding\\\\TokenBindingNotSupportedHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/symfony/src/Resources/config/services.php - - - - message: "#^Fetching class constant class of deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 2 - path: src/symfony/src/Resources/config/services.php - - - - message: """ - #^Class Webauthn\\\\Bundle\\\\Security\\\\Authentication\\\\Token\\\\WebauthnToken implements deprecated interface Webauthn\\\\Bundle\\\\Security\\\\Authentication\\\\Token\\\\WebauthnTokenInterface\\: - since 4\\.7\\.0, use \\{@see WebauthnToken\\} instead$# - """ - count: 1 - path: src/symfony/src/Security/Authentication/Token/WebauthnToken.php - - - - message: "#^Parameter \\#1 \\$data of method Symfony\\\\Component\\\\Security\\\\Core\\\\Authentication\\\\Token\\\\AbstractToken\\:\\:__unserialize\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/symfony/src/Security/Authentication/Token/WebauthnToken.php - - message: "#^Property Webauthn\\\\Bundle\\\\Security\\\\Authentication\\\\Token\\\\WebauthnToken\\:\\:\\$extensions \\(Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null\\) does not accept mixed\\.$#" count: 1 @@ -1410,34 +380,11 @@ parameters: count: 1 path: src/symfony/src/Security/Guesser/RequestBodyUserEntityGuesser.php - - - message: """ - #^Call to deprecated method generateNextUserEntityId\\(\\) of interface Webauthn\\\\Bundle\\\\Repository\\\\CanRegisterUserEntity\\: - since 4\\.7\\.0 and will be removed in 5\\.0\\.0\\. Please use Webauthn\\\\Bundle\\\\Repository\\\\CanGenerateUserEntity\\:\\:generateUserEntity\\(\\) instead\\.$# - """ - count: 1 - path: src/symfony/src/Security/Guesser/RequestBodyUserEntityGuesser.php - - message: "#^Call to function method_exists\\(\\) with Symfony\\\\Component\\\\HttpFoundation\\\\Request and 'getContentTypeFormat' will always evaluate to true\\.$#" count: 1 path: src/symfony/src/Security/Guesser/RequestBodyUserEntityGuesser.php - - - message: "#^Call to an undefined method Symfony\\\\Component\\\\HttpFoundation\\\\Request\\:\\:getContentType\\(\\)\\.$#" - count: 2 - path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php - - - - message: "#^Call to function method_exists\\(\\) with Symfony\\\\Component\\\\HttpFoundation\\\\Request and 'getContentTypeFormat' will always evaluate to true\\.$#" - count: 2 - path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php - - - - message: "#^Fetching class constant class of deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php - - message: "#^Method Webauthn\\\\Bundle\\\\Security\\\\Http\\\\Authenticator\\\\WebauthnAuthenticator\\:\\:__construct\\(\\) has parameter \\$userProvider with generic interface Symfony\\\\Component\\\\Security\\\\Core\\\\User\\\\UserProviderInterface but does not specify its types\\: TUser$#" count: 1 @@ -1453,24 +400,6 @@ parameters: count: 1 path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php - - - message: "#^Method Webauthn\\\\Bundle\\\\Security\\\\Storage\\\\OptionsStorage\\:\\:get\\(\\) invoked with 1 parameter, 0 required\\.$#" - count: 2 - path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php - - - - message: """ - #^Parameter \\$publicKeyCredentialLoader of method Webauthn\\\\Bundle\\\\Security\\\\Http\\\\Authenticator\\\\WebauthnAuthenticator\\:\\:__construct\\(\\) has typehint with deprecated class Webauthn\\\\PublicKeyCredentialLoader\\: - since 4\\.8\\.0 and will be removed in 5\\.0\\.0\\. Please use the Symfony serializer instead$# - """ - count: 1 - path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php - - - - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\Bundle\\\\Security\\\\Http\\\\Authenticator\\\\WebauthnAuthenticator\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php - - message: "#^Cannot access offset 'enabled' on mixed\\.$#" count: 2 @@ -1621,14 +550,6 @@ parameters: count: 1 path: src/symfony/src/Security/WebauthnFirewallConfig.php - - - message: """ - #^Call to method create\\(\\) of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 1 - path: src/symfony/src/Service/PublicKeyCredentialCreationOptionsFactory.php - - message: "#^Cannot access offset 'attestationâ€Ļ' on mixed\\.$#" count: 1 @@ -1659,11 +580,6 @@ parameters: count: 1 path: src/symfony/src/Service/PublicKeyCredentialCreationOptionsFactory.php - - - message: "#^Cannot access offset 'require_resident_key' on mixed\\.$#" - count: 1 - path: src/symfony/src/Service/PublicKeyCredentialCreationOptionsFactory.php - - message: "#^Cannot access offset 'resident_key' on mixed\\.$#" count: 1 @@ -1754,19 +670,6 @@ parameters: count: 1 path: src/symfony/src/Service/PublicKeyCredentialCreationOptionsFactory.php - - - message: "#^Parameter \\#4 \\$requireResidentKey of static method Webauthn\\\\AuthenticatorSelectionCriteria\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" - count: 1 - path: src/symfony/src/Service/PublicKeyCredentialCreationOptionsFactory.php - - - - message: """ - #^Call to method create\\(\\) of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 1 - path: src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php - - message: "#^Cannot access offset 'challenge_length' on mixed\\.$#" count: 1 @@ -1803,122 +706,64 @@ parameters: path: src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php - - message: "#^Parameter \\#1 \\$profile of method Webauthn\\\\Bundle\\\\Service\\\\PublicKeyCredentialRequestOptionsFactory\\:\\:createExtensions\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php - - - - message: "#^Parameter \\#3 \\.\\.\\.\\$arrays of function array_map expects array, mixed given\\.$#" - count: 1 - path: src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php - - - - message: """ - #^Instantiation of deprecated class Webauthn\\\\Bundle\\\\DependencyInjection\\\\Compiler\\\\EnforcedSafetyNetApiKeyVerificationCompilerPass\\: - since 4\\.9\\.0 and will be removed in 5\\.0\\.0\\. Android SafetyNet is now deprecated\\.$# - """ - count: 1 - path: src/symfony/src/WebauthnBundle.php - - - - message: "#^Method Webauthn\\\\Bundle\\\\WebauthnBundle\\:\\:getContainerExtension\\(\\) never returns null so it can be removed from the return type\\.$#" - count: 1 - path: src/symfony/src/WebauthnBundle.php - - - - message: "#^Cannot access offset 'x5c' on mixed\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - - - message: "#^Cannot cast mixed to int\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - - - message: "#^Parameter \\#1 \\$data of static method Cose\\\\Key\\\\Key\\:\\:createFromData\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects iterable\\, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - - - message: "#^Parameter \\#1 \\$fmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createBasic\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - - - message: "#^Parameter \\#1 \\$key of function openssl_pkey_get_details expects OpenSSLAsymmetricKey, OpenSSLAsymmetricKey\\|false given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - - - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - - - message: "#^Parameter \\#2 \\$attStmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createBasic\\(\\) expects array\\, mixed given\\.$#" + message: "#^Parameter \\#1 \\$profile of method Webauthn\\\\Bundle\\\\Service\\\\PublicKeyCredentialRequestOptionsFactory\\:\\:createExtensions\\(\\) expects array, mixed given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php + path: src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php - - message: "#^Parameter \\#2 \\$signature of function openssl_verify expects string, mixed given\\.$#" + message: "#^Parameter \\#3 \\.\\.\\.\\$arrays of function array_map expects array, mixed given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php + path: src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php - - message: "#^Cannot access offset 'jws' on mixed\\.$#" + message: "#^Method Webauthn\\\\Bundle\\\\WebauthnBundle\\:\\:getContainerExtension\\(\\) never returns null so it can be removed from the return type\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/symfony/src/WebauthnBundle.php - - message: "#^Cannot access offset 'response' on mixed\\.$#" + message: "#^Cannot access offset 'x5c' on mixed\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - message: "#^Cannot call method createRequest\\(\\) on Psr\\\\Http\\\\Message\\\\RequestFactoryInterface\\|null\\.$#" + message: "#^Cannot cast mixed to int\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - message: "#^Cannot call method request\\(\\) on Psr\\\\Http\\\\Client\\\\ClientInterface\\|Symfony\\\\Contracts\\\\HttpClient\\\\HttpClientInterface\\|null\\.$#" + message: "#^Parameter \\#1 \\$data of static method Cose\\\\Key\\\\Key\\:\\:createFromData\\(\\) expects array\\, mixed given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - message: "#^Cannot call method sendRequest\\(\\) on Psr\\\\Http\\\\Client\\\\ClientInterface\\|Symfony\\\\Contracts\\\\HttpClient\\\\HttpClientInterface\\|null\\.$#" + message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects array\\, mixed given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - message: "#^Parameter \\#1 \\$certificates of method Webauthn\\\\AttestationStatement\\\\AndroidSafetyNetAttestationStatementSupport\\:\\:convertCertificatesToPem\\(\\) expects array\\, mixed given\\.$#" + message: "#^Parameter \\#1 \\$fmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createBasic\\(\\) expects string, mixed given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - message: "#^Parameter \\#1 \\$input of method Jose\\\\Component\\\\Signature\\\\Serializer\\\\CompactSerializer\\:\\:unserialize\\(\\) expects string, mixed given\\.$#" + message: "#^Parameter \\#1 \\$key of function openssl_pkey_get_details expects OpenSSLAsymmetricKey, OpenSSLAsymmetricKey\\|false given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" - count: 3 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + count: 1 + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - message: "#^Parameter \\#2 \\$attStmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createBasic\\(\\) expects array\\, mixed given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - - message: "#^Parameter \\#2 \\.\\.\\.\\$values of function sprintf expects bool\\|float\\|int\\|string\\|null, mixed given\\.$#" + message: "#^Parameter \\#2 \\$signature of function openssl_verify expects string, mixed given\\.$#" count: 1 - path: src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php + path: src/webauthn/src/AttestationStatement/AndroidKeyAttestationStatementSupport.php - message: "#^Parameter \\#1 \\$data of static method Cose\\\\Key\\\\Key\\:\\:createFromData\\(\\) expects array\\, mixed given\\.$#" @@ -1945,33 +790,13 @@ parameters: count: 1 path: src/webauthn/src/AttestationStatement/AttestationStatement.php - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\TrustPath\\\\TrustPathLoader\\:\\:loadTrustPath\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AttestationStatement.php - - - - message: "#^Parameter \\#1 \\$fmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:create\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AttestationStatement.php - - - - message: "#^Parameter \\#2 \\$attStmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:create\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AttestationStatement.php - - - - message: "#^Parameter \\#3 \\$type of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:create\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/AttestationStatement.php - - message: "#^Cannot access offset 'x5c' on mixed\\.$#" count: 1 path: src/webauthn/src/AttestationStatement/FidoU2FAttestationStatementSupport.php - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects iterable\\, array given\\.$#" + message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects array\\, array given\\.$#" count: 1 path: src/webauthn/src/AttestationStatement/FidoU2FAttestationStatementSupport.php @@ -2000,19 +825,6 @@ parameters: count: 1 path: src/webauthn/src/AttestationStatement/FidoU2FAttestationStatementSupport.php - - - message: """ - #^Call to deprecated method createEcdaa\\(\\) of class Webauthn\\\\AttestationStatement\\\\AttestationStatement\\: - since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$# - """ - count: 1 - path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - - - message: "#^Cannot access offset 'ecdaaKeyId' on mixed\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - message: "#^Cannot access offset 'x5c' on mixed\\.$#" count: 1 @@ -2024,20 +836,7 @@ parameters: path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - message: """ - #^Instantiation of deprecated class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath\\: - since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$# - """ - count: 1 - path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects iterable\\, array given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - - - message: "#^Parameter \\#1 \\$ecdaaKeyId of class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath constructor expects string, mixed given\\.$#" + message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects array\\, array given\\.$#" count: 1 path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php @@ -2046,11 +845,6 @@ parameters: count: 1 path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - - message: "#^Parameter \\#1 \\$fmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createEcdaa\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - message: "#^Parameter \\#1 \\$fmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createSelf\\(\\) expects string, mixed given\\.$#" count: 1 @@ -2071,11 +865,6 @@ parameters: count: 1 path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - - message: "#^Parameter \\#2 \\$attStmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createEcdaa\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php - - message: "#^Parameter \\#2 \\$attStmt of static method Webauthn\\\\AttestationStatement\\\\AttestationStatement\\:\\:createSelf\\(\\) expects array\\, mixed given\\.$#" count: 1 @@ -2157,7 +946,7 @@ parameters: path: src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects iterable\\, mixed given\\.$#" + message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\MetadataService\\\\CertificateChain\\\\CertificateToolbox\\:\\:convertAllDERToPEM\\(\\) expects array\\, mixed given\\.$#" count: 1 path: src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php @@ -2168,7 +957,7 @@ parameters: - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" - count: 2 + count: 1 path: src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php - @@ -2181,9 +970,14 @@ parameters: count: 1 path: src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php + - + message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed, int\\|string\\)\\: mixed\\)\\|null, Closure\\(mixed, string\\)\\: Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtension given\\.$#" + count: 1 + path: src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionLoader.php + - message: "#^@readonly property Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\:\\:\\$extensions is assigned outside of the constructor\\.$#" - count: 4 + count: 3 path: src/webauthn/src/AuthenticationExtensions/AuthenticationExtensions.php - @@ -2201,81 +995,6 @@ parameters: count: 1 path: src/webauthn/src/AuthenticationExtensions/AuthenticationExtensions.php - - - message: "#^Class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensionsClientInputs extends @final class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\.$#" - count: 1 - path: src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php - - - - message: "#^Class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensionsClientOutputs extends @final class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\.$#" - count: 1 - path: src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputs.php - - - - message: """ - #^Call to method create\\(\\) of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 1 - path: src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed, int\\|string\\)\\: mixed\\)\\|null, Closure\\(mixed, string\\)\\: Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtension given\\.$#" - count: 1 - path: src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php - - - - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\AuthenticatorAssertionResponseValidator\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/webauthn/src/AuthenticatorAssertionResponseValidator.php - - - - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\AuthenticatorAssertionResponseValidator\\:\\:create\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/webauthn/src/AuthenticatorAssertionResponseValidator.php - - - - message: """ - #^Parameter \\$tokenBindingHandler of method Webauthn\\\\AuthenticatorAssertionResponseValidator\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\TokenBinding\\\\TokenBindingHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/webauthn/src/AuthenticatorAssertionResponseValidator.php - - - - message: """ - #^Parameter \\$tokenBindingHandler of method Webauthn\\\\AuthenticatorAssertionResponseValidator\\:\\:create\\(\\) has typehint with deprecated interface Webauthn\\\\TokenBinding\\\\TokenBindingHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/webauthn/src/AuthenticatorAssertionResponseValidator.php - - - - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\AuthenticatorAttestationResponseValidator\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/webauthn/src/AuthenticatorAttestationResponseValidator.php - - - - message: "#^Parameter \\$publicKeyCredentialSourceRepository of method Webauthn\\\\AuthenticatorAttestationResponseValidator\\:\\:create\\(\\) has typehint with deprecated interface Webauthn\\\\PublicKeyCredentialSourceRepository\\.$#" - count: 1 - path: src/webauthn/src/AuthenticatorAttestationResponseValidator.php - - - - message: """ - #^Parameter \\$tokenBindingHandler of method Webauthn\\\\AuthenticatorAttestationResponseValidator\\:\\:__construct\\(\\) has typehint with deprecated interface Webauthn\\\\TokenBinding\\\\TokenBindingHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/webauthn/src/AuthenticatorAttestationResponseValidator.php - - - - message: """ - #^Parameter \\$tokenBindingHandler of method Webauthn\\\\AuthenticatorAttestationResponseValidator\\:\\:create\\(\\) has typehint with deprecated interface Webauthn\\\\TokenBinding\\\\TokenBindingHandler\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/webauthn/src/AuthenticatorAttestationResponseValidator.php - - message: "#^Cannot access offset 1 on array\\|false\\.$#" count: 2 @@ -2301,40 +1020,6 @@ parameters: count: 1 path: src/webauthn/src/AuthenticatorDataLoader.php - - - message: """ - #^Access to deprecated property \\$requireResidentKey of class Webauthn\\\\AuthenticatorSelectionCriteria\\: - Will be removed in 5\\.0\\. Please use residentKey instead\\*$# - """ - count: 3 - path: src/webauthn/src/AuthenticatorSelectionCriteria.php - - - - message: "#^Method Webauthn\\\\AuthenticatorSelectionCriteria\\:\\:isRequireResidentKey\\(\\) should return bool but returns bool\\|null\\.$#" - count: 1 - path: src/webauthn/src/AuthenticatorSelectionCriteria.php - - - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\AuthenticatorSelectionCriteria\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/AuthenticatorSelectionCriteria.php - - - - message: """ - #^Fetching deprecated class constant ATTESTATION_ECDAA of class Webauthn\\\\MetadataService\\\\Statement\\\\MetadataStatement\\: - since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$# - """ - count: 1 - path: src/webauthn/src/CeremonyStep/CheckMetadataStatement.php - - - - message: """ - #^Fetching deprecated class constant TYPE_ECDAA of class Webauthn\\\\AttestationStatement\\\\AttestationStatement\\: - since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$# - """ - count: 1 - path: src/webauthn/src/CeremonyStep/CheckMetadataStatement.php - - message: "#^Access to an undefined property Webauthn\\\\PublicKeyCredentialCreationOptions\\|Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:\\$rp\\.$#" count: 1 @@ -2345,22 +1030,6 @@ parameters: count: 1 path: src/webauthn/src/CeremonyStep/CheckRelyingPartyIdIdHash.php - - - message: """ - #^Access to deprecated property \\$tokenBinding of class Webauthn\\\\CollectedClientData\\: - Since 4\\.3\\.0 and will be removed in 5\\.0\\.0$# - """ - count: 1 - path: src/webauthn/src/CollectedClientData.php - - - - message: """ - #^Access to deprecated property \\$id of class Webauthn\\\\Credential\\: - since 4\\.9\\.0\\. Please use the property rawId instead\\.$# - """ - count: 1 - path: src/webauthn/src/Credential.php - - message: "#^Cannot access offset 'authData' on mixed\\.$#" count: 1 @@ -2456,22 +1125,6 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/AuthenticationExtensionNormalizer.php - - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensionsClientInputs\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 2 - path: src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php - - - - message: """ - #^Fetching class constant class of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensionsClientOutputs\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 2 - path: src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php - - message: "#^Method Webauthn\\\\Denormalizer\\\\AuthenticationExtensionsDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 @@ -2713,7 +1366,7 @@ parameters: path: src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php - - message: "#^Parameter \\#4 \\$response of static method Webauthn\\\\PublicKeyCredential\\:\\:create\\(\\) expects Webauthn\\\\AuthenticatorResponse, mixed given\\.$#" + message: "#^Parameter \\#3 \\$response of static method Webauthn\\\\PublicKeyCredential\\:\\:create\\(\\) expects Webauthn\\\\AuthenticatorResponse, mixed given\\.$#" count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php @@ -2903,7 +1556,7 @@ parameters: path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php - - message: "#^Parameter \\#6 \\$extensions of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects array\\\\|Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null, mixed given\\.$#" + message: "#^Parameter \\#6 \\$extensions of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:create\\(\\) expects array\\\\|Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null, mixed given\\.$#" count: 1 path: src/webauthn/src/Denormalizer/PublicKeyCredentialOptionsDenormalizer.php @@ -3137,14 +1790,6 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/TrustPathDenormalizer.php - - - message: """ - #^Instantiation of deprecated class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath\\: - since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$# - """ - count: 1 - path: src/webauthn/src/Denormalizer/TrustPathDenormalizer.php - - message: "#^Method Webauthn\\\\Denormalizer\\\\TrustPathDenormalizer\\:\\:denormalize\\(\\) has parameter \\$context with no value type specified in iterable type array\\.$#" count: 1 @@ -3170,197 +1815,36 @@ parameters: count: 1 path: src/webauthn/src/Denormalizer/TrustPathDenormalizer.php - - - message: "#^Parameter \\#1 \\$ecdaaKeyId of class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath constructor expects string, array given\\.$#" - count: 1 - path: src/webauthn/src/Denormalizer/TrustPathDenormalizer.php - - message: "#^Parameter \\#2 \\$array of function array_key_exists expects array, mixed given\\.$#" - count: 2 - path: src/webauthn/src/Denormalizer/TrustPathDenormalizer.php - - - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\PublicKeyCredentialCreationOptions\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" count: 1 - path: src/webauthn/src/PublicKeyCredentialCreationOptions.php + path: src/webauthn/src/Denormalizer/TrustPathDenormalizer.php - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\PublicKeyCredentialDescriptor\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" + message: "#^Method Webauthn\\\\PublicKeyCredentialDescriptor\\:\\:createFromArray\\(\\) has parameter \\$data with no value type specified in iterable type array\\.$#" count: 1 path: src/webauthn/src/PublicKeyCredentialDescriptor.php - - message: "#^@readonly property Webauthn\\\\PublicKeyCredentialDescriptorCollection\\:\\:\\$publicKeyCredentialDescriptors is already assigned\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^@readonly property Webauthn\\\\PublicKeyCredentialDescriptorCollection\\:\\:\\$publicKeyCredentialDescriptors is assigned outside of the constructor\\.$#" - count: 2 - path: src/webauthn/src/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Method Webauthn\\\\PublicKeyCredentialDescriptorCollection\\:\\:jsonSerialize\\(\\) should return array\\\\> but returns array\\\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(mixed\\)\\: mixed\\)\\|null, Closure\\(array\\)\\: Webauthn\\\\PublicKeyCredentialDescriptor given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\PublicKeyCredentialDescriptorCollection\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Parameter \\#2 \\$mode of function count expects 0\\|1, int given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialDescriptorCollection.php - - - - message: "#^Cannot call method load\\(\\) on Webauthn\\\\AttestationStatement\\\\AttestationObjectLoader\\|null\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialLoader.php - - - - message: "#^Parameter \\#1 \\$json of method Webauthn\\\\PublicKeyCredentialLoader\\:\\:loadArray\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialLoader.php - - - - message: """ - #^Call to method create\\(\\) of deprecated class Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\: - since 4\\.8\\.0\\. Use \\{Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\} instead\\.$# - """ - count: 1 - path: src/webauthn/src/PublicKeyCredentialOptions.php - - - - message: "#^Parameter \\#1 \\$extensions of static method Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\:\\:create\\(\\) expects array\\, array\\ given\\.$#" + message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\PublicKeyCredentialDescriptor\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" count: 1 - path: src/webauthn/src/PublicKeyCredentialOptions.php + path: src/webauthn/src/PublicKeyCredentialDescriptor.php - - message: "#^Property Webauthn\\\\PublicKeyCredentialOptions\\:\\:\\$timeout \\(int\\<1, max\\>\\|null\\) does not accept int\\|null\\.$#" + message: "#^Parameter \\#1 \\$extensions of static method Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\:\\:create\\(\\) expects array\\, array\\ given\\.$#" count: 1 path: src/webauthn/src/PublicKeyCredentialOptions.php - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\PublicKeyCredentialParameters\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialParameters.php - - - - message: "#^Parameter \\#1 \\$json of static method Webauthn\\\\PublicKeyCredentialRequestOptions\\:\\:createFromArray\\(\\) expects array, mixed given\\.$#" + message: "#^Parameter \\#3 \\$extensions of method Webauthn\\\\PublicKeyCredentialOptions\\:\\:__construct\\(\\) expects array\\\\|Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null, array\\|Webauthn\\\\AuthenticationExtensions\\\\AuthenticationExtensions\\|null given\\.$#" count: 1 path: src/webauthn/src/PublicKeyCredentialRequestOptions.php - - - message: "#^Cannot cast mixed to string\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#1 \\$data of static method Webauthn\\\\TrustPath\\\\TrustPathLoader\\:\\:loadTrustPath\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#1 \\$encodedString of static method ParagonIE\\\\ConstantTime\\\\Base64\\:\\:decodeNoPadding\\(\\) expects string, mixed given\\.$#" - count: 3 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#1 \\$uuid of static method Symfony\\\\Component\\\\Uid\\\\Uuid\\:\\:fromString\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#10 \\$otherUI of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects array\\\\|null, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#11 \\$backupEligible of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#12 \\$backupStatus of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects bool\\|null, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#2 \\$type of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#3 \\$transports of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects array\\, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#4 \\$attestationType of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - - - message: "#^Parameter \\#9 \\$counter of static method Webauthn\\\\PublicKeyCredentialSource\\:\\:create\\(\\) expects int, mixed given\\.$#" - count: 1 - path: src/webauthn/src/PublicKeyCredentialSource.php - - message: "#^Method Webauthn\\\\SimpleFakeCredentialGenerator\\:\\:generate\\(\\) should return array\\ but returns mixed\\.$#" count: 1 path: src/webauthn/src/SimpleFakeCredentialGenerator.php - - - message: "#^Method Webauthn\\\\StringStream\\:\\:read\\(\\) should return string but returns string\\|false\\.$#" - count: 1 - path: src/webauthn/src/StringStream.php - - - - message: "#^Parameter \\#1 \\$stream of function fwrite expects resource, resource\\|false given\\.$#" - count: 1 - path: src/webauthn/src/StringStream.php - - - - message: "#^Parameter \\#1 \\$stream of function rewind expects resource, resource\\|false given\\.$#" - count: 1 - path: src/webauthn/src/StringStream.php - - - - message: "#^Parameter \\#1 \\$string of function mb_strlen expects string, string\\|false given\\.$#" - count: 2 - path: src/webauthn/src/StringStream.php - - - - message: "#^Property Webauthn\\\\StringStream\\:\\:\\$data \\(resource\\) does not accept resource\\|false\\.$#" - count: 1 - path: src/webauthn/src/StringStream.php - - - - message: "#^Parameter \\#1 \\$certificates of static method Webauthn\\\\TrustPath\\\\CertificateTrustPath\\:\\:create\\(\\) expects array\\, array given\\.$#" - count: 1 - path: src/webauthn/src/TrustPath/CertificateTrustPath.php - - - - message: "#^Parameter \\#1 \\$ecdaaKeyId of class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath constructor expects string, mixed given\\.$#" - count: 1 - path: src/webauthn/src/TrustPath/EcdaaKeyIdTrustPath.php - - - - message: """ - #^Instantiation of deprecated class Webauthn\\\\TrustPath\\\\EcdaaKeyIdTrustPath\\: - since 4\\.2\\.0 and will be removed in 5\\.0\\.0\\. The ECDAA Trust Anchor does no longer exist in Webauthn specification\\.$# - """ - count: 1 - path: src/webauthn/src/TrustPath/TrustPathLoader.php - - message: "#^Parameter \\#1 \\$certificates of static method Webauthn\\\\TrustPath\\\\CertificateTrustPath\\:\\:create\\(\\) expects array\\, array given\\.$#" count: 1 diff --git a/phpstan.neon b/phpstan.neon index bdf86577..a7bb9884 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,6 +8,14 @@ parameters: treatPhpDocTypesAsCertain: false scanFiles: - vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php +# todo_by: +# ticket: +# enabled: true +# tracker: github +# github: +# defaultOwner: spomky +# defaultRepo: web-auth/webauthn-framework +# credentials: %env.GH_TOKEN% includes: - vendor/phpstan/phpstan/conf/bleedingEdge.neon - phpstan-baseline.neon diff --git a/src/metadata-service/composer.json b/src/metadata-service/composer.json index 3bc891a7..abdc56e8 100644 --- a/src/metadata-service/composer.json +++ b/src/metadata-service/composer.json @@ -20,17 +20,16 @@ } ], "require": { - "php": ">=8.1", + "php": ">=8.3", "ext-json": "*", - "lcobucci/clock": "^2.2|^3.0", "paragonie/constant_time_encoding": "^2.6|^3.0", "psr/clock": "^1.0", "psr/event-dispatcher": "^1.0", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "spomky-labs/pki-framework": "^1.0", - "symfony/deprecation-contracts": "^3.2" + "symfony/deprecation-contracts": "^3.2", + "symfony/clock": "^7.0", + "web-token/jwt-library": "^3.3|^4.0" }, "autoload": { "psr-4": { @@ -44,12 +43,10 @@ } }, "suggest": { - "symfony/serializer": "As of 4.5.x, the symfony/serializer component will become mandatory for converting objects such as the Metadata Statement", - "symfony/property-access": "As of 4.5.x, the symfony/serializer component will become mandatory for converting objects such as the Metadata Statement", - "symfony/property-info": "As of 4.5.x, the symfony/serializer component will become mandatory for converting objects such as the Metadata Statement", + "symfony/serializer": "The symfony/serializer component is mandatory for converting objects such as the Metadata Statement", + "symfony/property-access": "The symfony/serializer component is mandatory for converting objects such as the Metadata Statement", + "symfony/property-info": "The symfony/serializer component is mandatory for converting objects such as the Metadata Statement", "phpdocumentor/reflection-docblock": "As of 4.5.x, the phpdocumentor/reflection-docblock component will become mandatory for converting objects such as the Metadata Statement", - "psr/clock-implementation": "As of 4.5.x, the PSR Clock implementation will replace lcobucci/clock", - "psr/log-implementation": "Recommended to receive logs from the library", - "web-token/jwt-library": "Mandatory for fetching Metadata Statement from distant sources" + "psr/log-implementation": "Recommended to receive logs from the library" } } diff --git a/src/metadata-service/src/CertificateChain/CertificateToolbox.php b/src/metadata-service/src/CertificateChain/CertificateToolbox.php index 47c4406f..2484ee7e 100644 --- a/src/metadata-service/src/CertificateChain/CertificateToolbox.php +++ b/src/metadata-service/src/CertificateChain/CertificateToolbox.php @@ -4,15 +4,13 @@ namespace Webauthn\MetadataService\CertificateChain; -use ParagonIE\ConstantTime\Base64; -use function preg_replace; use const PHP_EOL; -class CertificateToolbox +final readonly class CertificateToolbox { - private const PEM_HEADER = '-----BEGIN '; + private const string PEM_HEADER = '-----BEGIN '; - private const PEM_FOOTER = '-----END '; + private const string PEM_FOOTER = '-----END '; /** * @param string[] $data @@ -35,21 +33,6 @@ public static function fixPEMStructure(string $data, string $type = 'CERTIFICATE return $pem . (self::PEM_FOOTER . $type . '-----' . PHP_EOL); } - /** - * @deprecated since 4.7.0 and will be removed in 5.0.0. No replacement as not used internally. - * @infection-ignore-all - */ - public static function convertPEMToDER(string $data): string - { - if (! str_contains($data, self::PEM_HEADER)) { - return $data; - } - $data = preg_replace('/\-{5}.*\-{5}[\r\n]*/', '', $data); - $data = preg_replace("/[\r\n]*/", '', (string) $data); - - return Base64::decode(trim((string) $data), true); - } - public static function convertDERToPEM(string $data, string $type = 'CERTIFICATE'): string { if (str_contains($data, self::PEM_HEADER)) { @@ -64,7 +47,7 @@ public static function convertDERToPEM(string $data, string $type = 'CERTIFICATE * * @return string[] */ - public static function convertAllDERToPEM(iterable $data, string $type = 'CERTIFICATE'): array + public static function convertAllDERToPEM(array $data, string $type = 'CERTIFICATE'): array { return array_map(static fn ($d): string => self::convertDERToPEM($d, $type), $data); } diff --git a/src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php b/src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php index 27ba91c0..0e26ae02 100644 --- a/src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php +++ b/src/metadata-service/src/CertificateChain/PhpCertificateChainValidator.php @@ -4,18 +4,14 @@ namespace Webauthn\MetadataService\CertificateChain; -use DateTimeZone; -use Lcobucci\Clock\Clock; -use Lcobucci\Clock\SystemClock; use Psr\Clock\ClockInterface; use Psr\EventDispatcher\EventDispatcherInterface; -use Psr\Http\Client\ClientInterface; -use Psr\Http\Message\RequestFactoryInterface; use SpomkyLabs\Pki\ASN1\Type\UnspecifiedType; use SpomkyLabs\Pki\CryptoEncoding\PEM; use SpomkyLabs\Pki\X509\Certificate\Certificate; use SpomkyLabs\Pki\X509\CertificationPath\CertificationPath; use SpomkyLabs\Pki\X509\CertificationPath\PathValidation\PathValidationConfig; +use Symfony\Component\Clock\NativeClock; use Symfony\Contracts\HttpClient\HttpClientInterface; use Throwable; use Webauthn\MetadataService\Event\BeforeCertificateChainValidation; @@ -32,45 +28,29 @@ use const PHP_EOL; use const PHP_URL_SCHEME; -class PhpCertificateChainValidator implements CertificateChainValidator, CanDispatchEvents +final class PhpCertificateChainValidator implements CertificateChainValidator, CanDispatchEvents { - private const MAX_VALIDATION_LENGTH = 5; + private const int MAX_VALIDATION_LENGTH = 5; - private readonly Clock|ClockInterface $clock; + private readonly ClockInterface $clock; private EventDispatcherInterface $dispatcher; public function __construct( - private readonly ClientInterface|HttpClientInterface $client, - private readonly ?RequestFactoryInterface $requestFactory = null, - null|Clock|ClockInterface $clock = null, + private readonly HttpClientInterface $client, + null|ClockInterface $clock = null, private readonly bool $allowFailures = true ) { - if ($clock === null) { - trigger_deprecation( - 'web-auth/metadata-service', - '4.5.0', - 'The parameter "$clock" will become mandatory in 5.0.0. Please set a valid PSR Clock implementation instead of "null".' - ); - $clock = new SystemClock(new DateTimeZone('UTC')); - } - if ($requestFactory !== null && ! $client instanceof HttpClientInterface) { - trigger_deprecation( - 'web-auth/metadata-service', - '4.7.0', - 'The parameter "$requestFactory" will be removed in 5.0.0. Please set it to null and set an Symfony\Contracts\HttpClient\HttpClientInterface as "$client" argument.' - ); - } - $this->clock = $clock; + $this->clock = $clock ?? new NativeClock(); $this->dispatcher = new NullEventDispatcher(); } public static function create( HttpClientInterface $client, - null|Clock|ClockInterface $clock = null, + null|ClockInterface $clock = null, bool $allowFailures = true ): self { - return new self($client, null, $clock, $allowFailures); + return new self($client, $clock, $allowFailures); } public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): void @@ -111,22 +91,22 @@ public function check(array $untrustedCertificates, array $trustedCertificates): */ private function validateChain(array $untrustedCertificates, string $trustedCertificate): bool { - $untrustedCertificates = array_map( + $untrustedCertificateObjects = array_map( static fn (string $cert): Certificate => Certificate::fromPEM(PEM::fromString($cert)), array_reverse($untrustedCertificates) ); - $trustedCertificate = Certificate::fromPEM(PEM::fromString($trustedCertificate)); + $trustedCertificateObject = Certificate::fromPEM(PEM::fromString($trustedCertificate)); // The trust path and the authenticator certificate are the same if (count( - $untrustedCertificates - ) === 1 && $untrustedCertificates[0]->toPEM()->string() === $trustedCertificate->toPEM()->string()) { + $untrustedCertificateObjects + ) === 1 && $untrustedCertificateObjects[0]->toPEM()->string() === $trustedCertificateObject->toPEM()->string()) { return true; } $uniqueCertificates = array_map( static fn (Certificate $cert): string => $cert->toPEM() ->string(), - [...$untrustedCertificates, $trustedCertificate] + [...$untrustedCertificateObjects, $trustedCertificateObject] ); count(array_unique($uniqueCertificates)) === count( $uniqueCertificates @@ -136,11 +116,11 @@ private function validateChain(array $untrustedCertificates, string $trustedCert 'Invalid certificate chain with duplicated certificates.' ); - if (! $this->validateCertificates($trustedCertificate, ...$untrustedCertificates)) { + if (! $this->validateCertificates($trustedCertificateObject, ...$untrustedCertificateObjects)) { return false; } - $certificates = [$trustedCertificate, ...$untrustedCertificates]; + $certificates = [$trustedCertificateObject, ...$untrustedCertificateObjects]; $numCerts = count($certificates); for ($i = 1; $i < $numCerts; $i++) { if ($this->isRevoked($certificates[$i])) { @@ -221,12 +201,8 @@ private function validateCertificates(Certificate ...$certificates): bool private function retrieveRevokedSerialNumbers(string $url): array { try { - if ($this->client instanceof HttpClientInterface) { - $crlData = $this->client->request('GET', $url) - ->getContent(); - } else { - $crlData = $this->sendPsrRequest($url); - } + $crlData = $this->client->request('GET', $url) + ->getContent(); $crl = UnspecifiedType::fromDER($crlData)->asSequence(); count($crl) === 3 || throw CertificateRevocationListException::create($url); $tbsCertList = $crl->at(0) @@ -280,16 +256,4 @@ private function getCrlUrlList(Certificate $subject): array ); } } - - private function sendPsrRequest(string $url): string - { - $request = $this->requestFactory->createRequest('GET', $url); - $response = $this->client->sendRequest($request); - if ($response->getStatusCode() !== 200) { - throw CertificateRevocationListException::create($url, 'Failed to download the CRL'); - } - - return $response->getBody() - ->getContents(); - } } diff --git a/src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php b/src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php index 52626c46..cf6745e7 100644 --- a/src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php +++ b/src/metadata-service/src/Denormalizer/ExtensionDescriptorDenormalizer.php @@ -4,25 +4,23 @@ namespace Webauthn\MetadataService\Denormalizer; -use Symfony\Component\Serializer\Exception\BadMethodCallException; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Webauthn\MetadataService\Statement\ExtensionDescriptor; use function array_key_exists; +use function assert; +use function is_array; final class ExtensionDescriptorDenormalizer implements DenormalizerInterface, DenormalizerAwareInterface { use DenormalizerAwareTrait; - private const ALREADY_CALLED = 'EXTENSION_DESCRIPTOR_PREPROCESS_ALREADY_CALLED'; + private const string ALREADY_CALLED = 'EXTENSION_DESCRIPTOR_PREPROCESS_ALREADY_CALLED'; public function denormalize(mixed $data, string $type, string $format = null, array $context = []): mixed { - if ($this->denormalizer === null) { - throw new BadMethodCallException('Please set a denormalizer before calling denormalize()!'); - } - + assert(is_array($data), 'Data should be an array'); if (array_key_exists('fail_if_unknown', $data)) { $data['failIfUnknown'] = $data['fail_if_unknown']; unset($data['fail_if_unknown']); diff --git a/src/metadata-service/src/Denormalizer/MetadataStatementSerializerFactory.php b/src/metadata-service/src/Denormalizer/MetadataStatementSerializerFactory.php index e751c8bb..805857b2 100644 --- a/src/metadata-service/src/Denormalizer/MetadataStatementSerializerFactory.php +++ b/src/metadata-service/src/Denormalizer/MetadataStatementSerializerFactory.php @@ -4,6 +4,7 @@ namespace Webauthn\MetadataService\Denormalizer; +use RuntimeException; use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor; use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; use Symfony\Component\PropertyInfo\PropertyInfoExtractor; @@ -14,19 +15,23 @@ use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; -final class MetadataStatementSerializerFactory +final readonly class MetadataStatementSerializerFactory { private const PACKAGE_SYMFONY_PROPERTY_INFO = 'symfony/property-info'; private const PACKAGE_SYMFONY_SERIALIZER = 'symfony/serializer'; - private const PACKAGE_PHPDOCUMENTOR_REFLECTION_DOCBLOCK = 'phpdocumentor/reflection-docblock'; + private const string PACKAGE_PHPDOCUMENTOR_REFLECTION_DOCBLOCK = 'phpdocumentor/reflection-docblock'; - public static function create(): ?SerializerInterface + public static function create(): SerializerInterface { foreach (self::getRequiredSerializerClasses() as $class => $package) { if (! class_exists($class)) { - return null; + throw new RuntimeException(sprintf( + 'The class %s is required. Please install the package %s.', + $class, + $package + )); } } diff --git a/src/metadata-service/src/Service/DistantResourceMetadataService.php b/src/metadata-service/src/Service/DistantResourceMetadataService.php index 98eec3a7..7e148fad 100644 --- a/src/metadata-service/src/Service/DistantResourceMetadataService.php +++ b/src/metadata-service/src/Service/DistantResourceMetadataService.php @@ -6,8 +6,6 @@ use ParagonIE\ConstantTime\Base64; use Psr\EventDispatcher\EventDispatcherInterface; -use Psr\Http\Client\ClientInterface; -use Psr\Http\Message\RequestFactoryInterface; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Webauthn\MetadataService\Denormalizer\MetadataStatementSerializerFactory; @@ -25,26 +23,18 @@ final class DistantResourceMetadataService implements MetadataService, CanDispat private EventDispatcherInterface $dispatcher; - private readonly ?SerializerInterface $serializer; + private readonly SerializerInterface $serializer; /** * @param array $additionalHeaderParameters */ public function __construct( - private readonly ?RequestFactoryInterface $requestFactory, - private readonly ClientInterface|HttpClientInterface $httpClient, + private readonly HttpClientInterface $httpClient, private readonly string $uri, private readonly bool $isBase64Encoded = false, private readonly array $additionalHeaderParameters = [], ?SerializerInterface $serializer = null, ) { - if ($requestFactory !== null && ! $httpClient instanceof HttpClientInterface) { - trigger_deprecation( - 'web-auth/metadata-service', - '4.7.0', - 'The parameter "$requestFactory" will be removed in 5.0.0. Please set it to null and set an Symfony\Contracts\HttpClient\HttpClientInterface as "$httpClient" argument.' - ); - } $this->serializer = $serializer ?? MetadataStatementSerializerFactory::create(); $this->dispatcher = new NullEventDispatcher(); } @@ -55,17 +45,16 @@ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): v } /** - * @param array $additionalHeaderParameters + * @param array $additionalHeaderParameters */ public static function create( - ?RequestFactoryInterface $requestFactory, - ClientInterface|HttpClientInterface $httpClient, + HttpClientInterface $httpClient, string $uri, bool $isBase64Encoded = false, array $additionalHeaderParameters = [], ?SerializerInterface $serializer = null ): self { - return new self($requestFactory, $httpClient, $uri, $isBase64Encoded, $additionalHeaderParameters, $serializer); + return new self($httpClient, $uri, $isBase64Encoded, $additionalHeaderParameters, $serializer); } public function list(): iterable @@ -112,47 +101,10 @@ private function loadData(): void if ($this->isBase64Encoded) { $content = Base64::decode($content, true); } - if ($this->serializer !== null) { - $this->statement = $this->serializer->deserialize($content, MetadataStatement::class, 'json'); - return; - } - - $this->statement = MetadataStatement::createFromString($content); + $this->statement = $this->serializer->deserialize($content, MetadataStatement::class, 'json'); } private function fetch(): string - { - if ($this->httpClient instanceof HttpClientInterface) { - $content = $this->sendSymfonyRequest(); - } else { - $content = $this->sendPsrRequest(); - } - $content !== '' || throw MetadataStatementLoadingException::create( - 'Unable to contact the server. The response has no content' - ); - - return $content; - } - - private function sendPsrRequest(): string - { - $request = $this->requestFactory->createRequest('GET', $this->uri); - foreach ($this->additionalHeaderParameters as $k => $v) { - $request = $request->withHeader($k, $v); - } - $response = $this->httpClient->sendRequest($request); - $response->getStatusCode() === 200 || throw MetadataStatementLoadingException::create(sprintf( - 'Unable to contact the server. Response code is %d', - $response->getStatusCode() - )); - $response->getBody() - ->rewind(); - - return $response->getBody() - ->getContents(); - } - - private function sendSymfonyRequest(): string { $response = $this->httpClient->request('GET', $this->uri, [ 'headers' => $this->additionalHeaderParameters, @@ -162,6 +114,11 @@ private function sendSymfonyRequest(): string $response->getStatusCode() )); - return $response->getContent(); + $content = $response->getContent(); + $content !== '' || throw MetadataStatementLoadingException::create( + 'Unable to contact the server. The response has no content' + ); + + return $content; } } diff --git a/src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php b/src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php index bcef7c18..20555262 100644 --- a/src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php +++ b/src/metadata-service/src/Service/FidoAllianceCompliantMetadataService.php @@ -11,8 +11,6 @@ use Jose\Component\Signature\JWSVerifier; use Jose\Component\Signature\Serializer\CompactSerializer; use Psr\EventDispatcher\EventDispatcherInterface; -use Psr\Http\Client\ClientInterface; -use Psr\Http\Message\RequestFactoryInterface; use Symfony\Component\Serializer\SerializerInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Throwable; @@ -29,7 +27,6 @@ use function array_key_exists; use function is_array; use function sprintf; -use const JSON_THROW_ON_ERROR; final class FidoAllianceCompliantMetadataService implements MetadataService, CanDispatchEvents { @@ -47,27 +44,19 @@ final class FidoAllianceCompliantMetadataService implements MetadataService, Can private EventDispatcherInterface $dispatcher; - private readonly ?SerializerInterface $serializer; + private readonly SerializerInterface $serializer; /** * @param array $additionalHeaderParameters */ public function __construct( - private readonly ?RequestFactoryInterface $requestFactory, - private readonly ClientInterface|HttpClientInterface $httpClient, + private readonly HttpClientInterface $httpClient, private readonly string $uri, private readonly array $additionalHeaderParameters = [], private readonly ?CertificateChainValidator $certificateChainValidator = null, private readonly ?string $rootCertificateUri = null, - ?SerializerInterface $serializer = null, + SerializerInterface $serializer = null, ) { - if ($requestFactory !== null && ! $httpClient instanceof HttpClientInterface) { - trigger_deprecation( - 'web-auth/metadata-service', - '4.7.0', - 'The parameter "$requestFactory" will be removed in 5.0.0. Please set it to null and set an Symfony\Contracts\HttpClient\HttpClientInterface as "$httpClient" argument.' - ); - } $this->serializer = $serializer ?? MetadataStatementSerializerFactory::create(); $this->dispatcher = new NullEventDispatcher(); } @@ -81,8 +70,7 @@ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): v * @param array $additionalHeaderParameters */ public static function create( - ?RequestFactoryInterface $requestFactory, - ClientInterface|HttpClientInterface $httpClient, + HttpClientInterface $httpClient, string $uri, array $additionalHeaderParameters = [], ?CertificateChainValidator $certificateChainValidator = null, @@ -90,7 +78,6 @@ public static function create( ?SerializerInterface $serializer = null, ): self { return new self( - $requestFactory, $httpClient, $uri, $additionalHeaderParameters, @@ -148,23 +135,8 @@ private function loadData(): void try { $payload = $this->getJwsPayload($content, $jwtCertificates); $this->validateCertificates(...$jwtCertificates); - if ($this->serializer !== null) { - $blob = $this->serializer->deserialize($payload, MetadataBLOBPayload::class, 'json'); - foreach ($blob->entries as $entry) { - $mds = $entry->metadataStatement; - if ($mds !== null && $entry->aaguid !== null) { - $this->statements[$entry->aaguid] = $mds; - $this->statusReports[$entry->aaguid] = $entry->statusReports; - } - } - $this->loaded = true; - return; - } - $data = json_decode($payload, true, flags: JSON_THROW_ON_ERROR); - - foreach ($data['entries'] as $datum) { - $entry = MetadataBLOBPayloadEntry::createFromArray($datum); - + $blob = $this->serializer->deserialize($payload, MetadataBLOBPayload::class, 'json'); + foreach ($blob->entries as $entry) { $mds = $entry->metadataStatement; if ($mds !== null && $entry->aaguid !== null) { $this->statements[$entry->aaguid] = $mds; @@ -173,9 +145,9 @@ private function loadData(): void } } catch (Throwable) { // Nothing to do + } finally { + $this->loaded = true; } - - $this->loaded = true; } /** @@ -183,11 +155,15 @@ private function loadData(): void */ private function fetch(string $uri, array $headerParameters): string { - if ($this->httpClient instanceof HttpClientInterface) { - $content = $this->sendSymfonyRequest($uri, $headerParameters); - } else { - $content = $this->sendPsrRequest($uri, $headerParameters); - } + $response = $this->httpClient->request('GET', $uri, [ + 'headers' => $headerParameters, + ]); + $response->getStatusCode() === 200 || throw MetadataStatementLoadingException::create(sprintf( + 'Unable to contact the server. Response code is %d', + $response->getStatusCode() + )); + + $content = $response->getContent(); $content !== '' || throw MetadataStatementLoadingException::create( 'Unable to contact the server. The response has no content' ); @@ -244,40 +220,4 @@ private function validateCertificates(string ...$untrustedCertificates): void $rootCertificate = CertificateToolbox::convertDERToPEM($this->fetch($this->rootCertificateUri, [])); $this->certificateChainValidator->check($untrustedCertificates, [$rootCertificate]); } - - /** - * @param array $headerParameters - */ - private function sendPsrRequest(string $uri, array $headerParameters): string - { - $request = $this->requestFactory->createRequest('GET', $uri); - foreach ($headerParameters as $k => $v) { - $request = $request->withHeader($k, $v); - } - $response = $this->httpClient->sendRequest($request); - $response->getStatusCode() === 200 || throw MetadataStatementLoadingException::create(sprintf( - 'Unable to contact the server. Response code is %d', - $response->getStatusCode() - )); - $response->getBody() - ->rewind(); - return $response->getBody() - ->getContents(); - } - - /** - * @param array $headerParameters - */ - private function sendSymfonyRequest(string $uri, array $headerParameters): string - { - $response = $this->httpClient->request('GET', $uri, [ - 'headers' => $headerParameters, - ]); - $response->getStatusCode() === 200 || throw MetadataStatementLoadingException::create(sprintf( - 'Unable to contact the server. Response code is %d', - $response->getStatusCode() - )); - - return $response->getContent(); - } } diff --git a/src/metadata-service/src/Service/FolderResourceMetadataService.php b/src/metadata-service/src/Service/FolderResourceMetadataService.php index c14f5ece..4a386b4d 100644 --- a/src/metadata-service/src/Service/FolderResourceMetadataService.php +++ b/src/metadata-service/src/Service/FolderResourceMetadataService.php @@ -9,6 +9,7 @@ use Webauthn\MetadataService\Denormalizer\MetadataStatementSerializerFactory; use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\Statement\MetadataStatement; +use function assert; use function file_get_contents; use function is_array; use function sprintf; @@ -16,7 +17,7 @@ final class FolderResourceMetadataService implements MetadataService { - private readonly ?SerializerInterface $serializer; + private readonly SerializerInterface $serializer; public function __construct( private string $rootPath, @@ -62,13 +63,10 @@ public function get(string $aaguid): MetadataStatement $aaguid )); $filename = $this->rootPath . DIRECTORY_SEPARATOR . $aaguid; - $data = trim(file_get_contents($filename)); - if ($this->serializer !== null) { - $mds = $this->serializer->deserialize($data, MetadataStatement::class, 'json'); - } else { - $mds = MetadataStatement::createFromString($data); - } - + $content = file_get_contents($filename); + assert($content !== false, 'The file exists and is readable.'); + $data = trim($content); + $mds = $this->serializer->deserialize($data, MetadataStatement::class, 'json'); $mds->aaguid !== null || throw MetadataStatementLoadingException::create('Invalid Metadata Statement.'); return $mds; diff --git a/src/metadata-service/src/Service/JsonMetadataService.php b/src/metadata-service/src/Service/JsonMetadataService.php index 7aa57e81..ba167b6b 100644 --- a/src/metadata-service/src/Service/JsonMetadataService.php +++ b/src/metadata-service/src/Service/JsonMetadataService.php @@ -23,7 +23,7 @@ final class JsonMetadataService implements MetadataService, CanDispatchEvents private EventDispatcherInterface $dispatcher; - private readonly ?SerializerInterface $serializer; + private readonly SerializerInterface $serializer; /** * @param string[] $statements @@ -65,11 +65,7 @@ public function get(string $aaguid): MetadataStatement private function addStatement(string $statement): void { - if ($this->serializer === null) { - $mds = MetadataStatement::createFromString($statement); - } else { - $mds = $this->serializer->deserialize($statement, MetadataStatement::class, 'json'); - } + $mds = $this->serializer->deserialize($statement, MetadataStatement::class, 'json'); if ($mds->aaguid === null) { return; } diff --git a/src/metadata-service/src/Service/LocalResourceMetadataService.php b/src/metadata-service/src/Service/LocalResourceMetadataService.php index b522c2a2..5c93770d 100644 --- a/src/metadata-service/src/Service/LocalResourceMetadataService.php +++ b/src/metadata-service/src/Service/LocalResourceMetadataService.php @@ -14,6 +14,7 @@ use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\Exception\MissingMetadataStatementException; use Webauthn\MetadataService\Statement\MetadataStatement; +use function assert; use function file_get_contents; final class LocalResourceMetadataService implements MetadataService, CanDispatchEvents @@ -22,7 +23,7 @@ final class LocalResourceMetadataService implements MetadataService, CanDispatch private EventDispatcherInterface $dispatcher; - private readonly ?SerializerInterface $serializer; + private readonly SerializerInterface $serializer; public function __construct( private readonly string $filename, @@ -87,13 +88,10 @@ private function loadData(): void } $content = file_get_contents($this->filename); + assert($content !== false, 'The file could not be read'); if ($this->isBase64Encoded) { $content = Base64::decode($content, true); } - if ($this->serializer !== null) { - $this->statement = $this->serializer->deserialize($content, MetadataStatement::class, 'json'); - } else { - $this->statement = MetadataStatement::createFromString($content); - } + $this->statement = $this->serializer->deserialize($content, MetadataStatement::class, 'json'); } } diff --git a/src/metadata-service/src/Service/MetadataBLOBPayload.php b/src/metadata-service/src/Service/MetadataBLOBPayload.php index 3ab82458..0b10c7e5 100644 --- a/src/metadata-service/src/Service/MetadataBLOBPayload.php +++ b/src/metadata-service/src/Service/MetadataBLOBPayload.php @@ -5,22 +5,12 @@ namespace Webauthn\MetadataService\Service; use JsonSerializable; -use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; -use function is_array; -use function is_int; -use function is_string; class MetadataBLOBPayload implements JsonSerializable { use ValueFilter; - /** - * @var string[] - */ - private array $rootCertificates = []; - /** * @param MetadataBLOBPayloadEntry[] $entries */ @@ -32,85 +22,6 @@ public function __construct( ) { } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function addEntry(MetadataBLOBPayloadEntry $entry): self - { - $this->entries[] = $entry; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getLegalHeader(): ?string - { - return $this->legalHeader; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getNo(): int - { - return $this->no; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getNextUpdate(): string - { - return $this->nextUpdate; - } - - /** - * @return MetadataBLOBPayloadEntry[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getEntries(): array - { - return $this->entries; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - foreach (['no', 'nextUpdate', 'entries'] as $key) { - array_key_exists($key, $data) || throw MetadataStatementLoadingException::create(sprintf( - 'Invalid data. The parameter "%s" is missing', - $key - )); - } - is_int($data['no']) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "no" shall be an integer' - ); - is_string($data['nextUpdate']) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "nextUpdate" shall be a string' - ); - is_array($data['entries']) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "entries" shall be a n array of entries' - ); - $object = new self($data['no'], $data['nextUpdate'], $data['legalHeader'] ?? null); - foreach ($data['entries'] as $entry) { - $object->entries[] = MetadataBLOBPayloadEntry::createFromArray($entry); - } - - return $object; - } - /** * @return array */ @@ -125,26 +36,4 @@ public function jsonSerialize(): array return self::filterNullValues($data); } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRootCertificates(): array - { - return $this->rootCertificates; - } - - /** - * @param string[] $rootCertificates - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setRootCertificates(array $rootCertificates): self - { - $this->rootCertificates = $rootCertificates; - - return $this; - } } diff --git a/src/metadata-service/src/Service/MetadataBLOBPayloadEntry.php b/src/metadata-service/src/Service/MetadataBLOBPayloadEntry.php index f1d9011a..253ff99a 100644 --- a/src/metadata-service/src/Service/MetadataBLOBPayloadEntry.php +++ b/src/metadata-service/src/Service/MetadataBLOBPayloadEntry.php @@ -10,9 +10,7 @@ use Webauthn\MetadataService\Statement\MetadataStatement; use Webauthn\MetadataService\Statement\StatusReport; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; use function count; -use function is_array; use function is_string; class MetadataBLOBPayloadEntry implements JsonSerializable @@ -56,155 +54,6 @@ public function __construct( } } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAaid(): ?string - { - return $this->aaid; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAaguid(): ?string - { - return $this->aaguid; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestationCertificateKeyIdentifiers(): array - { - return $this->attestationCertificateKeyIdentifiers; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMetadataStatement(): ?MetadataStatement - { - return $this->metadataStatement; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function addBiometricStatusReports(BiometricStatusReport ...$biometricStatusReports): self - { - foreach ($biometricStatusReports as $biometricStatusReport) { - $this->biometricStatusReports[] = $biometricStatusReport; - } - - return $this; - } - - /** - * @return BiometricStatusReport[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getBiometricStatusReports(): array - { - return $this->biometricStatusReports; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function addStatusReports(StatusReport ...$statusReports): self - { - foreach ($statusReports as $statusReport) { - $this->statusReports[] = $statusReport; - } - - return $this; - } - - /** - * @return StatusReport[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getStatusReports(): array - { - return $this->statusReports; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTimeOfLastStatusChange(): string - { - return $this->timeOfLastStatusChange; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRogueListURL(): string|null - { - return $this->rogueListURL; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRogueListHash(): string|null - { - return $this->rogueListHash; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - array_key_exists('timeOfLastStatusChange', $data) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "timeOfLastStatusChange" is missing' - ); - array_key_exists('statusReports', $data) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "statusReports" is missing' - ); - is_array($data['statusReports']) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "statusReports" shall be an array of StatusReport objects' - ); - - return new self( - $data['timeOfLastStatusChange'], - array_map( - static fn (array $statusReport) => StatusReport::createFromArray($statusReport), - $data['statusReports'] - ), - $data['aaid'] ?? null, - $data['aaguid'] ?? null, - $data['attestationCertificateKeyIdentifiers'] ?? [], - isset($data['metadataStatement']) ? MetadataStatement::createFromArray($data['metadataStatement']) : null, - $data['rogueListURL'] ?? null, - $data['rogueListHash'] ?? null, - array_map( - static fn (array $biometricStatusReport) => BiometricStatusReport::createFromArray( - $biometricStatusReport - ), - $data['biometricStatusReports'] ?? [] - ) - ); - } - /** * @return array */ diff --git a/src/metadata-service/src/Service/StringMetadataService.php b/src/metadata-service/src/Service/StringMetadataService.php deleted file mode 100644 index 4edea340..00000000 --- a/src/metadata-service/src/Service/StringMetadataService.php +++ /dev/null @@ -1,77 +0,0 @@ -addStatements(MetadataStatement::createFromString($statement)); - } - $this->dispatcher = new NullEventDispatcher(); - } - - public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): void - { - $this->dispatcher = $eventDispatcher; - } - - public static function create(string ...$statements): self - { - return new self(...$statements); - } - - public function addStatements(MetadataStatement ...$statements): self - { - foreach ($statements as $statement) { - $aaguid = $statement->aaguid; - if ($aaguid === null) { - continue; - } - $this->statements[$aaguid] = $statement; - } - - return $this; - } - - public function list(): iterable - { - yield from array_keys($this->statements); - } - - public function has(string $aaguid): bool - { - return array_key_exists($aaguid, $this->statements); - } - - public function get(string $aaguid): MetadataStatement - { - array_key_exists($aaguid, $this->statements) || throw MissingMetadataStatementException::create($aaguid); - $mds = $this->statements[$aaguid]; - $this->dispatcher->dispatch(MetadataStatementFound::create($mds)); - - return $mds; - } -} diff --git a/src/metadata-service/src/Statement/AbstractDescriptor.php b/src/metadata-service/src/Statement/AbstractDescriptor.php index 08f1de46..b0710e5d 100644 --- a/src/metadata-service/src/Statement/AbstractDescriptor.php +++ b/src/metadata-service/src/Statement/AbstractDescriptor.php @@ -20,22 +20,4 @@ public function __construct( 'Invalid data. The value of "blockSlowdown" must be a positive integer' ); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMaxRetries(): ?int - { - return $this->maxRetries; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getBlockSlowdown(): ?int - { - return $this->blockSlowdown; - } } diff --git a/src/metadata-service/src/Statement/AlternativeDescriptions.php b/src/metadata-service/src/Statement/AlternativeDescriptions.php index 228811e0..25ed4f90 100644 --- a/src/metadata-service/src/Statement/AlternativeDescriptions.php +++ b/src/metadata-service/src/Statement/AlternativeDescriptions.php @@ -24,27 +24,6 @@ public static function create(array $descriptions = []): self return new self($descriptions); } - /** - * @return array - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function all(): array - { - return $this->descriptions; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function add(string $locale, string $description): self - { - $this->descriptions[$locale] = $description; - - return $this; - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/AuthenticatorGetInfo.php b/src/metadata-service/src/Statement/AuthenticatorGetInfo.php index a39f9830..83f7093a 100644 --- a/src/metadata-service/src/Statement/AuthenticatorGetInfo.php +++ b/src/metadata-service/src/Statement/AuthenticatorGetInfo.php @@ -9,7 +9,7 @@ class AuthenticatorGetInfo implements JsonSerializable { /** - * @param array $info + * @param array $info */ public function __construct( public array $info = [] @@ -17,7 +17,7 @@ public function __construct( } /** - * @param array $info + * @param array $info */ public static function create(array $info = []): self { @@ -25,18 +25,7 @@ public static function create(array $info = []): self } /** - * @deprecated since 4.7.0. Please use the constructor directly. - * @infection-ignore-all - */ - public function add(string|int $key, mixed $value): self - { - $this->info[$key] = $value; - - return $this; - } - - /** - * @return string[] + * @return array */ public function jsonSerialize(): array { diff --git a/src/metadata-service/src/Statement/AuthenticatorStatus.php b/src/metadata-service/src/Statement/AuthenticatorStatus.php index 03a008be..427171a3 100644 --- a/src/metadata-service/src/Statement/AuthenticatorStatus.php +++ b/src/metadata-service/src/Statement/AuthenticatorStatus.php @@ -6,41 +6,41 @@ final class AuthenticatorStatus { - final public const NOT_FIDO_CERTIFIED = 'NOT_FIDO_CERTIFIED'; + final public const string NOT_FIDO_CERTIFIED = 'NOT_FIDO_CERTIFIED'; - final public const FIDO_CERTIFIED = 'FIDO_CERTIFIED'; + final public const string FIDO_CERTIFIED = 'FIDO_CERTIFIED'; - final public const USER_VERIFICATION_BYPASS = 'USER_VERIFICATION_BYPASS'; + final public const string USER_VERIFICATION_BYPASS = 'USER_VERIFICATION_BYPASS'; - final public const ATTESTATION_KEY_COMPROMISE = 'ATTESTATION_KEY_COMPROMISE'; + final public const string ATTESTATION_KEY_COMPROMISE = 'ATTESTATION_KEY_COMPROMISE'; - final public const USER_KEY_REMOTE_COMPROMISE = 'USER_KEY_REMOTE_COMPROMISE'; + final public const string USER_KEY_REMOTE_COMPROMISE = 'USER_KEY_REMOTE_COMPROMISE'; - final public const USER_KEY_PHYSICAL_COMPROMISE = 'USER_KEY_PHYSICAL_COMPROMISE'; + final public const string USER_KEY_PHYSICAL_COMPROMISE = 'USER_KEY_PHYSICAL_COMPROMISE'; - final public const UPDATE_AVAILABLE = 'UPDATE_AVAILABLE'; + final public const string UPDATE_AVAILABLE = 'UPDATE_AVAILABLE'; - final public const REVOKED = 'REVOKED'; + final public const string REVOKED = 'REVOKED'; - final public const SELF_ASSERTION_SUBMITTED = 'SELF_ASSERTION_SUBMITTED'; + final public const string SELF_ASSERTION_SUBMITTED = 'SELF_ASSERTION_SUBMITTED'; - final public const FIDO_CERTIFIED_L1 = 'FIDO_CERTIFIED_L1'; + final public const string FIDO_CERTIFIED_L1 = 'FIDO_CERTIFIED_L1'; - final public const FIDO_CERTIFIED_L1plus = 'FIDO_CERTIFIED_L1plus'; + final public const string FIDO_CERTIFIED_L1plus = 'FIDO_CERTIFIED_L1plus'; - final public const FIDO_CERTIFIED_L2 = 'FIDO_CERTIFIED_L2'; + final public const string FIDO_CERTIFIED_L2 = 'FIDO_CERTIFIED_L2'; - final public const FIDO_CERTIFIED_L2plus = 'FIDO_CERTIFIED_L2plus'; + final public const string FIDO_CERTIFIED_L2plus = 'FIDO_CERTIFIED_L2plus'; - final public const FIDO_CERTIFIED_L3 = 'FIDO_CERTIFIED_L3'; + final public const string FIDO_CERTIFIED_L3 = 'FIDO_CERTIFIED_L3'; - final public const FIDO_CERTIFIED_L3plus = 'FIDO_CERTIFIED_L3plus'; + final public const string FIDO_CERTIFIED_L3plus = 'FIDO_CERTIFIED_L3plus'; - final public const FIDO_CERTIFIED_L4 = 'FIDO_CERTIFIED_L4'; + final public const string FIDO_CERTIFIED_L4 = 'FIDO_CERTIFIED_L4'; - final public const FIDO_CERTIFIED_L5 = 'FIDO_CERTIFIED_L5'; + final public const string FIDO_CERTIFIED_L5 = 'FIDO_CERTIFIED_L5'; - final public const STATUSES = [ + final public const array STATUSES = [ self::NOT_FIDO_CERTIFIED, self::FIDO_CERTIFIED, self::USER_VERIFICATION_BYPASS, @@ -59,14 +59,4 @@ final class AuthenticatorStatus self::FIDO_CERTIFIED_L4, self::FIDO_CERTIFIED_L5, ]; - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the constant STATUSES instead. - * @infection-ignore-all - */ - public static function list(): array - { - return self::STATUSES; - } } diff --git a/src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php b/src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php index 14c0e34d..df8ae4c8 100644 --- a/src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php +++ b/src/metadata-service/src/Statement/BiometricAccuracyDescriptor.php @@ -30,45 +30,6 @@ public static function create( return new self($selfAttestedFRR, $selfAttestedFAR, $maxTemplates, $maxRetries, $blockSlowdown); } - /** - * @deprecated since 4.7.0. Please use the property directly. - */ - public function getSelfAttestedFRR(): ?float - { - return $this->selfAttestedFRR; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - */ - public function getSelfAttestedFAR(): ?float - { - return $this->selfAttestedFAR; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - */ - public function getMaxTemplates(): ?float - { - return $this->maxTemplates; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - */ - public static function createFromArray(array $data): self - { - return self::create( - $data['selfAttestedFRR'] ?? null, - $data['selfAttestedFAR'] ?? null, - $data['maxTemplates'] ?? null, - $data['maxRetries'] ?? null, - $data['blockSlowdown'] ?? null - ); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/BiometricStatusReport.php b/src/metadata-service/src/Statement/BiometricStatusReport.php index a6b0f3a9..3b4c22f9 100644 --- a/src/metadata-service/src/Statement/BiometricStatusReport.php +++ b/src/metadata-service/src/Statement/BiometricStatusReport.php @@ -39,87 +39,6 @@ public static function create( ); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertLevel(): int|null - { - return $this->certLevel; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getModality(): int|null - { - return $this->modality; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getEffectiveDate(): ?string - { - return $this->effectiveDate; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificationDescriptor(): ?string - { - return $this->certificationDescriptor; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificateNumber(): ?string - { - return $this->certificateNumber; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificationPolicyVersion(): ?string - { - return $this->certificationPolicyVersion; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificationRequirementsVersion(): ?string - { - return $this->certificationRequirementsVersion; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - return self::create( - $data['certLevel'] ?? null, - $data['modality'] ?? null, - $data['effectiveDate'] ?? null, - $data['certificationDescriptor'] ?? null, - $data['certificateNumber'] ?? null, - $data['certificationPolicyVersion'] ?? null, - $data['certificationRequirementsVersion'] ?? null, - ); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/CodeAccuracyDescriptor.php b/src/metadata-service/src/Statement/CodeAccuracyDescriptor.php index cb15d760..bc1d7b09 100644 --- a/src/metadata-service/src/Statement/CodeAccuracyDescriptor.php +++ b/src/metadata-service/src/Statement/CodeAccuracyDescriptor.php @@ -6,7 +6,6 @@ use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; class CodeAccuracyDescriptor extends AbstractDescriptor { @@ -32,46 +31,6 @@ public static function create(int $base, int $minLength, ?int $maxRetries = null return new self($base, $minLength, $maxRetries, $blockSlowdown); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getBase(): int - { - return $this->base; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMinLength(): int - { - return $this->minLength; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - array_key_exists('base', $data) || throw MetadataStatementLoadingException::create( - 'The parameter "base" is missing' - ); - array_key_exists('minLength', $data) || throw MetadataStatementLoadingException::create( - 'The parameter "minLength" is missing' - ); - - return self::create( - $data['base'], - $data['minLength'], - $data['maxRetries'] ?? null, - $data['blockSlowdown'] ?? null - ); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php b/src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php index 20226470..1574ae24 100644 --- a/src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php +++ b/src/metadata-service/src/Statement/DisplayPNGCharacteristicsDescriptor.php @@ -7,7 +7,6 @@ use JsonSerializable; use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; class DisplayPNGCharacteristicsDescriptor implements JsonSerializable { @@ -58,127 +57,6 @@ public static function create( return new self($width, $height, $bitDepth, $colorType, $compression, $filter, $interlace, $plte); } - /** - * @deprecated since 4.7.0. Please use {self::create} directly. - * @infection-ignore-all - */ - public function addPalettes(RgbPaletteEntry ...$rgbPaletteEntries): self - { - foreach ($rgbPaletteEntries as $rgbPaletteEntry) { - $this->plte[] = $rgbPaletteEntry; - } - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getWidth(): int - { - return $this->width; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getHeight(): int - { - return $this->height; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getBitDepth(): int - { - return $this->bitDepth; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getColorType(): int - { - return $this->colorType; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCompression(): int - { - return $this->compression; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getFilter(): int - { - return $this->filter; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getInterlace(): int - { - return $this->interlace; - } - - /** - * @return RgbPaletteEntry[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getPaletteEntries(): array - { - return $this->plte; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - foreach ([ - 'width', - 'compression', - 'height', - 'bitDepth', - 'colorType', - 'compression', - 'filter', - 'interlace', - ] as $key) { - array_key_exists($key, $data) || throw MetadataStatementLoadingException::create(sprintf( - 'Invalid data. The key "%s" is missing', - $key - )); - } - return self::create( - $data['width'], - $data['height'], - $data['bitDepth'], - $data['colorType'], - $data['compression'], - $data['filter'], - $data['interlace'], - array_map(static fn (array $item) => RgbPaletteEntry::createFromArray($item), $data['plte'] ?? []) - ); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/EcdaaTrustAnchor.php b/src/metadata-service/src/Statement/EcdaaTrustAnchor.php deleted file mode 100644 index fd426c13..00000000 --- a/src/metadata-service/src/Statement/EcdaaTrustAnchor.php +++ /dev/null @@ -1,101 +0,0 @@ -X; - } - - public function getY(): string - { - return $this->Y; - } - - public function getC(): string - { - return $this->c; - } - - public function getSx(): string - { - return $this->sx; - } - - public function getSy(): string - { - return $this->sy; - } - - public function getG1Curve(): string - { - return $this->G1Curve; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - foreach (['X', 'Y', 'c', 'sx', 'sy', 'G1Curve'] as $key) { - array_key_exists($key, $data) || throw MetadataStatementLoadingException::create(sprintf( - 'Invalid data. The key "%s" is missing', - $key - )); - } - - return new self( - Base64UrlSafe::decode($data['X']), - Base64UrlSafe::decode($data['Y']), - Base64UrlSafe::decode($data['c']), - Base64UrlSafe::decode($data['sx']), - Base64UrlSafe::decode($data['sy']), - $data['G1Curve'] - ); - } - - /** - * @return array - */ - public function jsonSerialize(): array - { - $data = [ - 'X' => Base64UrlSafe::encodeUnpadded($this->X), - 'Y' => Base64UrlSafe::encodeUnpadded($this->Y), - 'c' => Base64UrlSafe::encodeUnpadded($this->c), - 'sx' => Base64UrlSafe::encodeUnpadded($this->sx), - 'sy' => Base64UrlSafe::encodeUnpadded($this->sy), - 'G1Curve' => $this->G1Curve, - ]; - - return self::filterNullValues($data); - } -} diff --git a/src/metadata-service/src/Statement/ExtensionDescriptor.php b/src/metadata-service/src/Statement/ExtensionDescriptor.php index 4b040436..1ed4a101 100644 --- a/src/metadata-service/src/Statement/ExtensionDescriptor.php +++ b/src/metadata-service/src/Statement/ExtensionDescriptor.php @@ -7,7 +7,6 @@ use JsonSerializable; use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; class ExtensionDescriptor implements JsonSerializable { @@ -35,60 +34,6 @@ public static function create( return new self($id, $tag, $data, $failIfUnknown); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getId(): string - { - return $this->id; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTag(): ?int - { - return $this->tag; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getData(): ?string - { - return $this->data; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function isFailIfUnknown(): bool - { - return $this->failIfUnknown; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - array_key_exists('id', $data) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "id" is missing' - ); - array_key_exists('fail_if_unknown', $data) || throw MetadataStatementLoadingException::create( - 'Invalid data. The parameter "fail_if_unknown" is missing' - ); - - return new self($data['id'], $data['tag'] ?? null, $data['data'] ?? null, $data['fail_if_unknown']); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/MetadataStatement.php b/src/metadata-service/src/Statement/MetadataStatement.php index d14f1e41..217305db 100644 --- a/src/metadata-service/src/Statement/MetadataStatement.php +++ b/src/metadata-service/src/Statement/MetadataStatement.php @@ -6,38 +6,33 @@ use JsonSerializable; use Webauthn\MetadataService\CertificateChain\CertificateToolbox; -use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; -use function is_array; -use function is_string; -use const JSON_THROW_ON_ERROR; class MetadataStatement implements JsonSerializable { use ValueFilter; - final public const KEY_PROTECTION_SOFTWARE = 'software'; + final public const string KEY_PROTECTION_SOFTWARE = 'software'; - final public const KEY_PROTECTION_SOFTWARE_INT = 0x0001; + final public const int KEY_PROTECTION_SOFTWARE_INT = 0x0001; - final public const KEY_PROTECTION_HARDWARE = 'hardware'; + final public const string KEY_PROTECTION_HARDWARE = 'hardware'; - final public const KEY_PROTECTION_HARDWARE_INT = 0x0002; + final public const int KEY_PROTECTION_HARDWARE_INT = 0x0002; - final public const KEY_PROTECTION_TEE = 'tee'; + final public const string KEY_PROTECTION_TEE = 'tee'; - final public const KEY_PROTECTION_TEE_INT = 0x0004; + final public const int KEY_PROTECTION_TEE_INT = 0x0004; - final public const KEY_PROTECTION_SECURE_ELEMENT = 'secure_element'; + final public const string KEY_PROTECTION_SECURE_ELEMENT = 'secure_element'; - final public const KEY_PROTECTION_SECURE_ELEMENT_INT = 0x0008; + final public const int KEY_PROTECTION_SECURE_ELEMENT_INT = 0x0008; - final public const KEY_PROTECTION_REMOTE_HANDLE = 'remote_handle'; + final public const string KEY_PROTECTION_REMOTE_HANDLE = 'remote_handle'; - final public const KEY_PROTECTION_REMOTE_HANDLE_INT = 0x0010; + final public const int KEY_PROTECTION_REMOTE_HANDLE_INT = 0x0010; - final public const KEY_PROTECTION_TYPES = [ + final public const array KEY_PROTECTION_TYPES = [ self::KEY_PROTECTION_SOFTWARE, self::KEY_PROTECTION_HARDWARE, self::KEY_PROTECTION_TEE, @@ -45,7 +40,7 @@ class MetadataStatement implements JsonSerializable self::KEY_PROTECTION_REMOTE_HANDLE, ]; - final public const KEY_PROTECTION_TYPES_INT = [ + final public const array KEY_PROTECTION_TYPES_INT = [ self::KEY_PROTECTION_SOFTWARE_INT, self::KEY_PROTECTION_HARDWARE_INT, self::KEY_PROTECTION_TEE_INT, @@ -53,117 +48,111 @@ class MetadataStatement implements JsonSerializable self::KEY_PROTECTION_REMOTE_HANDLE_INT, ]; - final public const MATCHER_PROTECTION_SOFTWARE = 'software'; + final public const string MATCHER_PROTECTION_SOFTWARE = 'software'; - final public const MATCHER_PROTECTION_SOFTWARE_INT = 0x0001; + final public const int MATCHER_PROTECTION_SOFTWARE_INT = 0x0001; - final public const MATCHER_PROTECTION_TEE = 'tee'; + final public const string MATCHER_PROTECTION_TEE = 'tee'; - final public const MATCHER_PROTECTION_TEE_INT = 0x0002; + final public const int MATCHER_PROTECTION_TEE_INT = 0x0002; - final public const MATCHER_PROTECTION_ON_CHIP = 'on_chip'; + final public const string MATCHER_PROTECTION_ON_CHIP = 'on_chip'; - final public const MATCHER_PROTECTION_ON_CHIP_INT = 0x0004; + final public const int MATCHER_PROTECTION_ON_CHIP_INT = 0x0004; - final public const MATCHER_PROTECTION_TYPES = [ + final public const array MATCHER_PROTECTION_TYPES = [ self::MATCHER_PROTECTION_SOFTWARE, self::MATCHER_PROTECTION_TEE, self::MATCHER_PROTECTION_ON_CHIP, ]; - final public const MATCHER_PROTECTION_TYPES_INT = [ + final public const array MATCHER_PROTECTION_TYPES_INT = [ self::MATCHER_PROTECTION_SOFTWARE_INT, self::MATCHER_PROTECTION_TEE_INT, self::MATCHER_PROTECTION_ON_CHIP_INT, ]; - final public const ATTACHMENT_HINT_INTERNAL = 'internal'; + final public const string ATTACHMENT_HINT_INTERNAL = 'internal'; - final public const ATTACHMENT_HINT_EXTERNAL = 'external'; + final public const string ATTACHMENT_HINT_EXTERNAL = 'external'; - final public const ATTACHMENT_HINT_WIRED = 'wired'; + final public const string ATTACHMENT_HINT_WIRED = 'wired'; - final public const ATTACHMENT_HINT_WIRELESS = 'wireless'; + final public const string ATTACHMENT_HINT_WIRELESS = 'wireless'; - final public const ATTACHMENT_HINT_NFC = 'nfc'; + final public const string ATTACHMENT_HINT_NFC = 'nfc'; - final public const ATTACHMENT_HINT_BLUETOOTH = 'bluetooth'; + final public const string ATTACHMENT_HINT_BLUETOOTH = 'bluetooth'; - final public const ATTACHMENT_HINT_NETWORK = 'network'; + final public const string ATTACHMENT_HINT_NETWORK = 'network'; - final public const ATTACHMENT_HINT_READY = 'ready'; + final public const string ATTACHMENT_HINT_READY = 'ready'; - final public const ATTACHMENT_HINT_WIFI_DIRECT = 'wifi_direct'; + final public const string ATTACHMENT_HINT_WIFI_DIRECT = 'wifi_direct'; - final public const TRANSACTION_CONFIRMATION_DISPLAY_ANY = 'any'; + final public const string TRANSACTION_CONFIRMATION_DISPLAY_ANY = 'any'; - final public const TRANSACTION_CONFIRMATION_DISPLAY_PRIVILEGED_SOFTWARE = 'privileged_software'; + final public const string TRANSACTION_CONFIRMATION_DISPLAY_PRIVILEGED_SOFTWARE = 'privileged_software'; - final public const TRANSACTION_CONFIRMATION_DISPLAY_TEE = 'tee'; + final public const string TRANSACTION_CONFIRMATION_DISPLAY_TEE = 'tee'; - final public const TRANSACTION_CONFIRMATION_DISPLAY_HARDWARE = 'hardware'; + final public const string TRANSACTION_CONFIRMATION_DISPLAY_HARDWARE = 'hardware'; - final public const TRANSACTION_CONFIRMATION_DISPLAY_REMOTE = 'remote'; + final public const string TRANSACTION_CONFIRMATION_DISPLAY_REMOTE = 'remote'; - final public const ALG_SIGN_SECP256R1_ECDSA_SHA256_RAW = 'secp256r1_ecdsa_sha256_raw'; + final public const string ALG_SIGN_SECP256R1_ECDSA_SHA256_RAW = 'secp256r1_ecdsa_sha256_raw'; - final public const ALG_SIGN_SECP256R1_ECDSA_SHA256_DER = 'secp256r1_ecdsa_sha256_der'; + final public const string ALG_SIGN_SECP256R1_ECDSA_SHA256_DER = 'secp256r1_ecdsa_sha256_der'; - final public const ALG_SIGN_RSASSA_PSS_SHA256_RAW = 'rsassa_pss_sha256_raw'; + final public const string ALG_SIGN_RSASSA_PSS_SHA256_RAW = 'rsassa_pss_sha256_raw'; - final public const ALG_SIGN_RSASSA_PSS_SHA256_DER = 'rsassa_pss_sha256_der'; + final public const string ALG_SIGN_RSASSA_PSS_SHA256_DER = 'rsassa_pss_sha256_der'; - final public const ALG_SIGN_SECP256K1_ECDSA_SHA256_RAW = 'secp256k1_ecdsa_sha256_raw'; + final public const string ALG_SIGN_SECP256K1_ECDSA_SHA256_RAW = 'secp256k1_ecdsa_sha256_raw'; - final public const ALG_SIGN_SECP256K1_ECDSA_SHA256_DER = 'secp256k1_ecdsa_sha256_der'; + final public const string ALG_SIGN_SECP256K1_ECDSA_SHA256_DER = 'secp256k1_ecdsa_sha256_der'; - final public const ALG_SIGN_SM2_SM3_RAW = 'sm2_sm3_raw'; + final public const string ALG_SIGN_SM2_SM3_RAW = 'sm2_sm3_raw'; - final public const ALG_SIGN_RSA_EMSA_PKCS1_SHA256_RAW = 'rsa_emsa_pkcs1_sha256_raw'; + final public const string ALG_SIGN_RSA_EMSA_PKCS1_SHA256_RAW = 'rsa_emsa_pkcs1_sha256_raw'; - final public const ALG_SIGN_RSA_EMSA_PKCS1_SHA256_DER = 'rsa_emsa_pkcs1_sha256_der'; + final public const string ALG_SIGN_RSA_EMSA_PKCS1_SHA256_DER = 'rsa_emsa_pkcs1_sha256_der'; - final public const ALG_SIGN_RSASSA_PSS_SHA384_RAW = 'rsassa_pss_sha384_raw'; + final public const string ALG_SIGN_RSASSA_PSS_SHA384_RAW = 'rsassa_pss_sha384_raw'; - final public const ALG_SIGN_RSASSA_PSS_SHA512_RAW = 'rsassa_pss_sha256_raw'; + final public const string ALG_SIGN_RSASSA_PSS_SHA512_RAW = 'rsassa_pss_sha256_raw'; - final public const ALG_SIGN_RSASSA_PKCSV15_SHA256_RAW = 'rsassa_pkcsv15_sha256_raw'; + final public const string ALG_SIGN_RSASSA_PKCSV15_SHA256_RAW = 'rsassa_pkcsv15_sha256_raw'; - final public const ALG_SIGN_RSASSA_PKCSV15_SHA384_RAW = 'rsassa_pkcsv15_sha384_raw'; + final public const string ALG_SIGN_RSASSA_PKCSV15_SHA384_RAW = 'rsassa_pkcsv15_sha384_raw'; - final public const ALG_SIGN_RSASSA_PKCSV15_SHA512_RAW = 'rsassa_pkcsv15_sha512_raw'; + final public const string ALG_SIGN_RSASSA_PKCSV15_SHA512_RAW = 'rsassa_pkcsv15_sha512_raw'; - final public const ALG_SIGN_RSASSA_PKCSV15_SHA1_RAW = 'rsassa_pkcsv15_sha1_raw'; + final public const string ALG_SIGN_RSASSA_PKCSV15_SHA1_RAW = 'rsassa_pkcsv15_sha1_raw'; - final public const ALG_SIGN_SECP384R1_ECDSA_SHA384_RAW = 'secp384r1_ecdsa_sha384_raw'; + final public const string ALG_SIGN_SECP384R1_ECDSA_SHA384_RAW = 'secp384r1_ecdsa_sha384_raw'; - final public const ALG_SIGN_SECP521R1_ECDSA_SHA512_RAW = 'secp512r1_ecdsa_sha256_raw'; + final public const string ALG_SIGN_SECP521R1_ECDSA_SHA512_RAW = 'secp512r1_ecdsa_sha256_raw'; - final public const ALG_SIGN_ED25519_EDDSA_SHA256_RAW = 'ed25519_eddsa_sha512_raw'; + final public const string ALG_SIGN_ED25519_EDDSA_SHA256_RAW = 'ed25519_eddsa_sha512_raw'; - final public const ALG_KEY_ECC_X962_RAW = 'ecc_x962_raw'; + final public const string ALG_KEY_ECC_X962_RAW = 'ecc_x962_raw'; - final public const ALG_KEY_ECC_X962_DER = 'ecc_x962_der'; + final public const string ALG_KEY_ECC_X962_DER = 'ecc_x962_der'; - final public const ALG_KEY_RSA_2048_RAW = 'rsa_2048_raw'; + final public const string ALG_KEY_RSA_2048_RAW = 'rsa_2048_raw'; - final public const ALG_KEY_RSA_2048_DER = 'rsa_2048_der'; + final public const string ALG_KEY_RSA_2048_DER = 'rsa_2048_der'; - final public const ALG_KEY_COSE = 'cose'; + final public const string ALG_KEY_COSE = 'cose'; - final public const ATTESTATION_BASIC_FULL = 'basic_full'; + final public const string ATTESTATION_BASIC_FULL = 'basic_full'; - final public const ATTESTATION_BASIC_SURROGATE = 'basic_surrogate'; + final public const string ATTESTATION_BASIC_SURROGATE = 'basic_surrogate'; - /** - * @deprecated since 4.2.0 and will be removed in 5.0.0. The ECDAA Trust Anchor does no longer exist in Webauthn specification. - * @infection-ignore-all - */ - final public const ATTESTATION_ECDAA = 'ecdaa'; - - final public const ATTESTATION_ATTCA = 'attca'; + final public const string ATTESTATION_ATTCA = 'attca'; - final public const ATTESTATION_ANONCA = 'anonca'; + final public const string ATTESTATION_ANONCA = 'anonca'; public readonly AuthenticatorGetInfo $authenticatorGetInfo; @@ -179,8 +168,8 @@ class MetadataStatement implements JsonSerializable * @param string[] $attestationCertificateKeyIdentifiers * @param string[] $keyProtection * @param string[] $attachmentHint - * @param EcdaaTrustAnchor[] $ecdaaTrustAnchors * @param ExtensionDescriptor[] $supportedExtensions + * @param DisplayPNGCharacteristicsDescriptor[] $tcDisplayPNGCharacteristics */ public function __construct( public readonly string $description, @@ -207,7 +196,6 @@ public function __construct( public array $attachmentHint = [], public ?string $tcDisplayContentType = null, public array $tcDisplayPNGCharacteristics = [], - public array $ecdaaTrustAnchors = [], public ?string $icon = null, public array $supportedExtensions = [], ?AuthenticatorGetInfo $authenticatorGetInfo = null, @@ -215,6 +203,22 @@ public function __construct( $this->authenticatorGetInfo = $authenticatorGetInfo ?? AuthenticatorGetInfo::create($attestationTypes); } + /** + * @param Version[] $upv + * @param string[] $authenticationAlgorithms + * @param string[] $publicKeyAlgAndEncodings + * @param string[] $attestationTypes + * @param VerificationMethodANDCombinations[] $userVerificationDetails + * @param string[] $matcherProtection + * @param string[] $tcDisplay + * @param string[] $attestationRootCertificates + * @param string[] $attestationCertificateKeyIdentifiers + * @param string[] $keyProtection + * @param string[] $attachmentHint + * @param ExtensionDescriptor[] $supportedExtensions + * @param DisplayPNGCharacteristicsDescriptor[] $tcDisplayPNGCharacteristics + * @param string[] $alternativeDescriptions + */ public static function create( string $description, int $authenticatorVersion, @@ -240,7 +244,6 @@ public static function create( array $attachmentHint = [], ?string $tcDisplayContentType = null, array $tcDisplayPNGCharacteristics = [], - array $ecdaaTrustAnchors = [], ?string $icon = null, array $supportedExtensions = [], ?AuthenticatorGetInfo $authenticatorGetInfo = null, @@ -270,389 +273,12 @@ public static function create( $attachmentHint, $tcDisplayContentType, $tcDisplayPNGCharacteristics, - $ecdaaTrustAnchors, $icon, $supportedExtensions, $authenticatorGetInfo, ); } - /** - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromString(string $statement): self - { - $data = json_decode($statement, true, flags: JSON_THROW_ON_ERROR); - - return self::createFromArray($data); - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getLegalHeader(): ?string - { - return $this->legalHeader; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAaid(): ?string - { - return $this->aaid; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAaguid(): ?string - { - return $this->aaguid; - } - - public function isKeyRestricted(): ?bool - { - return $this->isKeyRestricted; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function isFreshUserVerificationRequired(): ?bool - { - return $this->isFreshUserVerificationRequired; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAuthenticatorGetInfo(): AuthenticatorGetInfo|null - { - return $this->authenticatorGetInfo; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestationCertificateKeyIdentifiers(): array - { - return $this->attestationCertificateKeyIdentifiers; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getDescription(): string - { - return $this->description; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAlternativeDescriptions(): null|AlternativeDescriptions - { - return $this->alternativeDescriptions; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAuthenticatorVersion(): int - { - return $this->authenticatorVersion; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getProtocolFamily(): string - { - return $this->protocolFamily; - } - - /** - * @return Version[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUpv(): array - { - return $this->upv; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getSchema(): ?int - { - return $this->schema; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAuthenticationAlgorithms(): array - { - return $this->authenticationAlgorithms; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getPublicKeyAlgAndEncodings(): array - { - return $this->publicKeyAlgAndEncodings; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestationTypes(): array - { - return $this->attestationTypes; - } - - /** - * @return VerificationMethodANDCombinations[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUserVerificationDetails(): array - { - return $this->userVerificationDetails; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getKeyProtection(): array - { - return $this->keyProtection; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMatcherProtection(): array - { - return $this->matcherProtection; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCryptoStrength(): ?int - { - return $this->cryptoStrength; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttachmentHint(): array - { - return $this->attachmentHint; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTcDisplay(): array - { - return $this->tcDisplay; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTcDisplayContentType(): ?string - { - return $this->tcDisplayContentType; - } - - /** - * @return DisplayPNGCharacteristicsDescriptor[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTcDisplayPNGCharacteristics(): array - { - return $this->tcDisplayPNGCharacteristics; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestationRootCertificates(): array - { - return $this->attestationRootCertificates; - } - - /** - * @return EcdaaTrustAnchor[] - * - * @deprecated since 4.2.0 and will be removed in 5.0.0. The ECDAA Trust Anchor does no longer exist in Webauthn specification. - * @infection-ignore-all - */ - public function getEcdaaTrustAnchors(): array - { - return $this->ecdaaTrustAnchors; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getIcon(): ?string - { - return $this->icon; - } - - /** - * @return ExtensionDescriptor[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getSupportedExtensions(): array - { - return $this->supportedExtensions; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $requiredKeys = [ - 'description', - 'authenticatorVersion', - 'protocolFamily', - 'schema', - 'upv', - 'authenticationAlgorithms', - 'publicKeyAlgAndEncodings', - 'attestationTypes', - 'userVerificationDetails', - 'matcherProtection', - 'tcDisplay', - 'attestationRootCertificates', - ]; - foreach ($requiredKeys as $key) { - array_key_exists($key, $data) || throw MetadataStatementLoadingException::create(sprintf( - 'Invalid data. The key "%s" is missing', - $key - )); - } - $subObjects = [ - 'authenticationAlgorithms', - 'publicKeyAlgAndEncodings', - 'attestationTypes', - 'matcherProtection', - 'tcDisplay', - 'attestationRootCertificates', - ]; - foreach ($subObjects as $subObject) { - is_array($data[$subObject]) || throw MetadataStatementLoadingException::create(sprintf( - 'Invalid Metadata Statement. The parameter "%s" shall be a list of strings.', - $subObject - )); - foreach ($data[$subObject] as $datum) { - is_string($datum) || throw MetadataStatementLoadingException::create(sprintf( - 'Invalid Metadata Statement. The parameter "%s" shall be a list of strings.', - $subObject - )); - } - } - - return self::create( - $data['description'], - $data['authenticatorVersion'], - $data['protocolFamily'], - $data['schema'], - array_map(static function ($upv): Version { - is_array($upv) || throw MetadataStatementLoadingException::create( - 'Invalid Metadata Statement. The parameter "upv" shall be a list of objects.' - ); - - return Version::createFromArray($upv); - }, $data['upv']), - $data['authenticationAlgorithms'], - $data['publicKeyAlgAndEncodings'], - $data['attestationTypes'], - array_map(static function ($userVerificationDetails): VerificationMethodANDCombinations { - is_array($userVerificationDetails) || throw MetadataStatementLoadingException::create( - 'Invalid Metadata Statement. The parameter "userVerificationDetails" shall be a list of objects.' - ); - - return VerificationMethodANDCombinations::createFromArray($userVerificationDetails); - }, $data['userVerificationDetails']), - $data['matcherProtection'], - $data['tcDisplay'], - CertificateToolbox::fixPEMStructures($data['attestationRootCertificates']), - $data['alternativeDescriptions'] ?? [], - $data['legalHeader'] ?? null, - $data['aaid'] ?? null, - $data['aaguid'] ?? null, - $data['attestationCertificateKeyIdentifiers'] ?? [], - $data['keyProtection'] ?? [], - $data['isKeyRestricted'] ?? null, - $data['isFreshUserVerificationRequired'] ?? null, - $data['cryptoStrength'] ?? null, - $data['attachmentHint'] ?? [], - $data['tcDisplayContentType'] ?? null, - array_map( - static fn (array $data): DisplayPNGCharacteristicsDescriptor => DisplayPNGCharacteristicsDescriptor::createFromArray( - $data - ), - $data['tcDisplayPNGCharacteristics'] ?? [] - ), - $data['ecdaaTrustAnchors'] ?? [], - $data['icon'] ?? null, - array_map( - static fn ($supportedExtension): ExtensionDescriptor => ExtensionDescriptor::createFromArray( - $supportedExtension - ), - $data['supportedExtensions'] ?? [] - ), - isset($data['authenticatorGetInfo']) ? AuthenticatorGetInfo::create($data['authenticatorGetInfo']) : null, - ); - } - /** * @return array */ @@ -683,7 +309,6 @@ public function jsonSerialize(): array 'tcDisplayContentType' => $this->tcDisplayContentType, 'tcDisplayPNGCharacteristics' => $this->tcDisplayPNGCharacteristics, 'attestationRootCertificates' => CertificateToolbox::fixPEMStructures($this->attestationRootCertificates), - 'ecdaaTrustAnchors' => $this->ecdaaTrustAnchors, 'icon' => $this->icon, 'authenticatorGetInfo' => $this->authenticatorGetInfo, 'supportedExtensions' => $this->supportedExtensions, diff --git a/src/metadata-service/src/Statement/PatternAccuracyDescriptor.php b/src/metadata-service/src/Statement/PatternAccuracyDescriptor.php index 9838e1db..d5b54c26 100644 --- a/src/metadata-service/src/Statement/PatternAccuracyDescriptor.php +++ b/src/metadata-service/src/Statement/PatternAccuracyDescriptor.php @@ -6,8 +6,6 @@ use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; -use function is_int; class PatternAccuracyDescriptor extends AbstractDescriptor { @@ -30,38 +28,7 @@ public static function create(int $minComplexity, ?int $maxRetries = null, ?int } /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMinComplexity(): int - { - return $this->minComplexity; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - array_key_exists('minComplexity', $data) || throw MetadataStatementLoadingException::create( - 'The key "minComplexity" is missing' - ); - foreach (['minComplexity', 'maxRetries', 'blockSlowdown'] as $key) { - if (array_key_exists($key, $data)) { - is_int($data[$key]) || throw MetadataStatementLoadingException::create( - sprintf('Invalid data. The value of "%s" must be a positive integer', $key) - ); - } - } - - return self::create($data['minComplexity'], $data['maxRetries'] ?? null, $data['blockSlowdown'] ?? null); - } - - /** - * @return array + * @return array */ public function jsonSerialize(): array { diff --git a/src/metadata-service/src/Statement/RgbPaletteEntry.php b/src/metadata-service/src/Statement/RgbPaletteEntry.php index a2bd1ea3..ef5e7d41 100644 --- a/src/metadata-service/src/Statement/RgbPaletteEntry.php +++ b/src/metadata-service/src/Statement/RgbPaletteEntry.php @@ -6,8 +6,6 @@ use JsonSerializable; use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; -use function array_key_exists; -use function is_int; class RgbPaletteEntry implements JsonSerializable { @@ -26,53 +24,6 @@ public static function create(int $r, int $g, int $b): self return new self($r, $g, $b); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getR(): int - { - return $this->r; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getG(): int - { - return $this->g; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getB(): int - { - return $this->b; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - foreach (['r', 'g', 'b'] as $key) { - array_key_exists($key, $data) || throw MetadataStatementLoadingException::create(sprintf( - 'The key "%s" is missing', - $key - )); - is_int($data[$key]) || throw MetadataStatementLoadingException::create( - sprintf('The key "%s" is invalid', $key) - ); - } - - return self::create($data['r'], $data['g'], $data['b']); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/RogueListEntry.php b/src/metadata-service/src/Statement/RogueListEntry.php index bea96c6a..85581fe6 100644 --- a/src/metadata-service/src/Statement/RogueListEntry.php +++ b/src/metadata-service/src/Statement/RogueListEntry.php @@ -5,9 +5,6 @@ namespace Webauthn\MetadataService\Statement; use JsonSerializable; -use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; -use function array_key_exists; -use function is_string; class RogueListEntry implements JsonSerializable { @@ -22,41 +19,6 @@ public static function create(string $sk, string $date): self return new self($sk, $date); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getSk(): string - { - return $this->sk; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getDate(): ?string - { - return $this->date; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - array_key_exists('sk', $data) || throw MetadataStatementLoadingException::create('The key "sk" is missing'); - is_string($data['sk']) || throw MetadataStatementLoadingException::create('The key "date" is invalid'); - array_key_exists('date', $data) || throw MetadataStatementLoadingException::create( - 'The key "date" is missing' - ); - is_string($data['date']) || throw MetadataStatementLoadingException::create('The key "date" is invalid'); - - return self::create($data['sk'], $data['date']); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/StatusReport.php b/src/metadata-service/src/Statement/StatusReport.php index 45b78f6a..276d3874 100644 --- a/src/metadata-service/src/Statement/StatusReport.php +++ b/src/metadata-service/src/Statement/StatusReport.php @@ -7,9 +7,7 @@ use JsonSerializable; use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; use function in_array; -use function is_string; class StatusReport implements JsonSerializable { @@ -65,119 +63,6 @@ public function isCompromised(): bool ], true); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getStatus(): string - { - return $this->status; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getEffectiveDate(): ?string - { - return $this->effectiveDate; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificate(): ?string - { - return $this->certificate; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUrl(): ?string - { - return $this->url; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificationDescriptor(): ?string - { - return $this->certificationDescriptor; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificateNumber(): ?string - { - return $this->certificateNumber; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificationPolicyVersion(): ?string - { - return $this->certificationPolicyVersion; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificationRequirementsVersion(): ?string - { - return $this->certificationRequirementsVersion; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - array_key_exists('status', $data) || throw MetadataStatementLoadingException::create( - 'The key "status" is missing' - ); - foreach ([ - 'effectiveDate', - 'certificate', - 'url', - 'certificationDescriptor', - 'certificateNumber', - 'certificationPolicyVersion', - 'certificationRequirementsVersion', - ] as $key) { - if (isset($data[$key])) { - $value = $data[$key]; - $value === null || is_string($value) || throw MetadataStatementLoadingException::create(sprintf( - 'The value of the key "%s" is invalid', - $key - )); - } - } - - return self::create( - $data['status'], - $data['effectiveDate'] ?? null, - $data['certificate'] ?? null, - $data['url'] ?? null, - $data['certificationDescriptor'] ?? null, - $data['certificateNumber'] ?? null, - $data['certificationPolicyVersion'] ?? null, - $data['certificationRequirementsVersion'] ?? null - ); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/VerificationMethodANDCombinations.php b/src/metadata-service/src/Statement/VerificationMethodANDCombinations.php index 174dcc83..65f31f52 100644 --- a/src/metadata-service/src/Statement/VerificationMethodANDCombinations.php +++ b/src/metadata-service/src/Statement/VerificationMethodANDCombinations.php @@ -25,44 +25,6 @@ public static function create(array $verificationMethods): self return new self($verificationMethods); } - /** - * @deprecated since 4.7.0. Please use the {self::create} directly. - * @infection-ignore-all - */ - public function addVerificationMethodDescriptor(VerificationMethodDescriptor $verificationMethodDescriptor): self - { - $this->verificationMethods[] = $verificationMethodDescriptor; - - return $this; - } - - /** - * @return VerificationMethodDescriptor[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getVerificationMethods(): array - { - return $this->verificationMethods; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - return self::create( - array_map( - static fn (array $datum): VerificationMethodDescriptor => VerificationMethodDescriptor::createFromArray( - $datum - ), - $data - ) - ); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/VerificationMethodDescriptor.php b/src/metadata-service/src/Statement/VerificationMethodDescriptor.php index 3fb2aeb9..6ec1a893 100644 --- a/src/metadata-service/src/Statement/VerificationMethodDescriptor.php +++ b/src/metadata-service/src/Statement/VerificationMethodDescriptor.php @@ -7,66 +7,64 @@ use JsonSerializable; use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; -use function is_array; class VerificationMethodDescriptor implements JsonSerializable { use ValueFilter; - final public const USER_VERIFY_PRESENCE_INTERNAL = 'presence_internal'; + final public const string USER_VERIFY_PRESENCE_INTERNAL = 'presence_internal'; - final public const USER_VERIFY_PRESENCE_INTERNAL_INT = 0x00000001; + final public const int USER_VERIFY_PRESENCE_INTERNAL_INT = 0x00000001; - final public const USER_VERIFY_FINGERPRINT_INTERNAL = 'fingerprint_internal'; + final public const string USER_VERIFY_FINGERPRINT_INTERNAL = 'fingerprint_internal'; - final public const USER_VERIFY_FINGERPRINT_INTERNAL_INT = 0x00000002; + final public const int USER_VERIFY_FINGERPRINT_INTERNAL_INT = 0x00000002; - final public const USER_VERIFY_PASSCODE_INTERNAL = 'passcode_internal'; + final public const string USER_VERIFY_PASSCODE_INTERNAL = 'passcode_internal'; - final public const USER_VERIFY_PASSCODE_INTERNAL_INT = 0x00000004; + final public const int USER_VERIFY_PASSCODE_INTERNAL_INT = 0x00000004; - final public const USER_VERIFY_VOICEPRINT_INTERNAL = 'voiceprint_internal'; + final public const string USER_VERIFY_VOICEPRINT_INTERNAL = 'voiceprint_internal'; - final public const USER_VERIFY_VOICEPRINT_INTERNAL_INT = 0x00000008; + final public const int USER_VERIFY_VOICEPRINT_INTERNAL_INT = 0x00000008; - final public const USER_VERIFY_FACEPRINT_INTERNAL = 'faceprint_internal'; + final public const string USER_VERIFY_FACEPRINT_INTERNAL = 'faceprint_internal'; - final public const USER_VERIFY_FACEPRINT_INTERNAL_INT = 0x00000010; + final public const int USER_VERIFY_FACEPRINT_INTERNAL_INT = 0x00000010; - final public const USER_VERIFY_LOCATION_INTERNAL = 'location_internal'; + final public const string USER_VERIFY_LOCATION_INTERNAL = 'location_internal'; - final public const USER_VERIFY_LOCATION_INTERNAL_INT = 0x00000020; + final public const int USER_VERIFY_LOCATION_INTERNAL_INT = 0x00000020; - final public const USER_VERIFY_EYEPRINT_INTERNAL = 'eyeprint_internal'; + final public const string USER_VERIFY_EYEPRINT_INTERNAL = 'eyeprint_internal'; - final public const USER_VERIFY_EYEPRINT_INTERNAL_INT = 0x00000040; + final public const int USER_VERIFY_EYEPRINT_INTERNAL_INT = 0x00000040; - final public const USER_VERIFY_PATTERN_INTERNAL = 'pattern_internal'; + final public const string USER_VERIFY_PATTERN_INTERNAL = 'pattern_internal'; - final public const USER_VERIFY_PATTERN_INTERNAL_INT = 0x00000080; + final public const int USER_VERIFY_PATTERN_INTERNAL_INT = 0x00000080; - final public const USER_VERIFY_HANDPRINT_INTERNAL = 'handprint_internal'; + final public const string USER_VERIFY_HANDPRINT_INTERNAL = 'handprint_internal'; - final public const USER_VERIFY_HANDPRINT_INTERNAL_INT = 0x00000100; + final public const int USER_VERIFY_HANDPRINT_INTERNAL_INT = 0x00000100; - final public const USER_VERIFY_PASSCODE_EXTERNAL = 'passcode_external'; + final public const string USER_VERIFY_PASSCODE_EXTERNAL = 'passcode_external'; - final public const USER_VERIFY_PASSCODE_EXTERNAL_INT = 0x00000800; + final public const int USER_VERIFY_PASSCODE_EXTERNAL_INT = 0x00000800; - final public const USER_VERIFY_PATTERN_EXTERNAL = 'pattern_external'; + final public const string USER_VERIFY_PATTERN_EXTERNAL = 'pattern_external'; - final public const USER_VERIFY_PATTERN_EXTERNAL_INT = 0x00001000; + final public const int USER_VERIFY_PATTERN_EXTERNAL_INT = 0x00001000; - final public const USER_VERIFY_NONE = 'none'; + final public const string USER_VERIFY_NONE = 'none'; - final public const USER_VERIFY_NONE_INT = 0x00000200; + final public const int USER_VERIFY_NONE_INT = 0x00000200; - final public const USER_VERIFY_ALL = 'all'; + final public const string USER_VERIFY_ALL = 'all'; - final public const USER_VERIFY_ALL_INT = 0x00000400; + final public const int USER_VERIFY_ALL_INT = 0x00000400; - final public const USER_VERIFICATION_METHODS = [ + final public const array USER_VERIFICATION_METHODS = [ self::USER_VERIFY_PRESENCE_INTERNAL, self::USER_VERIFY_FINGERPRINT_INTERNAL, self::USER_VERIFY_PASSCODE_INTERNAL, @@ -82,7 +80,7 @@ class VerificationMethodDescriptor implements JsonSerializable self::USER_VERIFY_ALL, ]; - final public const USER_VERIFICATION_METHODS_INT = [ + final public const array USER_VERIFICATION_METHODS_INT = [ self::USER_VERIFY_PRESENCE_INTERNAL_INT, self::USER_VERIFY_FINGERPRINT_INTERNAL_INT, self::USER_VERIFY_PASSCODE_INTERNAL_INT, @@ -118,15 +116,6 @@ public static function create( return new self($userVerificationMethod, $caDesc, $baDesc, $paDesc); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUserVerificationMethod(): string - { - return $this->userVerificationMethod; - } - public function userPresence(): bool { return $this->userVerificationMethod === self::USER_VERIFY_PRESENCE_INTERNAL; @@ -192,64 +181,6 @@ public function all(): bool return $this->userVerificationMethod === self::USER_VERIFY_ALL; } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCaDesc(): ?CodeAccuracyDescriptor - { - return $this->caDesc; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getBaDesc(): ?BiometricAccuracyDescriptor - { - return $this->baDesc; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getPaDesc(): ?PatternAccuracyDescriptor - { - return $this->paDesc; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - if (isset($data['userVerification']) && ! isset($data['userVerificationMethod'])) { - $data['userVerificationMethod'] = $data['userVerification']; - unset($data['userVerification']); - } - array_key_exists('userVerificationMethod', $data) || throw MetadataStatementLoadingException::create( - 'The parameters "userVerificationMethod" is missing' - ); - - foreach (['caDesc', 'baDesc', 'paDesc'] as $key) { - if (isset($data[$key])) { - is_array($data[$key]) || throw MetadataStatementLoadingException::create( - sprintf('Invalid parameter "%s"', $key) - ); - } - } - - $caDesc = isset($data['caDesc']) ? CodeAccuracyDescriptor::createFromArray($data['caDesc']) : null; - $baDesc = isset($data['baDesc']) ? BiometricAccuracyDescriptor::createFromArray($data['baDesc']) : null; - $paDesc = isset($data['paDesc']) ? PatternAccuracyDescriptor::createFromArray($data['paDesc']) : null; - - return self::create($data['userVerificationMethod'], $caDesc, $baDesc, $paDesc); - } - /** * @return array */ diff --git a/src/metadata-service/src/Statement/Version.php b/src/metadata-service/src/Statement/Version.php index 8588e620..b787503a 100644 --- a/src/metadata-service/src/Statement/Version.php +++ b/src/metadata-service/src/Statement/Version.php @@ -7,8 +7,6 @@ use JsonSerializable; use Webauthn\MetadataService\Exception\MetadataStatementLoadingException; use Webauthn\MetadataService\ValueFilter; -use function array_key_exists; -use function is_int; class Version implements JsonSerializable { @@ -31,44 +29,7 @@ public static function create(?int $major, ?int $minor): self } /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMajor(): ?int - { - return $this->major; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMinor(): ?int - { - return $this->minor; - } - - /** - * @param array $data - * @deprecated since 4.7.0. Please use the symfony/serializer for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $data = self::filterNullValues($data); - foreach (['major', 'minor'] as $key) { - if (array_key_exists($key, $data)) { - is_int($data[$key]) || throw MetadataStatementLoadingException::create( - sprintf('Invalid value for key "%s"', $key) - ); - } - } - - return self::create($data['major'] ?? null, $data['minor'] ?? null); - } - - /** - * @return array + * @return array */ public function jsonSerialize(): array { diff --git a/src/metadata-service/src/ValueFilter.php b/src/metadata-service/src/ValueFilter.php index 23a9700c..7bdec6b6 100644 --- a/src/metadata-service/src/ValueFilter.php +++ b/src/metadata-service/src/ValueFilter.php @@ -10,9 +10,9 @@ trait ValueFilter { /** - * @param array $data + * @param array $data * - * @return array + * @return array */ private static function filterNullValues(array $data): array { diff --git a/src/stimulus/assets/dist/controller.d.ts b/src/stimulus/assets/dist/controller.d.ts index 4366bd63..b4534c73 100644 --- a/src/stimulus/assets/dist/controller.d.ts +++ b/src/stimulus/assets/dist/controller.d.ts @@ -39,10 +39,6 @@ export default class extends Controller { type: StringConstructor; default: string; }; - requireResidentKeyField: { - type: StringConstructor; - default: string; - }; authenticatorAttachmentField: { type: StringConstructor; default: string; @@ -63,7 +59,6 @@ export default class extends Controller { readonly attestationFieldValue: string; readonly userVerificationFieldValue: string; readonly residentKeyFieldValue: string; - readonly requireResidentKeyFieldValue: string; readonly authenticatorAttachmentFieldValue: string; readonly useBrowserAutofillValue: boolean; connect(): void; diff --git a/src/stimulus/assets/dist/controller.js b/src/stimulus/assets/dist/controller.js index 53058c16..5afeee2e 100644 --- a/src/stimulus/assets/dist/controller.js +++ b/src/stimulus/assets/dist/controller.js @@ -104,7 +104,6 @@ class default_1 extends Controller { attestation: data.get(this.attestationFieldValue), userVerification: data.get(this.userVerificationFieldValue), residentKey: data.get(this.residentKeyFieldValue), - requireResidentKey: data.get(this.requireResidentKeyFieldValue), authenticatorAttachment: data.get(this.authenticatorAttachmentFieldValue), }); } @@ -121,7 +120,6 @@ default_1.values = { attestationField: { type: String, default: 'attestation' }, userVerificationField: { type: String, default: 'userVerification' }, residentKeyField: { type: String, default: 'residentKey' }, - requireResidentKeyField: { type: String, default: 'requireResidentKey' }, authenticatorAttachmentField: { type: String, default: 'authenticatorAttachment' }, useBrowserAutofill: { type: Boolean, default: false }, }; diff --git a/src/stimulus/assets/src/controller.ts b/src/stimulus/assets/src/controller.ts index ea8b597f..662f3788 100644 --- a/src/stimulus/assets/src/controller.ts +++ b/src/stimulus/assets/src/controller.ts @@ -16,7 +16,6 @@ export default class extends Controller { attestationField: { type: String, default: 'attestation' }, userVerificationField: { type: String, default: 'userVerification' }, residentKeyField: { type: String, default: 'residentKey' }, - requireResidentKeyField: { type: String, default: 'requireResidentKey' }, authenticatorAttachmentField: { type: String, default: 'authenticatorAttachment' }, useBrowserAutofill: { type: Boolean, default: false }, }; @@ -32,7 +31,6 @@ export default class extends Controller { declare readonly attestationFieldValue: string; declare readonly userVerificationFieldValue: string; declare readonly residentKeyFieldValue: string; - declare readonly requireResidentKeyFieldValue: string; declare readonly authenticatorAttachmentFieldValue: string; declare readonly useBrowserAutofillValue: boolean; @@ -149,7 +147,6 @@ export default class extends Controller { attestation: data.get(this.attestationFieldValue), userVerification: data.get(this.userVerificationFieldValue), residentKey: data.get(this.residentKeyFieldValue), - requireResidentKey: data.get(this.requireResidentKeyFieldValue), authenticatorAttachment: data.get(this.authenticatorAttachmentFieldValue), }); } diff --git a/src/stimulus/src/WebauthnStimulusBundle.php b/src/stimulus/src/WebauthnStimulusBundle.php index 0850e5cc..6f8181ac 100644 --- a/src/stimulus/src/WebauthnStimulusBundle.php +++ b/src/stimulus/src/WebauthnStimulusBundle.php @@ -11,7 +11,7 @@ final class WebauthnStimulusBundle extends Bundle { - public function getContainerExtension(): ?ExtensionInterface + public function getContainerExtension(): ExtensionInterface { return new WebauthnStimulusExtension(); } diff --git a/src/symfony/composer.json b/src/symfony/composer.json index 968cc307..1c0c583c 100644 --- a/src/symfony/composer.json +++ b/src/symfony/composer.json @@ -23,24 +23,18 @@ } ], "require": { - "php": ">=8.1", - "nyholm/psr7": "^1.5", - "phpdocumentor/reflection-docblock": "^5.3", + "php": ">=8.3", "psr/event-dispatcher": "^1.0", - "symfony/config": "^6.1|^7.0", - "symfony/dependency-injection": "^6.1|^7.0", - "symfony/framework-bundle": "^6.1|^7.0", - "symfony/http-client": "^6.1|^7.0", - "symfony/psr-http-message-bridge": "^2.1|^6.1|^7.0", - "symfony/property-access": "^6.1|^7.0", - "symfony/property-info": "^6.1|^7.0", - "symfony/security-bundle": "^6.1|^7.0", - "symfony/security-core": "^6.1|^7.0", - "symfony/security-http": "^6.1|^7.0", - "symfony/serializer": "^6.1|^7.0", - "symfony/validator": "^6.1|^7.0", - "web-auth/webauthn-lib": "self.version", - "web-token/jwt-library": "^3.3|^4.0" + "symfony/config": "^7.0", + "symfony/dependency-injection": "^7.0", + "symfony/framework-bundle": "^7.0", + "symfony/http-client": "^7.0", + "symfony/security-bundle": "^7.0", + "symfony/security-core": "^7.0", + "symfony/security-http": "^7.0", + "symfony/serializer": "^7.0", + "symfony/validator": "^7.0", + "web-auth/webauthn-lib": "self.version" }, "extra": { "thanks": { diff --git a/src/symfony/src/Controller/AssertionControllerFactory.php b/src/symfony/src/Controller/AssertionControllerFactory.php index 7b8f9660..24c7c159 100644 --- a/src/symfony/src/Controller/AssertionControllerFactory.php +++ b/src/symfony/src/Controller/AssertionControllerFactory.php @@ -8,21 +8,14 @@ use Psr\Log\NullLogger; use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Validator\Validator\ValidatorInterface; use Webauthn\AuthenticatorAssertionResponseValidator; -use Webauthn\Bundle\CredentialOptionsBuilder\ProfileBasedRequestOptionsBuilder; use Webauthn\Bundle\CredentialOptionsBuilder\PublicKeyCredentialRequestOptionsBuilder; use Webauthn\Bundle\Repository\PublicKeyCredentialSourceRepositoryInterface; -use Webauthn\Bundle\Repository\PublicKeyCredentialUserEntityRepositoryInterface; use Webauthn\Bundle\Security\Handler\FailureHandler; use Webauthn\Bundle\Security\Handler\RequestOptionsHandler; use Webauthn\Bundle\Security\Handler\SuccessHandler; use Webauthn\Bundle\Security\Storage\OptionsStorage; -use Webauthn\Bundle\Service\PublicKeyCredentialRequestOptionsFactory; -use Webauthn\FakeCredentialGenerator; use Webauthn\MetadataService\CanLogData; -use Webauthn\PublicKeyCredentialLoader; -use Webauthn\PublicKeyCredentialSourceRepository; final class AssertionControllerFactory implements CanLogData { @@ -30,21 +23,9 @@ final class AssertionControllerFactory implements CanLogData public function __construct( private readonly SerializerInterface $serializer, - private readonly ValidatorInterface $validator, - private readonly PublicKeyCredentialRequestOptionsFactory $publicKeyCredentialRequestOptionsFactory, - private readonly null|PublicKeyCredentialLoader $publicKeyCredentialLoader, private readonly AuthenticatorAssertionResponseValidator $authenticatorAssertionResponseValidator, - private readonly PublicKeyCredentialUserEntityRepositoryInterface $publicKeyCredentialUserEntityRepository, - private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository, - private readonly null|FakeCredentialGenerator $fakeCredentialGenerator = null, + private readonly PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository, ) { - if ($this->publicKeyCredentialLoader !== null) { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.8.0', - 'The argument "$publicKeyCredentialLoader" is deprecated since 4.5.0 and will be removed in 5.0.0. Please set null instead; the serializer will be used instead.' - ); - } $this->logger = new NullLogger(); } @@ -53,29 +34,6 @@ public function setLogger(LoggerInterface $logger): void $this->logger = $logger; } - /** - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use createRequestController instead. - * @infection-ignore-all - */ - public function createAssertionRequestController( - string $profile, - OptionsStorage $optionStorage, - RequestOptionsHandler $optionsHandler, - FailureHandler|AuthenticationFailureHandlerInterface $failureHandler - ): AssertionRequestController { - $optionsBuilder = new ProfileBasedRequestOptionsBuilder( - $this->serializer, - $this->validator, - $this->publicKeyCredentialUserEntityRepository, - $this->publicKeyCredentialSourceRepository, - $this->publicKeyCredentialRequestOptionsFactory, - $profile, - $this->fakeCredentialGenerator, - ); - - return $this->createRequestController($optionsBuilder, $optionStorage, $optionsHandler, $failureHandler); - } - public function createRequestController( PublicKeyCredentialRequestOptionsBuilder $optionsBuilder, OptionsStorage $optionStorage, @@ -91,43 +49,19 @@ public function createRequestController( ); } - /** - * @param string[] $securedRelyingPartyIds - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use createResponseController instead. - * @infection-ignore-all - */ - public function createAssertionResponseController( - OptionsStorage $optionStorage, - SuccessHandler $successHandler, - FailureHandler|AuthenticationFailureHandlerInterface $failureHandler, - array $securedRelyingPartyIds - ): AssertionResponseController { - return $this->createResponseController( - $optionStorage, - $successHandler, - $failureHandler, - $securedRelyingPartyIds - ); - } - - /** - * @param null|string[] $securedRelyingPartyIds - */ public function createResponseController( OptionsStorage $optionStorage, SuccessHandler $successHandler, FailureHandler|AuthenticationFailureHandlerInterface $failureHandler, - null|array $securedRelyingPartyIds = null, null|AuthenticatorAssertionResponseValidator $authenticatorAssertionResponseValidator = null, ): AssertionResponseController { return new AssertionResponseController( - $this->publicKeyCredentialLoader ?? $this->serializer, + $this->serializer, $authenticatorAssertionResponseValidator ?? $this->authenticatorAssertionResponseValidator, $this->logger, $optionStorage, $successHandler, $failureHandler, - $securedRelyingPartyIds, $this->publicKeyCredentialSourceRepository ); } diff --git a/src/symfony/src/Controller/AssertionResponseController.php b/src/symfony/src/Controller/AssertionResponseController.php index 6e1b155a..b160a1b4 100644 --- a/src/symfony/src/Controller/AssertionResponseController.php +++ b/src/symfony/src/Controller/AssertionResponseController.php @@ -20,46 +20,33 @@ use Webauthn\Bundle\Security\Storage\OptionsStorage; use Webauthn\Exception\AuthenticatorResponseVerificationException; use Webauthn\PublicKeyCredential; -use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialRequestOptions; -final class AssertionResponseController +final readonly class AssertionResponseController { - /** - * @param null|string[] $securedRelyingPartyIds - */ public function __construct( - private readonly SerializerInterface|PublicKeyCredentialLoader $publicKeyCredentialLoader, - private readonly AuthenticatorAssertionResponseValidator $assertionResponseValidator, - private readonly LoggerInterface $logger, - private readonly OptionsStorage $optionsStorage, - private readonly SuccessHandler $successHandler, - private readonly FailureHandler|AuthenticationFailureHandlerInterface $failureHandler, - private readonly null|array $securedRelyingPartyIds = null, - private readonly ?PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository = null + private SerializerInterface $publicKeyCredentialLoader, + private AuthenticatorAssertionResponseValidator $assertionResponseValidator, + private LoggerInterface $logger, + private OptionsStorage $optionsStorage, + private SuccessHandler $successHandler, + private FailureHandler|AuthenticationFailureHandlerInterface $failureHandler, + private PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository ) { - if ($this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader) { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.8.0', - 'The argument "$publicKeyCredentialLoader" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a Symfony Serializer instead.' - ); - } } public function __invoke(Request $request): Response { try { - $format = method_exists( - $request, - 'getContentTypeFormat' - ) ? $request->getContentTypeFormat() : $request->getContentType(); + $format = $request->getContentTypeFormat(); $format === 'json' || throw new BadRequestHttpException('Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( - $content - ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); + $publicKeyCredential = $this->publicKeyCredentialLoader->deserialize( + $content, + PublicKeyCredential::class, + 'json' + ); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAssertionResponse || throw new BadRequestHttpException( 'Invalid response' @@ -70,7 +57,7 @@ public function __invoke(Request $request): Response 'Invalid response' ); $userEntity = $data->getPublicKeyCredentialUserEntity(); - $publicKeyCredentialSource = $this->publicKeyCredentialSourceRepository === null ? $publicKeyCredential->rawId : $this->publicKeyCredentialSourceRepository->findOneByCredentialId( + $publicKeyCredentialSource = $this->publicKeyCredentialSourceRepository->findOneByCredentialId( $publicKeyCredential->rawId ); $publicKeyCredentialSource !== null || throw AuthenticatorResponseVerificationException::create( @@ -83,7 +70,6 @@ public function __invoke(Request $request): Response $publicKeyCredentialRequestOptions, $request->getHost(), $userEntity?->id, - $this->securedRelyingPartyIds ); return $this->successHandler->onSuccess($request); } catch (Throwable $throwable) { diff --git a/src/symfony/src/Controller/AttestationControllerFactory.php b/src/symfony/src/Controller/AttestationControllerFactory.php index d2fef6a0..aab81a49 100644 --- a/src/symfony/src/Controller/AttestationControllerFactory.php +++ b/src/symfony/src/Controller/AttestationControllerFactory.php @@ -6,9 +6,7 @@ use Symfony\Component\Security\Http\Authentication\AuthenticationFailureHandlerInterface; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Validator\Validator\ValidatorInterface; use Webauthn\AuthenticatorAttestationResponseValidator; -use Webauthn\Bundle\CredentialOptionsBuilder\ProfileBasedCreationOptionsBuilder; use Webauthn\Bundle\CredentialOptionsBuilder\PublicKeyCredentialCreationOptionsBuilder; use Webauthn\Bundle\Repository\PublicKeyCredentialSourceRepositoryInterface; use Webauthn\Bundle\Security\Guesser\UserEntityGuesser; @@ -16,54 +14,14 @@ use Webauthn\Bundle\Security\Handler\FailureHandler; use Webauthn\Bundle\Security\Handler\SuccessHandler; use Webauthn\Bundle\Security\Storage\OptionsStorage; -use Webauthn\Bundle\Service\PublicKeyCredentialCreationOptionsFactory; -use Webauthn\PublicKeyCredentialLoader; -use Webauthn\PublicKeyCredentialSourceRepository; -final class AttestationControllerFactory +final readonly class AttestationControllerFactory { public function __construct( - private readonly SerializerInterface $serializer, - private readonly ValidatorInterface $validator, - private readonly PublicKeyCredentialCreationOptionsFactory $publicKeyCredentialCreationOptionsFactory, - private readonly null|PublicKeyCredentialLoader $publicKeyCredentialLoader, - private readonly AuthenticatorAttestationResponseValidator $attestationResponseValidator, - private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository + private SerializerInterface $serializer, + private AuthenticatorAttestationResponseValidator $attestationResponseValidator, + private PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository ) { - if ($this->publicKeyCredentialLoader !== null) { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.8.0', - 'The argument "$publicKeyCredentialLoader" is deprecated since 4.5.0 and will be removed in 5.0.0. Please set null instead; the serializer will be used instead.' - ); - } - } - - /** - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use createResponseController instead. - * @infection-ignore-all - */ - public function createAttestationRequestController( - UserEntityGuesser $userEntityGuesser, - string $profile, - OptionsStorage $optionStorage, - CreationOptionsHandler $creationOptionsHandler, - FailureHandler|AuthenticationFailureHandlerInterface $failureHandler, - ): AttestationRequestController { - $optionsBuilder = new ProfileBasedCreationOptionsBuilder( - $this->serializer, - $this->validator, - $this->publicKeyCredentialSourceRepository, - $this->publicKeyCredentialCreationOptionsFactory, - $profile - ); - return $this->createRequestController( - $optionsBuilder, - $userEntityGuesser, - $optionStorage, - $creationOptionsHandler, - $failureHandler - ); } public function createRequestController( @@ -84,36 +42,19 @@ public function createRequestController( ); } - /** - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use createResponseController instead. - * @infection-ignore-all - */ - public function createAttestationResponseController( - OptionsStorage $optionStorage, - SuccessHandler $successHandler, - FailureHandler|AuthenticationFailureHandlerInterface $failureHandler - ): AttestationResponseController { - return $this->createResponseController($optionStorage, $successHandler, $failureHandler); - } - - /** - * @param null|string[] $securedRelyingPartyIds - */ public function createResponseController( OptionsStorage $optionStorage, SuccessHandler $successHandler, FailureHandler|AuthenticationFailureHandlerInterface $failureHandler, - null|array $securedRelyingPartyIds = null, null|AuthenticatorAttestationResponseValidator $attestationResponseValidator = null, ): AttestationResponseController { return new AttestationResponseController( - $this->publicKeyCredentialLoader ?? $this->serializer, + $this->serializer, $attestationResponseValidator ?? $this->attestationResponseValidator, $this->publicKeyCredentialSourceRepository, $optionStorage, $successHandler, $failureHandler, - $securedRelyingPartyIds ); } } diff --git a/src/symfony/src/Controller/AttestationResponseController.php b/src/symfony/src/Controller/AttestationResponseController.php index 8877af0d..cabaa341 100644 --- a/src/symfony/src/Controller/AttestationResponseController.php +++ b/src/symfony/src/Controller/AttestationResponseController.php @@ -22,42 +22,18 @@ use Webauthn\Bundle\Security\Storage\OptionsStorage; use Webauthn\PublicKeyCredential; use Webauthn\PublicKeyCredentialCreationOptions; -use Webauthn\PublicKeyCredentialLoader; -use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; final class AttestationResponseController { - /** - * @param null|string[] $securedRelyingPartyIds - */ public function __construct( - private readonly SerializerInterface|PublicKeyCredentialLoader $publicKeyCredentialLoader, + private readonly SerializerInterface $publicKeyCredentialLoader, private readonly AuthenticatorAttestationResponseValidator $attestationResponseValidator, - private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $credentialSourceRepository, + private readonly PublicKeyCredentialSourceRepositoryInterface $credentialSourceRepository, private readonly OptionsStorage $optionStorage, private readonly SuccessHandler $successHandler, private readonly FailureHandler|AuthenticationFailureHandlerInterface $failureHandler, - private readonly null|array $securedRelyingPartyIds = null, ) { - if (! $this->credentialSourceRepository instanceof PublicKeyCredentialSourceRepositoryInterface) { - trigger_deprecation( - 'web-auth/webauthn-symfony-bundle', - '4.6.0', - sprintf( - 'Since 4.6.0, the parameter "$credentialSourceRepository" expects an instance of "%s". Please implement that interface instead of "%s".', - PublicKeyCredentialSourceRepositoryInterface::class, - PublicKeyCredentialSourceRepository::class - ) - ); - } - if ($this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader) { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.8.0', - 'The argument "$publicKeyCredentialLoader" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a Symfony Serializer instead.' - ); - } } public function __invoke(Request $request): Response @@ -66,15 +42,14 @@ public function __invoke(Request $request): Response if (! $this->credentialSourceRepository instanceof CanSaveCredentialSource) { throw MissingFeatureException::create('Unable to register the credential.'); } - $format = method_exists( - $request, - 'getContentTypeFormat' - ) ? $request->getContentTypeFormat() : $request->getContentType(); + $format = $request->getContentTypeFormat(); $format === 'json' || throw new BadRequestHttpException('Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( - $content - ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); + $publicKeyCredential = $this->publicKeyCredentialLoader->deserialize( + $content, + PublicKeyCredential::class, + 'json' + ); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAttestationResponse || throw new BadRequestHttpException( 'Invalid response' @@ -92,7 +67,6 @@ public function __invoke(Request $request): Response $response, $publicKeyCredentialCreationOptions, $request->getHost(), - $this->securedRelyingPartyIds ); if ($this->credentialSourceRepository->findOneByCredentialId( $credentialSource->publicKeyCredentialId @@ -102,10 +76,10 @@ public function __invoke(Request $request): Response $this->credentialSourceRepository->saveCredentialSource($credentialSource); return $this->successHandler->onSuccess($request); } catch (Throwable $throwable) { - $exception = new AuthenticationException($throwable->getMessage(), 401, $throwable); if ($throwable instanceof MissingFeatureException) { - $exception = new HttpNotImplementedException($throwable->getMessage(), $throwable); + throw new HttpNotImplementedException($throwable->getMessage(), $throwable); } + $exception = new AuthenticationException($throwable->getMessage(), 401, $throwable); if ($this->failureHandler instanceof AuthenticationFailureHandlerInterface) { return $this->failureHandler->onAuthenticationFailure($request, $exception); } diff --git a/src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php b/src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php index 7b9a10f8..a4e99b65 100644 --- a/src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php +++ b/src/symfony/src/CredentialOptionsBuilder/ProfileBasedCreationOptionsBuilder.php @@ -10,7 +10,7 @@ use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Webauthn\AuthenticationExtensions\AuthenticationExtension; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; +use Webauthn\AuthenticationExtensions\AuthenticationExtensions; use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\Bundle\Dto\PublicKeyCredentialCreationOptionsRequest; use Webauthn\Bundle\Repository\PublicKeyCredentialSourceRepositoryInterface; @@ -18,32 +18,19 @@ use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialSource; -use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; use function count; use function is_array; -use const FILTER_VALIDATE_BOOLEAN; final class ProfileBasedCreationOptionsBuilder implements PublicKeyCredentialCreationOptionsBuilder { public function __construct( private readonly SerializerInterface $serializer, private readonly ValidatorInterface $validator, - private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $credentialSourceRepository, + private readonly PublicKeyCredentialSourceRepositoryInterface $credentialSourceRepository, private readonly PublicKeyCredentialCreationOptionsFactory $publicKeyCredentialCreationOptionsFactory, private readonly string $profile, ) { - if (! $this->credentialSourceRepository instanceof PublicKeyCredentialSourceRepositoryInterface) { - trigger_deprecation( - 'web-auth/webauthn-symfony-bundle', - '4.6.0', - sprintf( - 'Since 4.6.0, the parameter "$credentialSourceRepository" expects an instance of "%s". Please implement that interface instead of "%s".', - PublicKeyCredentialSourceRepositoryInterface::class, - PublicKeyCredentialSourceRepository::class - ) - ); - } } public function getFromRequest( @@ -51,36 +38,22 @@ public function getFromRequest( PublicKeyCredentialUserEntity $userEntity, bool $hideExistingExcludedCredentials = false ): PublicKeyCredentialCreationOptions { - $format = method_exists( - $request, - 'getContentTypeFormat' - ) ? $request->getContentTypeFormat() : $request->getContentType(); + $format = $request->getContentTypeFormat(); $format === 'json' || throw new BadRequestHttpException('Only JSON content type allowed'); $content = $request->getContent(); $excludedCredentials = $hideExistingExcludedCredentials === true ? [] : $this->getCredentials($userEntity); $optionsRequest = $this->getServerPublicKeyCredentialCreationOptionsRequest($content); - $authenticatorSelectionData = $optionsRequest->authenticatorSelection; - $authenticatorSelection = null; - if (is_array($authenticatorSelectionData)) { - $authenticatorSelection = AuthenticatorSelectionCriteria::createFromArray($authenticatorSelectionData); - } elseif ($optionsRequest->userVerification !== null || $optionsRequest->residentKey !== null || $optionsRequest->authenticatorAttachment !== null) { - $residentKey = $optionsRequest->residentKey ?? null; - $requireResidentKey = $optionsRequest->requireResidentKey !== null ? filter_var( - $optionsRequest->requireResidentKey, - FILTER_VALIDATE_BOOLEAN - ) : null; - $authenticatorSelection = AuthenticatorSelectionCriteria::create( - $optionsRequest->authenticatorAttachment, - $optionsRequest->userVerification ?? AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_PREFERRED, - $residentKey, - $requireResidentKey - ); - } + $residentKey = $optionsRequest->residentKey ?? null; + $authenticatorSelection = AuthenticatorSelectionCriteria::create( + $optionsRequest->authenticatorAttachment, + $optionsRequest->userVerification ?? AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_PREFERRED, + $residentKey, + ); $extensions = null; if (is_array($optionsRequest->extensions)) { - $extensions = AuthenticationExtensionsClientInputs::create(array_map( + $extensions = AuthenticationExtensions::create(array_map( static fn (string $name, mixed $data): AuthenticationExtension => AuthenticationExtension::create( $name, $data diff --git a/src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php b/src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php index e0658324..6a26a890 100644 --- a/src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php +++ b/src/symfony/src/CredentialOptionsBuilder/ProfileBasedRequestOptionsBuilder.php @@ -10,7 +10,7 @@ use Symfony\Component\Serializer\SerializerInterface; use Symfony\Component\Validator\Validator\ValidatorInterface; use Webauthn\AuthenticationExtensions\AuthenticationExtension; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; +use Webauthn\AuthenticationExtensions\AuthenticationExtensions; use Webauthn\Bundle\Dto\ServerPublicKeyCredentialRequestOptionsRequest; use Webauthn\Bundle\Repository\PublicKeyCredentialSourceRepositoryInterface; use Webauthn\Bundle\Repository\PublicKeyCredentialUserEntityRepositoryInterface; @@ -19,7 +19,6 @@ use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialRequestOptions; use Webauthn\PublicKeyCredentialSource; -use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; use function count; use function is_array; @@ -30,38 +29,24 @@ public function __construct( private readonly SerializerInterface $serializer, private readonly ValidatorInterface $validator, private readonly PublicKeyCredentialUserEntityRepositoryInterface $userEntityRepository, - private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $credentialSourceRepository, + private readonly PublicKeyCredentialSourceRepositoryInterface $credentialSourceRepository, private readonly PublicKeyCredentialRequestOptionsFactory $publicKeyCredentialRequestOptionsFactory, private readonly string $profile, private readonly null|FakeCredentialGenerator $fakeCredentialGenerator = null, ) { - if (! $this->credentialSourceRepository instanceof PublicKeyCredentialSourceRepositoryInterface) { - trigger_deprecation( - 'web-auth/webauthn-symfony-bundle', - '4.6.0', - sprintf( - 'Since 4.6.0, the parameter "$credentialSourceRepository" expects an instance of "%s". Please implement that interface instead of "%s".', - PublicKeyCredentialSourceRepositoryInterface::class, - PublicKeyCredentialSourceRepository::class - ) - ); - } } public function getFromRequest( Request $request, ?PublicKeyCredentialUserEntity &$userEntity = null ): PublicKeyCredentialRequestOptions { - $format = method_exists( - $request, - 'getContentTypeFormat' - ) ? $request->getContentTypeFormat() : $request->getContentType(); + $format = $request->getContentTypeFormat(); $format === 'json' || throw new BadRequestHttpException('Only JSON content type allowed'); $content = $request->getContent(); $optionsRequest = $this->getServerPublicKeyCredentialRequestOptionsRequest($content); $extensions = null; if (is_array($optionsRequest->extensions)) { - $extensions = AuthenticationExtensionsClientInputs::create(array_map( + $extensions = AuthenticationExtensions::create(array_map( static fn (string $name, mixed $data): AuthenticationExtension => AuthenticationExtension::create( $name, $data diff --git a/src/symfony/src/DataCollector/WebauthnCollector.php b/src/symfony/src/DataCollector/WebauthnCollector.php index 2f7c4366..9972f0b6 100644 --- a/src/symfony/src/DataCollector/WebauthnCollector.php +++ b/src/symfony/src/DataCollector/WebauthnCollector.php @@ -15,12 +15,12 @@ use Symfony\Component\VarDumper\Cloner\Data; use Symfony\Component\VarDumper\Cloner\VarCloner; use Throwable; -use Webauthn\Bundle\Event\AuthenticatorAssertionResponseValidationFailedEvent; -use Webauthn\Bundle\Event\AuthenticatorAssertionResponseValidationSucceededEvent; -use Webauthn\Bundle\Event\AuthenticatorAttestationResponseValidationSucceededEvent; use Webauthn\Bundle\Event\PublicKeyCredentialCreationOptionsCreatedEvent; use Webauthn\Bundle\Event\PublicKeyCredentialRequestOptionsCreatedEvent; +use Webauthn\Event\AuthenticatorAssertionResponseValidationFailedEvent; +use Webauthn\Event\AuthenticatorAssertionResponseValidationSucceededEvent; use Webauthn\Event\AuthenticatorAttestationResponseValidationFailedEvent; +use Webauthn\Event\AuthenticatorAttestationResponseValidationSucceededEvent; use const JSON_PRETTY_PRINT; use const JSON_THROW_ON_ERROR; @@ -190,7 +190,7 @@ public function addAuthenticatorAssertionResponseValidationSucceeded( $cloner = new VarCloner(); $this->authenticatorAssertionResponseValidationSucceeded[] = [ 'user_handle' => $cloner->cloneVar($event->userHandle), - 'credential_id' => $cloner->cloneVar($event->credentialId), + 'credential_id' => $cloner->cloneVar($event->publicKeyCredentialSource->publicKeyCredentialId), 'assertion_response' => $cloner->cloneVar($event->authenticatorAssertionResponse), 'options' => $cloner->cloneVar($event->publicKeyCredentialRequestOptions), 'options_json' => $this->serializer->serialize( @@ -211,7 +211,7 @@ public function addAuthenticatorAssertionResponseValidationFailed( $cloner = new VarCloner(); $this->authenticatorAssertionResponseValidationFailed[] = [ 'user_handle' => $cloner->cloneVar($event->userHandle), - 'credential_id' => $cloner->cloneVar($event->getCredential()?->publicKeyCredentialId), + 'credential_id' => $cloner->cloneVar($event->credentialSource->publicKeyCredentialId), 'assertion_response' => $cloner->cloneVar($event->authenticatorAssertionResponse), 'options' => $cloner->cloneVar($event->publicKeyCredentialRequestOptions), 'options_json' => $this->serializer->serialize( diff --git a/src/symfony/src/DependencyInjection/Compiler/AttestationStatementSupportCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/AttestationStatementSupportCompilerPass.php index 34624701..814b4ca3 100644 --- a/src/symfony/src/DependencyInjection/Compiler/AttestationStatementSupportCompilerPass.php +++ b/src/symfony/src/DependencyInjection/Compiler/AttestationStatementSupportCompilerPass.php @@ -9,9 +9,9 @@ use Symfony\Component\DependencyInjection\Reference; use Webauthn\AttestationStatement\AttestationStatementSupportManager; -final class AttestationStatementSupportCompilerPass implements CompilerPassInterface +final readonly class AttestationStatementSupportCompilerPass implements CompilerPassInterface { - public const TAG = 'webauthn_attestation_statement_support'; + public const string TAG = 'webauthn_attestation_statement_support'; public function process(ContainerBuilder $container): void { diff --git a/src/symfony/src/DependencyInjection/Compiler/CoseAlgorithmCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/CoseAlgorithmCompilerPass.php index 0a05bd24..1701d8ee 100644 --- a/src/symfony/src/DependencyInjection/Compiler/CoseAlgorithmCompilerPass.php +++ b/src/symfony/src/DependencyInjection/Compiler/CoseAlgorithmCompilerPass.php @@ -8,9 +8,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -final class CoseAlgorithmCompilerPass implements CompilerPassInterface +final readonly class CoseAlgorithmCompilerPass implements CompilerPassInterface { - public const TAG = 'webauthn_cose_algorithm'; + public const string TAG = 'webauthn_cose_algorithm'; public function process(ContainerBuilder $container): void { diff --git a/src/symfony/src/DependencyInjection/Compiler/CounterCheckerSetterCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/CounterCheckerSetterCompilerPass.php index 9e0e95e1..e210e860 100644 --- a/src/symfony/src/DependencyInjection/Compiler/CounterCheckerSetterCompilerPass.php +++ b/src/symfony/src/DependencyInjection/Compiler/CounterCheckerSetterCompilerPass.php @@ -7,7 +7,7 @@ use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -use Webauthn\AuthenticatorAssertionResponseValidator; +use Webauthn\CeremonyStep\CeremonyStepManagerFactory; use Webauthn\Counter\CounterChecker; final class CounterCheckerSetterCompilerPass implements CompilerPassInterface @@ -16,12 +16,12 @@ public function process(ContainerBuilder $container): void { if ( ! $container->hasAlias(CounterChecker::class) - || ! $container->hasDefinition(AuthenticatorAssertionResponseValidator::class) + || ! $container->hasDefinition(CeremonyStepManagerFactory::class) ) { return; } - $definition = $container->getDefinition(AuthenticatorAssertionResponseValidator::class); + $definition = $container->getDefinition(CeremonyStepManagerFactory::class); $definition->addMethodCall('setCounterChecker', [new Reference(CounterChecker::class)]); } } diff --git a/src/symfony/src/DependencyInjection/Compiler/DynamicRouteCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/DynamicRouteCompilerPass.php index e2a4fede..33844329 100644 --- a/src/symfony/src/DependencyInjection/Compiler/DynamicRouteCompilerPass.php +++ b/src/symfony/src/DependencyInjection/Compiler/DynamicRouteCompilerPass.php @@ -10,9 +10,9 @@ use Webauthn\Bundle\Routing\Loader; use function array_key_exists; -final class DynamicRouteCompilerPass implements CompilerPassInterface +final readonly class DynamicRouteCompilerPass implements CompilerPassInterface { - public const TAG = 'webauthn_controller'; + public const string TAG = 'webauthn_controller'; public function process(ContainerBuilder $container): void { diff --git a/src/symfony/src/DependencyInjection/Compiler/EnforcedSafetyNetApiKeyVerificationCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/EnforcedSafetyNetApiKeyVerificationCompilerPass.php deleted file mode 100644 index b767e500..00000000 --- a/src/symfony/src/DependencyInjection/Compiler/EnforcedSafetyNetApiKeyVerificationCompilerPass.php +++ /dev/null @@ -1,39 +0,0 @@ -hasDefinition(AndroidSafetyNetAttestationStatementSupport::class) - || ! $container->hasAlias('webauthn.android_safetynet.http_client') - || ! $container->hasParameter('webauthn.android_safetynet.api_key') - || $container->getParameter('webauthn.android_safetynet.api_key') === null - ) { - return; - } - - $requestFactoryReference = null; - if ($container->hasAlias('webauthn.android_safetynet.request_factory')) { - $requestFactoryReference = new Reference('webauthn.android_safetynet.request_factory'); - } - - $definition = $container->getDefinition(AndroidSafetyNetAttestationStatementSupport::class); - $definition->addMethodCall('enableApiVerification', [ - new Reference('webauthn.android_safetynet.http_client'), - $container->getParameter('webauthn.android_safetynet.api_key'), - $requestFactoryReference, - ]); - } -} diff --git a/src/symfony/src/DependencyInjection/Compiler/EventDispatcherSetterCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/EventDispatcherSetterCompilerPass.php index d60039b5..f99323db 100644 --- a/src/symfony/src/DependencyInjection/Compiler/EventDispatcherSetterCompilerPass.php +++ b/src/symfony/src/DependencyInjection/Compiler/EventDispatcherSetterCompilerPass.php @@ -8,9 +8,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -final class EventDispatcherSetterCompilerPass implements CompilerPassInterface +final readonly class EventDispatcherSetterCompilerPass implements CompilerPassInterface { - public const TAG = 'webauthn_can_dispatch_events'; + public const string TAG = 'webauthn_can_dispatch_events'; public function process(ContainerBuilder $container): void { diff --git a/src/symfony/src/DependencyInjection/Compiler/ExtensionOutputCheckerCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/ExtensionOutputCheckerCompilerPass.php index 15841f43..6dacf6b3 100644 --- a/src/symfony/src/DependencyInjection/Compiler/ExtensionOutputCheckerCompilerPass.php +++ b/src/symfony/src/DependencyInjection/Compiler/ExtensionOutputCheckerCompilerPass.php @@ -9,9 +9,9 @@ use Symfony\Component\DependencyInjection\Reference; use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler; -final class ExtensionOutputCheckerCompilerPass implements CompilerPassInterface +final readonly class ExtensionOutputCheckerCompilerPass implements CompilerPassInterface { - public const TAG = 'webauthn_extension_output_checker'; + public const string TAG = 'webauthn_extension_output_checker'; public function process(ContainerBuilder $container): void { diff --git a/src/symfony/src/DependencyInjection/Compiler/LoggerSetterCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/LoggerSetterCompilerPass.php index cc1a4f94..e138dec4 100644 --- a/src/symfony/src/DependencyInjection/Compiler/LoggerSetterCompilerPass.php +++ b/src/symfony/src/DependencyInjection/Compiler/LoggerSetterCompilerPass.php @@ -8,9 +8,9 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; -final class LoggerSetterCompilerPass implements CompilerPassInterface +final readonly class LoggerSetterCompilerPass implements CompilerPassInterface { - public const TAG = 'webauthn_can_log_data'; + public const string TAG = 'webauthn_can_log_data'; public function process(ContainerBuilder $container): void { diff --git a/src/symfony/src/DependencyInjection/Compiler/MetadataStatementSupportCompilerPass.php b/src/symfony/src/DependencyInjection/Compiler/MetadataStatementSupportCompilerPass.php deleted file mode 100644 index 72aaa65f..00000000 --- a/src/symfony/src/DependencyInjection/Compiler/MetadataStatementSupportCompilerPass.php +++ /dev/null @@ -1,39 +0,0 @@ -hasAlias(MetadataStatementRepository::class) - || ! $container->hasAlias(CertificateChainValidator::class) - || ! $container->hasAlias(StatusReportRepository::class) - ) { - return; - } - if (! $container->hasDefinition(AuthenticatorAttestationResponseValidator::class)) { - return; - } - - $definition = $container->getDefinition(AuthenticatorAttestationResponseValidator::class); - $definition->addMethodCall( - 'enableMetadataStatementSupport', - [ - new Reference(MetadataStatementRepository::class), - new Reference(StatusReportRepository::class), - new Reference(CertificateChainValidator::class), - ] - ); - } -} diff --git a/src/symfony/src/DependencyInjection/Configuration.php b/src/symfony/src/DependencyInjection/Configuration.php index b1031004..48c4322d 100644 --- a/src/symfony/src/DependencyInjection/Configuration.php +++ b/src/symfony/src/DependencyInjection/Configuration.php @@ -9,7 +9,6 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Contracts\HttpClient\HttpClientInterface; use Webauthn\AuthenticatorSelectionCriteria; use Webauthn\Bundle\Repository\DummyPublicKeyCredentialSourceRepository; use Webauthn\Bundle\Repository\DummyPublicKeyCredentialUserEntityRepository; @@ -54,15 +53,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->end(); $rootNode->children() - ->scalarNode('http_message_factory') - ->setDeprecated( - 'web-auth/webauthn-symfony-bundle', - '4.5.0', - 'The class "http_message_factory" configuration option is deprecated since 4.5.0 and will be removed in 5.0.0. Not needed anymore.' - ) - ->defaultNull() - ->info('Creates PSR-7 HTTP Request and Response instances from Symfony ones.') - ->end() ->scalarNode('fake_credential_generator') ->defaultValue(SimpleFakeCredentialGenerator::class) ->cannotBeEmpty() @@ -78,10 +68,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->defaultValue(EventDispatcherInterface::class) ->info('PSR-14 Event Dispatcher service.') ->end() - ->scalarNode('request_factory') - ->defaultNull() - ->info('PSR-17 Request Factory.') - ->end() ->scalarNode('http_client') ->cannotBeEmpty() ->defaultValue('webauthn.http_client.default') @@ -101,11 +87,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->defaultValue(DummyPublicKeyCredentialUserEntityRepository::class) ->info('This repository is responsible of the user storage') ->end() - ->scalarNode('token_binding_support_handler') - ->defaultNull() - ->setDeprecated('web-auth/webauthn-symfony-bundle', '4.3.0') - ->info('This handler will check the token binding header from the request. By default, it is ignored.') - ->end() ->arrayNode('secured_rp_ids') ->treatFalseLike(null) ->treatTrueLike(null) @@ -131,7 +112,6 @@ public function getConfigTreeBuilder(): TreeBuilder $this->addRequestProfilesConfig($rootNode); $this->addMetadataConfig($rootNode); $this->addControllersConfig($rootNode); - $this->addAndroidSafetynetConfig($rootNode); return $treeBuilder; } @@ -192,18 +172,6 @@ private function addCreationProfilesConfig(ArrayNodeDefinition $rootNode): void }) ->end() ->children() - ->scalarNode('attachment_mode') - ->setDeprecated('web-auth/webauthn-symfony-bundle', '4.7.0', 'Use "authenticator_attachment" instead') - ->defaultValue(AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE) - ->validate() - ->ifNotInArray([ - AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE, - AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM, - AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM, - ]) - ->thenInvalid($errorTemplate) - ->end() - ->end() ->scalarNode('authenticator_attachment') ->defaultValue(AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE) ->validate() @@ -469,42 +437,4 @@ private function addMetadataConfig(ArrayNodeDefinition $rootNode): void ->end() ->end(); } - - /** - * @deprecated since 4.9.0 and will be removed in 5.0.0. Android SafetyNet is now deprecated. - */ - private function addAndroidSafetynetConfig(ArrayNodeDefinition $rootNode): void - { - $rootNode->children() - ->arrayNode('android_safetynet') - ->setDeprecated('web-auth/webauthn-symfony-bundle', '4.9.0', 'Android SafetyNet is now deprecated.') - ->addDefaultsIfNotSet() - ->info('Additional configuration options for the Android SafetyNet attestation.') - ->children() - ->integerNode('leeway') - ->defaultValue(0) - ->min(0) - ->info( - 'Leeway for timestamp verification in response (in millisecond). At least 2000 msec are recommended.' - ) - ->end() - ->integerNode('max_age') - ->min(0) - ->defaultValue(60000) - ->info('Maximum age of the response (in millisecond)') - ->end() - ->scalarNode('api_key') - ->defaultNull() - ->info( - 'If set, the application will verify the statements using Google API. See https://console.cloud.google.com/apis/library to get it.' - ) - ->end() - ->scalarNode('http_client') - ->defaultValue(HttpClientInterface::class) - ->info('Symfony client to use to send the request to Google API.') - ->end() - ->end() - ->end() - ->end(); - } } diff --git a/src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php b/src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php index 7daae1b1..a37af7bb 100644 --- a/src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php +++ b/src/symfony/src/DependencyInjection/Factory/Security/WebauthnFactory.php @@ -40,78 +40,54 @@ use function array_key_exists; use function assert; -final class WebauthnFactory implements FirewallListenerFactoryInterface, AuthenticatorFactoryInterface +final readonly class WebauthnFactory implements FirewallListenerFactoryInterface, AuthenticatorFactoryInterface { - public const AUTHENTICATION_PROVIDER_KEY = 'webauthn'; + public const string AUTHENTICATION_PROVIDER_KEY = 'webauthn'; - public const AUTHENTICATOR_ID_PREFIX = 'security.authenticator.webauthn.'; + public const string AUTHENTICATOR_ID_PREFIX = 'security.authenticator.webauthn.'; - public const AUTHENTICATOR_DEFINITION_ID = 'webauthn.security.authenticator'; + public const string AUTHENTICATOR_DEFINITION_ID = 'webauthn.security.authenticator'; - public const DEFAULT_SESSION_STORAGE_SERVICE = SessionStorage::class; + public const string DEFAULT_SESSION_STORAGE_SERVICE = SessionStorage::class; - public const DEFAULT_SUCCESS_HANDLER_SERVICE = DefaultSuccessHandler::class; + public const string DEFAULT_SUCCESS_HANDLER_SERVICE = DefaultSuccessHandler::class; - public const DEFAULT_FAILURE_HANDLER_SERVICE = DefaultFailureHandler::class; + public const string DEFAULT_FAILURE_HANDLER_SERVICE = DefaultFailureHandler::class; - public const DEFAULT_LOGIN_OPTIONS_METHOD = Request::METHOD_POST; + public const string DEFAULT_LOGIN_OPTIONS_METHOD = Request::METHOD_POST; - public const DEFAULT_LOGIN_OPTIONS_PATH = '/login/options'; + public const string DEFAULT_LOGIN_OPTIONS_PATH = '/login/options'; - public const DEFAULT_LOGIN_RESULT_METHOD = Request::METHOD_POST; + public const string DEFAULT_LOGIN_RESULT_METHOD = Request::METHOD_POST; - public const DEFAULT_LOGIN_RESULT_PATH = '/login'; + public const string DEFAULT_LOGIN_RESULT_PATH = '/login'; - public const DEFAULT_REQUEST_OPTIONS_HANDLER_SERVICE = DefaultRequestOptionsHandler::class; + public const string DEFAULT_REQUEST_OPTIONS_HANDLER_SERVICE = DefaultRequestOptionsHandler::class; - public const DEFAULT_REGISTER_OPTIONS_METHOD = Request::METHOD_POST; + public const string DEFAULT_REGISTER_OPTIONS_METHOD = Request::METHOD_POST; - public const DEFAULT_REGISTER_OPTIONS_PATH = '/register/options'; + public const string DEFAULT_REGISTER_OPTIONS_PATH = '/register/options'; - public const DEFAULT_REGISTER_RESULT_METHOD = Request::METHOD_POST; + public const string DEFAULT_REGISTER_RESULT_METHOD = Request::METHOD_POST; - public const DEFAULT_REGISTER_RESULT_PATH = '/register'; + public const string DEFAULT_REGISTER_RESULT_PATH = '/register'; - public const DEFAULT_CREATION_OPTIONS_HANDLER_SERVICE = DefaultCreationOptionsHandler::class; + public const string DEFAULT_CREATION_OPTIONS_HANDLER_SERVICE = DefaultCreationOptionsHandler::class; - public const FIREWALL_CONFIG_ID_PREFIX = 'security.firewall_config.webauthn.'; + public const string FIREWALL_CONFIG_ID_PREFIX = 'security.firewall_config.webauthn.'; - public const AUTHENTICATOR_ATTESTATION_RESPONSE_VALIDATOR_ID_PREFIX = 'security.authenticator_attestation_response_validator.webauthn.'; + public const string AUTHENTICATOR_ATTESTATION_RESPONSE_VALIDATOR_ID_PREFIX = 'security.authenticator_attestation_response_validator.webauthn.'; - public const AUTHENTICATOR_ASSERTION_RESPONSE_VALIDATOR_ID_PREFIX = 'security.authenticator_assertion_response_validator.webauthn.'; + public const string AUTHENTICATOR_ASSERTION_RESPONSE_VALIDATOR_ID_PREFIX = 'security.authenticator_assertion_response_validator.webauthn.'; - public const CEREMONY_STEP_MANAGER_ID_PREFIX = 'security.ceremony_step_manager.webauthn.'; + public const string CEREMONY_STEP_MANAGER_ID_PREFIX = 'security.ceremony_step_manager.webauthn.'; - public const FIREWALL_CONFIG_DEFINITION_ID = 'webauthn.security.firewall_config'; + public const string FIREWALL_CONFIG_DEFINITION_ID = 'webauthn.security.firewall_config'; - /** - * @deprecated This constant is not used anymore and will be removed in 5.0 - * @infection-ignore-all - */ - public const REQUEST_RESULT_LISTENER_DEFINITION_ID = 'webauthn.security.authentication.request_result_listener'; - - /** - * @deprecated This constant is not used anymore and will be removed in 5.0 - * @infection-ignore-all - */ - public const CREATION_RESULT_LISTENER_DEFINITION_ID = 'webauthn.security.authentication.creation_result_listener'; - - /** - * @deprecated This constant is not used anymore and will be removed in 5.0 - * @infection-ignore-all - */ - public const SUCCESS_HANDLER_ID_PREFIX = 'security.authentication.success_handler.webauthn.'; - - /** - * @deprecated This constant is not used anymore and will be removed in 5.0 - * @infection-ignore-all - */ - public const FAILURE_HANDLER_ID_PREFIX = 'security.authentication.failure_handler.webauthn.'; - - private const PRIORITY = 0; + private const int PRIORITY = 0; public function __construct( - private readonly WebauthnServicesFactory $servicesFactory + private WebauthnServicesFactory $servicesFactory ) { } @@ -225,14 +201,14 @@ public function addConfiguration(NodeDefinition $builder): void /** * Creates the authenticator service(s) for the provided configuration. * - * @return string|string[] The authenticator service ID(s) to be used by the firewall + * @return string The authenticator service ID to be used by the firewall */ public function createAuthenticator( ContainerBuilder $container, string $firewallName, array $config, string $userProviderId - ): string|array { + ): string { $firewallConfigId = $this->servicesFactory->createWebauthnFirewallConfig($container, $firewallName, $config); $authenticatorAssertionResponseValidatorId = $this->servicesFactory->createAuthenticatorAssertionResponseValidator( $container, @@ -264,6 +240,7 @@ public function createAuthenticator( /** * Creates the firewall listener services for the provided configuration. * + * @param array $config * @return string[] The listener service IDs to be used by the firewall */ public function createListeners(ContainerBuilder $container, string $firewallName, array $config): array @@ -298,7 +275,7 @@ private function createAuthenticatorService( } /** - * @param mixed[] $config + * @param array $config */ private function createAssertionControllersAndRoutes( ContainerBuilder $container, @@ -332,7 +309,7 @@ private function createAssertionControllersAndRoutes( } /** - * @param mixed[] $config + * @param array $config */ private function createAttestationControllersAndRoutes( ContainerBuilder $container, @@ -475,6 +452,9 @@ private function createControllerAndRoute( $container->setDefinition($controllerId, $controller); } + /** + * @param array $config + */ private function getAssertionOptionsBuilderId( ContainerBuilder $container, string $firewallName, @@ -500,6 +480,9 @@ private function getAssertionOptionsBuilderId( return $optionsBuilderId; } + /** + * @param array $config + */ private function getAttestationOptionsBuilderId( ContainerBuilder $container, string $firewallName, diff --git a/src/symfony/src/DependencyInjection/Factory/Security/WebauthnServicesFactory.php b/src/symfony/src/DependencyInjection/Factory/Security/WebauthnServicesFactory.php index c429f0b1..d9c0dbb5 100644 --- a/src/symfony/src/DependencyInjection/Factory/Security/WebauthnServicesFactory.php +++ b/src/symfony/src/DependencyInjection/Factory/Security/WebauthnServicesFactory.php @@ -57,8 +57,9 @@ public function createAuthenticatorAssertionResponseValidator( $authenticatorAssertionResponseValidatorId, new Definition(AuthenticatorAssertionResponseValidator::class) ) - ->setArguments([null, null, null, null, null, new Reference($ceremonyStepManagerId)]) - ->addTag(EventDispatcherSetterCompilerPass::TAG); + ->setArguments([new Reference($ceremonyStepManagerId)]) + ->addTag(EventDispatcherSetterCompilerPass::TAG) + ; return $authenticatorAssertionResponseValidatorId; } @@ -84,8 +85,9 @@ public function createAuthenticatorAttestationResponseValidator( $authenticatorAttestationResponseValidatorId, new Definition(AuthenticatorAttestationResponseValidator::class) ) - ->setArguments([null, null, null, null, null, new Reference($ceremonyStepManagerId)]) - ->addTag(EventDispatcherSetterCompilerPass::TAG); + ->setArguments([new Reference($ceremonyStepManagerId)]) + ->addTag(EventDispatcherSetterCompilerPass::TAG) + ; return $authenticatorAttestationResponseValidatorId; } diff --git a/src/symfony/src/DependencyInjection/WebauthnExtension.php b/src/symfony/src/DependencyInjection/WebauthnExtension.php index 8c92df26..8dceaba9 100644 --- a/src/symfony/src/DependencyInjection/WebauthnExtension.php +++ b/src/symfony/src/DependencyInjection/WebauthnExtension.php @@ -38,7 +38,6 @@ use Webauthn\Bundle\DependencyInjection\Compiler\LoggerSetterCompilerPass; use Webauthn\Bundle\Doctrine\Type as DbalType; use Webauthn\Bundle\Repository\PublicKeyCredentialSourceRepositoryInterface; -use Webauthn\Bundle\Repository\PublicKeyCredentialUserEntityRepository; use Webauthn\Bundle\Repository\PublicKeyCredentialUserEntityRepositoryInterface; use Webauthn\Bundle\Service\PublicKeyCredentialCreationOptionsFactory; use Webauthn\Bundle\Service\PublicKeyCredentialRequestOptionsFactory; @@ -52,8 +51,6 @@ use Webauthn\MetadataService\Event\CanDispatchEvents; use Webauthn\MetadataService\MetadataStatementRepository; use Webauthn\MetadataService\StatusReportRepository; -use Webauthn\PublicKeyCredentialSourceRepository; -use Webauthn\TokenBinding\TokenBindingHandler; use function array_key_exists; use function count; use function is_array; @@ -93,9 +90,6 @@ public function load(array $configs, ContainerBuilder $container): void $container->setParameter('webauthn.secured_relying_party_ids', $config['secured_rp_ids']); $container->setAlias('webauthn.event_dispatcher', $config['event_dispatcher']); $container->setAlias('webauthn.clock', $config['clock']); - if ($config['request_factory'] !== null) { - $container->setAlias('webauthn.request_factory', $config['request_factory']); - } if ($config['top_origin_validator'] !== null) { $container->setAlias(TopOriginValidator::class, $config['top_origin_validator']); } @@ -103,18 +97,12 @@ public function load(array $configs, ContainerBuilder $container): void $container->setAlias('webauthn.logger', $config['logger']); $container->setAlias(FakeCredentialGenerator::class, $config['fake_credential_generator']); - $container->setAlias(PublicKeyCredentialSourceRepository::class, $config['credential_repository']); $container->setAlias(PublicKeyCredentialSourceRepositoryInterface::class, $config['credential_repository']); - $container->setAlias(PublicKeyCredentialUserEntityRepository::class, $config['user_repository']); $container->setAlias(PublicKeyCredentialUserEntityRepositoryInterface::class, $config['user_repository']); - if ($config['token_binding_support_handler'] !== null) { - $container->setAlias(TokenBindingHandler::class, $config['token_binding_support_handler']); - } $container->setAlias(CounterChecker::class, $config['counter_checker']); $loader = new PhpFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config/')); - $this->loadAndroidSafetyNet($container, $loader, $config['android_safetynet']); $this->loadMetadataServices($container, $loader, $config['metadata']); $this->loadControllersSupport($container, $config['controllers']); @@ -240,15 +228,7 @@ private function loadCreationControllersSupport(ContainerBuilder $container, arr $name ); $attestationResponseValidator = new Definition(AuthenticatorAttestationResponseValidator::class); - $attestationResponseValidator->setArguments([ - null, - null, - null, - null, - null, - new Reference($creationCeremonyStepManagerId), - ]); - $attestationResponseValidator->addTag(EventDispatcherSetterCompilerPass::TAG); + $attestationResponseValidator->setArguments([new Reference($creationCeremonyStepManagerId)]); $container->setDefinition($attestationResponseValidatorId, $attestationResponseValidator); $attestationResponseControllerId = sprintf('webauthn.controller.creation.response.%s', $name); @@ -328,14 +308,7 @@ private function loadRequestControllersSupport(ContainerBuilder $container, arra $name ); $assertionResponseValidator = new Definition(AuthenticatorAssertionResponseValidator::class); - $assertionResponseValidator->setArguments([ - null, - null, - null, - null, - null, - new Reference($requestCeremonyStepManagerId), - ]); + $assertionResponseValidator->setArguments([new Reference($requestCeremonyStepManagerId)]); $assertionResponseValidator->addTag(EventDispatcherSetterCompilerPass::TAG); $container->setDefinition($assertionResponseValidatorId, $assertionResponseValidator); @@ -361,20 +334,6 @@ private function loadRequestControllersSupport(ContainerBuilder $container, arra } } - /** - * @deprecated since 4.9.0 and will be removed in 5.0.0. Android SafetyNet is now deprecated. - * @param mixed[] $config - */ - private function loadAndroidSafetyNet(ContainerBuilder $container, FileLoader $loader, array $config): void - { - //Android SafetyNet - $container->setAlias('webauthn.android_safetynet.http_client', $config['http_client']); - $container->setParameter('webauthn.android_safetynet.leeway', $config['leeway']); - $container->setParameter('webauthn.android_safetynet.max_age', $config['max_age']); - $container->setParameter('webauthn.android_safetynet.api_key', $config['api_key']); - $loader->load('android_safetynet.php'); - } - /** * @param mixed[] $config */ diff --git a/src/symfony/src/Doctrine/Type/AAGUIDDataType.php b/src/symfony/src/Doctrine/Type/AAGUIDDataType.php index 58436046..6d418a3c 100644 --- a/src/symfony/src/Doctrine/Type/AAGUIDDataType.php +++ b/src/symfony/src/Doctrine/Type/AAGUIDDataType.php @@ -7,25 +7,31 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\Type; use Symfony\Component\Uid\Uuid; +use function is_string; final class AAGUIDDataType extends Type { public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string { - if (! $value instanceof Uuid) { + if (is_string($value)) { return $value; } - - return $value->__toString(); + if ($value instanceof Uuid) { + return $value->__toString(); + } + return null; } public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Uuid { - if ($value instanceof Uuid || mb_strlen((string) $value, '8bit') !== 36) { + if ($value instanceof Uuid) { return $value; } + if (is_string($value)) { + return Uuid::fromString($value); + } - return Uuid::fromString($value); + return null; } public function getSQLDeclaration(array $column, AbstractPlatform $platform): string diff --git a/src/symfony/src/Doctrine/Type/AttestedCredentialDataType.php b/src/symfony/src/Doctrine/Type/AttestedCredentialDataType.php index 4130b04f..3687e0fa 100644 --- a/src/symfony/src/Doctrine/Type/AttestedCredentialDataType.php +++ b/src/symfony/src/Doctrine/Type/AttestedCredentialDataType.php @@ -7,6 +7,8 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\Type; use Webauthn\AttestedCredentialData; +use function is_array; +use function is_string; use const JSON_THROW_ON_ERROR; final class AttestedCredentialDataType extends Type @@ -16,8 +18,14 @@ public function convertToDatabaseValue($value, AbstractPlatform $platform): ?str if ($value === null) { return $value; } + if (is_string($value)) { + return $value; + } + if ($value instanceof AttestedCredentialData) { + return json_encode($value, JSON_THROW_ON_ERROR); + } - return json_encode($value, JSON_THROW_ON_ERROR); + return null; } public function convertToPHPValue($value, AbstractPlatform $platform): ?AttestedCredentialData @@ -25,9 +33,14 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?Attested if ($value === null || $value instanceof AttestedCredentialData) { return $value; } - $json = json_decode((string) $value, true, flags: JSON_THROW_ON_ERROR); + if (is_string($value)) { + $json = json_decode($value, true, 512, JSON_THROW_ON_ERROR); + if (is_array($json)) { + return AttestedCredentialData::createFromArray($json); + } + } - return AttestedCredentialData::createFromArray($json); + return null; } public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string diff --git a/src/symfony/src/Doctrine/Type/Base64BinaryDataType.php b/src/symfony/src/Doctrine/Type/Base64BinaryDataType.php index 593e4567..8bed545a 100644 --- a/src/symfony/src/Doctrine/Type/Base64BinaryDataType.php +++ b/src/symfony/src/Doctrine/Type/Base64BinaryDataType.php @@ -14,7 +14,7 @@ final class Base64BinaryDataType extends Type public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string { if (! is_string($value)) { - return $value; + return null; } return Base64::encode($value); @@ -22,11 +22,11 @@ public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform) public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?string { - if ($value === null) { - return $value; + if (is_string($value)) { + return Base64::decode($value, true); } - return Base64::decode($value, true); + return null; } public function getSQLDeclaration(array $column, AbstractPlatform $platform): string diff --git a/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php b/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php index 70b796e8..3e53d3d0 100644 --- a/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php +++ b/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorCollection.php @@ -11,8 +11,9 @@ use IteratorAggregate; use JsonSerializable; use Webauthn\PublicKeyCredentialDescriptor; -use function array_key_exists; +use function assert; use function count; +use function is_array; use const COUNT_NORMAL; use const JSON_THROW_ON_ERROR; @@ -20,28 +21,27 @@ * @implements IteratorAggregate * @internal */ -final class PublicKeyCredentialDescriptorCollection implements JsonSerializable, Countable, IteratorAggregate +final readonly class PublicKeyCredentialDescriptorCollection implements JsonSerializable, Countable, IteratorAggregate { /** * @var array - * @readonly */ public array $publicKeyCredentialDescriptors; /** - * @private * @param PublicKeyCredentialDescriptor[] $pkCredentialDescriptors */ public function __construct( array $pkCredentialDescriptors = [] ) { - $this->publicKeyCredentialDescriptors = []; + $result = []; foreach ($pkCredentialDescriptors as $pkCredentialDescriptor) { $pkCredentialDescriptor instanceof PublicKeyCredentialDescriptor || throw new InvalidArgumentException( 'Expected only instances of ' . PublicKeyCredentialDescriptor::class ); - $this->publicKeyCredentialDescriptors[$pkCredentialDescriptor->id] = $pkCredentialDescriptor; + $result[$pkCredentialDescriptor->id] = $pkCredentialDescriptor; } + $this->publicKeyCredentialDescriptors = $result; } /** @@ -52,39 +52,6 @@ public static function create(array $publicKeyCredentialDescriptors): self return new self($publicKeyCredentialDescriptors); } - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function add(PublicKeyCredentialDescriptor ...$publicKeyCredentialDescriptors): void - { - foreach ($publicKeyCredentialDescriptors as $publicKeyCredentialDescriptor) { - $this->publicKeyCredentialDescriptors[$publicKeyCredentialDescriptor->id] = $publicKeyCredentialDescriptor; - } - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function has(string $id): bool - { - return array_key_exists($id, $this->publicKeyCredentialDescriptors); - } - - /** - * @deprecated since 4.7.0. No replacement. - * @infection-ignore-all - */ - public function remove(string $id): void - { - if (! array_key_exists($id, $this->publicKeyCredentialDescriptors)) { - return; - } - - unset($this->publicKeyCredentialDescriptors[$id]); - } - /** * @return Iterator */ @@ -99,7 +66,7 @@ public function count(int $mode = COUNT_NORMAL): int } /** - * @return array[] + * @return array */ public function jsonSerialize(): array { @@ -109,6 +76,7 @@ public function jsonSerialize(): array public static function createFromString(string $data): self { $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); + assert(is_array($data), 'Invalid data. Expected an array of PublicKeyCredentialDescriptor'); return self::createFromArray($data); } @@ -120,9 +88,10 @@ public static function createFromArray(array $json): self { return self::create( array_map( - static fn (array $item): PublicKeyCredentialDescriptor => PublicKeyCredentialDescriptor::createFromArray( - $item - ), + static function (mixed $item): PublicKeyCredentialDescriptor { + assert(is_array($item), 'Invalid data. Expected an array of PublicKeyCredentialDescriptor'); + return PublicKeyCredentialDescriptor::createFromArray($item); + }, $json ) ); diff --git a/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorType.php b/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorType.php index 85ef449f..8c2e993c 100644 --- a/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorType.php +++ b/src/symfony/src/Doctrine/Type/PublicKeyCredentialDescriptorType.php @@ -7,12 +7,16 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Types\Type; use Webauthn\PublicKeyCredentialDescriptor; +use function is_string; use const JSON_THROW_ON_ERROR; final class PublicKeyCredentialDescriptorType extends Type { public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string { + if (is_string($value)) { + return $value; + } if ($value === null) { return $value; } @@ -25,6 +29,9 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?PublicKe if ($value === null || $value instanceof PublicKeyCredentialDescriptor) { return $value; } + if (! is_string($value)) { + return null; + } return PublicKeyCredentialDescriptor::createFromString($value); } diff --git a/src/symfony/src/Doctrine/Type/TrustPathDataType.php b/src/symfony/src/Doctrine/Type/TrustPathDataType.php index 677dfc6c..cd4b8deb 100644 --- a/src/symfony/src/Doctrine/Type/TrustPathDataType.php +++ b/src/symfony/src/Doctrine/Type/TrustPathDataType.php @@ -8,17 +8,22 @@ use Doctrine\DBAL\Types\Type; use Webauthn\TrustPath\TrustPath; use Webauthn\TrustPath\TrustPathLoader; +use function is_array; +use function is_string; use const JSON_THROW_ON_ERROR; final class TrustPathDataType extends Type { public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string { - if ($value === null) { + if ($value === null || is_string($value)) { return $value; } + if ($value instanceof TrustPath) { + return json_encode($value, JSON_THROW_ON_ERROR); + } - return json_encode($value, JSON_THROW_ON_ERROR); + return null; } public function convertToPHPValue($value, AbstractPlatform $platform): ?TrustPath @@ -26,7 +31,13 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?TrustPat if ($value === null || $value instanceof TrustPath) { return $value; } - $json = json_decode((string) $value, true, flags: JSON_THROW_ON_ERROR); + if (! is_string($value)) { + return null; + } + $json = json_decode($value, true, flags: JSON_THROW_ON_ERROR); + if (! is_array($json)) { + return null; + } return TrustPathLoader::loadTrustPath($json); } diff --git a/src/symfony/src/Dto/AdditionalPublicKeyCredentialCreationOptionsRequest.php b/src/symfony/src/Dto/AdditionalPublicKeyCredentialCreationOptionsRequest.php deleted file mode 100644 index 90b0881c..00000000 --- a/src/symfony/src/Dto/AdditionalPublicKeyCredentialCreationOptionsRequest.php +++ /dev/null @@ -1,13 +0,0 @@ -|null - * - * @deprecated Use $userVerification, $residentKey and $authenticatorAttachment - * @infection-ignore-all - */ - public ?array $authenticatorSelection = null; - #[NotBlank(allowNull: true)] #[Choice(choices: [ PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE, @@ -44,9 +36,6 @@ class PublicKeyCredentialCreationOptionsRequest ])] public ?string $residentKey = null; - #[NotBlank(allowNull: true)] - public ?string $requireResidentKey = null; - #[NotBlank(allowNull: true)] #[Choice(choices: [ AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE, diff --git a/src/symfony/src/Event/AuthenticatorAssertionResponseValidationFailedEvent.php b/src/symfony/src/Event/AuthenticatorAssertionResponseValidationFailedEvent.php deleted file mode 100644 index b7e5c0da..00000000 --- a/src/symfony/src/Event/AuthenticatorAssertionResponseValidationFailedEvent.php +++ /dev/null @@ -1,46 +0,0 @@ -publicKeyCredentialCreationOptions; - } } diff --git a/src/symfony/src/Event/PublicKeyCredentialRequestOptionsCreatedEvent.php b/src/symfony/src/Event/PublicKeyCredentialRequestOptionsCreatedEvent.php index 80b3794a..7d9bd363 100644 --- a/src/symfony/src/Event/PublicKeyCredentialRequestOptionsCreatedEvent.php +++ b/src/symfony/src/Event/PublicKeyCredentialRequestOptionsCreatedEvent.php @@ -18,12 +18,4 @@ public static function create(PublicKeyCredentialRequestOptions $publicKeyCreden { return new self($publicKeyCredentialRequestOptions); } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getPublicKeyCredentialRequestOptions(): PublicKeyCredentialRequestOptions - { - return $this->publicKeyCredentialRequestOptions; - } } diff --git a/src/symfony/src/Repository/CanRegisterUserEntity.php b/src/symfony/src/Repository/CanRegisterUserEntity.php index e928edbc..d97b1a7a 100644 --- a/src/symfony/src/Repository/CanRegisterUserEntity.php +++ b/src/symfony/src/Repository/CanRegisterUserEntity.php @@ -8,11 +8,5 @@ interface CanRegisterUserEntity { - /** - * @deprecated since 4.7.0 and will be removed in 5.0.0. Please use Webauthn\Bundle\Repository\CanGenerateUserEntity::generateUserEntity() instead. - * @infection-ignore-all - */ - public function generateNextUserEntityId(): string; - public function saveUserEntity(PublicKeyCredentialUserEntity $userEntity): void; } diff --git a/src/symfony/src/Repository/DoctrineCredentialSourceRepository.php b/src/symfony/src/Repository/DoctrineCredentialSourceRepository.php index f64da34b..4a2b69da 100644 --- a/src/symfony/src/Repository/DoctrineCredentialSourceRepository.php +++ b/src/symfony/src/Repository/DoctrineCredentialSourceRepository.php @@ -42,36 +42,20 @@ public function saveCredentialSource(PublicKeyCredentialSource $publicKeyCredent ->flush(); } + /** + * @return array + */ public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity): array { - return $this->getEntityManager() - ->createQueryBuilder() - ->from($this->class, 'c') - ->select('c') - ->where('c.userHandle = :userHandle') - ->setParameter(':userHandle', $publicKeyCredentialUserEntity->id) - ->getQuery() - ->execute(); + return $this->findBy([ + 'userHandle' => $publicKeyCredentialUserEntity->id, + ]); } public function findOneByCredentialId(string $publicKeyCredentialId): ?PublicKeyCredentialSource { - return $this->getEntityManager() - ->createQueryBuilder() - ->from($this->class, 'c') - ->select('c') - ->where('c.publicKeyCredentialId = :publicKeyCredentialId') - ->setParameter(':publicKeyCredentialId', base64_encode($publicKeyCredentialId)) - ->setMaxResults(1) - ->getQuery() - ->getOneOrNullResult(); - } - - /** - * @deprecated since 4.7.2 and will be removed in 5.0.0. Please use the property instead. - */ - protected function getClass(): string - { - return $this->class; + return $this->findOneBy([ + 'publicKeyCredentialId' => base64_encode($publicKeyCredentialId), + ]); } } diff --git a/src/symfony/src/Repository/PublicKeyCredentialSourceRepository.php b/src/symfony/src/Repository/PublicKeyCredentialSourceRepository.php deleted file mode 100644 index 4e31bec8..00000000 --- a/src/symfony/src/Repository/PublicKeyCredentialSourceRepository.php +++ /dev/null @@ -1,15 +0,0 @@ -=5.0.0: Remove this file -return static function (ContainerConfigurator $container): void { - $container = $container->services() - ->defaults() - ->private() - ->autoconfigure(); - - if (class_exists(JWKFactory::class) && class_exists(RS256::class)) { - $container - ->set(AndroidSafetyNetAttestationStatementSupport::class) - ->deprecate( - 'web-auth/webauthn-symfony-bundle', - '4.9.0', - 'The "%service_id%" service is deprecated and will be removed in version 5.0.0. Android SafetyNet is now deprecated.' - ) - ->args([service(ClockInterface::class)->nullOnInvalid()]) - ->call('setMaxAge', [param('webauthn.android_safetynet.max_age')]) - ->call('setLeeway', [param('webauthn.android_safetynet.leeway')]); - } -}; diff --git a/src/symfony/src/Resources/config/cose.php b/src/symfony/src/Resources/config/cose.php index a38fb39b..872ba2c3 100644 --- a/src/symfony/src/Resources/config/cose.php +++ b/src/symfony/src/Resources/config/cose.php @@ -20,11 +20,6 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return static function (ContainerConfigurator $container): void { - $deprecationData = [ - 'web-auth/webauthn-symfony-bundle', - '4.7.0', - 'The "%alias_id%" service alias is deprecated, use "%service_id%" instead.', - ]; $container = $container->services() ->defaults() ->private() @@ -37,112 +32,56 @@ $container ->set('webauthn.cose.algorithm.RS1') ->class(RS1::class); - $container - ->alias('webauthn.cose.algoritm.RS1', 'webauthn.cose.algorithm.RS1') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.RS256') ->class(RS256::class); - $container - ->alias('webauthn.cose.algoritm.RS256', 'webauthn.cose.algorithm.RS256') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.RS384') ->class(RS384::class); - $container - ->alias('webauthn.cose.algoritm.RS384', 'webauthn.cose.algorithm.RS384') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.RS512') ->class(RS512::class); - $container - ->alias('webauthn.cose.algoritm.RS512', 'webauthn.cose.algorithm.RS512') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.PS256') ->class(PS256::class); - $container - ->alias('webauthn.cose.algoritm.PS256', 'webauthn.cose.algorithm.PS256') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.PS384') ->class(PS384::class); - $container - ->alias('webauthn.cose.algoritm.PS384', 'webauthn.cose.algorithm.PS384') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.PS512') ->class(PS512::class); - $container - ->alias('webauthn.cose.algoritm.PS512', 'webauthn.cose.algorithm.PS512') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.ES256K') ->class(ES256K::class); - $container - ->alias('webauthn.cose.algoritm.ES256K', 'webauthn.cose.algorithm.ES256K') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.ES256') ->class(ES256::class); - $container - ->alias('webauthn.cose.algoritm.ES256', 'webauthn.cose.algorithm.ES256') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.ES384') ->class(ES384::class); - $container - ->alias('webauthn.cose.algoritm.ES384', 'webauthn.cose.algorithm.ES384') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.ES512') ->class(ES512::class); - $container - ->alias('webauthn.cose.algoritm.ES512', 'webauthn.cose.algorithm.ES512') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.ED256') ->class(Ed256::class); - $container - ->alias('webauthn.cose.algoritm.ED256', 'webauthn.cose.algorithm.ED256') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.ED512') ->class(Ed512::class); - $container - ->alias('webauthn.cose.algoritm.ED512', 'webauthn.cose.algorithm.ED512') - ->deprecate(...$deprecationData) - ; $container ->set('webauthn.cose.algorithm.Ed25519ph') ->class(Ed25519::class); - $container - ->alias('webauthn.cose.algoritm.Ed25519ph', 'webauthn.cose.algorithm.Ed25519ph') - ->deprecate(...$deprecationData) - ; }; diff --git a/src/symfony/src/Resources/config/metadata_statement_supports.php b/src/symfony/src/Resources/config/metadata_statement_supports.php index da48ac79..6dd6e7b7 100644 --- a/src/symfony/src/Resources/config/metadata_statement_supports.php +++ b/src/symfony/src/Resources/config/metadata_statement_supports.php @@ -21,7 +21,7 @@ ->set(AppleAttestationStatementSupport::class); $container ->set(TPMAttestationStatementSupport::class) - ->args([service('webauthn.clock') ->nullOnInvalid()]) + ->args([service('webauthn.clock')]) ; $container ->set(FidoU2FAttestationStatementSupport::class); @@ -33,9 +33,5 @@ $container ->set(PhpCertificateChainValidator::class) - ->args( - [service('webauthn.http_client'), service('webauthn.request_factory')->nullOnInvalid(), service( - 'webauthn.clock' - )] - ); + ->args([service('webauthn.http_client'), service('webauthn.clock')]); }; diff --git a/src/symfony/src/Resources/config/services.php b/src/symfony/src/Resources/config/services.php index 7f337d61..5d3240a3 100644 --- a/src/symfony/src/Resources/config/services.php +++ b/src/symfony/src/Resources/config/services.php @@ -2,13 +2,11 @@ declare(strict_types=1); -use Lcobucci\Clock\SystemClock; use Psr\Cache\CacheItemPoolInterface; -use Psr\Http\Message\RequestFactoryInterface; use Psr\Log\NullLogger; +use Symfony\Component\Clock\NativeClock; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\Serializer\SerializerInterface; -use Symfony\Component\Validator\Validator\ValidatorInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use Webauthn\AttestationStatement\AttestationObjectLoader; use Webauthn\AttestationStatement\AttestationStatementSupportManager; @@ -21,7 +19,7 @@ use Webauthn\Bundle\Controller\DummyControllerFactory; use Webauthn\Bundle\Repository\DummyPublicKeyCredentialSourceRepository; use Webauthn\Bundle\Repository\DummyPublicKeyCredentialUserEntityRepository; -use Webauthn\Bundle\Repository\PublicKeyCredentialUserEntityRepositoryInterface; +use Webauthn\Bundle\Repository\PublicKeyCredentialSourceRepositoryInterface; use Webauthn\Bundle\Routing\Loader; use Webauthn\Bundle\Service\DefaultFailureHandler; use Webauthn\Bundle\Service\DefaultSuccessHandler; @@ -46,37 +44,25 @@ use Webauthn\Denormalizer\PublicKeyCredentialSourceDenormalizer; use Webauthn\Denormalizer\PublicKeyCredentialUserEntityDenormalizer; use Webauthn\Denormalizer\WebauthnSerializerFactory; -use Webauthn\FakeCredentialGenerator; use Webauthn\MetadataService\Denormalizer\ExtensionDescriptorDenormalizer; use Webauthn\MetadataService\Denormalizer\MetadataStatementSerializerFactory; -use Webauthn\PublicKeyCredentialLoader; -use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\SimpleFakeCredentialGenerator; -use Webauthn\TokenBinding\IgnoreTokenBindingHandler; -use Webauthn\TokenBinding\SecTokenBindingHandler; -use Webauthn\TokenBinding\TokenBindingNotSupportedHandler; use function Symfony\Component\DependencyInjection\Loader\Configurator\param; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; return static function (ContainerConfigurator $container): void { - $deprecationData = [ - 'web-auth/webauthn-symfony-bundle', - '4.3.0', - '%service_id% is deprecated since 4.3.0 and will be removed in 5.0.0', - ]; $container = $container->services() ->defaults() ->private() ->autoconfigure(); $container - ->set('webauthn.clock.default') - ->class(SystemClock::class) - ->factory([SystemClock::class, 'fromSystemTimezone']) + ->set(CeremonyStepManagerFactory::class) ; $container - ->set(CeremonyStepManagerFactory::class) + ->set('webauthn.clock.default') + ->class(NativeClock::class) ; $container @@ -100,21 +86,12 @@ $container ->set(AuthenticatorAttestationResponseValidator::class) - ->args([null, null, null, null, null, service('webauthn.ceremony_step_manager.creation')]) + ->args([service('webauthn.ceremony_step_manager.creation')]) ->public(); $container ->set(AuthenticatorAssertionResponseValidator::class) ->class(AuthenticatorAssertionResponseValidator::class) - ->args([null, null, null, null, null, service('webauthn.ceremony_step_manager.request')]) - ->public(); - $container - ->set(PublicKeyCredentialLoader::class) - ->deprecate( - 'web-auth/webauthn-symfony-bundle', - '4.8.0', - '%service_id% is deprecated since 4.8.0 and will be removed in 5.0.0', - ) - ->args([null, service(SerializerInterface::class)]) + ->args([service('webauthn.ceremony_step_manager.request')]) ->public(); $container ->set(PublicKeyCredentialCreationOptionsFactory::class) @@ -135,16 +112,6 @@ $container ->set(NoneAttestationStatementSupport::class); - $container - ->set(IgnoreTokenBindingHandler::class) - ->deprecate(...$deprecationData); - $container - ->set(TokenBindingNotSupportedHandler::class) - ->deprecate(...$deprecationData); - $container - ->set(SecTokenBindingHandler::class) - ->deprecate(...$deprecationData); - $container ->set(ThrowExceptionIfInvalid::class) ->autowire(false); @@ -157,23 +124,15 @@ ->set(AttestationControllerFactory::class) ->args([ service(SerializerInterface::class), - service(ValidatorInterface::class), - service(PublicKeyCredentialCreationOptionsFactory::class), - null, service(AuthenticatorAttestationResponseValidator::class), - service(PublicKeyCredentialSourceRepository::class)->nullOnInvalid(), + service(PublicKeyCredentialSourceRepositoryInterface::class), ]); $container ->set(AssertionControllerFactory::class) ->args([ service(SerializerInterface::class), - service(ValidatorInterface::class), - service(PublicKeyCredentialRequestOptionsFactory::class), - null, service(AuthenticatorAssertionResponseValidator::class), - service(PublicKeyCredentialUserEntityRepositoryInterface::class), - service(PublicKeyCredentialSourceRepository::class)->nullOnInvalid(), - service(FakeCredentialGenerator::class)->nullOnInvalid(), + service(PublicKeyCredentialSourceRepositoryInterface::class), ]); $container @@ -193,9 +152,6 @@ $container ->alias('webauthn.http_client.default', HttpClientInterface::class); - $container - ->alias('webauthn.request_factory.default', RequestFactoryInterface::class); - $container ->set(ExtensionDescriptorDenormalizer::class) ->tag('serializer.normalizer', [ diff --git a/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvent.php b/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvent.php index c61845bf..f87154c0 100644 --- a/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvent.php +++ b/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvent.php @@ -8,9 +8,7 @@ final class WebauthnAuthenticationEvent extends BadCredentialsException { - public const MESSAGE = 'Invalid Webauthn credentials.'; - - private const MESSAGE_KEY = 'invalid'; + private const string MESSAGE_KEY = 'invalid'; public function getMessageKey(): string { diff --git a/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvents.php b/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvents.php index e1d3769e..ffeafe34 100644 --- a/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvents.php +++ b/src/symfony/src/Security/Authentication/Exception/WebauthnAuthenticationEvents.php @@ -6,7 +6,7 @@ interface WebauthnAuthenticationEvents { - public const FAILURE = 'failure'; + public const string FAILURE = 'failure'; - public const SUCCESS = 'success'; + public const string SUCCESS = 'success'; } diff --git a/src/symfony/src/Security/Authentication/Token/WebauthnToken.php b/src/symfony/src/Security/Authentication/Token/WebauthnToken.php index e7fa0def..97d1ad83 100644 --- a/src/symfony/src/Security/Authentication/Token/WebauthnToken.php +++ b/src/symfony/src/Security/Authentication/Token/WebauthnToken.php @@ -11,8 +11,10 @@ use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialOptions; use Webauthn\PublicKeyCredentialUserEntity; +use function assert; +use function is_array; -class WebauthnToken extends AbstractToken implements WebauthnTokenInterface +class WebauthnToken extends AbstractToken { public function __construct( private readonly PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity, @@ -74,6 +76,7 @@ public function __unserialize(array $data): void $this->firewallName, $parentData ] = $data; + assert(is_array($parentData), 'Invalid data'); parent::__unserialize($parentData); } diff --git a/src/symfony/src/Security/Authentication/Token/WebauthnTokenInterface.php b/src/symfony/src/Security/Authentication/Token/WebauthnTokenInterface.php deleted file mode 100644 index 83e68d6d..00000000 --- a/src/symfony/src/Security/Authentication/Token/WebauthnTokenInterface.php +++ /dev/null @@ -1,40 +0,0 @@ -userEntityRepository->generateUserEntity($dto->username, $dto->displayName); } - if (! $this->userEntityRepository instanceof CanRegisterUserEntity) { - throw MissingUserEntityException::create('Unable to find the user entity'); - } - if ($dto->username === null || $dto->username === '') { - throw InvalidDataException::create($dto, 'The parameter "username" is missing or empty.'); - } - if ($dto->displayName === null || $dto->displayName === '') { - throw InvalidDataException::create($dto, 'The parameter "displayName" is missing or empty.'); - } - - return PublicKeyCredentialUserEntity::create( - $dto->username, - $this->userEntityRepository->generateNextUserEntityId(), - $dto->displayName - ); + throw MissingUserEntityException::create('Unable to find the user entity'); } } diff --git a/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php b/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php index 53862aad..8b99eca6 100644 --- a/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php +++ b/src/symfony/src/Security/Http/Authenticator/WebauthnAuthenticator.php @@ -40,9 +40,7 @@ use Webauthn\MetadataService\CanLogData; use Webauthn\PublicKeyCredential; use Webauthn\PublicKeyCredentialCreationOptions; -use Webauthn\PublicKeyCredentialLoader; use Webauthn\PublicKeyCredentialRequestOptions; -use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; final class WebauthnAuthenticator implements AuthenticatorInterface, InteractiveAuthenticatorInterface, CanLogData @@ -55,30 +53,12 @@ public function __construct( private readonly AuthenticationSuccessHandlerInterface $successHandler, private readonly AuthenticationFailureHandlerInterface $failureHandler, private readonly OptionsStorage $optionsStorage, - private readonly PublicKeyCredentialSourceRepository|PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository, + private readonly PublicKeyCredentialSourceRepositoryInterface $publicKeyCredentialSourceRepository, private readonly PublicKeyCredentialUserEntityRepositoryInterface $credentialUserEntityRepository, - private readonly PublicKeyCredentialLoader|SerializerInterface $publicKeyCredentialLoader, + private readonly SerializerInterface $publicKeyCredentialLoader, private readonly AuthenticatorAssertionResponseValidator $assertionResponseValidator, private readonly AuthenticatorAttestationResponseValidator $attestationResponseValidator ) { - if (! $this->publicKeyCredentialSourceRepository instanceof PublicKeyCredentialSourceRepositoryInterface) { - trigger_deprecation( - 'web-auth/webauthn-symfony-bundle', - '4.6.0', - sprintf( - 'Since 4.6.0, the parameter "$publicKeyCredentialSourceRepository" expects an instance of "%s". Please implement that interface instead of "%s".', - PublicKeyCredentialSourceRepositoryInterface::class, - PublicKeyCredentialSourceRepository::class - ) - ); - } - if ($this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader) { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.8.0', - 'The argument "$publicKeyCredentialLoader" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a Symfony Serializer instead.' - ); - } $this->logger = new NullLogger(); } @@ -180,15 +160,14 @@ public function isInteractive(): bool private function processWithAssertion(Request $request): Passport { try { - $format = method_exists( - $request, - 'getContentTypeFormat' - ) ? $request->getContentTypeFormat() : $request->getContentType(); + $format = $request->getContentTypeFormat(); $format === 'json' || throw InvalidDataException::create($format, 'Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( - $content - ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); + $publicKeyCredential = $this->publicKeyCredentialLoader->deserialize( + $content, + PublicKeyCredential::class, + 'json' + ); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAssertionResponse || throw InvalidDataException::create( $response, @@ -248,15 +227,14 @@ private function processWithAttestation(Request $request): Passport if (! $this->publicKeyCredentialSourceRepository instanceof CanSaveCredentialSource) { throw MissingFeatureException::create('Unable to register the credential.'); } - $format = method_exists( - $request, - 'getContentTypeFormat' - ) ? $request->getContentTypeFormat() : $request->getContentType(); + $format = $request->getContentTypeFormat(); $format === 'json' || throw InvalidDataException::create($format, 'Only JSON content type allowed'); $content = $request->getContent(); - $publicKeyCredential = $this->publicKeyCredentialLoader instanceof PublicKeyCredentialLoader ? $this->publicKeyCredentialLoader->load( - $content - ) : $this->publicKeyCredentialLoader->deserialize($content, PublicKeyCredential::class, 'json'); + $publicKeyCredential = $this->publicKeyCredentialLoader->deserialize( + $content, + PublicKeyCredential::class, + 'json' + ); $response = $publicKeyCredential->response; $response instanceof AuthenticatorAttestationResponse || throw InvalidDataException::create( $response, diff --git a/src/symfony/src/Security/Storage/CacheStorage.php b/src/symfony/src/Security/Storage/CacheStorage.php index 34a9d6c9..e68356b0 100644 --- a/src/symfony/src/Security/Storage/CacheStorage.php +++ b/src/symfony/src/Security/Storage/CacheStorage.php @@ -7,12 +7,12 @@ use Psr\Cache\CacheItemPoolInterface; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -final class CacheStorage implements OptionsStorage +final readonly class CacheStorage implements OptionsStorage { - private const CACHE_PARAMETER = 'WEBAUTHN_PUBLIC_KEY_OPTIONS'; + private const string CACHE_PARAMETER = 'WEBAUTHN_PUBLIC_KEY_OPTIONS'; public function __construct( - private readonly CacheItemPoolInterface $cache + private CacheItemPoolInterface $cache ) { } @@ -29,12 +29,9 @@ public function store(Item $item): void $this->cache->save($cacheItem); } - public function get(string|null $challenge = null): Item + public function get(string $challenge): Item { - if ($challenge === null) { - throw new BadRequestHttpException('No public key credential options available.'); - } - $key = sprintf('%s-%s', self::CACHE_PARAMETER, hash('sha512', $challenge)); + $key = sprintf('%s-%s', self::CACHE_PARAMETER, hash('xxh128', $challenge)); $cacheItem = $this->cache->getItem($key); if (! $cacheItem->isHit()) { throw new BadRequestHttpException('No public key credential options available.'); diff --git a/src/symfony/src/Security/Storage/OptionsStorage.php b/src/symfony/src/Security/Storage/OptionsStorage.php index f04df3d1..b3f6448b 100644 --- a/src/symfony/src/Security/Storage/OptionsStorage.php +++ b/src/symfony/src/Security/Storage/OptionsStorage.php @@ -8,5 +8,5 @@ interface OptionsStorage { public function store(Item $item): void; - public function get(/*string|null $challenge = null*/): Item; + public function get(string $challenge): Item; } diff --git a/src/symfony/src/Security/Storage/SessionStorage.php b/src/symfony/src/Security/Storage/SessionStorage.php index 91b4724c..efc4a6d4 100644 --- a/src/symfony/src/Security/Storage/SessionStorage.php +++ b/src/symfony/src/Security/Storage/SessionStorage.php @@ -11,12 +11,12 @@ use function array_key_exists; use function is_array; -final class SessionStorage implements OptionsStorage +final readonly class SessionStorage implements OptionsStorage { - private const SESSION_PARAMETER = 'WEBAUTHN_PUBLIC_KEY_OPTIONS'; + private const string SESSION_PARAMETER = 'WEBAUTHN_PUBLIC_KEY_OPTIONS'; public function __construct( - private readonly RequestStack $requestStack + private RequestStack $requestStack ) { } @@ -29,10 +29,11 @@ public function store(Item $item, string|null $tag = null): void ]); } - public function get(string|null $tag = null): Item + public function get(string $challenge): Item { $session = $this->requestStack->getSession(); - $sessionValue = $session->remove(self::SESSION_PARAMETER); + $key = sprintf('%s-%s', self::SESSION_PARAMETER, hash('xxh128', $challenge)); + $sessionValue = $session->remove($key); if (! is_array($sessionValue) || ! array_key_exists('options', $sessionValue) || ! array_key_exists( 'userEntity', $sessionValue diff --git a/src/symfony/src/Service/AuthenticatorAssertionResponseValidator.php b/src/symfony/src/Service/AuthenticatorAssertionResponseValidator.php deleted file mode 100644 index a74297c0..00000000 --- a/src/symfony/src/Service/AuthenticatorAssertionResponseValidator.php +++ /dev/null @@ -1,80 +0,0 @@ -eventDispatcher = new NullEventDispatcher(); - } else { - $this->eventDispatcher = $eventDispatcher; - trigger_deprecation( - 'web-auth/webauthn-symfony-bundle', - '4.5.0', - 'The parameter "$eventDispatcher" is deprecated since 4.5.0 will be removed in 5.0.0. Please use `setEventDispatcher` instead.' - ); - } + $this->eventDispatcher = new NullEventDispatcher(); } public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): void @@ -60,7 +49,7 @@ public function create( array $excludeCredentials = [], null|AuthenticatorSelectionCriteria $authenticatorSelection = null, null|string $attestationConveyance = null, - null|AuthenticationExtensions $authenticationExtensionsClientInputs = null + null|AuthenticationExtensions $AuthenticationExtensions = null ): PublicKeyCredentialCreationOptions { array_key_exists($key, $this->profiles) || throw new InvalidArgumentException(sprintf( 'The profile with key "%s" does not exist.', @@ -93,7 +82,7 @@ public function create( attestation: $attestation, excludeCredentials: $excludeCredentials, timeout: $timeout, - extensions: $authenticationExtensionsClientInputs ?? $this->createExtensions($profile) + extensions: $AuthenticationExtensions ?? $this->createExtensions($profile) ); $this->eventDispatcher->dispatch(PublicKeyCredentialCreationOptionsCreatedEvent::create($options)); @@ -105,7 +94,7 @@ public function create( */ private function createExtensions(array $profile): AuthenticationExtensions { - return AuthenticationExtensionsClientInputs::create( + return AuthenticationExtensions::create( array_map( static fn (string $name, mixed $value): AuthenticationExtension => AuthenticationExtension::create( $name, @@ -126,7 +115,6 @@ private function createAuthenticatorSelectionCriteria(array $profile): Authentic $profile['authenticator_selection_criteria']['authenticator_attachment'], $profile['authenticator_selection_criteria']['user_verification'], $profile['authenticator_selection_criteria']['resident_key'], - $profile['authenticator_selection_criteria']['require_resident_key'], ); } diff --git a/src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php b/src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php index 0c694651..9778441e 100644 --- a/src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php +++ b/src/symfony/src/Service/PublicKeyCredentialRequestOptionsFactory.php @@ -8,7 +8,6 @@ use Psr\EventDispatcher\EventDispatcherInterface; use Webauthn\AuthenticationExtensions\AuthenticationExtension; use Webauthn\AuthenticationExtensions\AuthenticationExtensions; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; use Webauthn\Bundle\Event\PublicKeyCredentialRequestOptionsCreatedEvent; use Webauthn\MetadataService\Event\CanDispatchEvents; use Webauthn\MetadataService\Event\NullEventDispatcher; @@ -28,18 +27,8 @@ final class PublicKeyCredentialRequestOptionsFactory implements CanDispatchEvent */ public function __construct( private readonly array $profiles, - ?EventDispatcherInterface $eventDispatcher = null ) { - if ($eventDispatcher === null) { - $this->eventDispatcher = new NullEventDispatcher(); - } else { - $this->eventDispatcher = $eventDispatcher; - trigger_deprecation( - 'web-auth/webauthn-symfony-bundle', - '4.5.0', - 'The parameter "$eventDispatcher" is deprecated since 4.5.0 will be removed in 5.0.0. Please use `setEventDispatcher` instead.' - ); - } + $this->eventDispatcher = new NullEventDispatcher(); } /** @@ -49,7 +38,7 @@ public function create( string $key, array $allowCredentials, null|string $userVerification = null, - null|AuthenticationExtensions $authenticationExtensionsClientInputs = null + null|AuthenticationExtensions $AuthenticationExtensions = null ): PublicKeyCredentialRequestOptions { array_key_exists($key, $this->profiles) || throw new InvalidArgumentException(sprintf( 'The profile with key "%s" does not exist.', @@ -81,7 +70,7 @@ public function create( allowCredentials: $allowCredentials, userVerification: $userVerification, timeout: $timeout, - extensions: $authenticationExtensionsClientInputs ?? $this->createExtensions($profile) + extensions: $AuthenticationExtensions ?? $this->createExtensions($profile) ); $this->eventDispatcher->dispatch(PublicKeyCredentialRequestOptionsCreatedEvent::create($options)); @@ -98,7 +87,7 @@ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): v */ private function createExtensions(array $profile): AuthenticationExtensions { - return AuthenticationExtensionsClientInputs::create( + return AuthenticationExtensions::create( array_map( static fn (string $name, mixed $value): AuthenticationExtension => AuthenticationExtension::create( $name, diff --git a/src/symfony/src/WebauthnBundle.php b/src/symfony/src/WebauthnBundle.php index fa900cc2..698ca568 100644 --- a/src/symfony/src/WebauthnBundle.php +++ b/src/symfony/src/WebauthnBundle.php @@ -16,11 +16,9 @@ use Webauthn\Bundle\DependencyInjection\Compiler\CoseAlgorithmCompilerPass; use Webauthn\Bundle\DependencyInjection\Compiler\CounterCheckerSetterCompilerPass; use Webauthn\Bundle\DependencyInjection\Compiler\DynamicRouteCompilerPass; -use Webauthn\Bundle\DependencyInjection\Compiler\EnforcedSafetyNetApiKeyVerificationCompilerPass; use Webauthn\Bundle\DependencyInjection\Compiler\EventDispatcherSetterCompilerPass; use Webauthn\Bundle\DependencyInjection\Compiler\ExtensionOutputCheckerCompilerPass; use Webauthn\Bundle\DependencyInjection\Compiler\LoggerSetterCompilerPass; -use Webauthn\Bundle\DependencyInjection\Compiler\MetadataStatementSupportCompilerPass; use Webauthn\Bundle\DependencyInjection\Factory\Security\WebauthnFactory; use Webauthn\Bundle\DependencyInjection\Factory\Security\WebauthnServicesFactory; use Webauthn\Bundle\DependencyInjection\WebauthnExtension; @@ -58,22 +56,12 @@ public function build(ContainerBuilder $container): void ); $container->addCompilerPass(new CoseAlgorithmCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); $container->addCompilerPass(new DynamicRouteCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); - $container->addCompilerPass( - new EnforcedSafetyNetApiKeyVerificationCompilerPass(), - PassConfig::TYPE_BEFORE_OPTIMIZATION, - 0 - ); $container->addCompilerPass(new LoggerSetterCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); $container->addCompilerPass( new CounterCheckerSetterCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 0 ); - $container->addCompilerPass( - new MetadataStatementSupportCompilerPass(), - PassConfig::TYPE_BEFORE_OPTIMIZATION, - 0 - ); $this->registerMappings($container); diff --git a/src/webauthn/composer.json b/src/webauthn/composer.json index 934318d3..e32f2da8 100644 --- a/src/webauthn/composer.json +++ b/src/webauthn/composer.json @@ -20,17 +20,15 @@ } ], "require": { - "php": ">=8.1", + "php": ">=8.3", "ext-json": "*", "ext-openssl": "*", "ext-mbstring": "*", "paragonie/constant_time_encoding": "^2.6|^3.0", "psr/event-dispatcher": "^1.0", - "psr/http-client": "^1.0", - "psr/http-factory": "^1.0", "psr/log": "^1.0|^2.0|^3.0", "spomky-labs/cbor-php": "^3.0", - "symfony/uid": "^6.1|^7.0", + "symfony/uid": "^7.0", "web-auth/cose-lib": "^4.2.3", "web-auth/metadata-service": "self.version" }, diff --git a/src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php b/src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php deleted file mode 100644 index 48684671..00000000 --- a/src/webauthn/src/AttestationStatement/AndroidSafetyNetAttestationStatementSupport.php +++ /dev/null @@ -1,382 +0,0 @@ -clock === null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$clock" will be required in 5.0.0. Please set a clock instance.' - ); - } - if (! class_exists(RS256::class) || ! class_exists(JWKFactory::class)) { - throw UnsupportedFeatureException::create( - 'The algorithm RS256 is missing. Did you forget to install the package web-token/jwt-library?' - ); - } - $this->jwsSerializer = new CompactSerializer(); - $this->initJwsVerifier(); - $this->dispatcher = new NullEventDispatcher(); - } - - public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): void - { - $this->dispatcher = $eventDispatcher; - } - - public static function create(null|ClockInterface $clock = null): self - { - return new self($clock); - } - - public function enableApiVerification( - ClientInterface|HttpClientInterface $client, - string $apiKey, - ?RequestFactoryInterface $requestFactory = null - ): self { - $this->apiKey = $apiKey; - $this->client = $client; - $this->requestFactory = $requestFactory; - if ($requestFactory !== null && ! $client instanceof HttpClientInterface) { - trigger_deprecation( - 'web-auth/metadata-service', - '4.7.0', - 'The parameter "$requestFactory" will be removed in 5.0.0. Please set it to null and set an Symfony\Contracts\HttpClient\HttpClientInterface as "$client" argument.' - ); - } - - return $this; - } - - public function setMaxAge(int $maxAge): self - { - $this->maxAge = $maxAge; - - return $this; - } - - public function setLeeway(int $leeway): self - { - $this->leeway = $leeway; - - return $this; - } - - public function name(): string - { - return 'android-safetynet'; - } - - /** - * @param array $attestation - */ - public function load(array $attestation): AttestationStatement - { - array_key_exists('attStmt', $attestation) || throw AttestationStatementLoadingException::create( - $attestation - ); - foreach (['ver', 'response'] as $key) { - array_key_exists($key, $attestation['attStmt']) || throw AttestationStatementLoadingException::create( - $attestation, - sprintf('The attestation statement value "%s" is missing.', $key) - ); - $attestation['attStmt'][$key] !== '' || throw AttestationStatementLoadingException::create( - $attestation, - sprintf('The attestation statement value "%s" is empty.', $key) - ); - } - $jws = $this->jwsSerializer->unserialize($attestation['attStmt']['response']); - $jwsHeader = $jws->getSignature(0) - ->getProtectedHeader(); - array_key_exists('x5c', $jwsHeader) || throw AttestationStatementLoadingException::create( - $attestation, - 'The response in the attestation statement must contain a "x5c" header.' - ); - (is_countable($jwsHeader['x5c']) ? count( - $jwsHeader['x5c'] - ) : 0) > 0 || throw AttestationStatementLoadingException::create( - $attestation, - 'The "x5c" parameter in the attestation statement response must contain at least one certificate.' - ); - $certificates = $this->convertCertificatesToPem($jwsHeader['x5c']); - $attestation['attStmt']['jws'] = $jws; - - $attestationStatement = AttestationStatement::createBasic( - $this->name(), - $attestation['attStmt'], - CertificateTrustPath::create($certificates) - ); - $this->dispatcher->dispatch(AttestationStatementLoaded::create($attestationStatement)); - - return $attestationStatement; - } - - public function isValid( - string $clientDataJSONHash, - AttestationStatement $attestationStatement, - AuthenticatorData $authenticatorData - ): bool { - $trustPath = $attestationStatement->trustPath; - $trustPath instanceof CertificateTrustPath || throw InvalidAttestationStatementException::create( - $attestationStatement, - 'Invalid trust path' - ); - $certificates = $trustPath->certificates; - $firstCertificate = current($certificates); - is_string($firstCertificate) || throw InvalidAttestationStatementException::create( - $attestationStatement, - 'No certificate' - ); - - $parsedCertificate = openssl_x509_parse($firstCertificate); - is_array($parsedCertificate) || throw InvalidAttestationStatementException::create( - $attestationStatement, - 'Invalid attestation object' - ); - array_key_exists('subject', $parsedCertificate) || throw InvalidAttestationStatementException::create( - $attestationStatement, - 'Invalid attestation object' - ); - array_key_exists('CN', $parsedCertificate['subject']) || throw InvalidAttestationStatementException::create( - $attestationStatement, - 'Invalid attestation object' - ); - $parsedCertificate['subject']['CN'] === 'attest.android.com' || throw InvalidAttestationStatementException::create( - $attestationStatement, - 'Invalid attestation object' - ); - - /** @var JWS $jws */ - $jws = $attestationStatement->get('jws'); - $payload = $jws->getPayload(); - $this->validatePayload($payload, $clientDataJSONHash, $authenticatorData); - - //Check the signature - $this->validateSignature($jws, $trustPath); - - //Check against Google service - $this->validateUsingGoogleApi($attestationStatement); - - return true; - } - - private function validatePayload( - ?string $payload, - string $clientDataJSONHash, - AuthenticatorData $authenticatorData - ): void { - $payload !== null || throw AttestationStatementVerificationException::create('Invalid attestation object'); - $payload = json_decode($payload, true, flags: JSON_THROW_ON_ERROR); - array_key_exists('nonce', $payload) || throw AttestationStatementVerificationException::create( - 'Invalid attestation object. "nonce" is missing.' - ); - $payload['nonce'] === base64_encode( - hash('sha256', $authenticatorData->authData . $clientDataJSONHash, true) - ) || throw AttestationStatementVerificationException::create('Invalid attestation object. Invalid nonce'); - array_key_exists('ctsProfileMatch', $payload) || throw AttestationStatementVerificationException::create( - 'Invalid attestation object. "ctsProfileMatch" is missing.' - ); - $payload['ctsProfileMatch'] || throw AttestationStatementVerificationException::create( - 'Invalid attestation object. "ctsProfileMatch" value is false.' - ); - array_key_exists('timestampMs', $payload) || throw AttestationStatementVerificationException::create( - 'Invalid attestation object. Timestamp is missing.' - ); - is_int($payload['timestampMs']) || throw AttestationStatementVerificationException::create( - 'Invalid attestation object. Timestamp shall be an integer.' - ); - - $currentTime = ($this->clock?->now()->getTimestamp() ?? time()) * 1000; - $payload['timestampMs'] <= $currentTime + $this->leeway || throw AttestationStatementVerificationException::create( - sprintf( - 'Invalid attestation object. Issued in the future. Current time: %d. Response time: %d', - $currentTime, - $payload['timestampMs'] - ) - ); - $currentTime - $payload['timestampMs'] <= $this->maxAge || throw AttestationStatementVerificationException::create( - sprintf( - 'Invalid attestation object. Too old. Current time: %d. Response time: %d', - $currentTime, - $payload['timestampMs'] - ) - ); - } - - private function validateSignature(JWS $jws, CertificateTrustPath $trustPath): void - { - $jwk = JWKFactory::createFromCertificate($trustPath->certificates[0]); - $isValid = $this->jwsVerifier?->verifyWithKey($jws, $jwk, 0); - $isValid === true || throw AttestationStatementVerificationException::create('Invalid response signature'); - } - - private function validateUsingGoogleApi(AttestationStatement $attestationStatement): void - { - if ($this->client === null || $this->apiKey === null) { - return; - } - $uri = sprintf( - 'https://www.googleapis.com/androidcheck/v1/attestations/verify?key=%s', - urlencode($this->apiKey) - ); - $requestBody = sprintf('{"signedAttestation":"%s"}', $attestationStatement->get('response')); - if ($this->client instanceof HttpClientInterface) { - $responseBody = $this->validateUsingGoogleApiWithSymfonyClient($requestBody, $uri); - } else { - $responseBody = $this->validateUsingGoogleApiWithPsrClient($requestBody, $uri); - } - $responseBodyJson = json_decode($responseBody, true, flags: JSON_THROW_ON_ERROR); - array_key_exists( - 'isValidSignature', - $responseBodyJson - ) || throw AttestationStatementVerificationException::create('Invalid response.'); - $responseBodyJson['isValidSignature'] === true || throw AttestationStatementVerificationException::create( - 'Invalid response.' - ); - } - - private function getResponseBody(ResponseInterface $response): string - { - $responseBody = ''; - $response->getBody() - ->rewind(); - do { - $tmp = $response->getBody() - ->read(1024); - if ($tmp === '') { - break; - } - $responseBody .= $tmp; - } while (true); - - return $responseBody; - } - - /** - * @param string[] $certificates - * - * @return string[] - */ - private function convertCertificatesToPem(array $certificates): array - { - foreach ($certificates as $k => $v) { - $certificates[$k] = CertificateToolbox::fixPEMStructure($v); - } - - return $certificates; - } - - private function initJwsVerifier(): void - { - $algorithmClasses = [ - RS256::class, RS384::class, RS512::class, - PS256::class, PS384::class, PS512::class, - ES256::class, ES384::class, ES512::class, - EdDSA::class, - ]; - /** @var AlgorithmInterface[] $algorithms */ - $algorithms = []; - foreach ($algorithmClasses as $algorithm) { - if (class_exists($algorithm)) { - $algorithms[] = new $algorithm(); - } - } - $algorithmManager = new AlgorithmManager($algorithms); - $this->jwsVerifier = new JWSVerifier($algorithmManager); - } - - private function validateUsingGoogleApiWithSymfonyClient(string $requestBody, string $uri): string - { - $response = $this->client->request('POST', $uri, [ - 'headers' => [ - 'content-type' => 'application/json', - ], - 'body' => $requestBody, - ]); - $response->getStatusCode() === 200 || throw AttestationStatementVerificationException::create( - 'Request did not succeeded' - ); - - return $response->getContent(); - } - - private function validateUsingGoogleApiWithPsrClient(string $requestBody, string $uri): string - { - $request = $this->requestFactory->createRequest('POST', $uri); - $request = $request->withHeader('content-type', 'application/json'); - $request->getBody() - ->write($requestBody); - - $response = $this->client->sendRequest($request); - $response->getStatusCode() === 200 || throw AttestationStatementVerificationException::create( - 'Request did not succeeded' - ); - - return $this->getResponseBody($response); - } -} diff --git a/src/webauthn/src/AttestationStatement/AttestationObject.php b/src/webauthn/src/AttestationStatement/AttestationObject.php index a89cccac..5ad36ab7 100644 --- a/src/webauthn/src/AttestationStatement/AttestationObject.php +++ b/src/webauthn/src/AttestationStatement/AttestationObject.php @@ -25,60 +25,4 @@ public static function create( ): self { return new self($rawAttestationObject, $attStmt, $authData); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRawAttestationObject(): string - { - return $this->rawAttestationObject; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttStmt(): AttestationStatement - { - return $this->attStmt; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setAttStmt(AttestationStatement $attStmt): void - { - $this->attStmt = $attStmt; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAuthData(): AuthenticatorData - { - return $this->authData; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getMetadataStatement(): ?MetadataStatement - { - return $this->metadataStatement; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setMetadataStatement(MetadataStatement $metadataStatement): self - { - $this->metadataStatement = $metadataStatement; - - return $this; - } } diff --git a/src/webauthn/src/AttestationStatement/AttestationStatement.php b/src/webauthn/src/AttestationStatement/AttestationStatement.php index 4f300447..fe13ce12 100644 --- a/src/webauthn/src/AttestationStatement/AttestationStatement.php +++ b/src/webauthn/src/AttestationStatement/AttestationStatement.php @@ -4,29 +4,21 @@ namespace Webauthn\AttestationStatement; -use JsonSerializable; use Webauthn\Exception\InvalidDataException; use Webauthn\TrustPath\TrustPath; -use Webauthn\TrustPath\TrustPathLoader; use function array_key_exists; -class AttestationStatement implements JsonSerializable +class AttestationStatement { - final public const TYPE_NONE = 'none'; + final public const string TYPE_NONE = 'none'; - final public const TYPE_BASIC = 'basic'; + final public const string TYPE_BASIC = 'basic'; - final public const TYPE_SELF = 'self'; + final public const string TYPE_SELF = 'self'; - final public const TYPE_ATTCA = 'attca'; + final public const string TYPE_ATTCA = 'attca'; - /** - * @deprecated since 4.2.0 and will be removed in 5.0.0. The ECDAA Trust Anchor does no longer exist in Webauthn specification. - * @infection-ignore-all - */ - final public const TYPE_ECDAA = 'ecdaa'; - - final public const TYPE_ANONCA = 'anonca'; + final public const string TYPE_ANONCA = 'anonca'; /** * @param array $attStmt @@ -76,17 +68,6 @@ public static function createAttCA(string $fmt, array $attStmt, TrustPath $trust return self::create($fmt, $attStmt, self::TYPE_ATTCA, $trustPath); } - /** - * @param array $attStmt - * - * @deprecated since 4.2.0 and will be removed in 5.0.0. The ECDAA Trust Anchor does no longer exist in Webauthn specification. - * @infection-ignore-all - */ - public static function createEcdaa(string $fmt, array $attStmt, TrustPath $trustPath): self - { - return self::create($fmt, $attStmt, self::TYPE_ECDAA, $trustPath); - } - /** * @param array $attStmt */ @@ -95,25 +76,6 @@ public static function createAnonymizationCA(string $fmt, array $attStmt, TrustP return self::create($fmt, $attStmt, self::TYPE_ANONCA, $trustPath); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getFmt(): string - { - return $this->fmt; - } - - /** - * @return mixed[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttStmt(): array - { - return $this->attStmt; - } - public function has(string $key): bool { return array_key_exists($key, $this->attStmt); @@ -128,63 +90,4 @@ public function get(string $key): mixed return $this->attStmt[$key]; } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTrustPath(): TrustPath - { - return $this->trustPath; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getType(): string - { - return $this->type; - } - - /** - * @param mixed[] $data - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - foreach (['fmt', 'attStmt', 'trustPath', 'type'] as $key) { - array_key_exists($key, $data) || throw InvalidDataException::create($data, sprintf( - 'The key "%s" is missing', - $key - )); - } - - return self::create( - $data['fmt'], - $data['attStmt'], - $data['type'], - TrustPathLoader::loadTrustPath($data['trustPath']) - ); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - return [ - 'fmt' => $this->fmt, - 'attStmt' => $this->attStmt, - 'trustPath' => $this->trustPath, - 'type' => $this->type, - ]; - } } diff --git a/src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php b/src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php index f242004f..b08e8823 100644 --- a/src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php +++ b/src/webauthn/src/AttestationStatement/PackedAttestationStatementSupport.php @@ -17,13 +17,11 @@ use Webauthn\Exception\AttestationStatementVerificationException; use Webauthn\Exception\InvalidAttestationStatementException; use Webauthn\Exception\InvalidDataException; -use Webauthn\Exception\UnsupportedFeatureException; use Webauthn\MetadataService\CertificateChain\CertificateToolbox; use Webauthn\MetadataService\Event\CanDispatchEvents; use Webauthn\MetadataService\Event\NullEventDispatcher; use Webauthn\StringStream; use Webauthn\TrustPath\CertificateTrustPath; -use Webauthn\TrustPath\EcdaaKeyIdTrustPath; use Webauthn\TrustPath\EmptyTrustPath; use Webauthn\Util\CoseSignatureFixer; use function array_key_exists; @@ -81,7 +79,6 @@ public function load(array $attestation): AttestationStatement return match (true) { array_key_exists('x5c', $attestation['attStmt']) => $this->loadBasicType($attestation), - array_key_exists('ecdaaKeyId', $attestation['attStmt']) => $this->loadEcdaaType($attestation['attStmt']), default => $this->loadEmptyType($attestation), }; } @@ -100,7 +97,6 @@ public function isValid( $authenticatorData, $trustPath ), - $trustPath instanceof EcdaaKeyIdTrustPath => $this->processWithECDAA(), $trustPath instanceof EmptyTrustPath => $this->processWithSelfAttestation( $clientDataJSONHash, $attestationStatement, @@ -137,26 +133,6 @@ private function loadBasicType(array $attestation): AttestationStatement return $attestationStatement; } - /** - * @param array $attestation - */ - private function loadEcdaaType(array $attestation): AttestationStatement - { - $ecdaaKeyId = $attestation['attStmt']['ecdaaKeyId']; - is_string($ecdaaKeyId) || throw AttestationStatementVerificationException::create( - 'The attestation statement value "ecdaaKeyId" is invalid.' - ); - - $attestationStatement = AttestationStatement::createEcdaa( - $attestation['fmt'], - $attestation['attStmt'], - new EcdaaKeyIdTrustPath($attestation['ecdaaKeyId']) - ); - $this->dispatcher->dispatch(AttestationStatementLoaded::create($attestationStatement)); - - return $attestationStatement; - } - /** * @param mixed[] $attestation */ @@ -256,11 +232,6 @@ private function processWithCertificate( return $result === 1; } - private function processWithECDAA(): never - { - throw UnsupportedFeatureException::create('ECDAA not supported'); - } - private function processWithSelfAttestation( string $clientDataJSONHash, AttestationStatement $attestationStatement, diff --git a/src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php b/src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php index 8d31c45f..64a00c60 100644 --- a/src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php +++ b/src/webauthn/src/AttestationStatement/TPMAttestationStatementSupport.php @@ -12,24 +12,20 @@ use Cose\Key\OkpKey; use Cose\Key\RsaKey; use DateTimeImmutable; -use DateTimeZone; -use Lcobucci\Clock\Clock; -use Lcobucci\Clock\SystemClock; use ParagonIE\ConstantTime\Base64UrlSafe; use Psr\Clock\ClockInterface; use Psr\EventDispatcher\EventDispatcherInterface; +use Symfony\Component\Clock\NativeClock; use Webauthn\AuthenticatorData; use Webauthn\Event\AttestationStatementLoaded; use Webauthn\Exception\AttestationStatementLoadingException; use Webauthn\Exception\AttestationStatementVerificationException; use Webauthn\Exception\InvalidAttestationStatementException; -use Webauthn\Exception\UnsupportedFeatureException; use Webauthn\MetadataService\CertificateChain\CertificateToolbox; use Webauthn\MetadataService\Event\CanDispatchEvents; use Webauthn\MetadataService\Event\NullEventDispatcher; use Webauthn\StringStream; use Webauthn\TrustPath\CertificateTrustPath; -use Webauthn\TrustPath\EcdaaKeyIdTrustPath; use function array_key_exists; use function count; use function in_array; @@ -40,21 +36,14 @@ final class TPMAttestationStatementSupport implements AttestationStatementSupport, CanDispatchEvents { - private readonly Clock|ClockInterface $clock; - private EventDispatcherInterface $dispatcher; - public function __construct(null|Clock|ClockInterface $clock = null) - { - if ($clock === null) { - trigger_deprecation( - 'web-auth/metadata-service', - '4.5.0', - 'The parameter "$clock" will become mandatory in 5.0.0. Please set a valid PSR Clock implementation instead of "null".' - ); - $clock = new SystemClock(new DateTimeZone('UTC')); - } - $this->clock = $clock; + private readonly ClockInterface $clock; + + public function __construct( + null|ClockInterface $clock = null + ) { + $this->clock = $clock ?? new NativeClock(); $this->dispatcher = new NullEventDispatcher(); } @@ -63,7 +52,7 @@ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): v $this->dispatcher = $eventDispatcher; } - public static function create(null|Clock|ClockInterface $clock = null): self + public static function create(null|ClockInterface $clock = null): self { return new self($clock); } @@ -82,10 +71,6 @@ public function load(array $attestation): AttestationStatement $attestation, 'Invalid attestation object' ); - ! array_key_exists( - 'ecdaaKeyId', - $attestation['attStmt'] - ) || throw AttestationStatementLoadingException::create($attestation, 'ECDAA not supported'); foreach (['ver', 'ver', 'sig', 'alg', 'certInfo', 'pubArea'] as $key) { array_key_exists($key, $attestation['attStmt']) || throw AttestationStatementLoadingException::create( $attestation, @@ -164,7 +149,6 @@ public function isValid( $attestationStatement, $authenticatorData ), - $attestationStatement->trustPath instanceof EcdaaKeyIdTrustPath => $this->processWithECDAA(), default => throw InvalidAttestationStatementException::create( $attestationStatement, 'Unsupported attestation statement' @@ -437,9 +421,4 @@ private function checkCertificate(string $attestnCert, AuthenticatorData $authen 'The value of the "aaguid" does not match with the certificate' ); } - - private function processWithECDAA(): never - { - throw UnsupportedFeatureException::create('ECDAA not supported'); - } } diff --git a/src/webauthn/src/AttestedCredentialData.php b/src/webauthn/src/AttestedCredentialData.php index 2f5d74f4..f69224f1 100644 --- a/src/webauthn/src/AttestedCredentialData.php +++ b/src/webauthn/src/AttestedCredentialData.php @@ -4,7 +4,6 @@ namespace Webauthn; -use JsonSerializable; use ParagonIE\ConstantTime\Base64; use Symfony\Component\Uid\Uuid; use Webauthn\Exception\InvalidDataException; @@ -14,7 +13,7 @@ /** * @see https://www.w3.org/TR/webauthn/#sec-attested-credential-data */ -class AttestedCredentialData implements JsonSerializable +class AttestedCredentialData { public function __construct( public Uuid $aaguid, @@ -28,42 +27,6 @@ public static function create(Uuid $aaguid, string $credentialId, ?string $crede return new self($aaguid, $credentialId, $credentialPublicKey); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAaguid(): Uuid - { - return $this->aaguid; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setAaguid(Uuid $aaguid): void - { - $this->aaguid = $aaguid; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCredentialId(): string - { - return $this->credentialId; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCredentialPublicKey(): ?string - { - return $this->credentialPublicKey; - } - /** * @param mixed[] $json */ @@ -102,26 +65,4 @@ public static function createFromArray(array $json): self return self::create($uuid, $credentialId, $credentialPublicKey); } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $result = [ - 'aaguid' => $this->aaguid->__toString(), - 'credentialId' => base64_encode($this->credentialId), - ]; - if ($this->credentialPublicKey !== null) { - $result['credentialPublicKey'] = base64_encode($this->credentialPublicKey); - } - - return $result; - } } diff --git a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtension.php b/src/webauthn/src/AuthenticationExtensions/AuthenticationExtension.php index 3ed9dc0c..725948c0 100644 --- a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtension.php +++ b/src/webauthn/src/AuthenticationExtensions/AuthenticationExtension.php @@ -4,9 +4,7 @@ namespace Webauthn\AuthenticationExtensions; -use JsonSerializable; - -class AuthenticationExtension implements JsonSerializable +class AuthenticationExtension { public function __construct( public readonly string $name, @@ -18,33 +16,4 @@ public static function create(string $name, mixed $value): self { return new self($name, $value); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function name(): string - { - return $this->name; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function value(): mixed - { - return $this->value; - } - - public function jsonSerialize(): mixed - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - return $this->value; - } } diff --git a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php b/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionLoader.php similarity index 83% rename from src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php rename to src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionLoader.php index ddf5e49f..0fc6bbec 100644 --- a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoader.php +++ b/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionLoader.php @@ -8,13 +8,13 @@ use CBOR\MapObject; use Webauthn\Exception\AuthenticationExtensionException; -abstract class AuthenticationExtensionsClientOutputsLoader +abstract class AuthenticationExtensionLoader { public static function load(CBORObject $object): AuthenticationExtensions { $object instanceof MapObject || throw AuthenticationExtensionException::create('Invalid extension object'); $data = $object->normalize(); - return AuthenticationExtensionsClientOutputs::create( + return AuthenticationExtensions::create( array_map( fn (mixed $value, string $key) => AuthenticationExtension::create($key, $value), $data, diff --git a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensions.php b/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensions.php index 9d7b2bed..a48ef007 100644 --- a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensions.php +++ b/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensions.php @@ -9,7 +9,6 @@ use Countable; use Iterator; use IteratorAggregate; -use JsonSerializable; use Webauthn\Exception\AuthenticationExtensionException; use function array_key_exists; use function count; @@ -20,7 +19,7 @@ * @implements IteratorAggregate * @final */ -class AuthenticationExtensions implements JsonSerializable, Countable, IteratorAggregate, ArrayAccess +class AuthenticationExtensions implements Countable, IteratorAggregate, ArrayAccess { /** * @var array @@ -57,38 +56,6 @@ public static function create(array $extensions = []): static return new static($extensions); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function add(AuthenticationExtension ...$extensions): static - { - foreach ($extensions as $extension) { - $this->extensions[$extension->name] = $extension; - } - - return $this; - } - - /** - * @param array $json - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $json): static - { - return static::create( - array_map( - static fn (string $key, mixed $value): AuthenticationExtension => AuthenticationExtension::create( - $key, - $value - ), - array_keys($json), - $json - ) - ); - } - public function has(string $key): bool { return array_key_exists($key, $this->extensions); @@ -104,20 +71,6 @@ public function get(string $key): AuthenticationExtension return $this->extensions[$key]; } - /** - * @return array - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - return $this->extensions; - } - /** * @return Iterator */ diff --git a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php b/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php deleted file mode 100644 index 5e054840..00000000 --- a/src/webauthn/src/AuthenticationExtensions/AuthenticationExtensionsClientInputs.php +++ /dev/null @@ -1,12 +0,0 @@ -authenticationExtension; - } } diff --git a/src/webauthn/src/AuthenticatorAssertionResponse.php b/src/webauthn/src/AuthenticatorAssertionResponse.php index 8b105a42..d41498f7 100644 --- a/src/webauthn/src/AuthenticatorAssertionResponse.php +++ b/src/webauthn/src/AuthenticatorAssertionResponse.php @@ -30,22 +30,4 @@ public static function create( ): self { return new self($clientDataJSON, $authenticatorData, $signature, $userHandle, $attestationObject); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getSignature(): string - { - return $this->signature; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUserHandle(): ?string - { - return $this->userHandle; - } } diff --git a/src/webauthn/src/AuthenticatorAssertionResponseValidator.php b/src/webauthn/src/AuthenticatorAssertionResponseValidator.php index 9867c5ef..f222484b 100644 --- a/src/webauthn/src/AuthenticatorAssertionResponseValidator.php +++ b/src/webauthn/src/AuthenticatorAssertionResponseValidator.php @@ -4,182 +4,48 @@ namespace Webauthn; -use Cose\Algorithm\Manager; use Psr\EventDispatcher\EventDispatcherInterface; -use Psr\Http\Message\ServerRequestInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Throwable; -use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler; use Webauthn\CeremonyStep\CeremonyStepManager; -use Webauthn\CeremonyStep\CeremonyStepManagerFactory; -use Webauthn\Counter\CounterChecker; use Webauthn\Event\AuthenticatorAssertionResponseValidationFailedEvent; use Webauthn\Event\AuthenticatorAssertionResponseValidationSucceededEvent; use Webauthn\Exception\AuthenticatorResponseVerificationException; use Webauthn\MetadataService\CanLogData; use Webauthn\MetadataService\Event\CanDispatchEvents; use Webauthn\MetadataService\Event\NullEventDispatcher; -use Webauthn\TokenBinding\TokenBindingHandler; -use function is_string; class AuthenticatorAssertionResponseValidator implements CanLogData, CanDispatchEvents { private LoggerInterface $logger; - private readonly CeremonyStepManagerFactory $ceremonyStepManagerFactory; - private EventDispatcherInterface $eventDispatcher; public function __construct( - private readonly null|PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository = null, - private readonly null|TokenBindingHandler $tokenBindingHandler = null, - null|ExtensionOutputCheckerHandler $extensionOutputCheckerHandler = null, - null|Manager $algorithmManager = null, - null|EventDispatcherInterface $eventDispatcher = null, - private null|CeremonyStepManager $ceremonyStepManager = null + private readonly CeremonyStepManager $ceremonyStepManager ) { - if ($this->publicKeyCredentialSourceRepository !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.6.0', - 'The parameter "$publicKeyCredentialSourceRepository" is deprecated since 4.6.0 and will be removed in 5.0.0. Please set "null" instead.' - ); - } - if ($this->tokenBindingHandler !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.3.0', - 'The parameter "$tokenBindingHandler" is deprecated since 4.3.0 and will be removed in 5.0.0. Please set "null" instead.' - ); - } - if ($extensionOutputCheckerHandler !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$extensionOutputCheckerHandler" is deprecated since 4.8.0 and will be removed in 5.0.0. Please set "null" instead and inject a CheckExtensions object into the CeremonyStepManager.' - ); - } - if ($algorithmManager !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$algorithmManager" is deprecated since 4.8.0 and will be removed in 5.0.0. Please set "null" instead and inject a CheckSignature object into the CeremonyStepManager.' - ); - } - $this->eventDispatcher = $eventDispatcher ?? new NullEventDispatcher(); - if ($eventDispatcher !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - 'The parameter "$eventDispatcher" is deprecated since 4.5.0 will be removed in 5.0.0. Please use `setEventDispatcher` instead.' - ); - } - if ($this->ceremonyStepManager === null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$ceremonyStepManager" will mandatory in 5.0.0. Please set a CeremonyStepManager object instead and set null for $algorithmManager and $extensionOutputCheckerHandler.' - ); - } + $this->eventDispatcher = new NullEventDispatcher(); $this->logger = new NullLogger(); - - $this->ceremonyStepManagerFactory = new CeremonyStepManagerFactory(); - if ($extensionOutputCheckerHandler !== null) { - $this->ceremonyStepManagerFactory->setExtensionOutputCheckerHandler($extensionOutputCheckerHandler); - } - if ($algorithmManager !== null) { - $this->ceremonyStepManagerFactory->setAlgorithmManager($algorithmManager); - } } - public static function create( - null|PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository = null, - null|TokenBindingHandler $tokenBindingHandler = null, - null|ExtensionOutputCheckerHandler $extensionOutputCheckerHandler = null, - null|Manager $algorithmManager = null, - null|EventDispatcherInterface $eventDispatcher = null, - null|CeremonyStepManager $ceremonyStepManager = null - ): self { - return new self( - $publicKeyCredentialSourceRepository, - $tokenBindingHandler, - $extensionOutputCheckerHandler, - $algorithmManager, - $eventDispatcher, - $ceremonyStepManager - ); + public static function create(CeremonyStepManager $ceremonyStepManager): self + { + return new self($ceremonyStepManager); } /** - * @param string[] $securedRelyingPartyId - * * @see https://www.w3.org/TR/webauthn/#verifying-assertion */ public function check( - string|PublicKeyCredentialSource $credentialId, + PublicKeyCredentialSource $publicKeyCredentialSource, AuthenticatorAssertionResponse $authenticatorAssertionResponse, PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, - ServerRequestInterface|string $request, + string $host, ?string $userHandle, - null|array $securedRelyingPartyId = null ): PublicKeyCredentialSource { - if ($request instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the method `check` of the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } - if (is_string($credentialId)) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.6.0', - sprintf( - 'Passing a string as first to the method `check` of the class "%s" is deprecated since 4.6.0. Please inject a %s object instead.', - self::class, - PublicKeyCredentialSource::class - ) - ); - } - if ($securedRelyingPartyId !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - sprintf( - 'Passing a list or secured relying party IDs to the method `check` of the class "%s" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a CheckOrigin into the CeremonyStepManager instead.', - self::class - ) - ); - } - - if ($credentialId instanceof PublicKeyCredentialSource) { - $publicKeyCredentialSource = $credentialId; - } else { - $this->publicKeyCredentialSourceRepository instanceof PublicKeyCredentialSourceRepository || throw AuthenticatorResponseVerificationException::create( - 'Please pass the Public Key Credential Source to the method "check".' - ); - $publicKeyCredentialSource = $this->publicKeyCredentialSourceRepository->findOneByCredentialId( - $credentialId - ); - } - $publicKeyCredentialSource !== null || throw AuthenticatorResponseVerificationException::create( - 'The credential ID is invalid.' - ); - $host = is_string($request) ? $request : $request->getUri() - ->getHost(); - - if ($this->ceremonyStepManager === null) { - $this->ceremonyStepManager = $this->ceremonyStepManagerFactory->requestCeremony($securedRelyingPartyId); - } - try { $this->logger->info('Checking the authenticator assertion response', [ - 'credentialId' => $credentialId, 'publicKeyCredentialSource' => $publicKeyCredentialSource, 'authenticatorAssertionResponse' => $authenticatorAssertionResponse, 'publicKeyCredentialRequestOptions' => $publicKeyCredentialRequestOptions, @@ -206,11 +72,6 @@ public function check( * OPTIONALLY, if response.attestationObject is present, update credentialRecord.attestationObject to the value of response.attestationObject and update credentialRecord.attestationClientDataJSON to the value of response.clientDataJSON. */ - if (is_string( - $credentialId - ) && ($this->publicKeyCredentialSourceRepository instanceof PublicKeyCredentialSourceRepository)) { - $this->publicKeyCredentialSourceRepository->saveCredentialSource($publicKeyCredentialSource); - } //All good. We can continue. $this->logger->info('The assertion is valid'); $this->logger->debug('Public Key Credential Source', [ @@ -218,7 +79,6 @@ public function check( ]); $this->eventDispatcher->dispatch( $this->createAuthenticatorAssertionResponseValidationSucceededEvent( - null, $authenticatorAssertionResponse, $publicKeyCredentialRequestOptions, $host, @@ -256,36 +116,14 @@ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): v $this->eventDispatcher = $eventDispatcher; } - /** - * @deprecated since 4.8.0 and will be removed in 5.0.0. Please inject a CheckCounter object into a CeremonyStepManager instead. - */ - public function setCounterChecker(CounterChecker $counterChecker): self - { - $this->ceremonyStepManagerFactory->setCounterChecker($counterChecker); - return $this; - } - protected function createAuthenticatorAssertionResponseValidationSucceededEvent( - null|string $credentialId, AuthenticatorAssertionResponse $authenticatorAssertionResponse, PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, - ServerRequestInterface|string $host, + string $host, ?string $userHandle, PublicKeyCredentialSource $publicKeyCredentialSource ): AuthenticatorAssertionResponseValidationSucceededEvent { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the method `createAuthenticatorAssertionResponseValidationSucceededEvent` of the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } return new AuthenticatorAssertionResponseValidationSucceededEvent( - $credentialId, $authenticatorAssertionResponse, $publicKeyCredentialRequestOptions, $host, @@ -295,24 +133,13 @@ protected function createAuthenticatorAssertionResponseValidationSucceededEvent( } protected function createAuthenticatorAssertionResponseValidationFailedEvent( - string|PublicKeyCredentialSource $publicKeyCredentialSource, + PublicKeyCredentialSource $publicKeyCredentialSource, AuthenticatorAssertionResponse $authenticatorAssertionResponse, PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, - ServerRequestInterface|string $host, + string $host, ?string $userHandle, Throwable $throwable ): AuthenticatorAssertionResponseValidationFailedEvent { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the method `createAuthenticatorAssertionResponseValidationFailedEvent` of the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } return new AuthenticatorAssertionResponseValidationFailedEvent( $publicKeyCredentialSource, $authenticatorAssertionResponse, diff --git a/src/webauthn/src/AuthenticatorAttestationResponse.php b/src/webauthn/src/AuthenticatorAttestationResponse.php index 875bc525..2c96be7a 100644 --- a/src/webauthn/src/AuthenticatorAttestationResponse.php +++ b/src/webauthn/src/AuthenticatorAttestationResponse.php @@ -32,24 +32,4 @@ public static function create( ): self { return new self($clientDataJSON, $attestationObject, $transports); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestationObject(): AttestationObject - { - return $this->attestationObject; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - * - * @return string[] - */ - public function getTransports(): array - { - return $this->transports; - } } diff --git a/src/webauthn/src/AuthenticatorAttestationResponseValidator.php b/src/webauthn/src/AuthenticatorAttestationResponseValidator.php index 34310b5d..775dbd4e 100644 --- a/src/webauthn/src/AuthenticatorAttestationResponseValidator.php +++ b/src/webauthn/src/AuthenticatorAttestationResponseValidator.php @@ -5,25 +5,16 @@ namespace Webauthn; use Psr\EventDispatcher\EventDispatcherInterface; -use Psr\Http\Message\ServerRequestInterface; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; use Throwable; -use Webauthn\AttestationStatement\AttestationStatementSupportManager; -use Webauthn\AuthenticationExtensions\ExtensionOutputCheckerHandler; use Webauthn\CeremonyStep\CeremonyStepManager; -use Webauthn\CeremonyStep\CeremonyStepManagerFactory; use Webauthn\Event\AuthenticatorAttestationResponseValidationFailedEvent; use Webauthn\Event\AuthenticatorAttestationResponseValidationSucceededEvent; use Webauthn\Exception\AuthenticatorResponseVerificationException; use Webauthn\MetadataService\CanLogData; -use Webauthn\MetadataService\CertificateChain\CertificateChainValidator; use Webauthn\MetadataService\Event\CanDispatchEvents; use Webauthn\MetadataService\Event\NullEventDispatcher; -use Webauthn\MetadataService\MetadataStatementRepository; -use Webauthn\MetadataService\StatusReportRepository; -use Webauthn\TokenBinding\TokenBindingHandler; -use function is_string; class AuthenticatorAttestationResponseValidator implements CanLogData, CanDispatchEvents { @@ -31,88 +22,16 @@ class AuthenticatorAttestationResponseValidator implements CanLogData, CanDispat private EventDispatcherInterface $eventDispatcher; - private readonly CeremonyStepManagerFactory $ceremonyStepManagerFactory; - public function __construct( - null|AttestationStatementSupportManager $attestationStatementSupportManager = null, - private readonly null|PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository = null, - private readonly null|TokenBindingHandler $tokenBindingHandler = null, - null|ExtensionOutputCheckerHandler $extensionOutputCheckerHandler = null, - null|EventDispatcherInterface $eventDispatcher = null, - private null|CeremonyStepManager $ceremonyStepManager = null + private readonly CeremonyStepManager $ceremonyStepManager ) { - if ($this->publicKeyCredentialSourceRepository !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.6.0', - 'The parameter "$publicKeyCredentialSourceRepository" is deprecated since 4.6.0 and will be removed in 5.0.0. Please set "null" instead.' - ); - } - if ($this->tokenBindingHandler !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.3.0', - 'The parameter "$tokenBindingHandler" is deprecated since 4.3.0 and will be removed in 5.0.0. Please set "null" instead.' - ); - } - if ($extensionOutputCheckerHandler !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$extensionOutputCheckerHandler" is deprecated since 4.8.0 and will be removed in 5.0.0. Please set "null" instead and inject a CheckExtensions object into the CeremonyStepManager.' - ); - } - $this->eventDispatcher = $eventDispatcher ?? new NullEventDispatcher(); - if ($eventDispatcher !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - 'The parameter "$eventDispatcher" is deprecated since 4.5.0 will be removed in 5.0.0. Please use `setEventDispatcher` instead.' - ); - } - if ($this->ceremonyStepManager === null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$ceremonyStepManager" will mandatory in 5.0.0. Please set a CeremonyStepManager object instead and set null for $attestationStatementSupportManager and $extensionOutputCheckerHandler.' - ); - } + $this->eventDispatcher = new NullEventDispatcher(); $this->logger = new NullLogger(); - $this->ceremonyStepManagerFactory = new CeremonyStepManagerFactory(); - if ($attestationStatementSupportManager !== null) { - $this->ceremonyStepManagerFactory->setAttestationStatementSupportManager( - $attestationStatementSupportManager - ); - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$attestationStatementSupportManager" is deprecated since 4.8.0 will be removed in 5.0.0. Please set a CheckAttestationFormatIsKnownAndValid object into CeremonyStepManager object instead.' - ); - } - if ($extensionOutputCheckerHandler !== null) { - $this->ceremonyStepManagerFactory->setExtensionOutputCheckerHandler($extensionOutputCheckerHandler); - } } - /** - * @private Will become private in 5.0.0 - */ - public static function create( - null|AttestationStatementSupportManager $attestationStatementSupportManager = null, - null|PublicKeyCredentialSourceRepository $publicKeyCredentialSourceRepository = null, - null|TokenBindingHandler $tokenBindingHandler = null, - null|ExtensionOutputCheckerHandler $extensionOutputCheckerHandler = null, - null|EventDispatcherInterface $eventDispatcher = null, - null|CeremonyStepManager $ceremonyStepManager = null, - ): self { - return new self( - $attestationStatementSupportManager, - $publicKeyCredentialSourceRepository, - $tokenBindingHandler, - $extensionOutputCheckerHandler, - $eventDispatcher, - $ceremonyStepManager - ); + public static function create(CeremonyStepManager $ceremonyStepManager): self + { + return new self($ceremonyStepManager); } public function setLogger(LoggerInterface $logger): void @@ -126,75 +45,19 @@ public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): v } /** - * @deprecated since 4.8.0 and will be removed in 5.0.0. Please use the CheckMetadataStatement object from the CeremonyStepManager instead. - */ - public function setCertificateChainValidator(CertificateChainValidator $certificateChainValidator): self - { - $this->ceremonyStepManagerFactory->enableCertificateChainValidator($certificateChainValidator); - return $this; - } - - /** - * @deprecated since 4.8.0 and will be removed in 5.0.0. Please use the CheckMetadataStatement object from the CeremonyStepManager instead. - */ - public function enableMetadataStatementSupport( - MetadataStatementRepository $metadataStatementRepository, - StatusReportRepository $statusReportRepository, - CertificateChainValidator $certificateChainValidator - ): self { - $this->ceremonyStepManagerFactory->enableMetadataStatementSupport( - $metadataStatementRepository, - $statusReportRepository, - $certificateChainValidator - ); - return $this; - } - - /** - * @param string[] $securedRelyingPartyId - * * @see https://www.w3.org/TR/webauthn/#registering-a-new-credential */ public function check( AuthenticatorAttestationResponse $authenticatorAttestationResponse, PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, - ServerRequestInterface|string $request, - null|array $securedRelyingPartyId = null, + string $host, ): PublicKeyCredentialSource { - if ($request instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the method `check` of the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } - if ($securedRelyingPartyId !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - sprintf( - 'Passing a list or secured relying party IDs to the method `check` of the class "%s" is deprecated since 4.8.0 and will be removed in 5.0.0. Please inject the list instead.', - self::class - ) - ); - } - $host = is_string($request) ? $request : $request->getUri() - ->getHost(); try { $this->logger->info('Checking the authenticator attestation response', [ 'authenticatorAttestationResponse' => $authenticatorAttestationResponse, 'publicKeyCredentialCreationOptions' => $publicKeyCredentialCreationOptions, 'host' => $host, ]); - if ($this->ceremonyStepManager === null) { - $this->ceremonyStepManager = $this->ceremonyStepManagerFactory->creationCeremony( - $securedRelyingPartyId - ); - } $publicKeyCredentialSource = $this->createPublicKeyCredentialSource( $authenticatorAttestationResponse, @@ -246,20 +109,9 @@ public function check( protected function createAuthenticatorAttestationResponseValidationSucceededEvent( AuthenticatorAttestationResponse $authenticatorAttestationResponse, PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, - ServerRequestInterface|string $host, + string $host, PublicKeyCredentialSource $publicKeyCredentialSource ): AuthenticatorAttestationResponseValidationSucceededEvent { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the method `createAuthenticatorAttestationResponseValidationSucceededEvent` of the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } return new AuthenticatorAttestationResponseValidationSucceededEvent( $authenticatorAttestationResponse, $publicKeyCredentialCreationOptions, @@ -271,20 +123,9 @@ protected function createAuthenticatorAttestationResponseValidationSucceededEven protected function createAuthenticatorAttestationResponseValidationFailedEvent( AuthenticatorAttestationResponse $authenticatorAttestationResponse, PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, - ServerRequestInterface|string $host, + string $host, Throwable $throwable ): AuthenticatorAttestationResponseValidationFailedEvent { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the method `createAuthenticatorAttestationResponseValidationFailedEvent` of the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } return new AuthenticatorAttestationResponseValidationFailedEvent( $authenticatorAttestationResponse, $publicKeyCredentialCreationOptions, diff --git a/src/webauthn/src/AuthenticatorData.php b/src/webauthn/src/AuthenticatorData.php index f21ff062..c2666342 100644 --- a/src/webauthn/src/AuthenticatorData.php +++ b/src/webauthn/src/AuthenticatorData.php @@ -13,24 +13,24 @@ */ class AuthenticatorData { - final public const FLAG_UP = 0b00000001; + final public const int FLAG_UP = 0b00000001; - final public const FLAG_RFU1 = 0b00000010; + final public const int FLAG_RFU1 = 0b00000010; - final public const FLAG_UV = 0b00000100; + final public const int FLAG_UV = 0b00000100; - final public const FLAG_BE = 0b00001000; + final public const int FLAG_BE = 0b00001000; - final public const FLAG_BS = 0b00010000; + final public const int FLAG_BS = 0b00010000; /** * TODO: remove bits 3 and 4 as they have been assigned to BE and BS in Webauthn level 3. */ - final public const FLAG_RFU2 = 0b00111000; + final public const int FLAG_RFU2 = 0b00111000; - final public const FLAG_AT = 0b01000000; + final public const int FLAG_AT = 0b01000000; - final public const FLAG_ED = 0b10000000; + final public const int FLAG_ED = 0b10000000; public function __construct( public readonly string $authData, @@ -53,24 +53,6 @@ public static function create( return new self($authData, $rpIdHash, $flags, $signCount, $attestedCredentialData, $extensions); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAuthData(): string - { - return $this->authData; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRpIdHash(): string - { - return $this->rpIdHash; - } - public function isUserPresent(): bool { return 0 !== (ord($this->flags) & self::FLAG_UP); @@ -110,31 +92,4 @@ public function getReservedForFutureUse2(): int { return ord($this->flags) & self::FLAG_RFU2; } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getSignCount(): int - { - return $this->signCount; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestedCredentialData(): ?AttestedCredentialData - { - return $this->attestedCredentialData; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getExtensions(): ?AuthenticationExtensions - { - return $this->extensions !== null && $this->hasExtensions() ? $this->extensions : null; - } } diff --git a/src/webauthn/src/AuthenticatorDataLoader.php b/src/webauthn/src/AuthenticatorDataLoader.php index e09e6437..a622e2f7 100644 --- a/src/webauthn/src/AuthenticatorDataLoader.php +++ b/src/webauthn/src/AuthenticatorDataLoader.php @@ -12,7 +12,7 @@ use CBOR\TextStringObject; use CBOR\UnsignedIntegerObject; use Symfony\Component\Uid\Uuid; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputsLoader; +use Webauthn\AuthenticationExtensions\AuthenticationExtensionLoader; use Webauthn\Exception\InvalidDataException; use function chr; use function ord; @@ -61,7 +61,7 @@ public function load(string $authData): AuthenticatorData $extension = null; if (0 !== (ord($flags) & AuthenticatorData::FLAG_ED)) { $extension = $this->decoder->decode($authDataStream); - $extension = AuthenticationExtensionsClientOutputsLoader::load($extension); + $extension = AuthenticationExtensionLoader::load($extension); } $authDataStream->isEOF() || throw InvalidDataException::create( $authData, diff --git a/src/webauthn/src/AuthenticatorResponse.php b/src/webauthn/src/AuthenticatorResponse.php index 162c24db..5e8cb43f 100644 --- a/src/webauthn/src/AuthenticatorResponse.php +++ b/src/webauthn/src/AuthenticatorResponse.php @@ -13,13 +13,4 @@ public function __construct( public readonly CollectedClientData $clientDataJSON ) { } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getClientDataJSON(): CollectedClientData - { - return $this->clientDataJSON; - } } diff --git a/src/webauthn/src/AuthenticatorSelectionCriteria.php b/src/webauthn/src/AuthenticatorSelectionCriteria.php index 8e47e92e..fb2e5931 100644 --- a/src/webauthn/src/AuthenticatorSelectionCriteria.php +++ b/src/webauthn/src/AuthenticatorSelectionCriteria.php @@ -5,54 +5,43 @@ namespace Webauthn; use InvalidArgumentException; -use JsonSerializable; -use Webauthn\Exception\InvalidDataException; use function in_array; -use function is_bool; -use function is_string; -use const JSON_THROW_ON_ERROR; -class AuthenticatorSelectionCriteria implements JsonSerializable +class AuthenticatorSelectionCriteria { - final public const AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE = null; + final public const null AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE = null; - final public const AUTHENTICATOR_ATTACHMENT_PLATFORM = 'platform'; + final public const string AUTHENTICATOR_ATTACHMENT_PLATFORM = 'platform'; - final public const AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM = 'cross-platform'; + final public const string AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM = 'cross-platform'; - final public const AUTHENTICATOR_ATTACHMENTS = [ + final public const array AUTHENTICATOR_ATTACHMENTS = [ self::AUTHENTICATOR_ATTACHMENT_NO_PREFERENCE, self::AUTHENTICATOR_ATTACHMENT_PLATFORM, self::AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM, ]; - final public const USER_VERIFICATION_REQUIREMENT_REQUIRED = 'required'; + final public const string USER_VERIFICATION_REQUIREMENT_REQUIRED = 'required'; - final public const USER_VERIFICATION_REQUIREMENT_PREFERRED = 'preferred'; + final public const string USER_VERIFICATION_REQUIREMENT_PREFERRED = 'preferred'; - final public const USER_VERIFICATION_REQUIREMENT_DISCOURAGED = 'discouraged'; + final public const string USER_VERIFICATION_REQUIREMENT_DISCOURAGED = 'discouraged'; - final public const USER_VERIFICATION_REQUIREMENTS = [ + final public const array USER_VERIFICATION_REQUIREMENTS = [ self::USER_VERIFICATION_REQUIREMENT_REQUIRED, self::USER_VERIFICATION_REQUIREMENT_PREFERRED, self::USER_VERIFICATION_REQUIREMENT_DISCOURAGED, ]; - final public const RESIDENT_KEY_REQUIREMENT_NO_PREFERENCE = null; + final public const null RESIDENT_KEY_REQUIREMENT_NO_PREFERENCE = null; - /** - * @deprecated Please use AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_NO_PREFERENCE instead - * @infection-ignore-all - */ - final public const RESIDENT_KEY_REQUIREMENT_NONE = null; + final public const string RESIDENT_KEY_REQUIREMENT_REQUIRED = 'required'; - final public const RESIDENT_KEY_REQUIREMENT_REQUIRED = 'required'; + final public const string RESIDENT_KEY_REQUIREMENT_PREFERRED = 'preferred'; - final public const RESIDENT_KEY_REQUIREMENT_PREFERRED = 'preferred'; + final public const string RESIDENT_KEY_REQUIREMENT_DISCOURAGED = 'discouraged'; - final public const RESIDENT_KEY_REQUIREMENT_DISCOURAGED = 'discouraged'; - - final public const RESIDENT_KEY_REQUIREMENTS = [ + final public const array RESIDENT_KEY_REQUIREMENTS = [ self::RESIDENT_KEY_REQUIREMENT_NO_PREFERENCE, self::RESIDENT_KEY_REQUIREMENT_REQUIRED, self::RESIDENT_KEY_REQUIREMENT_PREFERRED, @@ -63,8 +52,6 @@ public function __construct( public null|string $authenticatorAttachment = null, public string $userVerification = self::USER_VERIFICATION_REQUIREMENT_PREFERRED, public null|string $residentKey = self::RESIDENT_KEY_REQUIREMENT_NO_PREFERENCE, - /** @deprecated Will be removed in 5.0. Please use residentKey instead**/ - public null|bool $requireResidentKey = null, ) { in_array($authenticatorAttachment, self::AUTHENTICATOR_ATTACHMENTS, true) || throw new InvalidArgumentException( 'Invalid authenticator attachment' @@ -75,178 +62,13 @@ public function __construct( in_array($residentKey, self::RESIDENT_KEY_REQUIREMENTS, true) || throw new InvalidArgumentException( 'Invalid resident key' ); - if ($requireResidentKey === true && $residentKey !== null && $residentKey !== self::RESIDENT_KEY_REQUIREMENT_REQUIRED) { - throw new InvalidArgumentException( - 'Invalid resident key requirement. Resident key is required but requireResidentKey is false' - ); - } - if ($this->residentKey === null && $this->requireResidentKey === true) { - $this->residentKey = self::RESIDENT_KEY_REQUIREMENT_REQUIRED; - } - $this->requireResidentKey = $requireResidentKey ?? ($residentKey === null ? null : $residentKey === self::RESIDENT_KEY_REQUIREMENT_REQUIRED); } public static function create( ?string $authenticatorAttachment = null, string $userVerification = self::USER_VERIFICATION_REQUIREMENT_PREFERRED, null|string $residentKey = self::RESIDENT_KEY_REQUIREMENT_NO_PREFERENCE, - null|bool $requireResidentKey = null ): self { - return new self($authenticatorAttachment, $userVerification, $residentKey, $requireResidentKey); - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setAuthenticatorAttachment(?string $authenticatorAttachment): self - { - $this->authenticatorAttachment = $authenticatorAttachment; - - return $this; - } - - /** - * @deprecated since v4.1. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setRequireResidentKey(bool $requireResidentKey): self - { - $this->requireResidentKey = $requireResidentKey; - if ($requireResidentKey === true) { - $this->residentKey = self::RESIDENT_KEY_REQUIREMENT_REQUIRED; - } - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setUserVerification(string $userVerification): self - { - $this->userVerification = $userVerification; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setResidentKey(null|string $residentKey): self - { - $this->residentKey = $residentKey; - $this->requireResidentKey = $residentKey === self::RESIDENT_KEY_REQUIREMENT_REQUIRED; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAuthenticatorAttachment(): ?string - { - return $this->authenticatorAttachment; - } - - /** - * @deprecated Will be removed in 5.0. Please use the property directly. - * @infection-ignore-all - */ - public function isRequireResidentKey(): bool - { - return $this->requireResidentKey; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUserVerification(): string - { - return $this->userVerification; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getResidentKey(): null|string - { - return $this->residentKey; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromString(string $data): self - { - $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); - - return self::createFromArray($data); - } - - /** - * @param mixed[] $json - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $json): self - { - $authenticatorAttachment = $json['authenticatorAttachment'] ?? null; - $requireResidentKey = $json['requireResidentKey'] ?? null; - $userVerification = $json['userVerification'] ?? self::USER_VERIFICATION_REQUIREMENT_PREFERRED; - $residentKey = $json['residentKey'] ?? null; - - $authenticatorAttachment === null || is_string($authenticatorAttachment) || throw InvalidDataException::create( - $json, - 'Invalid "authenticatorAttachment" value' - ); - ($requireResidentKey === null || is_bool($requireResidentKey)) || throw InvalidDataException::create( - $json, - 'Invalid "requireResidentKey" value' - ); - is_string($userVerification) || throw InvalidDataException::create($json, 'Invalid "userVerification" value'); - ($residentKey === null || is_string($residentKey)) || throw InvalidDataException::create( - $json, - 'Invalid "residentKey" value' - ); - - return self::create( - $authenticatorAttachment ?? null, - $userVerification, - $residentKey, - $requireResidentKey, - ); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $json = [ - 'requireResidentKey' => $this->requireResidentKey, - 'userVerification' => $this->userVerification, - 'residentKey' => $this->residentKey, - 'authenticatorAttachment' => $this->authenticatorAttachment, - ]; - foreach ($json as $key => $value) { - if ($value === null) { - unset($json[$key]); - } - } - - return $json; + return new self($authenticatorAttachment, $userVerification, $residentKey); } } diff --git a/src/webauthn/src/CeremonyStep/CeremonyStepManagerFactory.php b/src/webauthn/src/CeremonyStep/CeremonyStepManagerFactory.php index cc58ae3b..efe4641e 100644 --- a/src/webauthn/src/CeremonyStep/CeremonyStepManagerFactory.php +++ b/src/webauthn/src/CeremonyStep/CeremonyStepManagerFactory.php @@ -98,10 +98,7 @@ public function enableTopOriginValidator(TopOriginValidator $topOriginValidator) $this->topOriginValidator = $topOriginValidator; } - /** - * @param null|string[] $securedRelyingPartyId - */ - public function creationCeremony(null|array $securedRelyingPartyId = null): CeremonyStepManager + public function creationCeremony(): CeremonyStepManager { $metadataStatementChecker = new CheckMetadataStatement(); if ($this->certificateChainValidator !== null) { @@ -119,7 +116,7 @@ public function creationCeremony(null|array $securedRelyingPartyId = null): Cere return new CeremonyStepManager([ new CheckClientDataCollectorType(), new CheckChallenge(), - new CheckOrigin($this->securedRelyingPartyId ?? $securedRelyingPartyId ?? []), + new CheckOrigin($this->securedRelyingPartyId ?? []), new CheckTopOrigin($this->topOriginValidator), new CheckRelyingPartyIdIdHash(), new CheckUserWasPresent(), @@ -134,10 +131,7 @@ public function creationCeremony(null|array $securedRelyingPartyId = null): Cere ]); } - /** - * @param null|string[] $securedRelyingPartyId - */ - public function requestCeremony(null|array $securedRelyingPartyId = null): CeremonyStepManager + public function requestCeremony(): CeremonyStepManager { /* @see https://www.w3.org/TR/webauthn-3/#sctn-verifying-assertion */ return new CeremonyStepManager([ @@ -145,7 +139,7 @@ public function requestCeremony(null|array $securedRelyingPartyId = null): Cerem new CheckUserHandle(), new CheckClientDataCollectorType(), new CheckChallenge(), - new CheckOrigin($this->securedRelyingPartyId ?? $securedRelyingPartyId ?? []), + new CheckOrigin($this->securedRelyingPartyId ?? []), new CheckTopOrigin(null), new CheckRelyingPartyIdIdHash(), new CheckUserWasPresent(), diff --git a/src/webauthn/src/CeremonyStep/CheckMetadataStatement.php b/src/webauthn/src/CeremonyStep/CheckMetadataStatement.php index ce482a4a..74debbd2 100644 --- a/src/webauthn/src/CeremonyStep/CheckMetadataStatement.php +++ b/src/webauthn/src/CeremonyStep/CheckMetadataStatement.php @@ -148,7 +148,6 @@ private function getAttestationType(AttestationStatement $attestationStatement): AttestationStatement::TYPE_BASIC => MetadataStatement::ATTESTATION_BASIC_FULL, AttestationStatement::TYPE_SELF => MetadataStatement::ATTESTATION_BASIC_SURROGATE, AttestationStatement::TYPE_ATTCA => MetadataStatement::ATTESTATION_ATTCA, - AttestationStatement::TYPE_ECDAA => MetadataStatement::ATTESTATION_ECDAA, AttestationStatement::TYPE_ANONCA => MetadataStatement::ATTESTATION_ANONCA, default => throw AuthenticatorResponseVerificationException::create('Invalid attestation type'), }; diff --git a/src/webauthn/src/CeremonyStep/CheckOrigin.php b/src/webauthn/src/CeremonyStep/CheckOrigin.php index 950cf6f8..1761aeec 100644 --- a/src/webauthn/src/CeremonyStep/CheckOrigin.php +++ b/src/webauthn/src/CeremonyStep/CheckOrigin.php @@ -15,13 +15,13 @@ use function is_array; use function is_string; -final class CheckOrigin implements CeremonyStep +final readonly class CheckOrigin implements CeremonyStep { /** * @param string[] $securedRelyingPartyId */ public function __construct( - private readonly array $securedRelyingPartyId + private array $securedRelyingPartyId ) { } @@ -58,15 +58,15 @@ public function process( private function getFacetId( string $rpId, - AuthenticationExtensions $authenticationExtensionsClientInputs, + AuthenticationExtensions $AuthenticationExtensions, null|AuthenticationExtensions $authenticationExtensionsClientOutputs ): string { - if ($authenticationExtensionsClientOutputs === null || ! $authenticationExtensionsClientInputs->has( + if ($authenticationExtensionsClientOutputs === null || ! $AuthenticationExtensions->has( 'appid' ) || ! $authenticationExtensionsClientOutputs->has('appid')) { return $rpId; } - $appId = $authenticationExtensionsClientInputs->get('appid') + $appId = $AuthenticationExtensions->get('appid') ->value; $wasUsed = $authenticationExtensionsClientOutputs->get('appid') ->value; diff --git a/src/webauthn/src/CeremonyStep/CheckRelyingPartyIdIdHash.php b/src/webauthn/src/CeremonyStep/CheckRelyingPartyIdIdHash.php index de45b27b..8465a01d 100644 --- a/src/webauthn/src/CeremonyStep/CheckRelyingPartyIdIdHash.php +++ b/src/webauthn/src/CeremonyStep/CheckRelyingPartyIdIdHash.php @@ -43,15 +43,15 @@ public function process( private function getFacetId( string $rpId, - AuthenticationExtensions $authenticationExtensionsClientInputs, + AuthenticationExtensions $AuthenticationExtensions, null|AuthenticationExtensions $authenticationExtensionsClientOutputs ): string { - if ($authenticationExtensionsClientOutputs === null || ! $authenticationExtensionsClientInputs->has( + if ($authenticationExtensionsClientOutputs === null || ! $AuthenticationExtensions->has( 'appid' ) || ! $authenticationExtensionsClientOutputs->has('appid')) { return $rpId; } - $appId = $authenticationExtensionsClientInputs->get('appid') + $appId = $AuthenticationExtensions->get('appid') ->value; $wasUsed = $authenticationExtensionsClientOutputs->get('appid') ->value; diff --git a/src/webauthn/src/CertificateChainChecker/CertificateChainChecker.php b/src/webauthn/src/CertificateChainChecker/CertificateChainChecker.php deleted file mode 100644 index 60837ccd..00000000 --- a/src/webauthn/src/CertificateChainChecker/CertificateChainChecker.php +++ /dev/null @@ -1,15 +0,0 @@ -tokenBinding = $tokenBinding; $this->data = $data; } @@ -99,60 +90,6 @@ public static function createFormJson(string $data): self return self::create($rawData, $json); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getType(): string - { - return $this->type; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getChallenge(): string - { - return $this->challenge; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getOrigin(): string - { - return $this->origin; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCrossOrigin(): bool - { - return $this->crossOrigin; - } - - /** - * @deprecated Since 4.3.0 and will be removed in 5.0.0 - * @infection-ignore-all - */ - public function getTokenBinding(): ?TokenBinding - { - return $this->tokenBinding === null ? null : TokenBinding::createFormArray($this->tokenBinding); - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRawData(): string - { - return $this->rawData; - } - /** * @return string[] */ diff --git a/src/webauthn/src/Credential.php b/src/webauthn/src/Credential.php index c53e8585..5b05f2eb 100644 --- a/src/webauthn/src/Credential.php +++ b/src/webauthn/src/Credential.php @@ -4,56 +4,14 @@ namespace Webauthn; -use InvalidArgumentException; - /** * @see https://w3c.github.io/webappsec-credential-management/#credential */ abstract class Credential { - /** - * @deprecated since 4.9.0. Please use the property rawId instead. - */ - public readonly string $id; - - public readonly string $rawId; - public function __construct( - null|string $id, public readonly string $type, - null|string $rawId = null, + public readonly string $rawId, ) { - if ($id === null && $rawId === null) { - throw new InvalidArgumentException('You must provide a valid raw ID'); - } - if ($id !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.9.0', - 'The property "$id" is deprecated and will be removed in 5.0.0. Please set null use "rawId" instead.' - ); - } else { - $id = base64_encode($rawId); - } - $this->id = $id; - $this->rawId = $rawId ?? base64_encode($id); - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getId(): string - { - return $this->id; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getType(): string - { - return $this->type; } } diff --git a/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php b/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php index 2a3f1ab2..6a5ac429 100644 --- a/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AuthenticationExtensionsDenormalizer.php @@ -8,10 +8,7 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Webauthn\AuthenticationExtensions\AuthenticationExtension; use Webauthn\AuthenticationExtensions\AuthenticationExtensions; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputs; use function assert; -use function in_array; use function is_array; use function is_string; @@ -35,15 +32,7 @@ public function denormalize(mixed $data, string $type, string $format = null, ar public function supportsDenormalization(mixed $data, string $type, string $format = null, array $context = []): bool { - return in_array( - $type, - [ - AuthenticationExtensions::class, - AuthenticationExtensionsClientOutputs::class, - AuthenticationExtensionsClientInputs::class, - ], - true - ); + return $type === AuthenticationExtensions::class; } /** @@ -53,16 +42,14 @@ public function getSupportedTypes(?string $format): array { return [ AuthenticationExtensions::class => true, - AuthenticationExtensionsClientInputs::class => true, - AuthenticationExtensionsClientOutputs::class => true, ]; } - public function normalize(mixed $data, ?string $format = null, array $context = []): array + public function normalize(mixed $object, ?string $format = null, array $context = []): array { - assert($data instanceof AuthenticationExtensions); + assert($object instanceof AuthenticationExtensions); $extensions = []; - foreach ($data->extensions as $extension) { + foreach ($object->extensions as $extension) { $extensions[$extension->name] = $extension->value; } diff --git a/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php b/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php index f13450d0..359edd59 100644 --- a/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php +++ b/src/webauthn/src/Denormalizer/AuthenticatorDataDenormalizer.php @@ -16,8 +16,8 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Uid\Uuid; use Webauthn\AttestedCredentialData; +use Webauthn\AuthenticationExtensions\AuthenticationExtensionLoader; use Webauthn\AuthenticationExtensions\AuthenticationExtensions; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputsLoader; use Webauthn\AuthenticatorData; use Webauthn\Exception\InvalidDataException; use Webauthn\StringStream; @@ -64,7 +64,7 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $extension = null; if (0 !== (ord($flags) & AuthenticatorData::FLAG_ED)) { $extension = $this->decoder->decode($authDataStream); - $extension = AuthenticationExtensionsClientOutputsLoader::load($extension); + $extension = AuthenticationExtensionLoader::load($extension); } $authDataStream->isEOF() || throw InvalidDataException::create( $authData, diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php index 33899b70..066b5a55 100644 --- a/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialDenormalizer.php @@ -29,7 +29,6 @@ public function denormalize(mixed $data, string $type, string $format = null, ar $data['rawId'] = $rawId; return PublicKeyCredential::create( - null, $data['type'], $data['rawId'], $this->denormalizer->denormalize($data['response'], AuthenticatorResponse::class, $format, $context), diff --git a/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php b/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php index d79b65c4..dcf7c06d 100644 --- a/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php +++ b/src/webauthn/src/Denormalizer/PublicKeyCredentialUserEntityDenormalizer.php @@ -44,14 +44,14 @@ public function getSupportedTypes(?string $format): array ]; } - public function normalize(mixed $data, ?string $format = null, array $context = []): array + public function normalize(mixed $object, ?string $format = null, array $context = []): array { - assert($data instanceof PublicKeyCredentialUserEntity); + assert($object instanceof PublicKeyCredentialUserEntity); $normalized = [ - 'id' => Base64UrlSafe::encodeUnpadded($data->id), - 'name' => $data->name, - 'displayName' => $data->displayName, - 'icon' => $data->icon, + 'id' => Base64UrlSafe::encodeUnpadded($object->id), + 'name' => $object->name, + 'displayName' => $object->displayName, + 'icon' => $object->icon, ]; return array_filter($normalized, fn ($value) => $value !== null); diff --git a/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php b/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php index c35ba1ff..b2397302 100644 --- a/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php +++ b/src/webauthn/src/Denormalizer/TrustPathDenormalizer.php @@ -8,7 +8,6 @@ use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Webauthn\Exception\InvalidTrustPathException; use Webauthn\TrustPath\CertificateTrustPath; -use Webauthn\TrustPath\EcdaaKeyIdTrustPath; use Webauthn\TrustPath\EmptyTrustPath; use Webauthn\TrustPath\TrustPath; use function array_key_exists; @@ -19,7 +18,6 @@ final class TrustPathDenormalizer implements DenormalizerInterface, NormalizerIn public function denormalize(mixed $data, string $type, string $format = null, array $context = []): mixed { return match (true) { - array_key_exists('ecdaaKeyId', $data) => new EcdaaKeyIdTrustPath($data), array_key_exists('x5c', $data) => CertificateTrustPath::create($data), $data === [], isset($data['type']) && $data['type'] === EmptyTrustPath::class => EmptyTrustPath::create(), default => throw new InvalidTrustPathException('Unsupported trust path type'), @@ -41,17 +39,14 @@ public function getSupportedTypes(?string $format): array ]; } - public function normalize(mixed $data, ?string $format = null, array $context = []): array + public function normalize(mixed $object, ?string $format = null, array $context = []): array { - assert($data instanceof TrustPath); + assert($object instanceof TrustPath); return match (true) { - $data instanceof EcdaaKeyIdTrustPath => [ - 'ecdaaKeyId' => $data->getEcdaaKeyId(), + $object instanceof CertificateTrustPath => [ + 'x5c' => $object->certificates, ], - $data instanceof CertificateTrustPath => [ - 'x5c' => $data->certificates, - ], - $data instanceof EmptyTrustPath => [], + $object instanceof EmptyTrustPath => [], default => throw new InvalidTrustPathException('Unsupported trust path type'), }; } diff --git a/src/webauthn/src/Denormalizer/WebauthnSerializerFactory.php b/src/webauthn/src/Denormalizer/WebauthnSerializerFactory.php index 694039a0..451339f4 100644 --- a/src/webauthn/src/Denormalizer/WebauthnSerializerFactory.php +++ b/src/webauthn/src/Denormalizer/WebauthnSerializerFactory.php @@ -16,16 +16,16 @@ use Symfony\Component\Serializer\SerializerInterface; use Webauthn\AttestationStatement\AttestationStatementSupportManager; -final class WebauthnSerializerFactory +final readonly class WebauthnSerializerFactory { private const PACKAGE_SYMFONY_PROPERTY_INFO = 'symfony/property-info'; private const PACKAGE_SYMFONY_SERIALIZER = 'symfony/serializer'; - private const PACKAGE_PHPDOCUMENTOR_REFLECTION_DOCBLOCK = 'phpdocumentor/reflection-docblock'; + private const string PACKAGE_PHPDOCUMENTOR_REFLECTION_DOCBLOCK = 'phpdocumentor/reflection-docblock'; public function __construct( - private readonly AttestationStatementSupportManager $attestationStatementSupportManager + private AttestationStatementSupportManager $attestationStatementSupportManager ) { } diff --git a/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationFailedEvent.php b/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationFailedEvent.php index fb542c43..371b6ad9 100644 --- a/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationFailedEvent.php +++ b/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationFailedEvent.php @@ -4,91 +4,20 @@ namespace Webauthn\Event; -use Psr\Http\Message\ServerRequestInterface; use Throwable; use Webauthn\AuthenticatorAssertionResponse; use Webauthn\PublicKeyCredentialRequestOptions; use Webauthn\PublicKeyCredentialSource; -class AuthenticatorAssertionResponseValidationFailedEvent +readonly class AuthenticatorAssertionResponseValidationFailedEvent { public function __construct( - public readonly string|PublicKeyCredentialSource $credentialId, - public readonly AuthenticatorAssertionResponse $authenticatorAssertionResponse, - public readonly PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, - public readonly ServerRequestInterface|string $host, - public readonly ?string $userHandle, - public readonly Throwable $throwable + public PublicKeyCredentialSource $credentialSource, + public AuthenticatorAssertionResponse $authenticatorAssertionResponse, + public PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, + public string $host, + public ?string $userHandle, + public Throwable $throwable ) { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } - if (! $this->credentialId instanceof PublicKeyCredentialSource) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.6.0', - 'Passing a string for the argument "$credentialId" is deprecated since 4.6.0. Please set the PublicKeyCredentialSource instead.' - ); - } - } - - /** - * @deprecated since 4.7.0 and will be removed in 5.0.0. Please use the `getCredential()` method instead - * @infection-ignore-all - */ - public function getCredentialId(): string - { - return $this->credentialId instanceof PublicKeyCredentialSource ? $this->credentialId->publicKeyCredentialId : $this->credentialId; - } - - public function getCredential(): ?PublicKeyCredentialSource - { - return $this->credentialId instanceof PublicKeyCredentialSource ? $this->credentialId : null; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getAuthenticatorAssertionResponse(): AuthenticatorAssertionResponse - { - return $this->authenticatorAssertionResponse; - } - - public function getPublicKeyCredentialRequestOptions(): PublicKeyCredentialRequestOptions - { - return $this->publicKeyCredentialRequestOptions; - } - - /** - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use the `host` property instead - * @infection-ignore-all - */ - public function getRequest(): ServerRequestInterface|string - { - return $this->host; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getUserHandle(): ?string - { - return $this->userHandle; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getThrowable(): Throwable - { - return $this->throwable; } } diff --git a/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationSucceededEvent.php b/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationSucceededEvent.php index 88442b17..d7797298 100644 --- a/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationSucceededEvent.php +++ b/src/webauthn/src/Event/AuthenticatorAssertionResponseValidationSucceededEvent.php @@ -4,7 +4,6 @@ namespace Webauthn\Event; -use Psr\Http\Message\ServerRequestInterface; use Webauthn\AuthenticatorAssertionResponse; use Webauthn\PublicKeyCredentialRequestOptions; use Webauthn\PublicKeyCredentialSource; @@ -12,79 +11,11 @@ class AuthenticatorAssertionResponseValidationSucceededEvent { public function __construct( - public readonly null|string $credentialId, public readonly AuthenticatorAssertionResponse $authenticatorAssertionResponse, public readonly PublicKeyCredentialRequestOptions $publicKeyCredentialRequestOptions, - public readonly ServerRequestInterface|string $host, + public readonly string $host, public readonly ?string $userHandle, public readonly PublicKeyCredentialSource $publicKeyCredentialSource ) { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } - if ($this->credentialId !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.6.0', - 'The argument "$credentialId" is deprecated since 4.6.0 and will be removed in 5.0.0. Please set null instead.' - ); - } - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getCredentialId(): string - { - return $this->publicKeyCredentialSource->publicKeyCredentialId; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getAuthenticatorAssertionResponse(): AuthenticatorAssertionResponse - { - return $this->authenticatorAssertionResponse; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getPublicKeyCredentialRequestOptions(): PublicKeyCredentialRequestOptions - { - return $this->publicKeyCredentialRequestOptions; - } - - /** - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use the `host` property instead - * @infection-ignore-all - */ - public function getRequest(): ServerRequestInterface|string - { - return $this->host; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getUserHandle(): ?string - { - return $this->userHandle; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getPublicKeyCredentialSource(): PublicKeyCredentialSource - { - return $this->publicKeyCredentialSource; } } diff --git a/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationFailedEvent.php b/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationFailedEvent.php index 59f7403b..d91082c2 100644 --- a/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationFailedEvent.php +++ b/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationFailedEvent.php @@ -4,62 +4,17 @@ namespace Webauthn\Event; -use Psr\Http\Message\ServerRequestInterface; use Throwable; use Webauthn\AuthenticatorAttestationResponse; use Webauthn\PublicKeyCredentialCreationOptions; -class AuthenticatorAttestationResponseValidationFailedEvent +readonly class AuthenticatorAttestationResponseValidationFailedEvent { public function __construct( - public readonly AuthenticatorAttestationResponse $authenticatorAttestationResponse, - public readonly PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, - public readonly ServerRequestInterface|string $host, - public readonly Throwable $throwable + public AuthenticatorAttestationResponse $authenticatorAttestationResponse, + public PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, + public string $host, + public Throwable $throwable ) { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getAuthenticatorAttestationResponse(): AuthenticatorAttestationResponse - { - return $this->authenticatorAttestationResponse; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getPublicKeyCredentialCreationOptions(): PublicKeyCredentialCreationOptions - { - return $this->publicKeyCredentialCreationOptions; - } - - /** - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use the `host` property instead - * @infection-ignore-all - */ - public function getRequest(): ServerRequestInterface|string - { - return $this->host; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getThrowable(): Throwable - { - return $this->throwable; } } diff --git a/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationSucceededEvent.php b/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationSucceededEvent.php index 59cca951..be5604d5 100644 --- a/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationSucceededEvent.php +++ b/src/webauthn/src/Event/AuthenticatorAttestationResponseValidationSucceededEvent.php @@ -4,62 +4,17 @@ namespace Webauthn\Event; -use Psr\Http\Message\ServerRequestInterface; use Webauthn\AuthenticatorAttestationResponse; use Webauthn\PublicKeyCredentialCreationOptions; use Webauthn\PublicKeyCredentialSource; -class AuthenticatorAttestationResponseValidationSucceededEvent +readonly class AuthenticatorAttestationResponseValidationSucceededEvent { public function __construct( - public readonly AuthenticatorAttestationResponse $authenticatorAttestationResponse, - public readonly PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, - public readonly ServerRequestInterface|string $host, - public readonly PublicKeyCredentialSource $publicKeyCredentialSource + public AuthenticatorAttestationResponse $authenticatorAttestationResponse, + public PublicKeyCredentialCreationOptions $publicKeyCredentialCreationOptions, + public string $host, + public PublicKeyCredentialSource $publicKeyCredentialSource ) { - if ($host instanceof ServerRequestInterface) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.5.0', - sprintf( - 'Passing a %s to the class "%s" is deprecated since 4.5.0 and will be removed in 5.0.0. Please inject the host as a string instead.', - ServerRequestInterface::class, - self::class - ) - ); - } - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getAuthenticatorAttestationResponse(): AuthenticatorAttestationResponse - { - return $this->authenticatorAttestationResponse; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getPublicKeyCredentialCreationOptions(): PublicKeyCredentialCreationOptions - { - return $this->publicKeyCredentialCreationOptions; - } - - /** - * @deprecated since 4.5.0 and will be removed in 5.0.0. Please use the `host` property instead - * @infection-ignore-all - */ - public function getRequest(): ServerRequestInterface|string - { - return $this->host; - } - - /** - * @deprecated since 4.8.0. Will be removed in 5.0.0. Please use the property instead. - */ - public function getPublicKeyCredentialSource(): PublicKeyCredentialSource - { - return $this->publicKeyCredentialSource; } } diff --git a/src/webauthn/src/PublicKeyCredential.php b/src/webauthn/src/PublicKeyCredential.php index 8e09ad65..1a50b595 100644 --- a/src/webauthn/src/PublicKeyCredential.php +++ b/src/webauthn/src/PublicKeyCredential.php @@ -4,76 +4,27 @@ namespace Webauthn; -use Stringable; -use const E_USER_DEPRECATED; -use const JSON_THROW_ON_ERROR; - /** * @see https://www.w3.org/TR/webauthn/#iface-pkcredential */ -class PublicKeyCredential extends Credential implements Stringable +class PublicKeyCredential extends Credential { public function __construct( - null|string $id, string $type, string $rawId, public readonly AuthenticatorResponse $response ) { - parent::__construct($id, $type, $rawId); - } - - /** - * @deprecated since 4.8.0. - * @infection-ignore-all - */ - public function __toString(): string - { - return json_encode($this->getPublicKeyCredentialDescriptor(), JSON_THROW_ON_ERROR); - } - - public static function create(null|string $id, string $type, string $rawId, AuthenticatorResponse $response): self - { - return new self($id, $type, $rawId, $response); - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRawId(): string - { - return $this->rawId; + parent::__construct($type, $rawId); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getResponse(): AuthenticatorResponse + public static function create(string $type, string $rawId, AuthenticatorResponse $response): self { - return $this->response; + return new self($type, $rawId, $response); } - /** - * @param string[] $transport - */ - public function getPublicKeyCredentialDescriptor(null|array $transport = null): PublicKeyCredentialDescriptor + public function getPublicKeyCredentialDescriptor(): PublicKeyCredentialDescriptor { - if ($transport !== null) { - trigger_deprecation( - 'web-auth/webauthn-lib', - '4.8.0', - 'The parameter "$transport" is deprecated and will be removed in 5.0.0.' - ); - @trigger_error( - sprintf( - 'The $transport argument of %s() is deprecated since 4.8.0 and will be removed in 5.0.0.', - __METHOD__ - ), - E_USER_DEPRECATED - ); - } - $transport ??= $this->response instanceof AuthenticatorAttestationResponse ? $this->response->transports : []; + $transport = $this->response instanceof AuthenticatorAttestationResponse ? $this->response->transports : []; return PublicKeyCredentialDescriptor::create($this->type, $this->rawId, $transport); } diff --git a/src/webauthn/src/PublicKeyCredentialCreationOptions.php b/src/webauthn/src/PublicKeyCredentialCreationOptions.php index d6088e97..ddf3a49f 100644 --- a/src/webauthn/src/PublicKeyCredentialCreationOptions.php +++ b/src/webauthn/src/PublicKeyCredentialCreationOptions.php @@ -5,30 +5,23 @@ namespace Webauthn; use InvalidArgumentException; -use ParagonIE\ConstantTime\Base64UrlSafe; use Webauthn\AuthenticationExtensions\AuthenticationExtensions; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; use Webauthn\Exception\InvalidDataException; -use Webauthn\Util\Base64; -use function array_key_exists; -use function count; use function in_array; -use function is_array; -use const JSON_THROW_ON_ERROR; final class PublicKeyCredentialCreationOptions extends PublicKeyCredentialOptions { - public const ATTESTATION_CONVEYANCE_PREFERENCE_DEFAULT = null; + public const null ATTESTATION_CONVEYANCE_PREFERENCE_DEFAULT = null; - public const ATTESTATION_CONVEYANCE_PREFERENCE_NONE = 'none'; + public const string ATTESTATION_CONVEYANCE_PREFERENCE_NONE = 'none'; - public const ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT = 'indirect'; + public const string ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT = 'indirect'; - public const ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT = 'direct'; + public const string ATTESTATION_CONVEYANCE_PREFERENCE_DIRECT = 'direct'; - public const ATTESTATION_CONVEYANCE_PREFERENCE_ENTERPRISE = 'enterprise'; + public const string ATTESTATION_CONVEYANCE_PREFERENCE_ENTERPRISE = 'enterprise'; - public const ATTESTATION_CONVEYANCE_PREFERENCES = [ + public const array ATTESTATION_CONVEYANCE_PREFERENCES = [ self::ATTESTATION_CONVEYANCE_PREFERENCE_DEFAULT, self::ATTESTATION_CONVEYANCE_PREFERENCE_NONE, self::ATTESTATION_CONVEYANCE_PREFERENCE_INDIRECT, @@ -37,7 +30,6 @@ final class PublicKeyCredentialCreationOptions extends PublicKeyCredentialOption ]; /** - * @private * @param PublicKeyCredentialParameters[] $pubKeyCredParams * @param PublicKeyCredentialDescriptor[] $excludeCredentials * @param null|positive-int $timeout @@ -99,253 +91,4 @@ public static function create( $extensions ); } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function addPubKeyCredParam(PublicKeyCredentialParameters $pubKeyCredParam): self - { - $this->pubKeyCredParams[] = $pubKeyCredParam; - - return $this; - } - - /** - * @deprecated since 4.7.0. No replacement. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function addPubKeyCredParams(PublicKeyCredentialParameters ...$pubKeyCredParams): self - { - foreach ($pubKeyCredParams as $pubKeyCredParam) { - $this->pubKeyCredParams[] = $pubKeyCredParam; - } - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function excludeCredential(PublicKeyCredentialDescriptor $excludeCredential): self - { - $this->excludeCredentials[] = $excludeCredential; - - return $this; - } - - /** - * @deprecated since 4.7.0. No replacement. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function excludeCredentials(PublicKeyCredentialDescriptor ...$excludeCredentials): self - { - foreach ($excludeCredentials as $excludeCredential) { - $this->excludeCredentials[] = $excludeCredential; - } - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setAuthenticatorSelection(?AuthenticatorSelectionCriteria $authenticatorSelection): self - { - $this->authenticatorSelection = $authenticatorSelection; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setAttestation(string $attestation): self - { - in_array($attestation, self::ATTESTATION_CONVEYANCE_PREFERENCES, true) || throw InvalidDataException::create( - $attestation, - 'Invalid attestation conveyance mode' - ); - $this->attestation = $attestation; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRp(): PublicKeyCredentialRpEntity - { - return $this->rp; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUser(): PublicKeyCredentialUserEntity - { - return $this->user; - } - - /** - * @return PublicKeyCredentialParameters[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getPubKeyCredParams(): array - { - return $this->pubKeyCredParams; - } - - /** - * @return PublicKeyCredentialDescriptor[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getExcludeCredentials(): array - { - return $this->excludeCredentials; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAuthenticatorSelection(): ?AuthenticatorSelectionCriteria - { - return $this->authenticatorSelection; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestation(): ?string - { - return $this->attestation; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromString(string $data): static - { - $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); - - return self::createFromArray($data); - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $json): static - { - array_key_exists('rp', $json) || throw InvalidDataException::create($json, 'Invalid input. "rp" is missing.'); - array_key_exists('pubKeyCredParams', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "pubKeyCredParams" is missing.' - ); - is_array($json['pubKeyCredParams']) || throw InvalidDataException::create( - $json, - 'Invalid input. "pubKeyCredParams" is not an array.' - ); - array_key_exists('challenge', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "challenge" is missing.' - ); - array_key_exists('attestation', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "attestation" is missing.' - ); - array_key_exists('user', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "user" is missing.' - ); - - $pubKeyCredParams = []; - foreach ($json['pubKeyCredParams'] as $pubKeyCredParam) { - if (! is_array($pubKeyCredParam)) { - continue; - } - $pubKeyCredParams[] = PublicKeyCredentialParameters::createFromArray($pubKeyCredParam); - } - $excludeCredentials = []; - if (isset($json['excludeCredentials'])) { - foreach ($json['excludeCredentials'] as $excludeCredential) { - $excludeCredentials[] = PublicKeyCredentialDescriptor::createFromArray($excludeCredential); - } - } - - $challenge = Base64::decode($json['challenge']); - - $authenticatorSelection = isset($json['authenticatorSelection']) ? AuthenticatorSelectionCriteria::createFromArray( - $json['authenticatorSelection'] - ) : null - ; - $extensions = - isset($json['extensions']) ? AuthenticationExtensionsClientInputs::createFromArray( - $json['extensions'] - ) : AuthenticationExtensionsClientInputs::create() - ; - return self - ::create( - PublicKeyCredentialRpEntity::createFromArray($json['rp']), - PublicKeyCredentialUserEntity::createFromArray($json['user']), - $challenge, - $pubKeyCredParams, - $authenticatorSelection, - $json['attestation'] ?? null, - $excludeCredentials, - $json['timeout'] ?? null, - $extensions - ); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $json = [ - 'rp' => $this->rp, - 'user' => $this->user, - 'challenge' => Base64UrlSafe::encodeUnpadded($this->challenge), - 'pubKeyCredParams' => $this->pubKeyCredParams, - ]; - - if ($this->timeout !== null) { - $json['timeout'] = $this->timeout; - } - - if (count($this->excludeCredentials) !== 0) { - $json['excludeCredentials'] = $this->excludeCredentials; - } - - if ($this->authenticatorSelection !== null) { - $json['authenticatorSelection'] = $this->authenticatorSelection; - } - - if ($this->attestation !== null) { - $json['attestation'] = $this->attestation; - } - - if ($this->extensions->count() !== 0) { - $json['extensions'] = $this->extensions; - } - - return $json; - } } diff --git a/src/webauthn/src/PublicKeyCredentialDescriptor.php b/src/webauthn/src/PublicKeyCredentialDescriptor.php index eac25690..e9531a26 100644 --- a/src/webauthn/src/PublicKeyCredentialDescriptor.php +++ b/src/webauthn/src/PublicKeyCredentialDescriptor.php @@ -4,28 +4,26 @@ namespace Webauthn; -use JsonSerializable; use ParagonIE\ConstantTime\Base64UrlSafe; use Webauthn\Exception\InvalidDataException; use function array_key_exists; -use function count; use const JSON_THROW_ON_ERROR; -class PublicKeyCredentialDescriptor implements JsonSerializable +class PublicKeyCredentialDescriptor { - final public const CREDENTIAL_TYPE_PUBLIC_KEY = 'public-key'; + final public const string CREDENTIAL_TYPE_PUBLIC_KEY = 'public-key'; - final public const AUTHENTICATOR_TRANSPORT_USB = 'usb'; + final public const string AUTHENTICATOR_TRANSPORT_USB = 'usb'; - final public const AUTHENTICATOR_TRANSPORT_NFC = 'nfc'; + final public const string AUTHENTICATOR_TRANSPORT_NFC = 'nfc'; - final public const AUTHENTICATOR_TRANSPORT_BLE = 'ble'; + final public const string AUTHENTICATOR_TRANSPORT_BLE = 'ble'; - final public const AUTHENTICATOR_TRANSPORT_CABLE = 'cable'; + final public const string AUTHENTICATOR_TRANSPORT_CABLE = 'cable'; - final public const AUTHENTICATOR_TRANSPORT_INTERNAL = 'internal'; + final public const string AUTHENTICATOR_TRANSPORT_INTERNAL = 'internal'; - final public const AUTHENTICATOR_TRANSPORTS = [ + final public const array AUTHENTICATOR_TRANSPORTS = [ self::AUTHENTICATOR_TRANSPORT_USB, self::AUTHENTICATOR_TRANSPORT_NFC, self::AUTHENTICATOR_TRANSPORT_BLE, @@ -51,34 +49,6 @@ public static function create(string $type, string $id, array $transports = []): return new self($type, $id, $transports); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getType(): string - { - return $this->type; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getId(): string - { - return $this->id; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTransports(): array - { - return $this->transports; - } - public static function createFromString(string $data): self { $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); @@ -86,41 +56,16 @@ public static function createFromString(string $data): self return self::createFromArray($data); } - /** - * @param mixed[] $json - */ - public static function createFromArray(array $json): self + public static function createFromArray(array $data): self { - array_key_exists('type', $json) || throw InvalidDataException::create( - $json, + array_key_exists('type', $data) || throw InvalidDataException::create( + $data, 'Invalid input. "type" is missing.' ); - array_key_exists('id', $json) || throw InvalidDataException::create($json, 'Invalid input. "id" is missing.'); + array_key_exists('id', $data) || throw InvalidDataException::create($data, 'Invalid input. "id" is missing.'); - $id = Base64UrlSafe::decodeNoPadding($json['id']); + $id = Base64UrlSafe::decodeNoPadding($data['id']); - return self::create($json['type'], $id, $json['transports'] ?? []); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $json = [ - 'type' => $this->type, - 'id' => Base64UrlSafe::encodeUnpadded($this->id), - ]; - if (count($this->transports) !== 0) { - $json['transports'] = $this->transports; - } - - return $json; + return self::create($data['type'], $id, $data['transports'] ?? []); } } diff --git a/src/webauthn/src/PublicKeyCredentialDescriptorCollection.php b/src/webauthn/src/PublicKeyCredentialDescriptorCollection.php deleted file mode 100644 index bbc3a8c1..00000000 --- a/src/webauthn/src/PublicKeyCredentialDescriptorCollection.php +++ /dev/null @@ -1,131 +0,0 @@ - - * @deprecated since 4.8.0 and will be removed in 5.0.0. - * @infection-ignore-all - */ -class PublicKeyCredentialDescriptorCollection implements JsonSerializable, Countable, IteratorAggregate -{ - /** - * @var array - * @readonly - */ - public array $publicKeyCredentialDescriptors; - - /** - * @private - * @param PublicKeyCredentialDescriptor[] $pkCredentialDescriptors - */ - public function __construct( - array $pkCredentialDescriptors = [] - ) { - $this->publicKeyCredentialDescriptors = []; - foreach ($pkCredentialDescriptors as $pkCredentialDescriptor) { - $pkCredentialDescriptor instanceof PublicKeyCredentialDescriptor || throw new InvalidArgumentException( - 'Expected only instances of ' . PublicKeyCredentialDescriptor::class - ); - $this->publicKeyCredentialDescriptors[$pkCredentialDescriptor->id] = $pkCredentialDescriptor; - } - } - - /** - * @param PublicKeyCredentialDescriptor[] $publicKeyCredentialDescriptors - */ - public static function create(array $publicKeyCredentialDescriptors): self - { - return new self($publicKeyCredentialDescriptors); - } - - /** - * @infection-ignore-all - */ - public function add(PublicKeyCredentialDescriptor ...$publicKeyCredentialDescriptors): void - { - foreach ($publicKeyCredentialDescriptors as $publicKeyCredentialDescriptor) { - $this->publicKeyCredentialDescriptors[$publicKeyCredentialDescriptor->id] = $publicKeyCredentialDescriptor; - } - } - - /** - * @infection-ignore-all - */ - public function has(string $id): bool - { - return array_key_exists($id, $this->publicKeyCredentialDescriptors); - } - - /** - * @infection-ignore-all - */ - public function remove(string $id): void - { - if (! array_key_exists($id, $this->publicKeyCredentialDescriptors)) { - return; - } - - unset($this->publicKeyCredentialDescriptors[$id]); - } - - /** - * @return Iterator - */ - public function getIterator(): Iterator - { - return new ArrayIterator($this->publicKeyCredentialDescriptors); - } - - public function count(int $mode = COUNT_NORMAL): int - { - return count($this->publicKeyCredentialDescriptors, $mode); - } - - /** - * @return array[] - */ - public function jsonSerialize(): array - { - return $this->publicKeyCredentialDescriptors; - } - - /** - * @infection-ignore-all - */ - public static function createFromString(string $data): self - { - $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); - - return self::createFromArray($data); - } - - /** - * @param mixed[] $json - * @infection-ignore-all - */ - public static function createFromArray(array $json): self - { - return self::create( - array_map( - static fn (array $item): PublicKeyCredentialDescriptor => PublicKeyCredentialDescriptor::createFromArray( - $item - ), - $json - ) - ); - } -} diff --git a/src/webauthn/src/PublicKeyCredentialEntity.php b/src/webauthn/src/PublicKeyCredentialEntity.php index 844a078b..ffb04677 100644 --- a/src/webauthn/src/PublicKeyCredentialEntity.php +++ b/src/webauthn/src/PublicKeyCredentialEntity.php @@ -4,46 +4,11 @@ namespace Webauthn; -use JsonSerializable; - -abstract class PublicKeyCredentialEntity implements JsonSerializable +abstract class PublicKeyCredentialEntity { public function __construct( public readonly string $name, public readonly ?string $icon ) { } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getName(): string - { - return $this->name; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getIcon(): ?string - { - return $this->icon; - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - $json = [ - 'name' => $this->name, - ]; - if ($this->icon !== null) { - $json['icon'] = $this->icon; - } - - return $json; - } } diff --git a/src/webauthn/src/PublicKeyCredentialLoader.php b/src/webauthn/src/PublicKeyCredentialLoader.php deleted file mode 100644 index 88b2a9c1..00000000 --- a/src/webauthn/src/PublicKeyCredentialLoader.php +++ /dev/null @@ -1,191 +0,0 @@ -attestationObjectLoader === null && $this->serializer === null) { - throw new InvalidArgumentException('You must provide an attestation object loader or a serializer'); - } - $this->logger = new NullLogger(); - } - - public static function create( - null|AttestationObjectLoader $attestationObjectLoader, - null|SerializerInterface $serializer = null - ): self { - return new self($attestationObjectLoader, $serializer); - } - - public function setLogger(LoggerInterface $logger): void - { - $this->logger = $logger; - } - - /** - * @param mixed[] $json - * @infection-ignore-all - */ - public function loadArray(array $json): PublicKeyCredential - { - $this->logger->info('Trying to load data from an array', [ - 'data' => $json, - ]); - try { - foreach (['id', 'rawId', 'type'] as $key) { - array_key_exists($key, $json) || throw InvalidDataException::create($json, sprintf( - 'The parameter "%s" is missing', - $key - )); - is_string($json[$key]) || throw InvalidDataException::create($json, sprintf( - 'The parameter "%s" shall be a string', - $key - )); - } - array_key_exists('response', $json) || throw InvalidDataException::create( - $json, - 'The parameter "response" is missing' - ); - is_array($json['response']) || throw InvalidDataException::create( - $json, - 'The parameter "response" shall be an array' - ); - $json['type'] === 'public-key' || throw InvalidDataException::create($json, sprintf( - 'Unsupported type "%s"', - $json['type'] - )); - - $id = Base64UrlSafe::decodeNoPadding($json['id']); - $rawId = Base64::decode($json['rawId']); - hash_equals($id, $rawId) || throw InvalidDataException::create($json, 'Invalid ID'); - - $publicKeyCredential = PublicKeyCredential::create( - null, - $json['type'], - $rawId, - $this->createResponse($json['response']) - ); - $this->logger->info('The data has been loaded'); - $this->logger->debug('Public Key Credential', [ - 'publicKeyCredential' => $publicKeyCredential, - ]); - - return $publicKeyCredential; - } catch (Throwable $throwable) { - $this->logger->error('An error occurred', [ - 'exception' => $throwable, - ]); - throw $throwable; - } - } - - public function load(string $data): PublicKeyCredential - { - $this->logger->info('Trying to load data from a string', [ - 'data' => $data, - ]); - try { - if ($this->serializer !== null) { - return $this->serializer->deserialize($data, PublicKeyCredential::class, 'json'); - } - $json = json_decode($data, true, flags: JSON_THROW_ON_ERROR); - - return $this->loadArray($json); - } catch (Throwable $throwable) { - $this->logger->error('An error occurred', [ - 'exception' => $throwable, - ]); - throw InvalidDataException::create($data, 'Unable to load the data', $throwable); - } - } - - /** - * @param mixed[] $response - */ - private function createResponse(array $response): AuthenticatorResponse - { - array_key_exists('clientDataJSON', $response) || throw InvalidDataException::create( - $response, - 'Invalid data. The parameter "clientDataJSON" is missing' - ); - is_string($response['clientDataJSON']) || throw InvalidDataException::create( - $response, - 'Invalid data. The parameter "clientDataJSON" is invalid' - ); - $userHandle = $response['userHandle'] ?? null; - $userHandle === null || is_string($userHandle) || throw InvalidDataException::create( - $response, - 'Invalid data. The parameter "userHandle" is invalid' - ); - /** @var string[] $transports */ - $transports = $response['transports'] ?? []; - is_array($transports) || throw InvalidDataException::create( - $response, - 'Invalid data. The parameter "transports" is invalid' - ); - if ($this->serializer !== null) { - return $this->serializer->deserialize($response, AuthenticatorResponse::class, 'json'); - } - switch (true) { - case array_key_exists('attestationObject', $response): - $attestationObject = $this->attestationObjectLoader->load($response['attestationObject']); - - return AuthenticatorAttestationResponse::create(CollectedClientData::createFormJson( - $response['clientDataJSON'] - ), $attestationObject, $transports); - case array_key_exists('signature', $response): - $authDataLoader = AuthenticatorDataLoader::create(); - $authData = Base64UrlSafe::decodeNoPadding($response['authenticatorData'] ?? ''); - $authenticatorData = $authDataLoader->load($authData); - - try { - $signature = Base64::decode($response['signature']); - } catch (Throwable $e) { - throw InvalidDataException::create( - $response['signature'], - 'The signature shall be Base64 Url Safe encoded', - $e - ); - } - $userHandle = $response['userHandle'] ?? null; - if ($userHandle !== '' && $userHandle !== null) { - $userHandle = Base64::decode($userHandle); - } - - return AuthenticatorAssertionResponse::create( - CollectedClientData::createFormJson($response['clientDataJSON']), - $authenticatorData, - $signature, - $userHandle - ); - default: - throw InvalidDataException::create($response, 'Unable to create the response object'); - } - } -} diff --git a/src/webauthn/src/PublicKeyCredentialOptions.php b/src/webauthn/src/PublicKeyCredentialOptions.php index 8e5ffbe4..6d054b42 100644 --- a/src/webauthn/src/PublicKeyCredentialOptions.php +++ b/src/webauthn/src/PublicKeyCredentialOptions.php @@ -5,119 +5,29 @@ namespace Webauthn; use InvalidArgumentException; -use JsonSerializable; -use Webauthn\AuthenticationExtensions\AuthenticationExtension; use Webauthn\AuthenticationExtensions\AuthenticationExtensions; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; -abstract class PublicKeyCredentialOptions implements JsonSerializable +abstract class PublicKeyCredentialOptions { public AuthenticationExtensions $extensions; /** * @param positive-int|null $timeout - * @param null|AuthenticationExtensions|array $extensions + * @param null|AuthenticationExtensions|array $extensions * @protected */ public function __construct( - public readonly string $challenge, + public string $challenge, public null|int $timeout = null, null|array|AuthenticationExtensions $extensions = null, ) { ($this->timeout === null || $this->timeout > 0) || throw new InvalidArgumentException('Invalid timeout'); if ($extensions === null) { - $this->extensions = AuthenticationExtensionsClientInputs::create(); + $this->extensions = AuthenticationExtensions::create(); } elseif ($extensions instanceof AuthenticationExtensions) { $this->extensions = $extensions; } else { $this->extensions = AuthenticationExtensions::create($extensions); } } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setTimeout(?int $timeout): static - { - $this->timeout = $timeout; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function addExtension(AuthenticationExtension $extension): static - { - $this->extensions[$extension->name] = $extension; - - return $this; - } - - /** - * @param AuthenticationExtension[] $extensions - * @deprecated since 4.7.0. No replacement. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function addExtensions(array $extensions): static - { - foreach ($extensions as $extension) { - $this->extensions[$extension->name] = $extension; - } - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the {self::create} instead. - * @infection-ignore-all - */ - public function setExtensions(AuthenticationExtensions $extensions): static - { - $this->extensions = $extensions; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getChallenge(): string - { - return $this->challenge; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTimeout(): ?int - { - return $this->timeout; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getExtensions(): AuthenticationExtensions - { - return $this->extensions; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - abstract public static function createFromString(string $data): static; - - /** - * @param mixed[] $json - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - abstract public static function createFromArray(array $json): static; } diff --git a/src/webauthn/src/PublicKeyCredentialParameters.php b/src/webauthn/src/PublicKeyCredentialParameters.php index 1eab10d5..7959951b 100644 --- a/src/webauthn/src/PublicKeyCredentialParameters.php +++ b/src/webauthn/src/PublicKeyCredentialParameters.php @@ -4,19 +4,11 @@ namespace Webauthn; -use JsonSerializable; -use Webauthn\Exception\InvalidDataException; -use function array_key_exists; -use const JSON_THROW_ON_ERROR; - -class PublicKeyCredentialParameters implements JsonSerializable +readonly class PublicKeyCredentialParameters { - /** - * @private - */ public function __construct( - public readonly string $type, - public readonly int $alg + public string $type, + public int $alg ) { } @@ -29,69 +21,4 @@ public static function createPk(int $alg): self { return self::create(PublicKeyCredentialDescriptor::CREDENTIAL_TYPE_PUBLIC_KEY, $alg); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getType(): string - { - return $this->type; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAlg(): int - { - return $this->alg; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromString(string $data): self - { - $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); - - return self::createFromArray($data); - } - - /** - * @param mixed[] $json - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $json): self - { - array_key_exists('type', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "type" is missing.' - ); - array_key_exists('alg', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "alg" is missing.' - ); - - return self::create($json['type'], $json['alg']); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - return [ - 'type' => $this->type, - 'alg' => $this->alg, - ]; - } } diff --git a/src/webauthn/src/PublicKeyCredentialRequestOptions.php b/src/webauthn/src/PublicKeyCredentialRequestOptions.php index a74d97b3..a8a9be87 100644 --- a/src/webauthn/src/PublicKeyCredentialRequestOptions.php +++ b/src/webauthn/src/PublicKeyCredentialRequestOptions.php @@ -4,27 +4,21 @@ namespace Webauthn; -use ParagonIE\ConstantTime\Base64UrlSafe; use Webauthn\AuthenticationExtensions\AuthenticationExtensions; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; use Webauthn\Exception\InvalidDataException; -use Webauthn\Util\Base64; -use function array_key_exists; -use function count; use function in_array; -use const JSON_THROW_ON_ERROR; final class PublicKeyCredentialRequestOptions extends PublicKeyCredentialOptions { - public const USER_VERIFICATION_REQUIREMENT_DEFAULT = null; + public const null USER_VERIFICATION_REQUIREMENT_DEFAULT = null; - public const USER_VERIFICATION_REQUIREMENT_REQUIRED = 'required'; + public const string USER_VERIFICATION_REQUIREMENT_REQUIRED = 'required'; - public const USER_VERIFICATION_REQUIREMENT_PREFERRED = 'preferred'; + public const string USER_VERIFICATION_REQUIREMENT_PREFERRED = 'preferred'; - public const USER_VERIFICATION_REQUIREMENT_DISCOURAGED = 'discouraged'; + public const string USER_VERIFICATION_REQUIREMENT_DISCOURAGED = 'discouraged'; - public const USER_VERIFICATION_REQUIREMENTS = [ + public const array USER_VERIFICATION_REQUIREMENTS = [ self::USER_VERIFICATION_REQUIREMENT_DEFAULT, self::USER_VERIFICATION_REQUIREMENT_REQUIRED, self::USER_VERIFICATION_REQUIREMENT_PREFERRED, @@ -32,9 +26,8 @@ final class PublicKeyCredentialRequestOptions extends PublicKeyCredentialOptions ]; /** - * @private * @param PublicKeyCredentialDescriptor[] $allowCredentials - * @param null|AuthenticationExtensions|array $extensions + * @param null|AuthenticationExtensions|array $extensions */ public function __construct( string $challenge, @@ -58,7 +51,7 @@ public function __construct( /** * @param PublicKeyCredentialDescriptor[] $allowCredentials * @param positive-int $timeout - * @param null|AuthenticationExtensions|array $extensions + * @param null|AuthenticationExtensions|array $extensions */ public static function create( string $challenge, @@ -70,170 +63,4 @@ public static function create( ): self { return new self($challenge, $rpId, $allowCredentials, $userVerification, $timeout, $extensions); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setRpId(?string $rpId): self - { - $this->rpId = $rpId; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function allowCredential(PublicKeyCredentialDescriptor $allowCredential): self - { - $this->allowCredentials[] = $allowCredential; - - return $this; - } - - /** - * @deprecated since 4.7.0. No replacement. Please use the property directly. - * @infection-ignore-all - */ - public function allowCredentials(PublicKeyCredentialDescriptor ...$allowCredentials): self - { - foreach ($allowCredentials as $allowCredential) { - $this->allowCredentials[] = $allowCredential; - } - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setUserVerification(?string $userVerification): self - { - if ($userVerification === null) { - $this->rpId = null; - - return $this; - } - in_array($userVerification, [ - self::USER_VERIFICATION_REQUIREMENT_REQUIRED, - self::USER_VERIFICATION_REQUIREMENT_PREFERRED, - self::USER_VERIFICATION_REQUIREMENT_DISCOURAGED, - ], true) || throw InvalidDataException::create($userVerification, 'Invalid user verification requirement'); - $this->userVerification = $userVerification; - - return $this; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getRpId(): ?string - { - return $this->rpId; - } - - /** - * @return PublicKeyCredentialDescriptor[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAllowCredentials(): array - { - return $this->allowCredentials; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUserVerification(): ?string - { - return $this->userVerification; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromString(string $data): static - { - $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); - - return self::createFromArray($data); - } - - /** - * @param mixed[] $json - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $json): static - { - array_key_exists('challenge', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "challenge" is missing.' - ); - - $allowCredentials = []; - $allowCredentialList = $json['allowCredentials'] ?? []; - foreach ($allowCredentialList as $allowCredential) { - $allowCredentials[] = PublicKeyCredentialDescriptor::createFromArray($allowCredential); - } - - $challenge = Base64::decode($json['challenge']); - $extensions = isset($json['extensions']) ? AuthenticationExtensionsClientInputs::createFromArray( - $json['extensions'] - ) : AuthenticationExtensionsClientInputs::create(); - - return self::create( - $challenge, - $json['rpId'] ?? null, - $allowCredentials, - $json['userVerification'] ?? null, - $json['timeout'] ?? null, - $extensions - ); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $json = [ - 'challenge' => Base64UrlSafe::encodeUnpadded($this->challenge), - ]; - - if ($this->rpId !== null) { - $json['rpId'] = $this->rpId; - } - - if ($this->userVerification !== null) { - $json['userVerification'] = $this->userVerification; - } - - if (count($this->allowCredentials) !== 0) { - $json['allowCredentials'] = $this->allowCredentials; - } - - if ($this->extensions->count() !== 0) { - $json['extensions'] = $this->extensions; - } - - if ($this->timeout !== null) { - $json['timeout'] = $this->timeout; - } - - return $json; - } } diff --git a/src/webauthn/src/PublicKeyCredentialRpEntity.php b/src/webauthn/src/PublicKeyCredentialRpEntity.php index bb40b539..da79df63 100644 --- a/src/webauthn/src/PublicKeyCredentialRpEntity.php +++ b/src/webauthn/src/PublicKeyCredentialRpEntity.php @@ -4,9 +4,6 @@ namespace Webauthn; -use Webauthn\Exception\InvalidDataException; -use function array_key_exists; - class PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity { public function __construct( @@ -21,47 +18,4 @@ public static function create(string $name, ?string $id = null, ?string $icon = { return new self($name, $id, $icon); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getId(): ?string - { - return $this->id; - } - - /** - * @param mixed[] $json - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $json): self - { - array_key_exists('name', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "name" is missing.' - ); - - return self::create($json['name'], $json['id'] ?? null, $json['icon'] ?? null); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $json = parent::jsonSerialize(); - if ($this->id !== null) { - $json['id'] = $this->id; - } - - return $json; - } } diff --git a/src/webauthn/src/PublicKeyCredentialSource.php b/src/webauthn/src/PublicKeyCredentialSource.php index ca94d8a5..bbf6a107 100644 --- a/src/webauthn/src/PublicKeyCredentialSource.php +++ b/src/webauthn/src/PublicKeyCredentialSource.php @@ -4,23 +4,15 @@ namespace Webauthn; -use JsonSerializable; -use ParagonIE\ConstantTime\Base64UrlSafe; use Symfony\Component\Uid\Uuid; -use Throwable; -use Webauthn\Exception\InvalidDataException; use Webauthn\TrustPath\TrustPath; -use Webauthn\TrustPath\TrustPathLoader; -use function array_key_exists; -use function in_array; /** * @see https://www.w3.org/TR/webauthn/#iface-pkcredential */ -class PublicKeyCredentialSource implements JsonSerializable +class PublicKeyCredentialSource { /** - * @private * @param string[] $transports * @param array|null $otherUI */ @@ -77,199 +69,13 @@ public static function create( ); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getPublicKeyCredentialId(): string - { - return $this->publicKeyCredentialId; - } - public function getPublicKeyCredentialDescriptor(): PublicKeyCredentialDescriptor { return PublicKeyCredentialDescriptor::create($this->type, $this->publicKeyCredentialId, $this->transports); } - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAttestationType(): string - { - return $this->attestationType; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTrustPath(): TrustPath - { - return $this->trustPath; - } - public function getAttestedCredentialData(): AttestedCredentialData { return AttestedCredentialData::create($this->aaguid, $this->publicKeyCredentialId, $this->credentialPublicKey); } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getType(): string - { - return $this->type; - } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getTransports(): array - { - return $this->transports; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getAaguid(): Uuid - { - return $this->aaguid; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCredentialPublicKey(): string - { - return $this->credentialPublicKey; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getUserHandle(): string - { - return $this->userHandle; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCounter(): int - { - return $this->counter; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setCounter(int $counter): void - { - $this->counter = $counter; - } - - /** - * @return array|null - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getOtherUI(): ?array - { - return $this->otherUI; - } - - /** - * @param array|null $otherUI - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function setOtherUI(?array $otherUI): self - { - $this->otherUI = $otherUI; - - return $this; - } - - /** - * @param mixed[] $data - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): self - { - $keys = array_keys(get_class_vars(self::class)); - foreach ($keys as $key) { - if (in_array($key, ['otherUI', 'backupEligible', 'backupStatus', 'uvInitialized'], true)) { - continue; - } - array_key_exists($key, $data) || throw InvalidDataException::create($data, sprintf( - 'The parameter "%s" is missing', - $key - )); - } - mb_strlen((string) $data['aaguid'], '8bit') === 36 || throw InvalidDataException::create( - $data, - 'Invalid AAGUID' - ); - $uuid = Uuid::fromString($data['aaguid']); - - try { - return self::create( - Base64UrlSafe::decodeNoPadding($data['publicKeyCredentialId']), - $data['type'], - $data['transports'], - $data['attestationType'], - TrustPathLoader::loadTrustPath($data['trustPath']), - $uuid, - Base64UrlSafe::decodeNoPadding($data['credentialPublicKey']), - Base64UrlSafe::decodeNoPadding($data['userHandle']), - $data['counter'], - $data['otherUI'] ?? null, - $data['backupEligible'] ?? null, - $data['backupStatus'] ?? null, - ); - } catch (Throwable $throwable) { - throw InvalidDataException::create($data, 'Unable to load the data', $throwable); - } - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $result = [ - 'publicKeyCredentialId' => Base64UrlSafe::encodeUnpadded($this->publicKeyCredentialId), - 'type' => $this->type, - 'transports' => $this->transports, - 'attestationType' => $this->attestationType, - 'trustPath' => $this->trustPath, - 'aaguid' => $this->aaguid->__toString(), - 'credentialPublicKey' => Base64UrlSafe::encodeUnpadded($this->credentialPublicKey), - 'userHandle' => Base64UrlSafe::encodeUnpadded($this->userHandle), - 'counter' => $this->counter, - 'otherUI' => $this->otherUI, - 'backupEligible' => $this->backupEligible, - 'backupStatus' => $this->backupStatus, - 'uvInitialized' => $this->uvInitialized, - ]; - - return array_filter($result, static fn ($value): bool => $value !== null); - } } diff --git a/src/webauthn/src/PublicKeyCredentialSourceRepository.php b/src/webauthn/src/PublicKeyCredentialSourceRepository.php deleted file mode 100644 index 5174a418..00000000 --- a/src/webauthn/src/PublicKeyCredentialSourceRepository.php +++ /dev/null @@ -1,21 +0,0 @@ -id; - } - - /** - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getDisplayName(): string - { - return $this->displayName; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromString(string $data): self - { - $data = json_decode($data, true, flags: JSON_THROW_ON_ERROR); - is_array($data) || throw InvalidDataException::create($data, 'Invalid data'); - - return self::createFromArray($data); - } - - /** - * @param mixed[] $json - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $json): self - { - array_key_exists('name', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "name" is missing.' - ); - array_key_exists('id', $json) || throw InvalidDataException::create($json, 'Invalid input. "id" is missing.'); - array_key_exists('displayName', $json) || throw InvalidDataException::create( - $json, - 'Invalid input. "displayName" is missing.' - ); - $id = Base64::decode($json['id'], true); - - return self::create($json['name'], $id, $json['displayName'], $json['icon'] ?? null); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - $json = parent::jsonSerialize(); - $json['id'] = Base64UrlSafe::encodeUnpadded($this->id); - $json['displayName'] = $this->displayName; - - return $json; - } } diff --git a/src/webauthn/src/StringStream.php b/src/webauthn/src/StringStream.php index 06784e7c..8cf19c96 100644 --- a/src/webauthn/src/StringStream.php +++ b/src/webauthn/src/StringStream.php @@ -6,6 +6,7 @@ use CBOR\Stream; use Webauthn\Exception\InvalidDataException; +use function assert; use function fclose; use function fopen; use function fread; @@ -27,6 +28,7 @@ public function __construct(string $data) { $this->length = mb_strlen($data, '8bit'); $resource = fopen('php://memory', 'rb+'); + assert($resource !== false, 'The resource could not be opened.'); fwrite($resource, $data); rewind($resource); $this->data = $resource; @@ -38,6 +40,7 @@ public function read(int $length): string return ''; } $read = fread($this->data, $length); + assert($read !== false, 'The data could not be read.'); $bytesRead = mb_strlen($read, '8bit'); mb_strlen($read, '8bit') === $length || throw InvalidDataException::create(null, sprintf( 'Out of range. Expected: %d, read: %d.', diff --git a/src/webauthn/src/TokenBinding/IgnoreTokenBindingHandler.php b/src/webauthn/src/TokenBinding/IgnoreTokenBindingHandler.php deleted file mode 100644 index 037fd8c7..00000000 --- a/src/webauthn/src/TokenBinding/IgnoreTokenBindingHandler.php +++ /dev/null @@ -1,24 +0,0 @@ -getStatus() !== TokenBinding::TOKEN_BINDING_STATUS_PRESENT) { - return; - } - - $request->hasHeader('Sec-Token-Binding') || throw InvalidDataException::create( - $tokenBinding, - 'The header parameter "Sec-Token-Binding" is missing.' - ); - $tokenBindingIds = $request->getHeader('Sec-Token-Binding'); - count($tokenBindingIds) === 1 || throw InvalidDataException::create( - $tokenBinding, - 'The header parameter "Sec-Token-Binding" is invalid.' - ); - $tokenBindingId = reset($tokenBindingIds); - $tokenBindingId === $tokenBinding->getId() || throw InvalidDataException::create( - $tokenBinding, - 'The header parameter "Sec-Token-Binding" is invalid.' - ); - } -} diff --git a/src/webauthn/src/TokenBinding/TokenBinding.php b/src/webauthn/src/TokenBinding/TokenBinding.php deleted file mode 100644 index cffc6ded..00000000 --- a/src/webauthn/src/TokenBinding/TokenBinding.php +++ /dev/null @@ -1,78 +0,0 @@ -status = $status; - $this->id = $id; - } - - /** - * @param mixed[] $json - */ - public static function createFormArray(array $json): self - { - array_key_exists('status', $json) || throw InvalidDataException::create( - $json, - 'The member "status" is required' - ); - $status = $json['status']; - in_array($status, self::getSupportedStatus(), true) || throw InvalidDataException::create($json, sprintf( - 'The member "status" is invalid. Supported values are: %s', - implode(', ', self::getSupportedStatus()) - )); - $id = array_key_exists('id', $json) ? Base64UrlSafe::decodeNoPadding($json['id']) : null; - - return new self($status, $id); - } - - public function getStatus(): string - { - return $this->status; - } - - public function getId(): ?string - { - return $this->id; - } - - /** - * @return string[] - */ - private static function getSupportedStatus(): array - { - return [ - self::TOKEN_BINDING_STATUS_PRESENT, - self::TOKEN_BINDING_STATUS_SUPPORTED, - self::TOKEN_BINDING_STATUS_NOT_SUPPORTED, - ]; - } -} diff --git a/src/webauthn/src/TokenBinding/TokenBindingHandler.php b/src/webauthn/src/TokenBinding/TokenBindingHandler.php deleted file mode 100644 index 8c907fdf..00000000 --- a/src/webauthn/src/TokenBinding/TokenBindingHandler.php +++ /dev/null @@ -1,16 +0,0 @@ -getStatus() !== TokenBinding::TOKEN_BINDING_STATUS_PRESENT || throw InvalidDataException::create( - $tokenBinding, - 'Token binding not supported.' - ); - } -} diff --git a/src/webauthn/src/TrustPath/CertificateTrustPath.php b/src/webauthn/src/TrustPath/CertificateTrustPath.php index 5bc39fbf..456f8369 100644 --- a/src/webauthn/src/TrustPath/CertificateTrustPath.php +++ b/src/webauthn/src/TrustPath/CertificateTrustPath.php @@ -4,17 +4,13 @@ namespace Webauthn\TrustPath; -use Webauthn\Exception\InvalidTrustPathException; -use function array_key_exists; -use function is_array; - -final class CertificateTrustPath implements TrustPath +final readonly class CertificateTrustPath implements TrustPath { /** * @param string[] $certificates */ public function __construct( - public readonly array $certificates + public array $certificates ) { } @@ -25,46 +21,4 @@ public static function create(array $certificates): self { return new self($certificates); } - - /** - * @return string[] - * @deprecated since 4.7.0. Please use the property directly. - * @infection-ignore-all - */ - public function getCertificates(): array - { - return $this->certificates; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): static - { - array_key_exists('x5c', $data) || throw InvalidTrustPathException::create('The trust path type is invalid'); - $x5c = $data['x5c']; - is_array($x5c) || throw InvalidTrustPathException::create( - 'The trust path type is invalid. The parameter "x5c" shall contain strings.' - ); - - return self::create($x5c); - } - - /** - * @return mixed[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - return [ - 'type' => self::class, - 'x5c' => $this->certificates, - ]; - } } diff --git a/src/webauthn/src/TrustPath/EcdaaKeyIdTrustPath.php b/src/webauthn/src/TrustPath/EcdaaKeyIdTrustPath.php deleted file mode 100644 index d0aa7ffa..00000000 --- a/src/webauthn/src/TrustPath/EcdaaKeyIdTrustPath.php +++ /dev/null @@ -1,45 +0,0 @@ -ecdaaKeyId; - } - - /** - * @return string[] - */ - public function jsonSerialize(): array - { - return [ - 'type' => self::class, - 'ecdaaKeyId' => $this->ecdaaKeyId, - ]; - } - - public static function createFromArray(array $data): static - { - array_key_exists('ecdaaKeyId', $data) || throw InvalidTrustPathException::create( - 'The trust path type is invalid' - ); - - return new self($data['ecdaaKeyId']); - } -} diff --git a/src/webauthn/src/TrustPath/EmptyTrustPath.php b/src/webauthn/src/TrustPath/EmptyTrustPath.php index a91a6121..11f28dd4 100644 --- a/src/webauthn/src/TrustPath/EmptyTrustPath.php +++ b/src/webauthn/src/TrustPath/EmptyTrustPath.php @@ -4,35 +4,10 @@ namespace Webauthn\TrustPath; -final class EmptyTrustPath implements TrustPath +final readonly class EmptyTrustPath implements TrustPath { public static function create(): self { return new self(); } - - /** - * @return string[] - */ - public function jsonSerialize(): array - { - trigger_deprecation( - 'web-auth/webauthn-bundle', - '4.9.0', - 'The "%s" method is deprecated and will be removed in 5.0. The serializer instead.', - __METHOD__ - ); - return [ - 'type' => self::class, - ]; - } - - /** - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): static - { - return self::create(); - } } diff --git a/src/webauthn/src/TrustPath/TrustPath.php b/src/webauthn/src/TrustPath/TrustPath.php index f28097e0..36e03178 100644 --- a/src/webauthn/src/TrustPath/TrustPath.php +++ b/src/webauthn/src/TrustPath/TrustPath.php @@ -4,14 +4,6 @@ namespace Webauthn\TrustPath; -use JsonSerializable; - -interface TrustPath extends JsonSerializable +interface TrustPath { - /** - * @param array $data - * @deprecated since 4.8.0. Please use {Webauthn\Denormalizer\WebauthnSerializerFactory} for converting the object. - * @infection-ignore-all - */ - public static function createFromArray(array $data): static; } diff --git a/src/webauthn/src/TrustPath/TrustPathLoader.php b/src/webauthn/src/TrustPath/TrustPathLoader.php index b79675bc..4f4b35ad 100644 --- a/src/webauthn/src/TrustPath/TrustPathLoader.php +++ b/src/webauthn/src/TrustPath/TrustPathLoader.php @@ -7,7 +7,6 @@ use Webauthn\Exception\InvalidTrustPathException; use function array_key_exists; use function is_array; -use function is_string; final class TrustPathLoader { @@ -21,10 +20,7 @@ public static function loadTrustPath(array $data): TrustPath 'type' => EmptyTrustPath::class, ] => EmptyTrustPath::create(), array_key_exists('x5c', $data) && is_array($data['x5c']) => CertificateTrustPath::create($data['x5c']), - array_key_exists('ecdaaKeyId', $data) && is_string($data['ecdaaKeyId']) => new EcdaaKeyIdTrustPath( - $data['ecdaaKeyId'] - ), - default => throw InvalidTrustPathException::create('Unsupported trust path'), + default => throw new InvalidTrustPathException('Invalid trust path'), }; } } diff --git a/src/webauthn/src/U2FPublicKey.php b/src/webauthn/src/U2FPublicKey.php index bbd85c2b..7bf7b64d 100644 --- a/src/webauthn/src/U2FPublicKey.php +++ b/src/webauthn/src/U2FPublicKey.php @@ -15,13 +15,13 @@ /** * @internal */ -final class U2FPublicKey +final readonly class U2FPublicKey { - private const U2F_KEY_PREFIX = "\x04"; + private const string U2F_KEY_PREFIX = "\x04"; - private const U2F_KEY_LENGTH = 65; + private const int U2F_KEY_LENGTH = 65; - private const U2F_KEY_PART_SIZE = 32; + private const int U2F_KEY_PART_SIZE = 32; public static function isU2FKey(string $publicKey): bool { diff --git a/src/webauthn/src/Util/CoseSignatureFixer.php b/src/webauthn/src/Util/CoseSignatureFixer.php index e7ed1ebb..bf3f4e51 100644 --- a/src/webauthn/src/Util/CoseSignatureFixer.php +++ b/src/webauthn/src/Util/CoseSignatureFixer.php @@ -4,7 +4,6 @@ namespace Webauthn\Util; -use Cose\Algorithm\Signature\ECDSA; use Cose\Algorithm\Signature\ECDSA\ECSignature; use Cose\Algorithm\Signature\ECDSA\ES256; use Cose\Algorithm\Signature\ECDSA\ES256K; @@ -19,13 +18,13 @@ * * @see https://www.w3.org/TR/webauthn/#signature-attestation-types */ -abstract class CoseSignatureFixer +final readonly class CoseSignatureFixer { - private const ES256_SIGNATURE_LENGTH = 64; + private const int ES256_SIGNATURE_LENGTH = 64; - private const ES384_SIGNATURE_LENGTH = 96; + private const int ES384_SIGNATURE_LENGTH = 96; - private const ES512_SIGNATURE_LENGTH = 132; + private const int ES512_SIGNATURE_LENGTH = 132; public static function fix(string $signature, Signature $algorithm): string { diff --git a/tests/library/AbstractTestCase.php b/tests/library/AbstractTestCase.php index 48fc750e..b1171960 100644 --- a/tests/library/AbstractTestCase.php +++ b/tests/library/AbstractTestCase.php @@ -18,9 +18,7 @@ use Symfony\Component\HttpClient\MockHttpClient; use Symfony\Component\Serializer\SerializerInterface; use Webauthn\AttestationStatement\AndroidKeyAttestationStatementSupport; -use Webauthn\AttestationStatement\AndroidSafetyNetAttestationStatementSupport; use Webauthn\AttestationStatement\AppleAttestationStatementSupport; -use Webauthn\AttestationStatement\AttestationObjectLoader; use Webauthn\AttestationStatement\AttestationStatementSupportManager; use Webauthn\AttestationStatement\FidoU2FAttestationStatementSupport; use Webauthn\AttestationStatement\NoneAttestationStatementSupport; @@ -37,7 +35,6 @@ use Webauthn\MetadataService\Service\ChainedMetadataServices; use Webauthn\MetadataService\Service\JsonMetadataService; use Webauthn\MetadataService\Service\LocalResourceMetadataService; -use Webauthn\PublicKeyCredentialLoader; use Webauthn\Tests\Bundle\Functional\MockClock; use Webauthn\Tests\Functional\MetadataStatementRepository; use Webauthn\Tests\Functional\StatusReportRepository; @@ -154,27 +151,12 @@ protected function getSerializer(): SerializerInterface return $this->webauthnSerializer; } - protected function getLegacyLoader(): PublicKeyCredentialLoader - { - return new PublicKeyCredentialLoader(new AttestationObjectLoader( - $this->getAttestationStatementSupportManager() - )); - } - private function getAttestationStatementSupportManager(): AttestationStatementSupportManager { $attestationStatementSupportManager = new AttestationStatementSupportManager(); $attestationStatementSupportManager->add(new NoneAttestationStatementSupport()); $attestationStatementSupportManager->add(new AppleAttestationStatementSupport()); $attestationStatementSupportManager->add(AndroidKeyAttestationStatementSupport::create()); - $androidSafetyNetAttestationStatementSupport = new AndroidSafetyNetAttestationStatementSupport( - $this->clock - ); - $androidSafetyNetAttestationStatementSupport - ->enableApiVerification($this->client, 'api_key') - ->setLeeway(0) - ->setMaxAge(99_999_999_999); - $attestationStatementSupportManager->add($androidSafetyNetAttestationStatementSupport); $attestationStatementSupportManager->add(new FidoU2FAttestationStatementSupport()); $attestationStatementSupportManager->add(new PackedAttestationStatementSupport( $this->getAlgorithmManager() diff --git a/tests/library/Functional/AndroidSafetyNetAttestationStatementTest.php b/tests/library/Functional/AndroidSafetyNetAttestationStatementTest.php deleted file mode 100644 index 1a2546b9..00000000 --- a/tests/library/Functional/AndroidSafetyNetAttestationStatementTest.php +++ /dev/null @@ -1,67 +0,0 @@ -getSerializer() - ->deserialize( - '{"id":"Ac8zKrpVWv9UCwxY1FyMqkESz2lV4CNwTk2-Hp19LgKbvh5uQ2_i6AMbTbTz1zcNapCEeiLJPlAAVM4L7AIow6I","type":"public-key","rawId":"Ac8zKrpVWv9UCwxY1FyMqkESz2lV4CNwTk2+Hp19LgKbvh5uQ2/i6AMbTbTz1zcNapCEeiLJPlAAVM4L7AIow6I=","response":{"clientDataJSON":"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmdlIjoia21uczQzQ1dWc3diTW92cktQa2dkMWxFcGM2TFpkZmswVVFfbnVaYnAwMGpXNUM2MVBFVzFkTmFwdFowR2tySUs5V1J0YUFYV2tuZElFRUJnTklDUnciLCJvcmlnaW4iOiJodHRwczpcL1wvd2ViYXV0aG4ubW9yc2VsbGkuZnIiLCJhbmRyb2lkUGFja2FnZU5hbWUiOiJjb20uYW5kcm9pZC5jaHJvbWUifQ","attestationObject":"o2NmbXRxYW5kcm9pZC1zYWZldHluZXRnYXR0U3RtdKJjdmVyaDE0Nzk5MDM3aHJlc3BvbnNlWRS9ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbmcxWXlJNld5Sk5TVWxHYTJwRFEwSkljV2RCZDBsQ1FXZEpVVkpZY205T01GcFBaRkpyUWtGQlFVRkJRVkIxYm5wQlRrSm5hM0ZvYTJsSE9YY3dRa0ZSYzBaQlJFSkRUVkZ6ZDBOUldVUldVVkZIUlhkS1ZsVjZSV1ZOUW5kSFFURlZSVU5vVFZaU01qbDJXako0YkVsR1VubGtXRTR3U1VaT2JHTnVXbkJaTWxaNlRWSk5kMFZSV1VSV1VWRkVSWGR3U0ZaR1RXZFJNRVZuVFZVNGVFMUNORmhFVkVVMFRWUkJlRTFFUVROTlZHc3dUbFp2V0VSVVJUVk5WRUYzVDFSQk0wMVVhekJPVm05M1lrUkZURTFCYTBkQk1WVkZRbWhOUTFaV1RYaEZla0ZTUW1kT1ZrSkJaMVJEYTA1b1lrZHNiV0l6U25WaFYwVjRSbXBCVlVKblRsWkNRV05VUkZVeGRtUlhOVEJaVjJ4MVNVWmFjRnBZWTNoRmVrRlNRbWRPVmtKQmIxUkRhMlIyWWpKa2MxcFRRazFVUlUxNFIzcEJXa0puVGxaQ1FVMVVSVzFHTUdSSFZucGtRelZvWW0xU2VXSXliR3RNYlU1MllsUkRRMEZUU1hkRVVWbEtTMjlhU1doMlkwNUJVVVZDUWxGQlJHZG5SVkJCUkVORFFWRnZRMmRuUlVKQlRtcFlhM293WlVzeFUwVTBiU3N2UnpWM1QyOHJXRWRUUlVOeWNXUnVPRGh6UTNCU04yWnpNVFJtU3pCU2FETmFRMWxhVEVaSWNVSnJOa0Z0V2xaM01rczVSa2N3VHpseVVsQmxVVVJKVmxKNVJUTXdVWFZ1VXpsMVowaEROR1ZuT1c5MmRrOXRLMUZrV2pKd09UTllhSHAxYmxGRmFGVlhXRU40UVVSSlJVZEtTek5UTW1GQlpucGxPVGxRVEZNeU9XaE1ZMUYxV1ZoSVJHRkROMDlhY1U1dWIzTnBUMGRwWm5NNGRqRnFhVFpJTDNob2JIUkRXbVV5YkVvck4wZDFkSHBsZUV0d2VIWndSUzkwV2xObVlsazVNRFZ4VTJ4Q2FEbG1jR293TVRWamFtNVJSbXRWYzBGVmQyMUxWa0ZWZFdWVmVqUjBTMk5HU3pSd1pYWk9UR0Y0UlVGc0swOXJhV3hOZEVsWlJHRmpSRFZ1Wld3MGVFcHBlWE0wTVROb1lXZHhWekJYYUdnMVJsQXpPV2hIYXpsRkwwSjNVVlJxWVhwVGVFZGtkbGd3YlRaNFJsbG9hQzh5VmsxNVdtcFVORXQ2VUVwRlEwRjNSVUZCWVU5RFFXeG5kMmRuU2xWTlFUUkhRVEZWWkVSM1JVSXZkMUZGUVhkSlJtOUVRVlJDWjA1V1NGTlZSVVJFUVV0Q1oyZHlRbWRGUmtKUlkwUkJWRUZOUW1kT1ZraFNUVUpCWmpoRlFXcEJRVTFDTUVkQk1WVmtSR2RSVjBKQ1VYRkNVWGRIVjI5S1FtRXhiMVJMY1hWd2J6UlhObmhVTm1veVJFRm1RbWRPVmtoVFRVVkhSRUZYWjBKVFdUQm1hSFZGVDNaUWJTdDRaMjU0YVZGSE5rUnlabEZ1T1V0NlFtdENaMmR5UW1kRlJrSlJZMEpCVVZKWlRVWlpkMHAzV1VsTGQxbENRbEZWU0UxQlIwZEhNbWd3WkVoQk5reDVPWFpaTTA1M1RHNUNjbUZUTlc1aU1qbHVUREprTUdONlJuWk5WRUZ5UW1kbmNrSm5SVVpDVVdOM1FXOVpabUZJVWpCalJHOTJURE5DY21GVE5XNWlNamx1VERKa2VtTnFTWFpTTVZKVVRWVTRlRXh0VG5sa1JFRmtRbWRPVmtoU1JVVkdha0ZWWjJoS2FHUklVbXhqTTFGMVdWYzFhMk50T1hCYVF6VnFZakl3ZDBsUldVUldVakJuUWtKdmQwZEVRVWxDWjFwdVoxRjNRa0ZuU1hkRVFWbExTM2RaUWtKQlNGZGxVVWxHUVhwQmRrSm5UbFpJVWpoRlMwUkJiVTFEVTJkSmNVRm5hR2cxYjJSSVVuZFBhVGgyV1ROS2MweHVRbkpoVXpWdVlqSTVia3d3WkZWVmVrWlFUVk0xYW1OdGQzZG5aMFZGUW1kdmNrSm5SVVZCWkZvMVFXZFJRMEpKU0RGQ1NVaDVRVkJCUVdSM1EydDFVVzFSZEVKb1dVWkpaVGRGTmt4TldqTkJTMUJFVjFsQ1VHdGlNemRxYW1RNE1FOTVRVE5qUlVGQlFVRlhXbVJFTTFCTVFVRkJSVUYzUWtsTlJWbERTVkZEVTFwRFYyVk1Tblp6YVZaWE5rTm5LMmRxTHpsM1dWUktVbnAxTkVocGNXVTBaVmswWXk5dGVYcHFaMGxvUVV4VFlta3ZWR2g2WTNweGRHbHFNMlJyTTNaaVRHTkpWek5NYkRKQ01HODNOVWRSWkdoTmFXZGlRbWRCU0ZWQlZtaFJSMjFwTDFoM2RYcFVPV1ZIT1ZKTVNTdDRNRm95ZFdKNVdrVldla0UzTlZOWlZtUmhTakJPTUVGQlFVWnRXRkU1ZWpWQlFVRkNRVTFCVW1wQ1JVRnBRbU5EZDBFNWFqZE9WRWRZVURJM09IbzBhSEl2ZFVOSWFVRkdUSGx2UTNFeVN6QXJlVXhTZDBwVlltZEpaMlk0WjBocWRuQjNNbTFDTVVWVGFuRXlUMll6UVRCQlJVRjNRMnR1UTJGRlMwWlZlVm8zWmk5UmRFbDNSRkZaU2t0dldrbG9kbU5PUVZGRlRFSlJRVVJuWjBWQ1FVazVibFJtVWt0SlYyZDBiRmRzTTNkQ1REVTFSVlJXTm10aGVuTndhRmN4ZVVGak5VUjFiVFpZVHpReGExcDZkMG8yTVhkS2JXUlNVbFF2VlhORFNYa3hTMFYwTW1Nd1JXcG5iRzVLUTBZeVpXRjNZMFZYYkV4UldUSllVRXg1Um1wclYxRk9ZbE5vUWpGcE5GY3lUbEpIZWxCb2RETnRNV0kwT1doaWMzUjFXRTAyZEZnMVEzbEZTRzVVYURoQ2IyMDBMMWRzUm1sb2VtaG5iamd4Ukd4a2IyZDZMMHN5VlhkTk5sTTJRMEl2VTBWNGEybFdabllyZW1KS01ISnFkbWM1TkVGc1pHcFZabFYzYTBrNVZrNU5ha1ZRTldVNGVXUkNNMjlNYkRabmJIQkRaVVkxWkdkbVUxZzBWVGw0TXpWdmFpOUpTV1F6VlVVdlpGQndZaTl4WjBkMmMydG1aR1Y2ZEcxVmRHVXZTMU50Y21sM1kyZFZWMWRsV0daVVlra3plbk5wYTNkYVltdHdiVkpaUzIxcVVHMW9kalJ5YkdsNlIwTkhkRGhRYmpod2NUaE5Na3RFWmk5UU0ydFdiM1F6WlRFNFVUMGlMQ0pOU1VsRlUycERRMEY2UzJkQmQwbENRV2RKVGtGbFR6QnRjVWRPYVhGdFFrcFhiRkYxUkVGT1FtZHJjV2hyYVVjNWR6QkNRVkZ6UmtGRVFrMU5VMEYzU0dkWlJGWlJVVXhGZUdSSVlrYzVhVmxYZUZSaFYyUjFTVVpLZG1JelVXZFJNRVZuVEZOQ1UwMXFSVlJOUWtWSFFURlZSVU5vVFV0U01uaDJXVzFHYzFVeWJHNWlha1ZVVFVKRlIwRXhWVVZCZUUxTFVqSjRkbGx0Um5OVk1teHVZbXBCWlVaM01IaE9la0V5VFZSVmQwMUVRWGRPUkVwaFJuY3dlVTFVUlhsTlZGVjNUVVJCZDA1RVNtRk5SVWw0UTNwQlNrSm5UbFpDUVZsVVFXeFdWRTFTTkhkSVFWbEVWbEZSUzBWNFZraGlNamx1WWtkVloxWklTakZqTTFGblZUSldlV1J0YkdwYVdFMTRSWHBCVWtKblRsWkNRVTFVUTJ0a1ZWVjVRa1JSVTBGNFZIcEZkMmRuUldsTlFUQkhRMU54UjFOSllqTkVVVVZDUVZGVlFVRTBTVUpFZDBGM1oyZEZTMEZ2U1VKQlVVUlJSMDA1UmpGSmRrNHdOWHByVVU4NUszUk9NWEJKVW5aS2VucDVUMVJJVnpWRWVrVmFhRVF5WlZCRGJuWlZRVEJSYXpJNFJtZEpRMlpMY1VNNVJXdHpRelJVTW1aWFFsbHJMMnBEWmtNelVqTldXazFrVXk5a1RqUmFTME5GVUZwU2NrRjZSSE5wUzFWRWVsSnliVUpDU2pWM2RXUm5lbTVrU1UxWlkweGxMMUpIUjBac05YbFBSRWxMWjJwRmRpOVRTa2d2VlV3clpFVmhiSFJPTVRGQ2JYTkxLMlZSYlUxR0t5dEJZM2hIVG1oeU5UbHhUUzg1YVd3M01Va3laRTQ0UmtkbVkyUmtkM1ZoWldvMFlsaG9jREJNWTFGQ1ltcDRUV05KTjBwUU1HRk5NMVEwU1N0RWMyRjRiVXRHYzJKcWVtRlVUa001ZFhwd1JteG5UMGxuTjNKU01qVjRiM2x1VlhoMk9IWk9iV3R4TjNwa1VFZElXR3Q0VjFrM2IwYzVhaXRLYTFKNVFrRkNhemRZY2twbWIzVmpRbHBGY1VaS1NsTlFhemRZUVRCTVMxY3dXVE42Tlc5Nk1rUXdZekYwU2t0M1NFRm5UVUpCUVVkcVoyZEZlazFKU1VKTWVrRlBRbWRPVmtoUk9FSkJaamhGUWtGTlEwRlpXWGRJVVZsRVZsSXdiRUpDV1hkR1FWbEpTM2RaUWtKUlZVaEJkMFZIUTBOelIwRlJWVVpDZDAxRFRVSkpSMEV4VldSRmQwVkNMM2RSU1UxQldVSkJaamhEUVZGQmQwaFJXVVJXVWpCUFFrSlpSVVpLYWxJclJ6UlJOamdyWWpkSFEyWkhTa0ZpYjA5ME9VTm1NSEpOUWpoSFFURlZaRWwzVVZsTlFtRkJSa3AyYVVJeFpHNUlRamRCWVdkaVpWZGlVMkZNWkM5alIxbFpkVTFFVlVkRFEzTkhRVkZWUmtKM1JVSkNRMnQzU25wQmJFSm5aM0pDWjBWR1FsRmpkMEZaV1ZwaFNGSXdZMFJ2ZGt3eU9XcGpNMEYxWTBkMGNFeHRaSFppTW1OMldqTk9lVTFxUVhsQ1owNVdTRkk0UlV0NlFYQk5RMlZuU21GQmFtaHBSbTlrU0ZKM1QyazRkbGt6U25OTWJrSnlZVk0xYm1JeU9XNU1NbVI2WTJwSmRsb3pUbmxOYVRWcVkyMTNkMUIzV1VSV1VqQm5Ra1JuZDA1cVFUQkNaMXB1WjFGM1FrRm5TWGRMYWtGdlFtZG5ja0puUlVaQ1VXTkRRVkpaWTJGSVVqQmpTRTAyVEhrNWQyRXlhM1ZhTWpsMlduazVlVnBZUW5aak1td3dZak5LTlV4NlFVNUNaMnR4YUd0cFJ6bDNNRUpCVVhOR1FVRlBRMEZSUlVGSGIwRXJUbTV1TnpoNU5uQlNhbVE1V0d4UlYwNWhOMGhVWjJsYUwzSXpVazVIYTIxVmJWbElVRkZ4TmxOamRHazVVRVZoYW5aM1VsUXlhVmRVU0ZGeU1ESm1aWE54VDNGQ1dUSkZWRlYzWjFwUksyeHNkRzlPUm5ab2MwODVkSFpDUTA5SllYcHdjM2RYUXpsaFNqbDRhblUwZEZkRVVVZzRUbFpWTmxsYVdpOVlkR1ZFVTBkVk9WbDZTbkZRYWxrNGNUTk5SSGh5ZW0xeFpYQkNRMlkxYnpodGR5OTNTalJoTWtjMmVIcFZjalpHWWpaVU9FMWpSRTh5TWxCTVVrdzJkVE5OTkZSNmN6TkJNazB4YWpaaWVXdEtXV2s0ZDFkSlVtUkJka3RNVjFwMUwyRjRRbFppZWxsdGNXMTNhMjAxZWt4VFJGYzFia2xCU21KRlRFTlJRMXAzVFVnMU5uUXlSSFp4YjJaNGN6WkNRbU5EUmtsYVZWTndlSFUyZURaMFpEQldOMU4yU2tORGIzTnBjbE50U1dGMGFpODVaRk5UVmtSUmFXSmxkRGh4THpkVlN6UjJORnBWVGpnd1lYUnVXbm94ZVdjOVBTSmRmUS5leUp1YjI1alpTSTZJbVoxUlZsb0szaFhVRkEzZUhCNVVUZzVhbGh3Y0ZGT05tMWlNV2RYWnpNM1JsQnZOM05VU2pFeFVFMDlJaXdpZEdsdFpYTjBZVzF3VFhNaU9qRTFORGcwT0RneU5UazRNamtzSW1Gd2ExQmhZMnRoWjJWT1lXMWxJam9pWTI5dExtZHZiMmRzWlM1aGJtUnliMmxrTG1kdGN5SXNJbUZ3YTBScFoyVnpkRk5vWVRJMU5pSTZJa0YyV0hGcE1FSnRiVXRKYm1KSVlqTXlaalI2VldoMmVqUmxjR3BwU25RM2EwdE5SMmhUZDNjeFJGVTlJaXdpWTNSelVISnZabWxzWlUxaGRHTm9JanAwY25WbExDSmhjR3REWlhKMGFXWnBZMkYwWlVScFoyVnpkRk5vWVRJMU5pSTZXeUk0VURGelZ6QkZVRXBqYzJ4M04xVjZVbk5wV0V3Mk5IY3JUelV3UldRclVrSkpRM1JoZVRGbk1qUk5QU0pkTENKaVlYTnBZMGx1ZEdWbmNtbDBlU0k2ZEhKMVpYMC5DQldQQ1FNaDBIdjhSTllZc05HTGVuci16RVEyY3o2Q25xalZhblZKOXV1b0d5WFpkc19mRTkwbFRjN0tpYVFMNExWSDl1TnNLWjdyN0xZSzRHTHhHekNqWklwZFlFZUIwdWxaWEN1bDdaVFI2MzZmODBWZmxkZ0dJdDRocWJ6S3dsd0EwNEZJN3ZpbDZjbkNJRHQ4SHVyTzVwRnJIdDVhUkpVcUxnOWhPT3VOaDVYS1JQS29aVTZyQlg5eVhxUmFtbl9SbWd6SkEwRGpqcXNaM3BlYUVvX2g5T0hJUHV3Q3FXZUdlZk5lRmoxVnBnaENpdW1lMXpPb2lwSmt3Tkx3dHdJamNDZ0VqYmc1OEF6ZHBPY01fLUtKYXBUeFJlYk9ZclM3dExTUlZfb2xjZG9PWGUtZ0ctVktCeTRUclJkdE9zNUdydTBqdlNyUGMwZXh6OHV2MkFoYXV0aERhdGFYxcrUbtuZYVMj5mIkvf6KvF1ZzC0gYwKd4+myQgSJCUO2RQAAAAC5P9lh8uZGL7EiggAiR954AEEBzzMqulVa/1QLDFjUXIyqQRLPaVXgI3BOTb4enX0uApu+Hm5Db+LoAxtNtPPXNw1qkIR6Isk+UABUzgvsAijDoqUBAgMmIAEhWCACJyweJ5aGUeFWycOhX/jCeAcTVjAxnbZnJmxj+aLWtyJYIAOY6jc/2y5iT60VYTtZaeBvsQIwgU/XR9Fax7xtatkY"}}', - PublicKeyCredential::class, - 'json' - ); - $this->clock->set((new DateTimeImmutable())->setTimestamp(1_548_489_000)); - - static::assertInstanceOf(AuthenticatorAttestationResponse::class, $publicKeyCredential->response); - $this->client->setResponseFactory(new MockResponse( - '{"isValidSignature":true}', - [ - 'headers' => [ - 'content-type' => 'application/json', - ], - ] - )); - - // When - $pkSource = $this->getAuthenticatorAttestationResponseValidator() - ->check($publicKeyCredential->response, $publicKeyCredentialCreationOptions, 'webauthn.morselli.fr'); - - // Then - static::assertSame('b93fd961-f2e6-462f-b122-82002247de78', $pkSource->aaguid->toRfc4122()); - } -} diff --git a/tests/library/Functional/AssertionTest.php b/tests/library/Functional/AssertionTest.php index 62e392b4..605ffc74 100644 --- a/tests/library/Functional/AssertionTest.php +++ b/tests/library/Functional/AssertionTest.php @@ -69,23 +69,6 @@ public function anAssertionCanBeVerified(): void static::assertSame(123, $publicKeyCredentialSource->counter); } - #[Test] - public function serializerAndLegacyMethodGiveTheSameResult(): void - { - // Given - $input = '{"id":"ADqYfFWXiscOCOPCd9OLiBtSGhletNPKlSOELS0Nuwj_uCzf9s3trLUK9ockO8xa8jBAYdKixLZYOAezy0FJiV1bnTCty_LiInWWJlov","type":"public-key","rawId":"ADqYfFWXiscOCOPCd9OLiBtSGhletNPKlSOELS0Nuwj/uCzf9s3trLUK9ockO8xa8jBAYdKixLZYOAezy0FJiV1bnTCty/LiInWWJlov","response":{"authenticatorData":"tIXbbgSILsWHHbR0Fjkl96X4ROZYLvVtOopBWCQoAqpFXFBJyQAAAAAAAAAAAAAAAAAAAAAATgA6mHxVl4rHDgjjwnfTi4gbUhoZXrTTypUjhC0tDbsI_7gs3_bN7ay1CvaHJDvMWvIwQGHSosS2WDgHs8tBSYldW50wrcvy4iJ1liZaL6UBAgMmIAEhWCAIpUDJSoLScguLRDKBEc32v682i6RPjy6SFZnFTBj2QSJYIG8DS0CpphjyFyZB9xyCTrKDsr_S5iX5hhidWLRdP_7B","clientDataJSON":"eyJjaGFsbGVuZ2UiOiJ3S2xXN1MzRUVOSGxjRjJOZ1loZFVKZlJKZUN2QXZsYmstTWxsdnhvMEhBIiwib3JpZ2luIjoiaHR0cHM6Ly9zcG9ta3ktd2ViYXV0aG4uaGVyb2t1YXBwLmNvbSIsInR5cGUiOiJ3ZWJhdXRobi5nZXQifQ","signature":"MEQCIBnVPX8inAXIxXAsMdF6nW6nZJa36G1O+G9JXiauenxBAiBU4MQoRWxiXGn0TcKTkRJafZ58KLqeCJiB2VFAplwPJA==","userHandle":"YWJmYzhmZGYtMDdmNi00NWE5LWFiZWMtZmExOTIyNzViMjc2"}}'; - - //When - $publicKeyCredential1 = $this->getSerializer() - ->deserialize($input, PublicKeyCredential::class, 'json'); - $publicKeyCredential2 = $this->getLegacyLoader() - ->load($input); - - //Then - static::assertEquals($publicKeyCredential1, $publicKeyCredential2); - - } - #[Test] public function anAssertionWithTokenBindingCanBeVerified(): void { diff --git a/tests/library/Functional/AttestationTest.php b/tests/library/Functional/AttestationTest.php index d44e0946..67f16e42 100644 --- a/tests/library/Functional/AttestationTest.php +++ b/tests/library/Functional/AttestationTest.php @@ -32,7 +32,7 @@ public function aResponseCannotBeLoaded(): void #[Test] public function anAttestationSignedWithEcDSA521ShouldBeVerified(): void { - $options = '{"rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-46},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"MJr5sD0WitVwZM0eoSO6kWhyseT67vc3oQdk_k1VdZQ","attestation":"direct","user":{"name":"zOEOkAZGg3ZrD8l_TFwD","id":"ZDYzNGZlZGQtMGZiNi00ZDY3LWI5OGEtNDk2OWY2ZTMwNTY1","displayName":"Shenika Olin"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; + $options = '{"rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-46},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"MJr5sD0WitVwZM0eoSO6kWhyseT67vc3oQdk_k1VdZQ","attestation":"direct","user":{"name":"zOEOkAZGg3ZrD8l_TFwD","id":"ZDYzNGZlZGQtMGZiNi00ZDY3LWI5OGEtNDk2OWY2ZTMwNTY1","displayName":"Shenika Olin"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}'; $response = '{"id":"R4fAVj9osgVVZL7yHftPeVOmjom3xw4ZLK7Dt_8mzOM","rawId":"R4fAVj9osgVVZL7yHftPeVOmjom3xw4ZLK7Dt/8mzOM","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSiY2FsZzgjY3NpZ1iLMIGIAkIA-KkXe-BmfxZgJNet2JPOZ6-fjPQskjnqOYWf7LW2iMFDbbZ3_oU18m0IGVksCPOaSsDs6MC14CQSqcQpvo0YxHMCQgFKm882cBfrPs4zM7piS3bM3yG6W4OrS9bbIj34e7b9JNH0Ee-w0cAeUaxQNyyedC4y4fSqvUjDT0f0Mj-iE0-pa2hhdXRoRGF0YVjplgTqgoJOmKStoUtEYtDXOo7EaRMNqRsZMHRZIp90o1lBAAAAlSOIq42JFUFGk7rUPmcdJTgAIEeHwFY_aLIFVWS-8h37T3lTpo6Jt8cOGSyuw7f_JszjpQECAzgjIAMhWEIA6Q6fXXQzt2RH6cq4eKJpfFU4nhmCWH2DKAa33T-uGStxA0zaA3goYphgRW6PkgyETh-Q4I3-NJ6KCx-5QV39v50iWEIAA9xyNnqltQaG2UuiLtuSNM59PLv3skYKKmnAvUDT7J6YwPwVyzOWKOyIfgQc9oPO9dRQ21Da498iOhx5qA5gbRo","clientDataJSON":"eyJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLnNwb21reS1sYWJzLmNvbSIsImNoYWxsZW5nZSI6Ik1KcjVzRDBXaXRWd1pNMGVvU082a1doeXNlVDY3dmMzb1Fka19rMVZkWlEiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0","transports":["usb"]},"type":"public-key"}'; $serializer = $this->getSerializer(); $publicKeyCredentialCreationOptions = $serializer->deserialize( diff --git a/tests/library/Functional/ConformanceTest.php b/tests/library/Functional/ConformanceTest.php index de89c59e..0588a295 100644 --- a/tests/library/Functional/ConformanceTest.php +++ b/tests/library/Functional/ConformanceTest.php @@ -46,19 +46,19 @@ public function validAttestationResponseWithLinkShouldSucceed(string $options, s public static function responsesWithLink(): iterable { yield [ - '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"8hPZ5agbQx6bCw_X9c75JyE3DP1PAvW1wv3WknpqBhc","attestation":"direct","user":{"name":"DQ3SnF1Eeq5Av2WCPtlP","id":"MDFHN1JTR1RKTk5OVEpFOUUyS1M2Q0I1U1M","displayName":"Clarice Zemlicka"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', + '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"8hPZ5agbQx6bCw_X9c75JyE3DP1PAvW1wv3WknpqBhc","attestation":"direct","user":{"name":"DQ3SnF1Eeq5Av2WCPtlP","id":"MDFHN1JTR1RKTk5OVEpFOUUyS1M2Q0I1U1M","displayName":"Clarice Zemlicka"},"authenticatorSelection":{"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', '{"id":"12Q1ykFsRWcUbO_y23o3cimk9Bn3rFahaKEAUHyMjrg","rawId":"12Q1ykFsRWcUbO_y23o3cimk9Bn3rFahaKEAUHyMjrg","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEgwRgIhAIVT1JJcjJlU4xyiEWB1DO3OqMLJdC62t8es-JvwbDTgAiEA4E9bIHL-bq4_r09qUBDcm-qCqz0a7NP42K_fSj1YoqBjeDVjglkCkjCCAo4wggI0oAMCAQICAQEwCgYIKoZIzj0EAwIwga8xJjAkBgNVBAMMHUZJRE8yIElOVEVSTUVESUFURSBwcmltZTI1NnYxMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29sc0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMQwwCgYDVQQLDANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2FrZWZpZWxkMB4XDTE4MDUyMzE0Mzc0MVoXDTI4MDUyMDE0Mzc0MVowgcIxIzAhBgNVBAMMGkZJRE8yIEJBVENIIEtFWSBwcmltZTI1NnYxMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29sc0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLrZYqzxrVIvmvsKDJIcF9vrOpmT0KSjZmO-xPXL8hr7gGRpZRxRkYP0fJEPzCo0ZTK3D-vHFtsdDgG9V24pSGSjLDAqMAkGA1UdEwQCMAAwHQYDVR0OBBYEFEpU5QbSkURPbQ8zXdb9x0ZsuV9UMAoGCCqGSM49BAMCA0gAMEUCIQC5Wza0c32jrBDTDb7165XlBCdCWkSVfzvhhqHTfyfqRQIgTQuswDhApHwqT_X6W8aYccqenKb9HKF8DNaRhHM3KXhZBDUwggQxMIICGaADAgECAgECMA0GCSqGSIb3DQEBCwUAMIGhMRgwFgYDVQQDDA9GSURPMiBURVNUIFJPT1QxMTAvBgkqhkiG9w0BCQEWImNvbmZvcm1hbmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxDDAKBgNVBAsMA0NXRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwHhcNMTgwNzIzMTQyOTA3WhcNNDUxMjA4MTQyOTA3WjCBrzEmMCQGA1UEAwwdRklETzIgSU5URVJNRURJQVRFIHByaW1lMjU2djExMTAvBgkqhkiG9w0BCQEWImNvbmZvcm1hbmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxDDAKBgNVBAsMA0NXRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATcQR3fVW1_TXOMqXUUelVx9GMAKSPWb7R7XpeHIHBZBQ7JzoepbzRXitTdCLTCfNXpLE1G6JRcstPmX9tLSXnzoy8wLTAMBgNVHRMEBTADAQH_MB0GA1UdDgQWBBRnwRmSkFv1XQDB1iEOjC12IZJHwDANBgkqhkiG9w0BAQsFAAOCAgEAC5gup7NUuwcndifv5dwlZ6GISPTEciQdMxmNo9nE9BRAO2btQ0DdJdifA8GnQQd29dIgk8U48WucY4qzuvRZaK6z6AIrU2bAUlJrKnlTZvjdiM3oiTY9WTiB9eyfmK_ZgEv7W9DEFW7vrh32-pjSNF1VyxuMEpna1X6syqtNDVG-w0YLjdkXi0ciuRJy0Q9A90vmMKgAxgnRfCol5aQUlHpZMTiK-8OCp8sSoq05QN39iy34u4AeKGUWeuKjYEwNsgKgn-v1-A1dbUw2cWYg53Oi5m_DQLlt-Ws1hokuwXxCekaBvieB9nu13fYXv7SkgwuWPNwyFPlQkWpIPgb9eZME3knUiJ2EAS1UE7kraWNg3cQO2v6tY24-5-FmEyuWinGChrHswT0sYtmhQGlWa0bCV9fELL69bCO64RiWoenLsiX15hmmC7-ZbF9D1VHj1BHR9eioAZUVonEiDJSZHtVxXlmU3jQBhrEPztF5Rn670dzq_E4HLPfzbrKW-L2F2i-WEWF7cticNVBBLXUHsFAvGYMqv7DE0zDGaZ7L-jXIjSCiE2IjixChMYw_aFYwmx0N6yuXeJDYu8fCSXOKTPR6ZRsLCQ38tXFSQRyn1T5Fgvxds7Q2sxgtVXCNy8FMoof27gjMu5i4pAt2ldXEOx1zI2P-Nv6GFxY2U_BtXINoYXV0aERhdGFYpJYE6oKCTpikraFLRGLQ1zqOxGkTDakbGTB0WSKfdKNZQQAAABuA9T0ehS5D7bs_0C8TIuWvACDXZDXKQWxFZxRs7_LbejdyKaT0GfesVqFooQBQfIyOuKUBAgMmIAEhWCCR3V4iMssbPhNCS1rk4wtdZKaqX9L5e3DwGUJKi0OBgCJYIKBBtvFMQHD3m-EgmcQOXmQhctxiyh68RT1QmNq_xWm4","clientDataJSON":"eyJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLnNwb21reS1sYWJzLmNvbSIsImNoYWxsZW5nZSI6IjhoUFo1YWdiUXg2YkN3X1g5Yzc1SnlFM0RQMVBBdlcxd3YzV2tucHFCaGMiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"},"getClientExtensionResults":{},"type":"public-key"}', ]; yield [ - '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"1qMOdI9GD4wEgSZx0IzOck_5PdevIxT8cHo_cbrsJCc","attestation":"direct","user":{"name":"z6Uy-cUKT3tL9m-r7tbv","id":"MDFHN1JTR1dQSE1YQU1XRDlUMUpZV0VDRTU","displayName":"Christiana Muntz"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', + '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"1qMOdI9GD4wEgSZx0IzOck_5PdevIxT8cHo_cbrsJCc","attestation":"direct","user":{"name":"z6Uy-cUKT3tL9m-r7tbv","id":"MDFHN1JTR1dQSE1YQU1XRDlUMUpZV0VDRTU","displayName":"Christiana Muntz"},"authenticatorSelection":{"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', '{"id":"0ByAKfKTliudMLi7-oGBL4DPy9fypqjRYcwUjlrkBlA","rawId":"0ByAKfKTliudMLi7-oGBL4DPy9fypqjRYcwUjlrkBlA","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIgDshB9oeskZ_m-lR77zBAZ69BB-SfJVcFgjx_t6fH0fsCIQCbPW6lFC8qMd9btL0bpRFKn03Zf3N0LOl6Pd58Dx4jw2N4NWOCWQKSMIICjjCCAjSgAwIBAgIBATAKBggqhkjOPQQDAjCBrzEmMCQGA1UEAwwdRklETzIgSU5URVJNRURJQVRFIHByaW1lMjU2djExMTAvBgkqhkiG9w0BCQEWImNvbmZvcm1hbmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxDDAKBgNVBAsMA0NXRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwHhcNMTgwNTIzMTQzNzQxWhcNMjgwNTIwMTQzNzQxWjCBwjEjMCEGA1UEAwwaRklETzIgQkFUQ0ggS0VZIHByaW1lMjU2djExMTAvBgkqhkiG9w0BCQEWImNvbmZvcm1hbmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxIjAgBgNVBAsMGUF1dGhlbnRpY2F0b3IgQXR0ZXN0YXRpb24xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2FrZWZpZWxkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEutlirPGtUi-a-woMkhwX2-s6mZPQpKNmY77E9cvyGvuAZGllHFGRg_R8kQ_MKjRlMrcP68cW2x0OAb1XbilIZKMsMCowCQYDVR0TBAIwADAdBgNVHQ4EFgQUSlTlBtKRRE9tDzNd1v3HRmy5X1QwCgYIKoZIzj0EAwIDSAAwRQIhALlbNrRzfaOsENMNvvXrleUEJ0JaRJV_O-GGodN_J-pFAiBNC6zAOECkfCpP9fpbxphxyp6cpv0coXwM1pGEczcpeFkENTCCBDEwggIZoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwgaExGDAWBgNVBAMMD0ZJRE8yIFRFU1QgUk9PVDExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2UtdG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEMMAoGA1UECwwDQ1dHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDAeFw0xODA3MjMxNDI5MDdaFw00NTEyMDgxNDI5MDdaMIGvMSYwJAYDVQQDDB1GSURPMiBJTlRFUk1FRElBVEUgcHJpbWUyNTZ2MTExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2UtdG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEMMAoGA1UECwwDQ1dHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNxBHd9VbX9Nc4ypdRR6VXH0YwApI9ZvtHtel4cgcFkFDsnOh6lvNFeK1N0ItMJ81eksTUbolFyy0-Zf20tJefOjLzAtMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFGfBGZKQW_VdAMHWIQ6MLXYhkkfAMA0GCSqGSIb3DQEBCwUAA4ICAQALmC6ns1S7Byd2J-_l3CVnoYhI9MRyJB0zGY2j2cT0FEA7Zu1DQN0l2J8DwadBB3b10iCTxTjxa5xjirO69FlorrPoAitTZsBSUmsqeVNm-N2IzeiJNj1ZOIH17J-Yr9mAS_tb0MQVbu-uHfb6mNI0XVXLG4wSmdrVfqzKq00NUb7DRguN2ReLRyK5EnLRD0D3S-YwqADGCdF8KiXlpBSUelkxOIr7w4KnyxKirTlA3f2LLfi7gB4oZRZ64qNgTA2yAqCf6_X4DV1tTDZxZiDnc6Lmb8NAuW35azWGiS7BfEJ6RoG-J4H2e7Xd9he_tKSDC5Y83DIU-VCRakg-Bv15kwTeSdSInYQBLVQTuStpY2DdxA7a_q1jbj7n4WYTK5aKcYKGsezBPSxi2aFAaVZrRsJX18Qsvr1sI7rhGJah6cuyJfXmGaYLv5lsX0PVUePUEdH16KgBlRWicSIMlJke1XFeWZTeNAGGsQ_O0XlGfrvR3Or8Tgcs9_Nuspb4vYXaL5YRYXty2Jw1UEEtdQewUC8Zgyq_sMTTMMZpnsv6NciNIKITYiOLEKExjD9oVjCbHQ3rK5d4kNi7x8JJc4pM9HplGwsJDfy1cVJBHKfVPkWC_F2ztDazGC1VcI3LwUyih_buCMy7mLikC3aV1cQ7HXMjY_42_oYXFjZT8G1cg2hhdXRoRGF0YViklgTqgoJOmKStoUtEYtDXOo7EaRMNqRsZMHRZIp90o1lBAAAASYD1PR6FLkPtuz_QLxMi5a8AINAcgCnyk5YrnTC4u_qBgS-Az8vX8qao0WHMFI5a5AZQpQECAyYgASFYIM9iyt8ZdmBMlZD5K6FOyg3VzDyeypk16mtTiCczNsTmIlggTpzgL3dp4U1t-Sj13YCqXdcvdqIWwqiX-f58oOuj-2g","clientDataJSON":"eyJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLnNwb21reS1sYWJzLmNvbSIsImNoYWxsZW5nZSI6IjFxTU9kSTlHRDR3RWdTWngwSXpPY2tfNVBkZXZJeFQ4Y0hvX2NicnNKQ2MiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"},"getClientExtensionResults":{},"type":"public-key"}', ]; yield [ - '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"o9mB70oaxj0fWTDR6-nR-shxSrElBwmVxOEqumGCdGw","attestation":"direct","user":{"name":"rSyypBidnHmRgi2FikRL","id":"MDFHN1JTR1lTQzhKS0pSTlNBUEdXTVZBN0M","displayName":"Rosalia Jarret"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', + '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"o9mB70oaxj0fWTDR6-nR-shxSrElBwmVxOEqumGCdGw","attestation":"direct","user":{"name":"rSyypBidnHmRgi2FikRL","id":"MDFHN1JTR1lTQzhKS0pSTlNBUEdXTVZBN0M","displayName":"Rosalia Jarret"},"authenticatorSelection":{"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', '{"id":"L79GI1pXKywl03yVsbI0Q0bxm9ddWhDEuNoYAYY9f54","rawId":"L79GI1pXKywl03yVsbI0Q0bxm9ddWhDEuNoYAYY9f54","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEgwRgIhANa4BX_M47mDRfREQGmUplXrk2M84uAW0F_CtKU-EeuOAiEA1wHGAxsOn4mm7EnmDyXSKp2MaT7KCM6l7oCOggUe6GBjeDVjglkCkjCCAo4wggI0oAMCAQICAQEwCgYIKoZIzj0EAwIwga8xJjAkBgNVBAMMHUZJRE8yIElOVEVSTUVESUFURSBwcmltZTI1NnYxMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29sc0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMQwwCgYDVQQLDANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2FrZWZpZWxkMB4XDTE4MDUyMzE0Mzc0MVoXDTI4MDUyMDE0Mzc0MVowgcIxIzAhBgNVBAMMGkZJRE8yIEJBVENIIEtFWSBwcmltZTI1NnYxMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29sc0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABLrZYqzxrVIvmvsKDJIcF9vrOpmT0KSjZmO-xPXL8hr7gGRpZRxRkYP0fJEPzCo0ZTK3D-vHFtsdDgG9V24pSGSjLDAqMAkGA1UdEwQCMAAwHQYDVR0OBBYEFEpU5QbSkURPbQ8zXdb9x0ZsuV9UMAoGCCqGSM49BAMCA0gAMEUCIQC5Wza0c32jrBDTDb7165XlBCdCWkSVfzvhhqHTfyfqRQIgTQuswDhApHwqT_X6W8aYccqenKb9HKF8DNaRhHM3KXhZBDUwggQxMIICGaADAgECAgECMA0GCSqGSIb3DQEBCwUAMIGhMRgwFgYDVQQDDA9GSURPMiBURVNUIFJPT1QxMTAvBgkqhkiG9w0BCQEWImNvbmZvcm1hbmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxDDAKBgNVBAsMA0NXRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwHhcNMTgwNzIzMTQyOTA3WhcNNDUxMjA4MTQyOTA3WjCBrzEmMCQGA1UEAwwdRklETzIgSU5URVJNRURJQVRFIHByaW1lMjU2djExMTAvBgkqhkiG9w0BCQEWImNvbmZvcm1hbmNlLXRvb2xzQGZpZG9hbGxpYW5jZS5vcmcxFjAUBgNVBAoMDUZJRE8gQWxsaWFuY2UxDDAKBgNVBAsMA0NXRzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATcQR3fVW1_TXOMqXUUelVx9GMAKSPWb7R7XpeHIHBZBQ7JzoepbzRXitTdCLTCfNXpLE1G6JRcstPmX9tLSXnzoy8wLTAMBgNVHRMEBTADAQH_MB0GA1UdDgQWBBRnwRmSkFv1XQDB1iEOjC12IZJHwDANBgkqhkiG9w0BAQsFAAOCAgEAC5gup7NUuwcndifv5dwlZ6GISPTEciQdMxmNo9nE9BRAO2btQ0DdJdifA8GnQQd29dIgk8U48WucY4qzuvRZaK6z6AIrU2bAUlJrKnlTZvjdiM3oiTY9WTiB9eyfmK_ZgEv7W9DEFW7vrh32-pjSNF1VyxuMEpna1X6syqtNDVG-w0YLjdkXi0ciuRJy0Q9A90vmMKgAxgnRfCol5aQUlHpZMTiK-8OCp8sSoq05QN39iy34u4AeKGUWeuKjYEwNsgKgn-v1-A1dbUw2cWYg53Oi5m_DQLlt-Ws1hokuwXxCekaBvieB9nu13fYXv7SkgwuWPNwyFPlQkWpIPgb9eZME3knUiJ2EAS1UE7kraWNg3cQO2v6tY24-5-FmEyuWinGChrHswT0sYtmhQGlWa0bCV9fELL69bCO64RiWoenLsiX15hmmC7-ZbF9D1VHj1BHR9eioAZUVonEiDJSZHtVxXlmU3jQBhrEPztF5Rn670dzq_E4HLPfzbrKW-L2F2i-WEWF7cticNVBBLXUHsFAvGYMqv7DE0zDGaZ7L-jXIjSCiE2IjixChMYw_aFYwmx0N6yuXeJDYu8fCSXOKTPR6ZRsLCQ38tXFSQRyn1T5Fgvxds7Q2sxgtVXCNy8FMoof27gjMu5i4pAt2ldXEOx1zI2P-Nv6GFxY2U_BtXINoYXV0aERhdGFYpJYE6oKCTpikraFLRGLQ1zqOxGkTDakbGTB0WSKfdKNZQQAAADOA9T0ehS5D7bs_0C8TIuWvACAvv0YjWlcrLCXTfJWxsjRDRvGb111aEMS42hgBhj1_nqUBAgMmIAEhWCA3vkG3so8pbk9SK-tpl_9YqSxbTCvqxsfjafUlYpoo3yJYIGJWHsBIqosST__pXP3Pzm8yYBYTuDlnyipmRPV6mkA5","clientDataJSON":"eyJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLnNwb21reS1sYWJzLmNvbSIsImNoYWxsZW5nZSI6Im85bUI3MG9heGowZldURFI2LW5SLXNoeFNyRWxCd21WeE9FcXVtR0NkR3ciLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"},"getClientExtensionResults":{},"type":"public-key"}', ]; yield [ - '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"bKFkOxTfxilb29NPsSIKRDaYot1Y5_-EHB-vhgKsnR4","attestation":"direct","user":{"name":"Eo-ImfxnA5fSEd9idRik","id":"MDFHN1JTSDBXSkIwSkNDOVQwMFpLRjY3WjI","displayName":"Katelynn Dunmore"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', + '{"rp":{"name":"Webauthn Demo, by Spomky-Labs","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-46},{"type":"public-key","alg":-7},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39},{"type":"public-key","alg":-65535}],"challenge":"bKFkOxTfxilb29NPsSIKRDaYot1Y5_-EHB-vhgKsnR4","attestation":"direct","user":{"name":"Eo-ImfxnA5fSEd9idRik","id":"MDFHN1JTSDBXSkIwSkNDOVQwMFpLRjY3WjI","displayName":"Katelynn Dunmore"},"authenticatorSelection":{"userVerification":"preferred"},"excludeCredentials":[],"timeout":60000,"status":"ok","errorMessage":""}', '{"id":"ogyur1pgyD4VwCiavjIUfQH0Yuxm9vdp7Hu7X8ZiHTY","rawId":"ogyur1pgyD4VwCiavjIUfQH0Yuxm9vdp7Hu7X8ZiHTY","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEYwRAIgSN7sowPNX_pU0aQMVyZIWESSfH8mHks31zfVF_p1o7ICIHVtDKOD40ubvi3yIL8HBIU8cDWmGzH34ZohgR6IRgzDY3g1Y4JZApIwggKOMIICNKADAgECAgEBMAoGCCqGSM49BAMCMIGvMSYwJAYDVQQDDB1GSURPMiBJTlRFUk1FRElBVEUgcHJpbWUyNTZ2MTExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2UtdG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEMMAoGA1UECwwDQ1dHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDAeFw0xODA1MjMxNDM3NDFaFw0yODA1MjAxNDM3NDFaMIHCMSMwIQYDVQQDDBpGSURPMiBCQVRDSCBLRVkgcHJpbWUyNTZ2MTExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2UtdG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEiMCAGA1UECwwZQXV0aGVudGljYXRvciBBdHRlc3RhdGlvbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS62WKs8a1SL5r7CgySHBfb6zqZk9Cko2ZjvsT1y_Ia-4BkaWUcUZGD9HyRD8wqNGUytw_rxxbbHQ4BvVduKUhkoywwKjAJBgNVHRMEAjAAMB0GA1UdDgQWBBRKVOUG0pFET20PM13W_cdGbLlfVDAKBggqhkjOPQQDAgNIADBFAiEAuVs2tHN9o6wQ0w2-9euV5QQnQlpElX874Yah038n6kUCIE0LrMA4QKR8Kk_1-lvGmHHKnpym_RyhfAzWkYRzNyl4WQQ1MIIEMTCCAhmgAwIBAgIBAjANBgkqhkiG9w0BAQsFADCBoTEYMBYGA1UEAwwPRklETzIgVEVTVCBST09UMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29sc0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMQwwCgYDVQQLDANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2FrZWZpZWxkMB4XDTE4MDcyMzE0MjkwN1oXDTQ1MTIwODE0MjkwN1owga8xJjAkBgNVBAMMHUZJRE8yIElOVEVSTUVESUFURSBwcmltZTI1NnYxMTEwLwYJKoZIhvcNAQkBFiJjb25mb3JtYW5jZS10b29sc0BmaWRvYWxsaWFuY2Uub3JnMRYwFAYDVQQKDA1GSURPIEFsbGlhbmNlMQwwCgYDVQQLDANDV0cxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJNWTESMBAGA1UEBwwJV2FrZWZpZWxkMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE3EEd31Vtf01zjKl1FHpVcfRjACkj1m-0e16XhyBwWQUOyc6HqW80V4rU3Qi0wnzV6SxNRuiUXLLT5l_bS0l586MvMC0wDAYDVR0TBAUwAwEB_zAdBgNVHQ4EFgQUZ8EZkpBb9V0AwdYhDowtdiGSR8AwDQYJKoZIhvcNAQELBQADggIBAAuYLqezVLsHJ3Yn7-XcJWehiEj0xHIkHTMZjaPZxPQUQDtm7UNA3SXYnwPBp0EHdvXSIJPFOPFrnGOKs7r0WWius-gCK1NmwFJSayp5U2b43YjN6Ik2PVk4gfXsn5iv2YBL-1vQxBVu764d9vqY0jRdVcsbjBKZ2tV-rMqrTQ1RvsNGC43ZF4tHIrkSctEPQPdL5jCoAMYJ0XwqJeWkFJR6WTE4ivvDgqfLEqKtOUDd_Yst-LuAHihlFnrio2BMDbICoJ_r9fgNXW1MNnFmIOdzouZvw0C5bflrNYaJLsF8QnpGgb4ngfZ7td32F7-0pIMLljzcMhT5UJFqSD4G_XmTBN5J1IidhAEtVBO5K2ljYN3EDtr-rWNuPufhZhMrlopxgoax7ME9LGLZoUBpVmtGwlfXxCy-vWwjuuEYlqHpy7Il9eYZpgu_mWxfQ9VR49QR0fXoqAGVFaJxIgyUmR7VcV5ZlN40AYaxD87ReUZ-u9Hc6vxOByz3826ylvi9hdovlhFhe3LYnDVQQS11B7BQLxmDKr-wxNMwxmmey_o1yI0gohNiI4sQoTGMP2hWMJsdDesrl3iQ2LvHwklzikz0emUbCwkN_LVxUkEcp9U-RYL8XbO0NrMYLVVwjcvBTKKH9u4IzLuYuKQLdpXVxDsdcyNj_jb-hhcWNlPwbVyDaGF1dGhEYXRhWKSWBOqCgk6YpK2hS0Ri0Nc6jsRpEw2pGxkwdFkin3SjWUEAAAAagPU9HoUuQ-27P9AvEyLlrwAgogyur1pgyD4VwCiavjIUfQH0Yuxm9vdp7Hu7X8ZiHTalAQIDJiABIVggJc-ci7oC-lyh5ZG3Hr0HjYgGKOfk3sg4VB3I8D4ReVsiWCDXYHqho7Ey_-R-CXdyP9FCWJjv09krm1HsJuYcnbFNqQ","clientDataJSON":"eyJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLnNwb21reS1sYWJzLmNvbSIsImNoYWxsZW5nZSI6ImJLRmtPeFRmeGlsYjI5TlBzU0lLUkRhWW90MVk1Xy1FSEItdmhnS3NuUjQiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"},"getClientExtensionResults":{},"type":"public-key"}', ]; } diff --git a/tests/library/Functional/PackedAttestationStatementTest.php b/tests/library/Functional/PackedAttestationStatementTest.php index 01b1b052..18e0f71f 100644 --- a/tests/library/Functional/PackedAttestationStatementTest.php +++ b/tests/library/Functional/PackedAttestationStatementTest.php @@ -150,7 +150,7 @@ public function p2(): void { $publicKeyCredentialCreationOptions = $this->getSerializer() ->deserialize( - '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"KhWQ12Gltp92RModoTPgDqpgXCvR73JXKozijHIfwHE","attestation":"direct","user":{"name":"hw1BfGxhRSKwTOAIx39K","id":"NzExYmI2ZTItYmU3My00YTcyLWE1MDUtYTQzYWE3ZTUyYzgw","displayName":"Leona Grayson"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}', + '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"KhWQ12Gltp92RModoTPgDqpgXCvR73JXKozijHIfwHE","attestation":"direct","user":{"name":"hw1BfGxhRSKwTOAIx39K","id":"NzExYmI2ZTItYmU3My00YTcyLWE1MDUtYTQzYWE3ZTUyYzgw","displayName":"Leona Grayson"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}', PublicKeyCredentialCreationOptions::class, 'json' ); diff --git a/tests/library/Functional/PublicKeyCreationCeremonyTest.php b/tests/library/Functional/PublicKeyCreationCeremonyTest.php index b1c1fd2c..6513adc0 100644 --- a/tests/library/Functional/PublicKeyCreationCeremonyTest.php +++ b/tests/library/Functional/PublicKeyCreationCeremonyTest.php @@ -40,7 +40,7 @@ public function theCeremonySucceeded( public static function getPublicKeyCredentialCreationOptions(): iterable { yield 'anAuthenticatorAttestationResponseWithSubdomainCanBeVerified' => [ - '{"rp":{"name":"Webauthn Demo","id":"spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-257}],"challenge":"xGQ2h2bK2tbn96eNutboG53FvUT30IV_2ThoeKPu778","attestation":"indirect","user":{"name":"fff","id":"MTY3YzljMjUtZThiYy00MzVmLTlhYmMtNDYxMWY5OTg3ODU4","displayName":"FFF"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}', + '{"rp":{"name":"Webauthn Demo","id":"spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-257}],"challenge":"xGQ2h2bK2tbn96eNutboG53FvUT30IV_2ThoeKPu778","attestation":"indirect","user":{"name":"fff","id":"MTY3YzljMjUtZThiYy00MzVmLTlhYmMtNDYxMWY5OTg3ODU4","displayName":"FFF"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}', '{"id":"-cGSjQwC4UBTsh2Mw6guep2uTdLXOExla3QJrVpByOkEWJaOljo54PWOazmHtxBuV5DeysX7qjohoGYK2YibdA","type":"public-key","rawId":"+cGSjQwC4UBTsh2Mw6guep2uTdLXOExla3QJrVpByOkEWJaOljo54PWOazmHtxBuV5DeysX7qjohoGYK2YibdA==","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiJ4R1EyaDJiSzJ0Ym45NmVOdXRib0c1M0Z2VVQzMElWXzJUaG9lS1B1Nzc4Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5zcG9ta3ktbGFicy5jb20iLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0","attestationObject":"o2NmbXRoZmlkby11MmZnYXR0U3RtdKJjc2lnWEcwRQIhALotmA9bjE8DC5afT4C6QJHwB2TDCgh+/DSpIuxt1Z2dAiBzVRmktx9Ur1sjxZJvjhAnzZCRDicD/h2dyd8a+MkVGWN4NWOBWQLCMIICvjCCAaagAwIBAgIEdIb9wjANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZdWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAwMDBaGA8yMDUwMDkwNDAwMDAwMFowbzELMAkGA1UEBhMCU0UxEjAQBgNVBAoMCVl1YmljbyBBQjEiMCAGA1UECwwZQXV0aGVudGljYXRvciBBdHRlc3RhdGlvbjEoMCYGA1UEAwwfWXViaWNvIFUyRiBFRSBTZXJpYWwgMTk1NTAwMzg0MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJVd8633JH0xde/9nMTzGk6HjrrhgQlWYVD7OIsuX2Unv1dAmqWBpQ0KxS8YRFwKE1SKE1PIpOWacE5SO8BN6+2jbDBqMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS4xMBMGCysGAQQBguUcAgEBBAQDAgUgMCEGCysGAQQBguUcAQEEBBIEEPigEfOMCk0VgAYXER+e3H0wDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAMVxIgOaaUn44Zom9af0KqG9J655OhUVBVW+q0As6AIod3AH5bHb2aDYakeIyyBCnnGMHTJtuekbrHbXYXERIn4aKdkPSKlyGLsA/A+WEi+OAfXrNVfjhrh7iE6xzq0sg4/vVJoywe4eAJx0fS+Dl3axzTTpYl71Nc7p/NX6iCMmdik0pAuYJegBcTckE3AoYEg4K99AM/JaaKIblsbFh8+3LxnemeNf7UwOczaGGvjS6UzGVI0Odf9lKcPIwYhuTxM5CaNMXTZQ7xq4/yTfC3kPWtE4hFT34UJJflZBiLrxG4OsYxkHw/n5vKgmpspB3GfYuYTWhkDKiE8CYtyg87mhhdXRoRGF0YVjEzJVnqxWDxWv1dKGpGXUmkUO/MGMFSRae4FA9zhbiR3VBAAAAAAAAAAAAAAAAAAAAAAAAAAAAQPnBko0MAuFAU7IdjMOoLnqdrk3S1zhMZWt0Ca1aQcjpBFiWjpY6OeD1jms5h7cQbleQ3srF+6o6IaBmCtmIm3SlAQIDJiABIVggZ9kAaP2QIzTF401zK9+GnJ9t5P5nZMd+7Uq2dj9zrDciWCAYPJnCkmc15U8txqQB+CdSKUhpVrhITkmBPycz6nzp8g=="}}', 'f9c1928d0c02e14053b21d8cc3a82e7a9dae4dd2d7384c656b7409ad5a41c8e90458968e963a39e0f58e6b3987b7106e5790decac5fbaa3a21a0660ad9889b74', 'basic', diff --git a/tests/library/Functional/W10Test.php b/tests/library/Functional/W10Test.php index 68a866e5..75e70fdb 100644 --- a/tests/library/Functional/W10Test.php +++ b/tests/library/Functional/W10Test.php @@ -75,7 +75,7 @@ public function anAttestationCanBeVerified( public static function getAttestationCanBeVerifiedData(): iterable { yield [ - '{"rp":{"name":"Webauthn Demo"},"pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-257}],"challenge":"XKADkZSW9B4h0Fek8KbhQun3m4dfJYN3ci9wdXDNJvU","attestation":"direct","user":{"name":"test**","id":"ZjZlYWJjNGItYjkyYi00YzI0LTg2N2MtZWZjYmE4OGNjOTRm","displayName":"test**"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}', '{"id":"WsVEgVplFhLkRd68yW3KAIyVJ90ZsQOHFjnL71YirSY","type":"public-key","rawId":"WsVEgVplFhLkRd68yW3KAIyVJ90ZsQOHFjnL71YirSY=","response":{"clientDataJSON":"ew0KCSJ0eXBlIiA6ICJ3ZWJhdXRobi5jcmVhdGUiLA0KCSJjaGFsbGVuZ2UiIDogIlhLQURrWlNXOUI0aDBGZWs4S2JoUXVuM200ZGZKWU4zY2k5d2RYRE5KdlUiLA0KCSJvcmlnaW4iIDogImh0dHBzOi8vd2ViYXV0aG4uc3BvbWt5LWxhYnMuY29tIiwNCgkidG9rZW5CaW5kaW5nIiA6IA0KCXsNCgkJInN0YXR1cyIgOiAic3VwcG9ydGVkIg0KCX0NCn0","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVkBZ5YE6oKCTpikraFLRGLQ1zqOxGkTDakbGTB0WSKfdKNZRQAAAABgKLAXsdRMArSzr82vyWuyACBaxUSBWmUWEuRF3rzJbcoAjJUn3RmxA4cWOcvvViKtJqQBAwM5AQAgWQEAv5VUWjpRGBvp2zawiX2JKC9WSDvVxlLfqNqU1EYsdN6iNg16FFF/0EHkt7tJz9wkwC3Cx5vYFyblUw7UF5m8qS579OcGRjvb6MHj+MQFuOKCoowBMY/VjuF+TT14deKMuWtShT2MCab1gtfnkuGAlEcu2CASvAwtbEPKZ2JkaouWWaJ3hDOYTXWYgCgtM5DqqnN9JUZjXrgmAfQC82SYh6ZAV+MQ2s4RG2jP/dvEt235oFSIkr3JEqhStQvJ+CFmjVk67oFtofcISax44CynCd2Lr89inWU1B0JwSB1oyuLPq5HCQuSmFed/piGjVfFgCbN0tCXJkAGufkDXE3J4xSFDAQAB"}}', base64_decode( + '{"rp":{"name":"Webauthn Demo"},"pubKeyCredParams":[{"type":"public-key","alg":-7},{"type":"public-key","alg":-257}],"challenge":"XKADkZSW9B4h0Fek8KbhQun3m4dfJYN3ci9wdXDNJvU","attestation":"direct","user":{"name":"test**","id":"ZjZlYWJjNGItYjkyYi00YzI0LTg2N2MtZWZjYmE4OGNjOTRm","displayName":"test**"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}', '{"id":"WsVEgVplFhLkRd68yW3KAIyVJ90ZsQOHFjnL71YirSY","type":"public-key","rawId":"WsVEgVplFhLkRd68yW3KAIyVJ90ZsQOHFjnL71YirSY=","response":{"clientDataJSON":"ew0KCSJ0eXBlIiA6ICJ3ZWJhdXRobi5jcmVhdGUiLA0KCSJjaGFsbGVuZ2UiIDogIlhLQURrWlNXOUI0aDBGZWs4S2JoUXVuM200ZGZKWU4zY2k5d2RYRE5KdlUiLA0KCSJvcmlnaW4iIDogImh0dHBzOi8vd2ViYXV0aG4uc3BvbWt5LWxhYnMuY29tIiwNCgkidG9rZW5CaW5kaW5nIiA6IA0KCXsNCgkJInN0YXR1cyIgOiAic3VwcG9ydGVkIg0KCX0NCn0","attestationObject":"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVkBZ5YE6oKCTpikraFLRGLQ1zqOxGkTDakbGTB0WSKfdKNZRQAAAABgKLAXsdRMArSzr82vyWuyACBaxUSBWmUWEuRF3rzJbcoAjJUn3RmxA4cWOcvvViKtJqQBAwM5AQAgWQEAv5VUWjpRGBvp2zawiX2JKC9WSDvVxlLfqNqU1EYsdN6iNg16FFF/0EHkt7tJz9wkwC3Cx5vYFyblUw7UF5m8qS579OcGRjvb6MHj+MQFuOKCoowBMY/VjuF+TT14deKMuWtShT2MCab1gtfnkuGAlEcu2CASvAwtbEPKZ2JkaouWWaJ3hDOYTXWYgCgtM5DqqnN9JUZjXrgmAfQC82SYh6ZAV+MQ2s4RG2jP/dvEt235oFSIkr3JEqhStQvJ+CFmjVk67oFtofcISax44CynCd2Lr89inWU1B0JwSB1oyuLPq5HCQuSmFed/piGjVfFgCbN0tCXJkAGufkDXE3J4xSFDAQAB"}}', base64_decode( 'WsVEgVplFhLkRd68yW3KAIyVJ90ZsQOHFjnL71YirSY=', true ), 'webauthn.spomky-labs.com', hex2bin( @@ -87,7 +87,7 @@ public static function getAttestationCanBeVerifiedData(): iterable EmptyTrustPath::class, ]; yield [ - '{"rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-46},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"8zaIzbt6jRK-dgL-QbWeuo2jkIeRC4OB89z7ZbKbucY","attestation":"none","user":{"name":"11","id":"N2Q3ZTQ2ZTktMzI5Yy00YzE0LWI5MWYtMDYyMWYyOTIyYWQ4","displayName":"ee1"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}', + '{"rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-46},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"8zaIzbt6jRK-dgL-QbWeuo2jkIeRC4OB89z7ZbKbucY","attestation":"none","user":{"name":"11","id":"N2Q3ZTQ2ZTktMzI5Yy00YzE0LWI5MWYtMDYyMWYyOTIyYWQ4","displayName":"ee1"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}', '{"id":"OiAPhrzVRTolk1HfuApGPO9-ZfB7t0txSSAc2evu-p3F5sr_f0qAHg4UJpv7L7146VDVZXTiko36s4rJN4tcmA","type":"public-key","rawId":"OiAPhrzVRTolk1HfuApGPO9+ZfB7t0txSSAc2evu+p3F5sr/f0qAHg4UJpv7L7146VDVZXTiko36s4rJN4tcmA==","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiI4emFJemJ0NmpSSy1kZ0wtUWJXZXVvMmprSWVSQzRPQjg5ejdaYktidWNZIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5zcG9ta3ktbGFicy5jb20iLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0","attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEcwRQIhAPrFFPc+JNPbQS9VLMZ0g8WC5cy7c0pCmd7acJmIY7hpAiAhW+5xovldQQixw/nAqdx5yTCffdrjBn9XfaGYhpxFLmN4NWOBWQLCMIICvjCCAaagAwIBAgIEdIb9wjANBgkqhkiG9w0BAQsFADAuMSwwKgYDVQQDEyNZdWJpY28gVTJGIFJvb3QgQ0EgU2VyaWFsIDQ1NzIwMDYzMTAgFw0xNDA4MDEwMDAwMDBaGA8yMDUwMDkwNDAwMDAwMFowbzELMAkGA1UEBhMCU0UxEjAQBgNVBAoMCVl1YmljbyBBQjEiMCAGA1UECwwZQXV0aGVudGljYXRvciBBdHRlc3RhdGlvbjEoMCYGA1UEAwwfWXViaWNvIFUyRiBFRSBTZXJpYWwgMTk1NTAwMzg0MjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJVd8633JH0xde/9nMTzGk6HjrrhgQlWYVD7OIsuX2Unv1dAmqWBpQ0KxS8YRFwKE1SKE1PIpOWacE5SO8BN6+2jbDBqMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS4xMBMGCysGAQQBguUcAgEBBAQDAgUgMCEGCysGAQQBguUcAQEEBBIEEPigEfOMCk0VgAYXER+e3H0wDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAMVxIgOaaUn44Zom9af0KqG9J655OhUVBVW+q0As6AIod3AH5bHb2aDYakeIyyBCnnGMHTJtuekbrHbXYXERIn4aKdkPSKlyGLsA/A+WEi+OAfXrNVfjhrh7iE6xzq0sg4/vVJoywe4eAJx0fS+Dl3axzTTpYl71Nc7p/NX6iCMmdik0pAuYJegBcTckE3AoYEg4K99AM/JaaKIblsbFh8+3LxnemeNf7UwOczaGGvjS6UzGVI0Odf9lKcPIwYhuTxM5CaNMXTZQ7xq4/yTfC3kPWtE4hFT34UJJflZBiLrxG4OsYxkHw/n5vKgmpspB3GfYuYTWhkDKiE8CYtyg87mhhdXRoRGF0YVjElgTqgoJOmKStoUtEYtDXOo7EaRMNqRsZMHRZIp90o1lFAAABhvigEfOMCk0VgAYXER+e3H0AQDogD4a81UU6JZNR37gKRjzvfmXwe7dLcUkgHNnr7vqdxebK/39KgB4OFCab+y+9eOlQ1WV04pKN+rOKyTeLXJilAQIDJiABIVgg7EAfa9hDOFV9meRyhpqEWhLWwhuZjCEs2eX6RN4TnusiWCD/H1u+zBIuH79akbnFHgEHMEy0FbNaCZwsjAxguhyQ7Q=="}}', hex2bin( '3a200f86bcd5453a259351dfb80a463cef7e65f07bb74b7149201cd9ebeefa9dc5e6caff7f4a801e0e14269bfb2fbd78e950d56574e2928dfab38ac9378b5c98' @@ -100,7 +100,7 @@ public static function getAttestationCanBeVerifiedData(): iterable CertificateTrustPath::class, ]; yield [ - '{"rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-46},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"33Hr5HpypBGbGvb2KNbyXft2z12eKUXPP9nYubuQwe0","attestation":"none","user":{"name":"55","id":"ZDZhOGNhMTAtNDhhZC00YmY1LTkyYWItZmYzOTlmNDZjY2Ew","displayName":"555"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}', + '{"rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-46},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"33Hr5HpypBGbGvb2KNbyXft2z12eKUXPP9nYubuQwe0","attestation":"none","user":{"name":"55","id":"ZDZhOGNhMTAtNDhhZC00YmY1LTkyYWItZmYzOTlmNDZjY2Ew","displayName":"555"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}', '{"id":"C2e2qx0JB7d0vWn25VUP6R8TGo5Id7Q6QX4zhTiuAP31YAwGO9yRhV-jxiHp0tIfzuec-UcgUAgnuBpc8eL_XQ","type":"public-key","rawId":"C2e2qx0JB7d0vWn25VUP6R8TGo5Id7Q6QX4zhTiuAP31YAwGO9yRhV+jxiHp0tIfzuec+UcgUAgnuBpc8eL/XQ==","response":{"clientDataJSON":"eyJjaGFsbGVuZ2UiOiIzM0hyNUhweXBCR2JHdmIyS05ieVhmdDJ6MTJlS1VYUFA5bll1YnVRd2UwIiwiY2xpZW50RXh0ZW5zaW9ucyI6e30sImhhc2hBbGdvcml0aG0iOiJTSEEtMjU2Iiwib3JpZ2luIjoiaHR0cHM6Ly93ZWJhdXRobi5zcG9ta3ktbGFicy5jb20iLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0","attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEYwRAIgB6C51QpoEFbsT2QoYk3NZnBqcHQXLMCt7gmFmqqJK3oCIEp3qKMLOweaj6zeZuvxnxgNo5ZmO6JgZt1LKRWUd9fpY3g1Y4FZAsAwggK8MIIBpKADAgECAgQDrfASMA0GCSqGSIb3DQEBCwUAMC4xLDAqBgNVBAMTI1l1YmljbyBVMkYgUm9vdCBDQSBTZXJpYWwgNDU3MjAwNjMxMCAXDTE0MDgwMTAwMDAwMFoYDzIwNTAwOTA0MDAwMDAwWjBtMQswCQYDVQQGEwJTRTESMBAGA1UECgwJWXViaWNvIEFCMSIwIAYDVQQLDBlBdXRoZW50aWNhdG9yIEF0dGVzdGF0aW9uMSYwJAYDVQQDDB1ZdWJpY28gVTJGIEVFIFNlcmlhbCA2MTczMDgzNDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABBmeh5wWLbfcOe5KQqBGFqWzCf7KCS92vglI+W1ulcrkzGXNVKBZz73HybMbKx1sGER5wsBh9BiqlUtZaiwc+hejbDBqMCIGCSsGAQQBgsQKAgQVMS4zLjYuMS40LjEuNDE0ODIuMS43MBMGCysGAQQBguUcAgEBBAQDAgQwMCEGCysGAQQBguUcAQEEBBIEEPormdyeOUJXj5JKMNI8QRgwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAKOuzZ/7R2PDiievKn/bYB1fGDprlfLFyjJscOMq7vYTZI32oMawhlJ8PLfwMMWv9sXWzbmOiK7tYDq3KUoDQeYQOWh4lcmJaO/uHYDPb+yKpack4uJzhcTWUAKElLZcCqRKT1UUZ6WDdIs6KJ+sF6355t1DAAv7ZAWtxHsmtdFAb2RTLvo7ZVxKBt09E6wd85h7LBquFqXJVJn7o45gr9D8Msho4LSNeueTObbKYxAVCUEAjKyth4QzXDGIVvAO36UBxtw4S0cR/lmVaLvmdTOVafxtLH/kU7hNtnmEgRxSIZGmIgEQxFmU4ibhkhtnJyf+8k4VFNWmzRXRLjKC0N2hhdXRoRGF0YVjElgTqgoJOmKStoUtEYtDXOo7EaRMNqRsZMHRZIp90o1lFAAAAhformdyeOUJXj5JKMNI8QRgAQAtntqsdCQe3dL1p9uVVD+kfExqOSHe0OkF+M4U4rgD99WAMBjvckYVfo8Yh6dLSH87nnPlHIFAIJ7gaXPHi/12lAQIDJiABIVgg55k5XWCizey2Eg3Wg1MArH1DFh9NRx1T5vbIZZWLxQoiWCAqZUDarejYw8p9BYLGckwg13MwLPHKjYCIOFDf2wY7SQ=="}}', hex2bin( '0b67b6ab1d0907b774bd69f6e5550fe91f131a8e4877b43a417e338538ae00fdf5600c063bdc91855fa3c621e9d2d21fcee79cf94720500827b81a5cf1e2ff5d' diff --git a/tests/library/Unit/AttestationStatement/AttestationStatementTest.php b/tests/library/Unit/AttestationStatement/AttestationStatementTest.php index 6471e2bb..c3f0a521 100644 --- a/tests/library/Unit/AttestationStatement/AttestationStatementTest.php +++ b/tests/library/Unit/AttestationStatement/AttestationStatementTest.php @@ -8,7 +8,6 @@ use PHPUnit\Framework\TestCase; use Webauthn\AttestationStatement\AttestationStatement; use Webauthn\TrustPath\CertificateTrustPath; -use Webauthn\TrustPath\EcdaaKeyIdTrustPath; use Webauthn\TrustPath\EmptyTrustPath; /** @@ -33,23 +32,6 @@ public function anAttestationStatementOfNoneTypeReturnsTheExpectedProperties(): static::assertSame('none', $attestationStatement->type); } - #[Test] - public function anAttestationStatementOfEcdaaTypeReturnsTheExpectedProperties(): void - { - $attestationStatement = AttestationStatement::createEcdaa('fmt', [ - 'bar' => 'FOO', - ], new EcdaaKeyIdTrustPath('key_id')); - static::assertSame('fmt', $attestationStatement->fmt); - static::assertSame([ - 'bar' => 'FOO', - ], $attestationStatement->attStmt); - static::assertTrue($attestationStatement->has('bar')); - static::assertFalse($attestationStatement->has('foo')); - static::assertSame('FOO', $attestationStatement->get('bar')); - static::assertInstanceOf(EcdaaKeyIdTrustPath::class, $attestationStatement->trustPath); - static::assertSame('ecdaa', $attestationStatement->type); - } - #[Test] public function anAttestationStatementOfBasicTypeReturnsTheExpectedProperties(): void { diff --git a/tests/library/Unit/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoaderTest.php b/tests/library/Unit/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoaderTest.php deleted file mode 100644 index 1ea8e2cd..00000000 --- a/tests/library/Unit/AuthenticationExtensions/AuthenticationExtensionsClientOutputsLoaderTest.php +++ /dev/null @@ -1,46 +0,0 @@ -getSerializer()->serialize($extensions, 'json', [ - AbstractObjectNormalizer::SKIP_NULL_VALUES => true, - ])); - } - - #[Test] - public function theCBORObjectIsInvalid(): void - { - $this->expectException(AuthenticationExtensionException::class); - $this->expectExceptionMessage('Invalid extension object'); - $cbor = new ByteStringObject('loc'); - - AuthenticationExtensionsClientOutputsLoader::load($cbor); - } -} diff --git a/tests/library/Unit/AuthenticationExtensions/AuthenticationExtensionsClientTest.php b/tests/library/Unit/AuthenticationExtensions/AuthenticationExtensionsClientTest.php index dc8118f7..f4bb13f3 100644 --- a/tests/library/Unit/AuthenticationExtensions/AuthenticationExtensionsClientTest.php +++ b/tests/library/Unit/AuthenticationExtensions/AuthenticationExtensionsClientTest.php @@ -7,8 +7,7 @@ use PHPUnit\Framework\Attributes\Test; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Webauthn\AuthenticationExtensions\AuthenticationExtension; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputs; +use Webauthn\AuthenticationExtensions\AuthenticationExtensions; use Webauthn\Tests\AbstractTestCase; /** @@ -29,25 +28,9 @@ public function anAuthenticationExtensionsClientCanBeCreatedAndValueAccessed(): } #[Test] - public function theAuthenticationExtensionsClientInputsCanManageExtensions(): void + public function theAuthenticationExtensionsCanManageExtensions(): void { - $inputs = AuthenticationExtensionsClientInputs::create([ - AuthenticationExtension::create('name', ['value']), - ]); - - static::assertSame(1, $inputs->count()); - static::assertSame('{"name":["value"]}', $this->getSerializer()->serialize($inputs, 'json', [ - AbstractObjectNormalizer::SKIP_NULL_VALUES => true, - ])); - static::assertContainsOnlyInstancesOf(AuthenticationExtension::class, $inputs); - } - - #[Test] - public function theAuthenticationExtensionsClientOutputsCanManageExtensions(): void - { - $inputs = AuthenticationExtensionsClientOutputs::create([ - AuthenticationExtension::create('name', ['value']), - ]); + $inputs = AuthenticationExtensions::create([AuthenticationExtension::create('name', ['value'])]); static::assertSame(1, $inputs->count()); static::assertSame('{"name":["value"]}', $this->getSerializer()->serialize($inputs, 'json', [ diff --git a/tests/library/Unit/AuthenticatorDataTest.php b/tests/library/Unit/AuthenticatorDataTest.php index 34d2ac85..757ef1df 100644 --- a/tests/library/Unit/AuthenticatorDataTest.php +++ b/tests/library/Unit/AuthenticatorDataTest.php @@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Uid\Uuid; use Webauthn\AttestedCredentialData; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientOutputs; +use Webauthn\AuthenticationExtensions\AuthenticationExtensions; use Webauthn\AuthenticatorData; /** @@ -20,7 +20,7 @@ final class AuthenticatorDataTest extends TestCase public function anAuthenticatorDataCanBeCreatedAndValueAccessed(): void { $attestedCredentialData = AttestedCredentialData::create(Uuid::v4(), '', null); - $extensions = AuthenticationExtensionsClientOutputs::create(); + $extensions = AuthenticationExtensions::create(); $authenticatorData = AuthenticatorData::create( 'auth_data', diff --git a/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php b/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php index 4ea84046..7292bb26 100644 --- a/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php +++ b/tests/library/Unit/AuthenticatorSelectionCriteriaTest.php @@ -40,7 +40,6 @@ public function anAuthenticatorSelectionCriteriaCanBeCreatedAndValueAccessed(): AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM, $data->authenticatorAttachment ); - static::assertNull($data->requireResidentKey); static::assertSame(AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_NO_PREFERENCE, $data->residentKey); static::assertJsonStringEqualsJsonString($expectedJson, $this->getSerializer()->serialize($data, 'json', [ AbstractObjectNormalizer::SKIP_NULL_VALUES => true, @@ -58,12 +57,11 @@ public function anAuthenticatorSelectionCriteriaCanBeCreatedAndValueAccessed(): public function anAuthenticatorSelectionCriteriaWithResidentKeyCanBeCreatedAndValueAccessed(): void { // Given - $expectedJson = '{"authenticatorAttachment":"platform","requireResidentKey":true,"userVerification":"required","residentKey":"required"}'; + $expectedJson = '{"userVerification":"required","residentKey":"required","authenticatorAttachment":"platform"}'; $authenticatorSelectionCriteria = AuthenticatorSelectionCriteria::create( AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM, AuthenticatorSelectionCriteria::USER_VERIFICATION_REQUIREMENT_REQUIRED, - AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_REQUIRED, - true + AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_REQUIRED ); //When @@ -81,13 +79,16 @@ public function anAuthenticatorSelectionCriteriaWithResidentKeyCanBeCreatedAndVa AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_PLATFORM, $data->authenticatorAttachment ); - static::assertTrue($data->requireResidentKey); static::assertSame(AuthenticatorSelectionCriteria::RESIDENT_KEY_REQUIREMENT_REQUIRED, $data->residentKey); - static::assertSame($expectedJson, $this->getSerializer()->serialize($data, 'json', [ - AbstractObjectNormalizer::SKIP_NULL_VALUES => true, - ])); - static::assertSame($expectedJson, $this->getSerializer()->serialize($authenticatorSelectionCriteria, 'json', [ + static::assertJsonStringEqualsJsonString($expectedJson, $this->getSerializer()->serialize($data, 'json', [ AbstractObjectNormalizer::SKIP_NULL_VALUES => true, ])); + static::assertJsonStringEqualsJsonString( + $expectedJson, + $this->getSerializer() + ->serialize($authenticatorSelectionCriteria, 'json', [ + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, + ]) + ); } } diff --git a/tests/library/Unit/MetadataServiceTest.php b/tests/library/Unit/MetadataServiceTest.php index d358752d..d4350e15 100644 --- a/tests/library/Unit/MetadataServiceTest.php +++ b/tests/library/Unit/MetadataServiceTest.php @@ -24,7 +24,7 @@ public function theMetadataServiceCanLoadUri(): void $client = new MockHttpClient(); $client->setResponseFactory($response); - $service = FidoAllianceCompliantMetadataService::create(null, $client, 'https://fidoalliance.co.nz'); + $service = FidoAllianceCompliantMetadataService::create($client, 'https://fidoalliance.co.nz'); $aaguids = $service->list(); foreach ($aaguids as $aaguid) { static::assertTrue($service->has($aaguid)); @@ -41,7 +41,6 @@ public function aMetadataStatementFromAnUriCanBeRetrieved(): void //When $service = DistantResourceMetadataService::create( - null, $client, 'https://raw.githubusercontent.com/solokeys/solo/2.1.0/metadata/Solo-FIDO2-CTAP2-Authenticator.json' ); diff --git a/tests/library/Unit/PublicKeyCredentialCreationOptionsTest.php b/tests/library/Unit/PublicKeyCredentialCreationOptionsTest.php index 2164f342..7a44dbf2 100644 --- a/tests/library/Unit/PublicKeyCredentialCreationOptionsTest.php +++ b/tests/library/Unit/PublicKeyCredentialCreationOptionsTest.php @@ -52,7 +52,7 @@ public function anPublicKeyCredentialCreationOptionsCanBeCreatedAndValueAccessed $data = $this->getSerializer() ->deserialize( - '{"rp":{"name":"RP"},"user":{"name":"USER","id":"aWQ","displayName":"FOO BAR"},"challenge":"Y2hhbGxlbmdl","pubKeyCredParams":[{"type":"type","alg":-100}],"timeout":1000,"excludeCredentials":[{"type":"type","id":"aWQ","transports":["transport"]}],"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred","residentKey":"preferred"},"attestation":"direct"}', + '{"rp":{"name":"RP"},"user":{"name":"USER","id":"aWQ","displayName":"FOO BAR"},"challenge":"Y2hhbGxlbmdl","pubKeyCredParams":[{"type":"type","alg":-100}],"timeout":1000,"excludeCredentials":[{"type":"type","id":"aWQ","transports":["transport"]}],"authenticatorSelection":{"userVerification":"preferred","residentKey":"preferred"},"attestation":"direct"}', PublicKeyCredentialCreationOptions::class, 'json' ); @@ -60,7 +60,7 @@ public function anPublicKeyCredentialCreationOptionsCanBeCreatedAndValueAccessed static::assertSame('direct', $data->attestation); static::assertSame(1000, $data->timeout); static::assertJsonStringEqualsJsonString( - '{"rp":{"name":"RP"},"user":{"name":"USER","id":"aWQ","displayName":"FOO BAR"},"challenge":"Y2hhbGxlbmdl","pubKeyCredParams":[{"type":"type","alg":-100}],"timeout":1000,"excludeCredentials":[{"type":"type","id":"aWQ","transports":["transport"]}],"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred","residentKey":"preferred"},"attestation":"direct"}', + '{"rp":{"name":"RP"},"user":{"name":"USER","id":"aWQ","displayName":"FOO BAR"},"challenge":"Y2hhbGxlbmdl","pubKeyCredParams":[{"type":"type","alg":-100}],"timeout":1000,"excludeCredentials":[{"type":"type","id":"aWQ","transports":["transport"]}],"authenticatorSelection":{"userVerification":"preferred","residentKey":"preferred"},"attestation":"direct"}', $this->getSerializer() ->serialize($data, 'json', [ AbstractObjectNormalizer::SKIP_NULL_VALUES => true, diff --git a/tests/library/Unit/PublicKeyCredentialRequestOptionsTest.php b/tests/library/Unit/PublicKeyCredentialRequestOptionsTest.php index 0ed8a85d..4bf537de 100644 --- a/tests/library/Unit/PublicKeyCredentialRequestOptionsTest.php +++ b/tests/library/Unit/PublicKeyCredentialRequestOptionsTest.php @@ -8,7 +8,6 @@ use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Webauthn\AuthenticationExtensions\AuthenticationExtension; use Webauthn\AuthenticationExtensions\AuthenticationExtensions; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; use Webauthn\PublicKeyCredentialDescriptor; use Webauthn\PublicKeyCredentialRequestOptions; use Webauthn\Tests\AbstractTestCase; @@ -46,7 +45,7 @@ public function authenticatorExtensionSerialization(): void #[Test] public function aPublicKeyCredentialRequestOptionsCanBeCreatedAndValueAccessed(): void { - $extensions = AuthenticationExtensionsClientInputs::create([AuthenticationExtension::create('foo', 'bar')]); + $extensions = AuthenticationExtensions::create([AuthenticationExtension::create('foo', 'bar')]); $credential = PublicKeyCredentialDescriptor::create('type', 'id', ['transport']); $publicKeyCredentialRequestOptions = PublicKeyCredentialRequestOptions::create( diff --git a/tests/library/Unit/PublicKeyCredentialSourceTest.php b/tests/library/Unit/PublicKeyCredentialSourceTest.php index cde05124..53559265 100644 --- a/tests/library/Unit/PublicKeyCredentialSourceTest.php +++ b/tests/library/Unit/PublicKeyCredentialSourceTest.php @@ -23,43 +23,15 @@ public function backwardCompatibilityIsEnsured(): void $data = '{"publicKeyCredentialId":"cHVibGljS2V5Q3JlZGVudGlhbElk","type":"type","transports":["transport1","transport2"],"attestationType":"attestationType","trustPath":[],"aaguid":"014c0f17-f86f-4586-9914-2779922ba877","credentialPublicKey":"cHVibGljS2V5","userHandle":"dXNlckhhbmRsZQ","counter":123456789}'; //When - $source1 = $this->getSerializer() + $source = $this->getSerializer() ->deserialize($data, PublicKeyCredentialSource::class, 'json'); - $source2 = PublicKeyCredentialSource::createFromArray(json_decode($data, true)); - static::assertSame('publicKeyCredentialId', $source1->publicKeyCredentialId); - static::assertEquals($source1, $source2); - static::assertJsonStringEqualsJsonString($data, $this->getSerializer()->serialize($source2, 'json', [ + static::assertSame('publicKeyCredentialId', $source->publicKeyCredentialId); + static::assertJsonStringEqualsJsonString($data, $this->getSerializer()->serialize($source, 'json', [ AbstractObjectNormalizer::SKIP_NULL_VALUES => true, ])); } - #[Test] - public function jsonObject(): void - { - $serializer = $this->getSerializer(); - $source = publicKeyCredentialSource::create( - 'publicKeyCredentialId', - 'type', - ['transport1', 'transport2'], - 'attestationType', - EmptyTrustPath::create(), - Uuid::fromString('02ffd35d-7f0c-46b5-9eae-851ee4807b25'), - 'publicKey', - 'userHandle', - 123_456_789 - ); - $asJson = $this->getSerializer() - ->serialize($source, 'json', [ - AbstractObjectNormalizer::SKIP_NULL_VALUES => true, - ]); - - $object1 = $serializer->deserialize($asJson, PublicKeyCredentialSource::class, 'json'); - $object2 = PublicKeyCredentialSource::createFromArray(json_decode($asJson, true)); - - static::assertEquals($object1, $object2); - } - #[Test] public function objectSerialization(): void { diff --git a/tests/library/Unit/TrustPath/TrustPathTest.php b/tests/library/Unit/TrustPath/TrustPathTest.php index 5a797d06..7a36b273 100644 --- a/tests/library/Unit/TrustPath/TrustPathTest.php +++ b/tests/library/Unit/TrustPath/TrustPathTest.php @@ -8,9 +8,8 @@ use PHPUnit\Framework\TestCase; use Webauthn\Exception\InvalidTrustPathException; use Webauthn\TrustPath\CertificateTrustPath; -use Webauthn\TrustPath\EcdaaKeyIdTrustPath; +use Webauthn\TrustPath\EmptyTrustPath; use Webauthn\TrustPath\TrustPathLoader; -use const JSON_THROW_ON_ERROR; /** * @internal @@ -23,59 +22,54 @@ final class TrustPathTest extends TestCase #[Test] public function aCertificateTrustPathCanBeCreated(): void { + //When $tp = CertificateTrustPath::create(['cert#1']); + //Then static::assertSame(['cert#1'], $tp->certificates); } /** - * @use EcdaaKeyIdTrustPath + * @use TrustPathLoader */ #[Test] - public function anEcdaaKeyIdTrustPathCanBeCreated(): void + public function canLoadCertificateTrustPath(): void { - $tp = new EcdaaKeyIdTrustPath('id'); + //When + $trustPath = TrustPathLoader::loadTrustPath([ + 'x5c' => ['foo'], + ]); - static::assertSame('id', $tp->getEcdaaKeyId()); + //Then + static::assertInstanceOf(CertificateTrustPath::class, $trustPath); } /** * @use TrustPathLoader */ #[Test] - public function theLoaderCannotLoadUnsupportedTypeName(): void + public function canLoadEmptyTrustPath(): void { - $this->expectException(InvalidTrustPathException::class); - $this->expectExceptionMessage('Unsupported trust path'); - TrustPathLoader::loadTrustPath([ - 'type' => 'foo', - ]); + //When + $trustPath = TrustPathLoader::loadTrustPath([]); + + //Then + static::assertInstanceOf(EmptyTrustPath::class, $trustPath); } /** * @use TrustPathLoader */ #[Test] - public function theLoaderCannotLoadUnsupportedTypeNameBasedOnClass(): void + public function cannotLoadUnknownTrustPath(): void { + //Then $this->expectException(InvalidTrustPathException::class); - $this->expectExceptionMessage('Unsupported trust path'); + $this->expectExceptionMessage('Invalid trust path'); + + //When TrustPathLoader::loadTrustPath([ 'type' => NotAValidTrustPath::class, ]); } - - /** - * @use TrustPathLoader - */ - #[Test] - public function theLoaderCanLoadNewTrustPathType(): void - { - $trustPath = json_encode(new EcdaaKeyIdTrustPath('key_id'), JSON_THROW_ON_ERROR); - $data = json_decode($trustPath, true, 512, JSON_THROW_ON_ERROR); - $loadedTrustPath = TrustPathLoader::loadTrustPath($data); - - static::assertInstanceOf(EcdaaKeyIdTrustPath::class, $loadedTrustPath); - static::assertSame('key_id', $loadedTrustPath->getEcdaaKeyId()); - } } diff --git a/tests/symfony/config/config.yml b/tests/symfony/config/config.yml index d04ba5a3..e66306d6 100644 --- a/tests/symfony/config/config.yml +++ b/tests/symfony/config/config.yml @@ -27,6 +27,9 @@ framework: uid: default_uuid_version: 7 time_based_uuid_version: 7 + assets: + base_urls: + - '%kernel.project_dir%/tests/symfony/public' services: _defaults: @@ -72,7 +75,6 @@ services: # tags: # - 'webauthn.mds_service' # arguments: - # - '@Psr\Http\Message\RequestFactoryInterface' # - '@Psr\Http\Client\ClientInterface' # - 'https://fidoalliance.co.nz/blob.jwt' # - [ ] @@ -124,9 +126,6 @@ doctrine: webauthn: credential_repository: 'Webauthn\Tests\Bundle\Functional\PublicKeyCredentialSourceRepository' user_repository: 'Webauthn\Tests\Bundle\Functional\PublicKeyCredentialUserEntityRepository' - android_safetynet: - max_age: 99999999999 - api_key: 'test' controllers: enabled: true creation: diff --git a/tests/symfony/functional/Assertion/AssertionTest.php b/tests/symfony/functional/Assertion/AssertionTest.php index 45f6b394..89ee83cd 100644 --- a/tests/symfony/functional/Assertion/AssertionTest.php +++ b/tests/symfony/functional/Assertion/AssertionTest.php @@ -8,7 +8,7 @@ use PHPUnit\Framework\Attributes\Test; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Serializer\SerializerInterface; -use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs; +use Webauthn\AuthenticationExtensions\AuthenticationExtensions; use Webauthn\AuthenticatorAssertionResponse; use Webauthn\AuthenticatorAssertionResponseValidator; use Webauthn\Bundle\Repository\PublicKeyCredentialSourceRepositoryInterface; @@ -98,6 +98,6 @@ public function aPublicKeyCredentialCreationOptionsCanBeCreatedFromProfile(): vo static::assertSame('localhost', $options->rpId); static::assertSame($allowedCredentials, $options->allowCredentials); static::assertSame('preferred', $options->userVerification); - static::assertInstanceOf(AuthenticationExtensionsClientInputs::class, $options->extensions); + static::assertInstanceOf(AuthenticationExtensions::class, $options->extensions); } } diff --git a/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php b/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php index afa63586..bea5a8ec 100644 --- a/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php +++ b/tests/symfony/functional/Attestation/AdditionalAuthenticatorTest.php @@ -171,7 +171,7 @@ private function logIn(KernelBrowser $client): void { /** @var SerializerInterface $serializer */ $serializer = static::getContainer()->get(SerializerInterface::class); - $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"EhNVt3T8V12FJvSAc50nhKnZ-MEc-kf84xepDcGyN1g","attestation":"direct","user":{"name":"XY5nn3p_6olTLjoB2Jbb","id":"OTI5ZmJhMmYtMjM2MS00YmM2LWE5MTctYmI3NmFhMTRjN2Y5","displayName":"Bennie Moneypenny"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; + $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"EhNVt3T8V12FJvSAc50nhKnZ-MEc-kf84xepDcGyN1g","attestation":"direct","user":{"name":"XY5nn3p_6olTLjoB2Jbb","id":"OTI5ZmJhMmYtMjM2MS00YmM2LWE5MTctYmI3NmFhMTRjN2Y5","displayName":"Bennie Moneypenny"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}'; $publicKeyCredentialCreationOptions = $serializer->deserialize( $options, PublicKeyCredentialCreationOptions::class, diff --git a/tests/symfony/functional/Attestation/AttestationTest.php b/tests/symfony/functional/Attestation/AttestationTest.php index 208e80a9..6a1cccab 100644 --- a/tests/symfony/functional/Attestation/AttestationTest.php +++ b/tests/symfony/functional/Attestation/AttestationTest.php @@ -119,7 +119,7 @@ public function aFullCertificateChainShouldNotBeUsedForThisSelfAttestation(): vo /** @var SerializerInterface $serializer */ $serializer = self::getContainer()->get(SerializerInterface::class); - $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"h8lQZpu-S0rTLOOeAr7BeWoPPTkhtqcEzlHizEyzVeQ","attestation":"direct","user":{"name":"fwOcfew16ujF_p7Hl5eh","id":"ZTc4N2YzZmItMDgwZS00ZDNjLTlhZDItYmE3OTAwYTVlNTg1","displayName":"Gretchen Mo"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; + $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"h8lQZpu-S0rTLOOeAr7BeWoPPTkhtqcEzlHizEyzVeQ","attestation":"direct","user":{"name":"fwOcfew16ujF_p7Hl5eh","id":"ZTc4N2YzZmItMDgwZS00ZDNjLTlhZDItYmE3OTAwYTVlNTg1","displayName":"Gretchen Mo"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}'; $publicKeyCredentialCreationOptions = $serializer->deserialize( $options, PublicKeyCredentialCreationOptions::class, @@ -161,7 +161,7 @@ public function eddsa(): void self::bootKernel(); self::$kernel->getContainer()->get(PublicKeyCredentialSourceRepository::class)->clearCredentials(); - $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"EhNVt3T8V12FJvSAc50nhKnZ-MEc-kf84xepDcGyN1g","attestation":"direct","user":{"name":"XY5nn3p_6olTLjoB2Jbb","id":"OTI5ZmJhMmYtMjM2MS00YmM2LWE5MTctYmI3NmFhMTRjN2Y5","displayName":"Bennie Moneypenny"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; + $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"EhNVt3T8V12FJvSAc50nhKnZ-MEc-kf84xepDcGyN1g","attestation":"direct","user":{"name":"XY5nn3p_6olTLjoB2Jbb","id":"OTI5ZmJhMmYtMjM2MS00YmM2LWE5MTctYmI3NmFhMTRjN2Y5","displayName":"Bennie Moneypenny"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}'; $publicKeyCredentialCreationOptions = $serializer->deserialize( $options, PublicKeyCredentialCreationOptions::class, @@ -200,7 +200,7 @@ public function certificateExpired(): void $this->expectException(CertificateChainException::class); $this->expectExceptionMessage('Unable to validate the certificate chain.'); - $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"vK4TDySRYWO-ZMLS19rRzbuqSDBz-QZRLBb9MB6TVek","attestation":"direct","user":{"name":"KO5UZZdhgkrDan8uypFD","id":"MWY1ODk4M2MtN2JlMi00ZWIxLTllMjMtMDAwZWQwMTk3OGZh","displayName":"Sharyl Seguin"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; + $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"vK4TDySRYWO-ZMLS19rRzbuqSDBz-QZRLBb9MB6TVek","attestation":"direct","user":{"name":"KO5UZZdhgkrDan8uypFD","id":"MWY1ODk4M2MtN2JlMi00ZWIxLTllMjMtMDAwZWQwMTk3OGZh","displayName":"Sharyl Seguin"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}'; $publicKeyCredentialCreationOptions = $serializer->deserialize( $options, PublicKeyCredentialCreationOptions::class, diff --git a/tests/symfony/functional/CompilerPass/CounterCheckerSetterCompilerPassTest.php b/tests/symfony/functional/CompilerPass/CounterCheckerSetterCompilerPassTest.php index ff92bd80..0c174c4f 100644 --- a/tests/symfony/functional/CompilerPass/CounterCheckerSetterCompilerPassTest.php +++ b/tests/symfony/functional/CompilerPass/CounterCheckerSetterCompilerPassTest.php @@ -10,8 +10,8 @@ use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; -use Webauthn\AuthenticatorAssertionResponseValidator; use Webauthn\Bundle\DependencyInjection\Compiler\CounterCheckerSetterCompilerPass; +use Webauthn\CeremonyStep\CeremonyStepManagerFactory; use Webauthn\Counter\CounterChecker; /** @@ -23,7 +23,7 @@ final class CounterCheckerSetterCompilerPassTest extends AbstractCompilerPassTes public function theCounterCheckerIsCorrectlyAddedIfItExists(): void { //Given - $this->setDefinition(AuthenticatorAssertionResponseValidator::class, new Definition()); + $this->setDefinition(CeremonyStepManagerFactory::class, new Definition()); $this->setDefinition('counter_checker', new Definition()); $this->container->setAlias(CounterChecker::class, 'counter_checker'); @@ -33,7 +33,7 @@ public function theCounterCheckerIsCorrectlyAddedIfItExists(): void //Then $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( - AuthenticatorAssertionResponseValidator::class, + CeremonyStepManagerFactory::class, 'setCounterChecker', [new Reference(CounterChecker::class)] ); diff --git a/tests/symfony/functional/CompilerPass/EnforcedSafetyNetApiKeyVerificationCompilerPassTest.php b/tests/symfony/functional/CompilerPass/EnforcedSafetyNetApiKeyVerificationCompilerPassTest.php deleted file mode 100644 index 018bf23f..00000000 --- a/tests/symfony/functional/CompilerPass/EnforcedSafetyNetApiKeyVerificationCompilerPassTest.php +++ /dev/null @@ -1,51 +0,0 @@ -setDefinition(AndroidSafetyNetAttestationStatementSupport::class, new Definition()); - - $this->setDefinition('http_client', new Definition()); - $this->container->setAlias('webauthn.android_safetynet.http_client', 'http_client'); - - $this->setParameter('webauthn.android_safetynet.api_key', 'api_key'); - - //When - $this->compile(); - - //Then - $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( - AndroidSafetyNetAttestationStatementSupport::class, - 'enableApiVerification', - [new Reference('webauthn.android_safetynet.http_client'), 'api_key', null] - ); - } - - protected function registerCompilerPass(ContainerBuilder $container): void - { - $container->addCompilerPass( - new EnforcedSafetyNetApiKeyVerificationCompilerPass(), - PassConfig::TYPE_BEFORE_OPTIMIZATION, - 0 - ); - } -} diff --git a/tests/symfony/functional/CompilerPass/EventDispatcherSetterCompilerPassTest.php b/tests/symfony/functional/CompilerPass/EventDispatcherSetterCompilerPassTest.php index bad0e126..9e14925b 100644 --- a/tests/symfony/functional/CompilerPass/EventDispatcherSetterCompilerPassTest.php +++ b/tests/symfony/functional/CompilerPass/EventDispatcherSetterCompilerPassTest.php @@ -12,7 +12,6 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Webauthn\AttestationStatement\AndroidKeyAttestationStatementSupport; -use Webauthn\AttestationStatement\AndroidSafetyNetAttestationStatementSupport; use Webauthn\AttestationStatement\AppleAttestationStatementSupport; use Webauthn\AttestationStatement\AttestationObjectLoader; use Webauthn\AttestationStatement\FidoU2FAttestationStatementSupport; @@ -26,7 +25,6 @@ use Webauthn\MetadataService\Service\FidoAllianceCompliantMetadataService; use Webauthn\MetadataService\Service\InMemoryMetadataService; use Webauthn\MetadataService\Service\LocalResourceMetadataService; -use Webauthn\MetadataService\Service\StringMetadataService; /** * @internal @@ -63,10 +61,8 @@ public static function getClassList(): iterable yield [FidoAllianceCompliantMetadataService::class]; yield [InMemoryMetadataService::class]; yield [LocalResourceMetadataService::class]; - yield [StringMetadataService::class]; yield [WebauthnExtension::class]; yield [AndroidKeyAttestationStatementSupport::class]; - yield [AndroidSafetyNetAttestationStatementSupport::class]; yield [AppleAttestationStatementSupport::class]; yield [AttestationObjectLoader::class]; yield [FidoU2FAttestationStatementSupport::class]; diff --git a/tests/symfony/functional/CompilerPass/MetadataStatementSupportCompilerPassTest.php b/tests/symfony/functional/CompilerPass/MetadataStatementSupportCompilerPassTest.php deleted file mode 100644 index b4154c57..00000000 --- a/tests/symfony/functional/CompilerPass/MetadataStatementSupportCompilerPassTest.php +++ /dev/null @@ -1,62 +0,0 @@ -setDefinition(AuthenticatorAttestationResponseValidator::class, new Definition()); - - $this->setDefinition('metadata_statement_repository', new Definition()); - $this->container->setAlias(MetadataStatementRepository::class, 'metadata_statement_repository'); - - $this->setDefinition('certificate_chain_checker', new Definition()); - $this->container->setAlias(CertificateChainValidator::class, 'certificate_chain_checker'); - - $this->setDefinition('status_report_repository', new Definition()); - $this->container->setAlias(StatusReportRepository::class, 'status_report_repository'); - - //When - $this->compile(); - - //Then - $this->assertContainerBuilderHasServiceDefinitionWithMethodCall( - AuthenticatorAttestationResponseValidator::class, - 'enableMetadataStatementSupport', - [ - new Reference(MetadataStatementRepository::class), - new Reference(StatusReportRepository::class), - new Reference(CertificateChainValidator::class), - ] - ); - } - - protected function registerCompilerPass(ContainerBuilder $container): void - { - $container->addCompilerPass( - new MetadataStatementSupportCompilerPass(), - PassConfig::TYPE_BEFORE_OPTIMIZATION, - 0 - ); - } -} diff --git a/tests/symfony/functional/CustomSessionStorage.php b/tests/symfony/functional/CustomSessionStorage.php index be6aa2c0..363ce450 100644 --- a/tests/symfony/functional/CustomSessionStorage.php +++ b/tests/symfony/functional/CustomSessionStorage.php @@ -17,7 +17,7 @@ public function store(Item $item): void $this->item = $item; } - public function get(): Item + public function get(string $challenge): Item { if ($this->item === null) { throw new LogicException('No public key credential options available for this session.'); diff --git a/tests/symfony/functional/Firewall/RegistrationAreaTest.php b/tests/symfony/functional/Firewall/RegistrationAreaTest.php index 9bd96006..acc630b2 100644 --- a/tests/symfony/functional/Firewall/RegistrationAreaTest.php +++ b/tests/symfony/functional/Firewall/RegistrationAreaTest.php @@ -75,11 +75,9 @@ public function aValidRequestProcessed(): void $content = [ 'username' => 'foo', 'displayName' => 'FOO', - 'authenticatorSelection' => [ - 'authenticatorAttachment' => 'cross-platform', - 'userVerification' => 'required', - 'requireResidentKey' => true, - ], + 'authenticatorAttachment' => 'cross-platform', + 'userVerification' => 'required', + 'residentKey' => 'required', 'attestation' => 'indirect', ]; $client = static::createClient([], [ @@ -104,7 +102,6 @@ public function aValidRequestProcessed(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ 'authenticatorAttachment' => 'cross-platform', - 'requireResidentKey' => true, 'userVerification' => 'required', 'residentKey' => 'required', ], $data['authenticatorSelection']); @@ -116,9 +113,8 @@ public function aValidRequestProcessedOnOtherHost(): void $content = [ 'username' => 'foo', 'displayName' => 'FOO', - 'authenticatorSelection' => [ - 'requireResidentKey' => true, - ], + 'userVerification' => 'preferred', + 'residentKey' => 'required', ]; $client = static::createClient([], [ 'HTTPS' => 'on', @@ -141,7 +137,6 @@ public function aValidRequestProcessedOnOtherHost(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ - 'requireResidentKey' => true, 'userVerification' => 'preferred', 'residentKey' => 'required', ], $data['authenticatorSelection']); @@ -153,11 +148,9 @@ public function aValidRequestProcessedWithExtensions(): void $content = [ 'username' => 'foo', 'displayName' => 'FOO', - 'authenticatorSelection' => [ - 'authenticatorAttachment' => 'platform', - 'userVerification' => 'required', - 'requireResidentKey' => true, - ], + 'userVerification' => 'required', + 'residentKey' => 'required', + 'authenticatorAttachment' => 'platform', 'extensions' => [ 'loc' => true, 'def' => '123', @@ -189,7 +182,6 @@ public function aValidRequestProcessedWithExtensions(): void static::assertArrayHasKey('authenticatorSelection', $data); static::assertSame([ 'authenticatorAttachment' => 'platform', - 'requireResidentKey' => true, 'userVerification' => 'required', 'residentKey' => 'required', ], $data['authenticatorSelection']); diff --git a/tests/symfony/functional/MetadataService/ConformanceTest.php b/tests/symfony/functional/MetadataService/ConformanceTest.php index e5ccd4ad..783c033a 100644 --- a/tests/symfony/functional/MetadataService/ConformanceTest.php +++ b/tests/symfony/functional/MetadataService/ConformanceTest.php @@ -39,7 +39,7 @@ public function theMetadataStatementIsMissing(): void $this->expectExceptionMessage( 'The Metadata Statement for the AAGUID "4b46ebe2-9866-427e-b7a4-ab926b2aa12f" is missing' ); - $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"625PSan72RKYZz_TA4aOLx7ohRptcGnJme6z4k4k6tU","attestation":"direct","user":{"name":"um-3Ch1opGUBzAgO0VE5","id":"OTk3OGFlYWItNmE5Yi00ZDNlLTk2ODMtOWM3MDViNWNiYjAw","displayName":"Christiana Muntz"},"authenticatorSelection":{"requireResidentKey":false,"userVerification":"preferred"},"timeout":60000}'; + $options = '{"status":"ok","errorMessage":"","rp":{"name":"Webauthn Demo","id":"webauthn.spomky-labs.com"},"pubKeyCredParams":[{"type":"public-key","alg":-8},{"type":"public-key","alg":-7},{"type":"public-key","alg":-43},{"type":"public-key","alg":-35},{"type":"public-key","alg":-36},{"type":"public-key","alg":-257},{"type":"public-key","alg":-258},{"type":"public-key","alg":-259},{"type":"public-key","alg":-37},{"type":"public-key","alg":-38},{"type":"public-key","alg":-39}],"challenge":"625PSan72RKYZz_TA4aOLx7ohRptcGnJme6z4k4k6tU","attestation":"direct","user":{"name":"um-3Ch1opGUBzAgO0VE5","id":"OTk3OGFlYWItNmE5Yi00ZDNlLTk2ODMtOWM3MDViNWNiYjAw","displayName":"Christiana Muntz"},"authenticatorSelection":{"userVerification":"preferred"},"timeout":60000}'; $result = '{"id":"8cQglUiAnc63hmOyudycW7xdaJoH-pPVlRyg5Xl7aYM","rawId":"8cQglUiAnc63hmOyudycW7xdaJoH+pPVlRyg5Xl7aYM","response":{"attestationObject":"o2NmbXRmcGFja2VkZ2F0dFN0bXSjY2FsZyZjc2lnWEgwRgIhALCSEVyBYqnkYZmp-ZGpnS3qgaYzEu-cOafnRqyFyvgVAiEAxjsiNt3SdvBc7Lwq9O2CSLRF6OQDDB0D1lBHNYiFV4FjeDVjgVkERTCCBEEwggIpoAMCAQICAQEwDQYJKoZIhvcNAQELBQAwgaExGDAWBgNVBAMMD0ZJRE8yIFRFU1QgUk9PVDExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2UtdG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEMMAoGA1UECwwDQ1dHMQswCQYDVQQGEwJVUzELMAkGA1UECAwCTVkxEjAQBgNVBAcMCVdha2VmaWVsZDAeFw0xODA1MjMxNDM5NDNaFw0yODA1MjAxNDM5NDNaMIHCMSMwIQYDVQQDDBpGSURPMiBCQVRDSCBLRVkgcHJpbWUyNTZ2MTExMC8GCSqGSIb3DQEJARYiY29uZm9ybWFuY2UtdG9vbHNAZmlkb2FsbGlhbmNlLm9yZzEWMBQGA1UECgwNRklETyBBbGxpYW5jZTEiMCAGA1UECwwZQXV0aGVudGljYXRvciBBdHRlc3RhdGlvbjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1ZMRIwEAYDVQQHDAlXYWtlZmllbGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARPOl5eq2wfvK6X9t9kSZZ2LHvvcgBAKnbG8jD2VW8XqpmbWX_Ev1CKr46e8M0BP1q5vSeRS_CAQ3jLzLEbibVGoywwKjAJBgNVHRMEAjAAMB0GA1UdDgQWBBRWTffA-MZVtqEfbE0Z879B4v0BeTANBgkqhkiG9w0BAQsFAAOCAgEAh92gn_ggiQXRLUHOCaTp1HpcBhsOw8ZwTKJBxwYK8ycQ5_QRXBcMRi8axVexH2HoUDTg_u-DkvH2UYGYjX_RAxgGIh4dPgrKXwVndtMwiI5QnQwXMocKtzyyeuSQv6INwk_QCuJL5LOAyPtNUWMTb_UvCcdYWjtZYFOeYQSK9T_6dtWSp6XAhIT4wf3CBaxyai-YiRn3nfi154vUrqtuDh56eODK7-Iezg9npbucln3XxW_kRhtk2FERSBmBoo7IotPd8NGTATnwUvt16vw6x3mW2a6zZGOOeYCQmeXlfNza7fSff1BdFWR5f4cJ0gFAv297Tf5dGZQvZD3DcyQ9OJeJ3RQQ9inX0Nhxk1-6cm1i2e8h9gTN7otjqYmnGjs3ezhPdax2AdrmckO43YNuchfTPECPTRzP4rQo3QbwGLeEAk_HV-oJmYiBkdhf2F2QLMm7SdeqZ1Jjg1W1vNJT288vj1EGF-_aKXg_bujAaK86_YNPBJaW9Rdw4EnfFUi5bEdkD5ZSpeAHCQzCDn2RzkBjs2rTFe4qRFUWtC-RZ4wFqRx70jXLIw-ArpeetpjtzJSNqQsqPlEvpyMxuV2ZjnruA2_ysP3RDzqNs7R8JVNKiie0RAbG7et43ULZcC7oix8JKYsJ6wDmX8Gyy7vWM-LS9XiZUH37sEvwKJbM-xxoYXV0aERhdGFYpJYE6oKCTpikraFLRGLQ1zqOxGkTDakbGTB0WSKfdKNZQQAAAFpLRuvimGZCfrekq5JrKqEvACDxxCCVSICdzreGY7K53JxbvF1omgf6k9WVHKDleXtpg6UBAgMmIAEhWCCPnYovnhb8uFlbWx3AJ68r1nA-r3Rp77jZ7QrzCi6LfyJYIIIvljxQ2lTzNH1o8YxxCLkUXT7NZP9Jf4pKHSLTkhka","clientDataJSON":"eyJvcmlnaW4iOiJodHRwczovL3dlYmF1dGhuLnNwb21reS1sYWJzLmNvbSIsImNoYWxsZW5nZSI6IjYyNVBTYW43MlJLWVp6X1RBNGFPTHg3b2hScHRjR25KbWU2ejRrNGs2dFUiLCJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIn0"},"type":"public-key"}'; $publicKeyCredentialCreationOptions = $serializer->deserialize( $options, diff --git a/tests/symfony/functional/ServiceDefinition/OptionsBuilderParameterTest.php b/tests/symfony/functional/ServiceDefinition/OptionsBuilderParameterTest.php index caed56b5..9a851146 100644 --- a/tests/symfony/functional/ServiceDefinition/OptionsBuilderParameterTest.php +++ b/tests/symfony/functional/ServiceDefinition/OptionsBuilderParameterTest.php @@ -19,6 +19,7 @@ public function theDefaultOptionsBuilderIsUsedWhenNoOptionIsSet(): void { // When $this->load([ + 'clock' => 'system', 'controllers' => [ 'creation' => [ 'creation_111' => [ @@ -67,6 +68,7 @@ public function aCustomOptionsBuilderCanBeSet(): void { // When $this->load([ + 'clock' => 'system', 'controllers' => [ 'creation' => [ 'creation_111' => [ diff --git a/tests/symfony/public/.gitignore b/tests/symfony/public/.gitignore new file mode 100644 index 00000000..e69de29b