diff --git a/composer.json b/composer.json index 76a5f595..5be74c0e 100644 --- a/composer.json +++ b/composer.json @@ -53,8 +53,8 @@ "ext-openssl": "*", "ext-sodium": "*", "brick/math": "^0.9|^0.10|^0.11|^0.12", - "paragonie/constant_time_encoding": "^2.6", - "paragonie/sodium_compat": "^1.20", + "paragonie/constant_time_encoding": "^2.6|^3.0", + "paragonie/sodium_compat": "^1.20|^2.0", "psr/cache": "^3.0", "psr/clock": "^1.0", "psr/event-dispatcher": "^1.0", @@ -75,7 +75,7 @@ "ext-gmp": "*", "bjeavons/zxcvbn-php": "^1.3", "ekino/phpstan-banned-code": "^1.0", - "infection/infection": "^0.27", + "infection/infection": "^0.29", "matthiasnoback/symfony-config-test": "^5.0", "nyholm/psr7": "^1.8", "php-http/mock-client": "^1.5", @@ -86,17 +86,17 @@ "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", - "symfony/browser-kit": "^6.1|^7.0", - "symfony/finder": "^6.1|^7.0", - "symfony/framework-bundle": "^6.1|^7.0", - "symfony/phpunit-bridge": "^6.1|^7.0", - "symfony/serializer": "^6.1|^7.0", - "symfony/var-dumper": "^6.1|^7.0", - "symfony/yaml": "^6.1|^7.0", + "symfony/browser-kit": "^5.4|^6.0|^7.0", + "symfony/finder": "^5.4|^6.0|^7.0", + "symfony/framework-bundle": "^5.4|^6.0|^7.0", + "symfony/phpunit-bridge": "^5.4|^6.0|^7.0", + "symfony/serializer": "^5.4|^6.0|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0", + "symfony/yaml": "^5.4|^6.0|^7.0", "symplify/easy-coding-standard": "^12.0" }, "replace": { diff --git a/deptrac.yaml b/deptrac.yaml index f0df0272..705b626d 100644 --- a/deptrac.yaml +++ b/deptrac.yaml @@ -4,38 +4,40 @@ parameters: layers: - name: 'Core' collectors: - - { type: className, regex: '^Jose\\Component\\Core\\' } + - { type: classLike, value: '^Jose\\Component\\Core\\' } - name: 'Checker' collectors: - - { type: className, regex: '^Jose\\Component\\Checker\\' } + - { type: classLike, value: '^Jose\\Component\\Checker\\' } - name: 'Console' collectors: - - { type: className, regex: '^Jose\\Component\\Console\\' } + - { type: classLike, value: '^Jose\\Component\\Console\\' } - name: 'KeyManagement' collectors: - - { type: className, regex: '^Jose\\Component\\KeyManagement\\' } + - { type: classLike, value: '^Jose\\Component\\KeyManagement\\' } - name: 'NestedToken' collectors: - - { type: className, regex: '^Jose\\Component\\NestedToken\\' } + - { type: classLike, value: '^Jose\\Component\\NestedToken\\' } - name: 'Encryption' collectors: - - { type: className, regex: '^Jose\\Component\\Encryption\\' } + - { type: classLike, value: '^Jose\\Component\\Encryption\\' } - name: 'Signature' collectors: - - { type: className, regex: '^Jose\\Component\\Signature\\' } + - { type: classLike, value: '^Jose\\Component\\Signature\\' } - name: 'Bundle' collectors: - - { type: className, regex: '^Jose\\Bundle\\JoseFramework\\' } + - { type: classLike, value: '^Jose\\Bundle\\JoseFramework\\' } - name: 'Vendors' collectors: - - { type: className, regex: '^Symfony\\' } - - { type: className, regex: '^SpomkyLabs\\Pki\\' } - - { type: className, regex: '^ParagonIE\\' } - - { type: className, regex: '^Psr\\EventDispatcher\\' } - - { type: className, regex: '^Psr\\Http\\' } - - { type: className, regex: '^Brick\\Math\\' } - - { type: className, regex: '^AESKW\\' } - - { type: className, regex: '^ZxcvbnPhp\\' } + - { type: classLike, value: '^Symfony\\' } + - { type: classLike, value: '^SpomkyLabs\\Pki\\' } + - { type: classLike, value: '^ParagonIE\\' } + - { type: classLike, value: '^Psr\\EventDispatcher\\' } + - { type: classLike, value: '^Psr\\Http\\' } + - { type: classLike, value: '^Psr\\Cache\\' } + - { type: classLike, value: '^Psr\\Clock\\' } + - { type: classLike, value: '^Brick\\Math\\' } + - { type: classLike, value: '^AESKW\\' } + - { type: classLike, value: '^ZxcvbnPhp\\' } ruleset: Core: - 'Vendors' diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 5e5d862e..02d1a774 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -4,7 +4,7 @@ backupGlobals="false" processIsolation="false" stopOnFailure="false" - bootstrap="vendor/autoload.php" + bootstrap="tests/autoload.php" beStrictAboutTestsThatDoNotTestAnything="false" colors="true" xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" diff --git a/rector.php b/rector.php index 69897c22..9793d157 100644 --- a/rector.php +++ b/rector.php @@ -5,18 +5,16 @@ use Rector\Config\RectorConfig; use Rector\Doctrine\Set\DoctrineSetList; use Rector\PHPUnit\CodeQuality\Rector\Class_\PreferPHPUnitThisCallRector; -use Rector\PHPUnit\Set\PHPUnitLevelSetList; use Rector\PHPUnit\Set\PHPUnitSetList; use Rector\Set\ValueObject\LevelSetList; use Rector\Set\ValueObject\SetList; -use Rector\Symfony\Set\SymfonyLevelSetList; use Rector\Symfony\Set\SymfonySetList; use Rector\ValueObject\PhpVersion; return static function (RectorConfig $config): void { $config->import(SetList::DEAD_CODE); $config->import(LevelSetList::UP_TO_PHP_81); - $config->import(SymfonyLevelSetList::UP_TO_SYMFONY_54); + $config->import(SymfonySetList::SYMFONY_54); $config->import(SymfonySetList::SYMFONY_50_TYPES); $config->import(SymfonySetList::SYMFONY_52_VALIDATOR_ATTRIBUTES); $config->import(SymfonySetList::SYMFONY_CODE_QUALITY); @@ -26,7 +24,7 @@ $config->import(DoctrineSetList::ANNOTATIONS_TO_ATTRIBUTES); $config->import(PHPUnitSetList::PHPUNIT_CODE_QUALITY); $config->import(PHPUnitSetList::ANNOTATIONS_TO_ATTRIBUTES); - $config->import(PHPUnitLevelSetList::UP_TO_PHPUNIT_100); + $config->import(PHPUnitSetList::PHPUNIT_100); $config->paths([ __DIR__ . '/ecs.php', __DIR__ . '/rector.php', diff --git a/src/Deprecated/Core/composer.json b/src/Deprecated/Core/composer.json index 783ad95d..2e4732e2 100644 --- a/src/Deprecated/Core/composer.json +++ b/src/Deprecated/Core/composer.json @@ -37,7 +37,7 @@ "ext-json": "*", "ext-mbstring": "*", "brick/math": "^0.9|^0.10|^0.11|^0.12", - "paragonie/constant_time_encoding": "^2.6", + "paragonie/constant_time_encoding": "^2.6|^3.0", "spomky-labs/pki-framework": "^1.2.1", "web-token/jwt-library": "^3.3" } diff --git a/src/Deprecated/SignatureAlgorithm/EdDSA/composer.json b/src/Deprecated/SignatureAlgorithm/EdDSA/composer.json index f572be83..f5bd1abb 100644 --- a/src/Deprecated/SignatureAlgorithm/EdDSA/composer.json +++ b/src/Deprecated/SignatureAlgorithm/EdDSA/composer.json @@ -35,7 +35,7 @@ "require": { "php": ">=8.1", "ext-sodium": "*", - "paragonie/sodium_compat": "^1.20", + "paragonie/sodium_compat": "^1.20|^2.0", "web-token/jwt-library": "^3.3" } } diff --git a/src/Library/Core/Util/ECKey.php b/src/Library/Core/Util/ECKey.php index 6cef9687..aa4aac88 100644 --- a/src/Library/Core/Util/ECKey.php +++ b/src/Library/Core/Util/ECKey.php @@ -12,7 +12,6 @@ use function is_array; use function is_string; use const OPENSSL_KEYTYPE_EC; -use const PHP_EOL; use const STR_PAD_LEFT; /** @@ -39,10 +38,10 @@ public static function convertPublicKeyToPEM(JWK $jwk): string default => throw new InvalidArgumentException('Unsupported curve.'), }; $der .= self::getKey($jwk); - $pem = '-----BEGIN PUBLIC KEY-----' . PHP_EOL; - $pem .= chunk_split(base64_encode($der), 64, PHP_EOL); + $pem = '-----BEGIN PUBLIC KEY-----' . "\n"; + $pem .= chunk_split(base64_encode($der), 64, "\n"); - return $pem . ('-----END PUBLIC KEY-----' . PHP_EOL); + return $pem . ('-----END PUBLIC KEY-----' . "\n"); } public static function convertPrivateKeyToPEM(JWK $jwk): string @@ -55,10 +54,10 @@ public static function convertPrivateKeyToPEM(JWK $jwk): string default => throw new InvalidArgumentException('Unsupported curve.'), }; $der .= self::getKey($jwk); - $pem = '-----BEGIN EC PRIVATE KEY-----' . PHP_EOL; - $pem .= chunk_split(base64_encode($der), 64, PHP_EOL); + $pem = '-----BEGIN EC PRIVATE KEY-----' . "\n"; + $pem .= chunk_split(base64_encode($der), 64, "\n"); - return $pem . ('-----END EC PRIVATE KEY-----' . PHP_EOL); + return $pem . ('-----END EC PRIVATE KEY-----' . "\n"); } /** diff --git a/src/Library/KeyManagement/KeyConverter/KeyConverter.php b/src/Library/KeyManagement/KeyConverter/KeyConverter.php index d7a0238f..4c8d938b 100644 --- a/src/Library/KeyManagement/KeyConverter/KeyConverter.php +++ b/src/Library/KeyManagement/KeyConverter/KeyConverter.php @@ -28,7 +28,6 @@ use const OPENSSL_KEYTYPE_EC; use const OPENSSL_KEYTYPE_RSA; use const OPENSSL_RAW_DATA; -use const PHP_EOL; use const PREG_PATTERN_ORDER; /** @@ -145,10 +144,10 @@ public static function loadFromX5C(array $x5c): array throw new InvalidArgumentException('The certificate chain is empty'); } foreach ($x5c as $id => $cert) { - $x5c[$id] = '-----BEGIN CERTIFICATE-----' . PHP_EOL . chunk_split( + $x5c[$id] = '-----BEGIN CERTIFICATE-----' . "\n" . chunk_split( (string) $cert, 64, - PHP_EOL + "\n" ) . '-----END CERTIFICATE-----'; $x509 = openssl_x509_read($x5c[$id]); if ($x509 === false) { @@ -372,9 +371,9 @@ private static function sanitizePEM(string &$pem): void $ciphertext = preg_replace('#-.*-|\r|\n| #', '', $pem); - $pem = $matches[0][0] . PHP_EOL; - $pem .= chunk_split($ciphertext ?? '', 64, PHP_EOL); - $pem .= $matches[0][1] . PHP_EOL; + $pem = $matches[0][0] . "\n"; + $pem .= chunk_split($ciphertext ?? '', 64, "\n"); + $pem .= $matches[0][1] . "\n"; } /** @@ -405,16 +404,16 @@ private static function decodePem(string $pem, array $matches, ?string $password throw new InvalidArgumentException('Unable to load the key'); } - $pem = $result[0][0] . PHP_EOL; + $pem = $result[0][0] . "\n"; $pem .= chunk_split(base64_encode($decoded), 64); - return $pem . ($result[0][1] . PHP_EOL); + return $pem . ($result[0][1] . "\n"); } private static function convertDerToPem(string $der_data): string { - $pem = chunk_split(base64_encode($der_data), 64, PHP_EOL); + $pem = chunk_split(base64_encode($der_data), 64, "\n"); - return '-----BEGIN CERTIFICATE-----' . PHP_EOL . $pem . '-----END CERTIFICATE-----' . PHP_EOL; + return '-----BEGIN CERTIFICATE-----' . "\n" . $pem . '-----END CERTIFICATE-----' . "\n"; } } diff --git a/src/Library/KeyManagement/X5UFactory.php b/src/Library/KeyManagement/X5UFactory.php index 1eaf9bf5..f08c2d8e 100644 --- a/src/Library/KeyManagement/X5UFactory.php +++ b/src/Library/KeyManagement/X5UFactory.php @@ -11,7 +11,6 @@ use RuntimeException; use function is_array; use function is_string; -use const PHP_EOL; class X5UFactory extends UrlKeySetFactory { @@ -29,7 +28,7 @@ public function loadFromUrl(string $url, array $header = []): JWKSet $keys = []; foreach ($data as $kid => $cert) { if (mb_strpos((string) $cert, '-----BEGIN CERTIFICATE-----') === false) { - $cert = '-----BEGIN CERTIFICATE-----' . PHP_EOL . $cert . PHP_EOL . '-----END CERTIFICATE-----'; + $cert = '-----BEGIN CERTIFICATE-----' . "\n" . $cert . "\n" . '-----END CERTIFICATE-----'; } $jwk = KeyConverter::loadKeyFromCertificate($cert); if (is_string($kid)) { diff --git a/src/Library/composer.json b/src/Library/composer.json index 271a683f..fee12b47 100644 --- a/src/Library/composer.json +++ b/src/Library/composer.json @@ -42,8 +42,8 @@ "ext-json": "*", "ext-mbstring": "*", "brick/math": "^0.9|^0.10|^0.11|^0.12", - "paragonie/constant_time_encoding": "^2.6", - "paragonie/sodium_compat": "^1.20", + "paragonie/constant_time_encoding": "^2.6|^3.0", + "paragonie/sodium_compat": "^1.20|^2.0", "psr/cache": "^3.0", "psr/clock": "^1.0", "psr/http-factory": "^1.0", diff --git a/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php b/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php index 235ba33f..2bb62576 100644 --- a/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php +++ b/tests/Bundle/JoseFramework/Functional/KeyManagement/JWKSetLoaderTest.php @@ -9,6 +9,7 @@ use PHPUnit\Framework\Attributes\Test; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpClient\Response\MockResponse; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; /** @@ -33,7 +34,7 @@ public static function aJWKSetCanBeSharedInTheConfiguration(): void static::ensureKernelShutdown(); $client = static::createClient(); - $client->request('GET', '/keys/1.jwkset'); + $client->request(Request::METHOD_GET, '/keys/1.jwkset'); /** @var Response $response */ $response = $client->getResponse(); @@ -62,7 +63,7 @@ public static function aJWKSetCanBeSharedFromAnotherBundle(): void static::ensureKernelShutdown(); $client = static::createClient(); - $client->request('GET', '/keys/2.jwkset'); + $client->request(Request::METHOD_GET, '/keys/2.jwkset'); /** @var Response $response */ $response = $client->getResponse(); diff --git a/tests/Component/KeyManagement/JWKFactoryTest.php b/tests/Component/KeyManagement/JWKFactoryTest.php index c777b503..aadcdf2a 100644 --- a/tests/Component/KeyManagement/JWKFactoryTest.php +++ b/tests/Component/KeyManagement/JWKFactoryTest.php @@ -245,7 +245,7 @@ public static function dataKeys(): iterable { yield [ 'filename' => __DIR__ . '/Keys/ED/public-ed448.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'Ed448', 'x' => 'wwHKDV7s4fBhmFSTzYorlaToGXNcsa7SakZdekT_sexD5ENj5lWP6_KX9_u--w_QSm80rNOodj0A', @@ -253,7 +253,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/public-ed25519.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'Ed25519', 'x' => 'wrI33AEj15KHHYplueUE5cnJKtbM8oVHFf6wGnw2oOE', @@ -261,7 +261,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/public-X448.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'X448', 'x' => 'UoPD73NQACC8A-otDUVun4IrMsk775ShMRf4ThDrq4xY2eAI-pOIVujrvBXXd9g8gUNwBT0fmnc', @@ -269,7 +269,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/public-X25519.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'X25519', 'x' => '3OJLiffmOCQGtil23QGyn0nk9EBKoZx6P-6o-EnsBB4', @@ -277,7 +277,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/private-ed448.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'Ed448', 'd' => '0GXSbNLOh7NQBlwoF8y2WJmjeP5Puif4_JL4ihFUzRLrb_3r4cH8l_HWJA-2ffY62LEB_ozsehG5', @@ -285,7 +285,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/private-X448.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'X448', 'd' => 'OHZK0Fp9MAAmk0yZekiAkB8qxpCVAF4dT2x_xmFNDdCTnyDvixaiZ0NSRpAdR59tA6OJmOFfbck', @@ -293,7 +293,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/private-ed25519.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'Ed25519', 'd' => 'Pr9AxZivB-zSq95wLrZfYa7DQ3TUPqZTkP_0w33r3rc', @@ -302,7 +302,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/private-secp384r1-with-public.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'EC', 'crv' => 'P-384', 'd' => '31taDOPQnlNl2aBC_EaGTqVGjGN_qg6iuLwP6cVTmhKMQ5PTL67wS6mmyKi8GdVP', @@ -312,7 +312,7 @@ public static function dataKeys(): iterable ]; yield [ 'filename' => __DIR__ . '/Keys/ED/private-X25519.pem', - 'values' => [ + 'expectedValues' => [ 'kty' => 'OKP', 'crv' => 'X25519', 'd' => 'mG-fgDwkr58hwIeqCQKZbR8HKeY4yg_AzvU6zyNaVUE', diff --git a/tests/autoload.php b/tests/autoload.php new file mode 100644 index 00000000..552064b8 --- /dev/null +++ b/tests/autoload.php @@ -0,0 +1,9 @@ +