diff --git a/composer.json b/composer.json index 281621dc2..8a178bd9f 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,7 @@ "psr/http-client": "^1.0", "psr/http-factory": "^1.0", "spomky-labs/aes-key-wrap": "^7.0", - "spomky-labs/pki-framework": "^1.0", + "spomky-labs/pki-framework": "^1.2.1", "symfony/config": "^5.4|^6.0|^7.0", "symfony/console": "^5.4|^6.0|^7.0", "symfony/dependency-injection": "^5.4|^6.0|^7.0", diff --git a/src/Bundle/DependencyInjection/Source/Encryption/AbstractEncryptionSource.php b/src/Bundle/DependencyInjection/Source/Encryption/AbstractEncryptionSource.php index 461a1db22..2bdffaf6e 100644 --- a/src/Bundle/DependencyInjection/Source/Encryption/AbstractEncryptionSource.php +++ b/src/Bundle/DependencyInjection/Source/Encryption/AbstractEncryptionSource.php @@ -17,22 +17,60 @@ public function getNodeDefinition(NodeDefinition $node): void ->arrayNode($this->name()) ->useAttributeAsKey('name') ->arrayPrototype() + ->beforeNormalization() + ->ifTrue( + static fn (array $v) => isset($v['key_encryption_algorithms']) || isset($v['content_encryption_algorithms']) + ) + ->then(static function (array $v) { + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'] ?? [], + $v['key_encryption_algorithms'] ?? [] + ); + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'], + $v['content_encryption_algorithms'] ?? [] + ); + unset($v['key_encryption_algorithms'], $v['content_encryption_algorithms']); + $v['encryption_algorithms'] = array_values(array_unique($v['encryption_algorithms'])); + + return $v; + }) + ->end() ->children() ->booleanNode('is_public') ->info('If true, the service will be public, else private.') ->defaultTrue() ->end() - ->arrayNode('key_encryption_algorithms') - ->info('A list of supported key encryption algorithms.') + ->arrayNode('encryption_algorithms') + ->info('A list of key or content encryption algorithm aliases.') ->useAttributeAsKey('name') ->isRequired() ->requiresAtLeastOneElement() ->scalarPrototype() ->end() ->end() + ->arrayNode('key_encryption_algorithms') + ->info('A list of supported key encryption algorithms.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) + ->useAttributeAsKey('name') + ->treatNullLike([]) + ->treatFalseLike([]) + ->defaultValue([]) + ->scalarPrototype() + ->end() + ->end() ->arrayNode('content_encryption_algorithms') ->info('A list of supported content encryption algorithms.') ->useAttributeAsKey('name') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) ->treatNullLike([]) ->treatFalseLike([]) ->defaultValue([]) @@ -41,6 +79,11 @@ public function getNodeDefinition(NodeDefinition $node): void ->end() ->arrayNode('compression_methods') ->info('A list of supported compression methods.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0.' + ) ->useAttributeAsKey('name') ->treatNullLike([]) ->treatFalseLike([]) diff --git a/src/Bundle/DependencyInjection/Source/Encryption/JWEBuilder.php b/src/Bundle/DependencyInjection/Source/Encryption/JWEBuilder.php index 2e5c8fe4e..1e5ae3442 100644 --- a/src/Bundle/DependencyInjection/Source/Encryption/JWEBuilder.php +++ b/src/Bundle/DependencyInjection/Source/Encryption/JWEBuilder.php @@ -25,8 +25,8 @@ public function load(array $configs, ContainerBuilder $container): void $definition ->setFactory([new Reference(JWEBuilderFactory::class), 'create']) ->setArguments([ - $itemConfig['key_encryption_algorithms'], - $itemConfig['content_encryption_algorithms'] === [] ? null : $itemConfig['content_encryption_algorithms'], + $itemConfig['encryption_algorithms'], + null, $itemConfig['compression_methods'] === [] ? null : $itemConfig['compression_methods'], ]) ->addTag('jose.jwe_builder') diff --git a/src/Bundle/DependencyInjection/Source/Encryption/JWEDecrypter.php b/src/Bundle/DependencyInjection/Source/Encryption/JWEDecrypter.php index 66588aa4d..45fd36829 100644 --- a/src/Bundle/DependencyInjection/Source/Encryption/JWEDecrypter.php +++ b/src/Bundle/DependencyInjection/Source/Encryption/JWEDecrypter.php @@ -25,8 +25,8 @@ public function load(array $configs, ContainerBuilder $container): void $definition ->setFactory([new Reference(JWEDecrypterFactory::class), 'create']) ->setArguments([ - $itemConfig['key_encryption_algorithms'], - $itemConfig['content_encryption_algorithms'] === [] ? null : $itemConfig['content_encryption_algorithms'], + $itemConfig['encryption_algorithms'], + null, $itemConfig['compression_methods'] === [] ? null : $itemConfig['compression_methods'], ]) ->addTag('jose.jwe_decrypter') diff --git a/src/Bundle/DependencyInjection/Source/Encryption/JWELoader.php b/src/Bundle/DependencyInjection/Source/Encryption/JWELoader.php index dde501ea1..3a1956dd0 100644 --- a/src/Bundle/DependencyInjection/Source/Encryption/JWELoader.php +++ b/src/Bundle/DependencyInjection/Source/Encryption/JWELoader.php @@ -28,8 +28,8 @@ public function load(array $configs, ContainerBuilder $container): void ->setFactory([new Reference(JWELoaderFactory::class), 'create']) ->setArguments([ $itemConfig['serializers'], - $itemConfig['key_encryption_algorithms'], - $itemConfig['content_encryption_algorithms'] === [] ? null : $itemConfig['content_encryption_algorithms'], + $itemConfig['encryption_algorithms'], + null, $itemConfig['compression_methods'] === [] ? null : $itemConfig['compression_methods'], $itemConfig['header_checkers'], ]) @@ -52,20 +52,59 @@ public function getNodeDefinition(NodeDefinition $node): void ->requiresAtLeastOneElement() ->useAttributeAsKey('name') ->arrayPrototype() + ->beforeNormalization() + ->ifTrue( + static fn (array $v) => isset($v['key_encryption_algorithms']) || isset($v['content_encryption_algorithms']) + ) + ->then(static function (array $v) { + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'] ?? [], + $v['key_encryption_algorithms'] ?? [] + ); + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'], + $v['content_encryption_algorithms'] ?? [] + ); + unset($v['key_encryption_algorithms'], $v['content_encryption_algorithms']); + $v['encryption_algorithms'] = array_values(array_unique($v['encryption_algorithms'])); + + return $v; + }) + ->end() ->children() ->booleanNode('is_public') ->info('If true, the service will be public, else private.') ->defaultTrue() ->end() + ->arrayNode('encryption_algorithms') + ->info('A list of key or content encryption algorithm aliases.') + ->useAttributeAsKey('name') + ->isRequired() + ->requiresAtLeastOneElement() + ->scalarPrototype() + ->end() + ->end() ->arrayNode('key_encryption_algorithms') ->info('A list of key encryption algorithm aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) ->useAttributeAsKey('name') - ->isRequired() + ->treatNullLike([]) + ->treatFalseLike([]) + ->defaultValue([]) ->scalarPrototype() ->end() ->end() ->arrayNode('content_encryption_algorithms') ->info('A list of key encryption algorithm aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) ->useAttributeAsKey('name') ->treatNullLike([]) ->treatFalseLike([]) @@ -75,6 +114,11 @@ public function getNodeDefinition(NodeDefinition $node): void ->end() ->arrayNode('compression_methods') ->info('A list of compression method aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0.' + ) ->useAttributeAsKey('name') ->treatNullLike([]) ->treatFalseLike([]) diff --git a/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php b/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php index 05c03f53b..ae048fe31 100644 --- a/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php +++ b/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenBuilder.php @@ -28,8 +28,8 @@ public function load(array $configs, ContainerBuilder $container): void ->setFactory([new Reference(NestedTokenBuilderFactory::class), 'create']) ->setArguments([ $itemConfig['jwe_serializers'], - $itemConfig['key_encryption_algorithms'], - $itemConfig['content_encryption_algorithms'] === [] ? null : $itemConfig['content_encryption_algorithms'], + $itemConfig['encryption_algorithms'], + null, $itemConfig['compression_methods'] === [] ? null : $itemConfig['compression_methods'], $itemConfig['jws_serializers'], $itemConfig['signature_algorithms'], @@ -52,6 +52,25 @@ public function getNodeDefinition(NodeDefinition $node): void ->treatFalseLike([]) ->useAttributeAsKey('name') ->arrayPrototype() + ->beforeNormalization() + ->ifTrue( + static fn (array $v) => isset($v['key_encryption_algorithms']) || isset($v['content_encryption_algorithms']) + ) + ->then(static function (array $v) { + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'] ?? [], + $v['key_encryption_algorithms'] ?? [] + ); + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'], + $v['content_encryption_algorithms'] ?? [] + ); + unset($v['key_encryption_algorithms'], $v['content_encryption_algorithms']); + $v['encryption_algorithms'] = array_unique(array_values($v['encryption_algorithms'])); + + return $v; + }) + ->end() ->children() ->booleanNode('is_public') ->info('If true, the service will be public, else private.') @@ -64,15 +83,35 @@ public function getNodeDefinition(NodeDefinition $node): void ->scalarPrototype() ->end() ->end() + ->arrayNode('encryption_algorithms') + ->info('A list of key or content encryption algorithm aliases.') + ->useAttributeAsKey('name') + ->isRequired() + ->requiresAtLeastOneElement() + ->scalarPrototype() + ->end() + ->end() ->arrayNode('key_encryption_algorithms') ->info('A list of key encryption algorithm aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) ->useAttributeAsKey('name') - ->isRequired() + ->treatNullLike([]) + ->treatFalseLike([]) + ->defaultValue([]) ->scalarPrototype() ->end() ->end() ->arrayNode('content_encryption_algorithms') ->info('A list of key encryption algorithm aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) ->useAttributeAsKey('name') ->treatNullLike([]) ->treatFalseLike([]) @@ -82,6 +121,11 @@ public function getNodeDefinition(NodeDefinition $node): void ->end() ->arrayNode('compression_methods') ->info('A list of compression method aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0.' + ) ->useAttributeAsKey('name') ->treatNullLike([]) ->treatFalseLike([]) diff --git a/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenLoader.php b/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenLoader.php index 077f35ef7..6009dcdbd 100644 --- a/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenLoader.php +++ b/src/Bundle/DependencyInjection/Source/NestedToken/NestedTokenLoader.php @@ -28,8 +28,8 @@ public function load(array $configs, ContainerBuilder $container): void ->setFactory([new Reference(NestedTokenLoaderFactory::class), 'create']) ->setArguments([ $itemConfig['jwe_serializers'], - $itemConfig['key_encryption_algorithms'], - $itemConfig['content_encryption_algorithms'] === [] ? null : $itemConfig['content_encryption_algorithms'], + $itemConfig['encryption_algorithms'], + null, $itemConfig['compression_methods'] === [] ? null : $itemConfig['compression_methods'], $itemConfig['jwe_header_checkers'], $itemConfig['jws_serializers'], @@ -54,6 +54,25 @@ public function getNodeDefinition(NodeDefinition $node): void ->treatFalseLike([]) ->useAttributeAsKey('name') ->arrayPrototype() + ->beforeNormalization() + ->ifTrue( + static fn (array $v) => isset($v['key_encryption_algorithms']) || isset($v['content_encryption_algorithms']) + ) + ->then(static function (array $v) { + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'] ?? [], + $v['key_encryption_algorithms'] ?? [] + ); + $v['encryption_algorithms'] = array_merge( + $v['encryption_algorithms'], + $v['content_encryption_algorithms'] ?? [] + ); + unset($v['key_encryption_algorithms'], $v['content_encryption_algorithms']); + $v['encryption_algorithms'] = array_values(array_unique($v['encryption_algorithms'])); + + return $v; + }) + ->end() ->children() ->booleanNode('is_public') ->info('If true, the service will be public, else private.') @@ -66,15 +85,35 @@ public function getNodeDefinition(NodeDefinition $node): void ->scalarPrototype() ->end() ->end() + ->arrayNode('encryption_algorithms') + ->info('A list of key or content encryption algorithm aliases.') + ->useAttributeAsKey('name') + ->isRequired() + ->requiresAtLeastOneElement() + ->scalarPrototype() + ->end() + ->end() ->arrayNode('key_encryption_algorithms') ->info('A list of key encryption algorithm aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) ->useAttributeAsKey('name') - ->isRequired() + ->treatNullLike([]) + ->treatFalseLike([]) + ->defaultValue([]) ->scalarPrototype() ->end() ->end() ->arrayNode('content_encryption_algorithms') ->info('A list of key encryption algorithm aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0. Please use "encryption_algorithms" instead.' + ) ->useAttributeAsKey('name') ->treatNullLike([]) ->treatFalseLike([]) @@ -84,6 +123,11 @@ public function getNodeDefinition(NodeDefinition $node): void ->end() ->arrayNode('compression_methods') ->info('A list of compression method aliases.') + ->setDeprecated( + 'web-token/jwt-bundle', + '3.3.0', + 'The child node "%node%" at path "%path%" is deprecated and will be removed in 4.0.0.' + ) ->useAttributeAsKey('name') ->treatNullLike([]) ->treatFalseLike([]) diff --git a/src/Deprecated/Core/composer.json b/src/Deprecated/Core/composer.json index 6bfeada3e..783ad95da 100644 --- a/src/Deprecated/Core/composer.json +++ b/src/Deprecated/Core/composer.json @@ -38,7 +38,7 @@ "ext-mbstring": "*", "brick/math": "^0.9|^0.10|^0.11|^0.12", "paragonie/constant_time_encoding": "^2.6", - "spomky-labs/pki-framework": "^1.0", + "spomky-labs/pki-framework": "^1.2.1", "web-token/jwt-library": "^3.3" } } diff --git a/src/Library/KeyManagement/KeyConverter/KeyConverter.php b/src/Library/KeyManagement/KeyConverter/KeyConverter.php index 82442bb7d..010c7ab88 100644 --- a/src/Library/KeyManagement/KeyConverter/KeyConverter.php +++ b/src/Library/KeyManagement/KeyConverter/KeyConverter.php @@ -4,14 +4,17 @@ namespace Jose\Component\KeyManagement\KeyConverter; +use Brick\Math\BigInteger; use InvalidArgumentException; use OpenSSLCertificate; use ParagonIE\ConstantTime\Base64UrlSafe; use ParagonIE\Sodium\Core\Ed25519; use RuntimeException; use SpomkyLabs\Pki\CryptoEncoding\PEM; +use SpomkyLabs\Pki\CryptoTypes\AlgorithmIdentifier\AlgorithmIdentifier; use SpomkyLabs\Pki\CryptoTypes\Asymmetric\PrivateKey; use SpomkyLabs\Pki\CryptoTypes\Asymmetric\PublicKey; +use SpomkyLabs\Pki\CryptoTypes\Asymmetric\RSA\RSASSAPSSPrivateKey; use Throwable; use function array_key_exists; use function assert; @@ -229,29 +232,79 @@ private static function tryToLoadECKey(string $input): array private static function tryToLoadOtherKeyTypes(string $input): array { $pem = PEM::fromString($input); + return match ($pem->type()) { + PEM::TYPE_PUBLIC_KEY => self::loadPublicKey($pem), + PEM::TYPE_PRIVATE_KEY => self::loadPrivateKey($pem), + default => throw new InvalidArgumentException('Unsupported key type'), + }; + } + + /** + * @return array + */ + private static function loadPrivateKey(PEM $pem): array + { try { $key = PrivateKey::fromPEM($pem); - $curve = self::getCurve($key->algorithmIdentifier()->oid()); - $values = [ - 'kty' => 'OKP', - 'crv' => $curve, - 'd' => Base64UrlSafe::encodeUnpadded($key->privateKeyData()), - ]; - return self::populatePoints($key, $values); - } catch (Throwable) { + switch ($key->algorithmIdentifier()->oid()) { + case AlgorithmIdentifier::OID_RSASSA_PSS_ENCRYPTION: + assert($key instanceof RSASSAPSSPrivateKey); + return [ + 'kty' => 'RSA', + 'n' => self::convertDecimalToBas64Url($key->modulus()), + 'e' => self::convertDecimalToBas64Url($key->publicExponent()), + 'd' => self::convertDecimalToBas64Url($key->privateExponent()), + 'dp' => self::convertDecimalToBas64Url($key->exponent1()), + 'dq' => self::convertDecimalToBas64Url($key->exponent2()), + 'p' => self::convertDecimalToBas64Url($key->prime1()), + 'q' => self::convertDecimalToBas64Url($key->prime2()), + 'qi' => self::convertDecimalToBas64Url($key->coefficient()), + ]; + case AlgorithmIdentifier::OID_ED25519: + case AlgorithmIdentifier::OID_ED448: + case AlgorithmIdentifier::OID_X25519: + case AlgorithmIdentifier::OID_X448: + $curve = self::getCurve($key->algorithmIdentifier()->oid()); + $values = [ + 'kty' => 'OKP', + 'crv' => $curve, + 'd' => Base64UrlSafe::encodeUnpadded($key->privateKeyData()), + ]; + return self::populatePoints($key, $values); + default: + throw new InvalidArgumentException('Unsupported key type'); + } + } catch (Throwable $e) { + throw new InvalidArgumentException('Unable to load the key.', 0, $e); } - try { - $key = PublicKey::fromPEM($pem); - $curve = self::getCurve($key->algorithmIdentifier()->oid()); - self::checkType($curve); - return [ - 'kty' => 'OKP', - 'crv' => $curve, - 'x' => Base64UrlSafe::encodeUnpadded((string) $key->subjectPublicKey()), - ]; - } catch (Throwable) { + } + + /** + * @return array + */ + private static function loadPublicKey(PEM $pem): array + { + $key = PublicKey::fromPEM($pem); + switch ($key->algorithmIdentifier()->oid()) { + case AlgorithmIdentifier::OID_ED25519: + case AlgorithmIdentifier::OID_ED448: + case AlgorithmIdentifier::OID_X25519: + case AlgorithmIdentifier::OID_X448: + $curve = self::getCurve($key->algorithmIdentifier()->oid()); + self::checkType($curve); + return [ + 'kty' => 'OKP', + 'crv' => $curve, + 'x' => Base64UrlSafe::encodeUnpadded((string) $key->subjectPublicKey()), + ]; + default: + throw new InvalidArgumentException('Unsupported key type'); } - throw new InvalidArgumentException('Unsupported key type'); + } + + private static function convertDecimalToBas64Url(string $decimal): string + { + return Base64UrlSafe::encodeUnpadded(BigInteger::fromBase($decimal, 10)->toBytes()); } /** diff --git a/src/Library/NestedToken/NestedTokenLoaderFactory.php b/src/Library/NestedToken/NestedTokenLoaderFactory.php index 04455d95c..632ff5e87 100644 --- a/src/Library/NestedToken/NestedTokenLoaderFactory.php +++ b/src/Library/NestedToken/NestedTokenLoaderFactory.php @@ -31,7 +31,7 @@ public function __construct( public function create( array $jweSerializers, array $keyEncryptionAlgorithms, - array $contentEncryptionAlgorithms, + null|array $contentEncryptionAlgorithms, null|array $compressionMethods, array $jweHeaderCheckers, array $jwsSerializers, diff --git a/src/Library/composer.json b/src/Library/composer.json index bf35f837b..0f7171839 100644 --- a/src/Library/composer.json +++ b/src/Library/composer.json @@ -47,7 +47,7 @@ "psr/clock": "^1.0", "psr/http-factory": "^1.0", "psr/http-client": "^1.0", - "spomky-labs/pki-framework": "^1.0", + "spomky-labs/pki-framework": "^1.2.1", "symfony/console": "^5.4|^6.0|^7.0", "symfony/http-client": "^5.4|^6.0|^7.0", "symfony/polyfill-mbstring": "^1.12" diff --git a/tests/Bundle/JoseFramework/Functional/Encryption/JweBuilderConfigurationTest.php b/tests/Bundle/JoseFramework/Functional/Encryption/JweBuilderConfigurationTest.php index db97ba94b..d1c8f1194 100644 --- a/tests/Bundle/JoseFramework/Functional/Encryption/JweBuilderConfigurationTest.php +++ b/tests/Bundle/JoseFramework/Functional/Encryption/JweBuilderConfigurationTest.php @@ -77,7 +77,7 @@ public function theConfigurationIsInvalidIfNotKeyEncryptionAlgorithmIsSet(): voi ], ], ], - 'The child config "key_encryption_algorithms" under "jose.jwe.builders.foo" must be configured:' + 'The child config "encryption_algorithms" under "jose.jwe.builders.foo" must be configured:' ); } @@ -96,7 +96,7 @@ public function theConfigurationIsInvalidIfTheKeyEncryptionAlgorithmIsEmpty(): v ], ], ], - 'The path "jose.jwe.builders.foo.key_encryption_algorithms" should have at least 1 element(s) defined.' + 'The path "jose.jwe.builders.foo.encryption_algorithms" should have at least 1 element(s) defined.' ); } diff --git a/tests/Bundle/JoseFramework/Functional/Encryption/JweDecrypterConfigurationTest.php b/tests/Bundle/JoseFramework/Functional/Encryption/JweDecrypterConfigurationTest.php index b04588aef..019821ea3 100644 --- a/tests/Bundle/JoseFramework/Functional/Encryption/JweDecrypterConfigurationTest.php +++ b/tests/Bundle/JoseFramework/Functional/Encryption/JweDecrypterConfigurationTest.php @@ -77,7 +77,7 @@ public function theConfigurationIsInvalidIfNotKeyEncryptionAlgorithmIsSet(): voi ], ], ], - 'The child config "key_encryption_algorithms" under "jose.jwe.decrypters.foo" must be configured:' + 'The child config "encryption_algorithms" under "jose.jwe.decrypters.foo" must be configured:' ); } @@ -96,7 +96,7 @@ public function theConfigurationIsInvalidIfTheKeyEncryptionAlgorithmIsEmpty(): v ], ], ], - 'The path "jose.jwe.decrypters.foo.key_encryption_algorithms" should have at least 1 element(s) defined.' + 'The path "jose.jwe.decrypters.foo.encryption_algorithms" should have at least 1 element(s) defined.' ); } diff --git a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderConfigurationTest.php b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderConfigurationTest.php index 55d9e955a..dde5359f4 100644 --- a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderConfigurationTest.php +++ b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenBuilderConfigurationTest.php @@ -99,7 +99,7 @@ public function theConfigurationIsInvalidIfNoKeyEncryptionAlgorithmIsSet(): void ], ], ], - 'The child config "key_encryption_algorithms" under "jose.nested_token.builders.foo" must be configured:' + 'The child config "encryption_algorithms" under "jose.nested_token.builders.foo" must be configured:' ); } diff --git a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderConfigurationTest.php b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderConfigurationTest.php index 879fa5b8e..808b2b09b 100644 --- a/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderConfigurationTest.php +++ b/tests/Bundle/JoseFramework/Functional/NestedToken/NestedTokenLoaderConfigurationTest.php @@ -99,7 +99,7 @@ public function theConfigurationIsInvalidIfNoKeyEncryptionAlgorithmIsSet(): void ], ], ], - 'The child config "key_encryption_algorithms" under "jose.nested_token.loaders.foo" must be configured:' + 'The child config "encryption_algorithms" under "jose.nested_token.loaders.foo" must be configured:' ); } diff --git a/tests/Component/KeyManagement/Keys/RSA/rsassa-pss.pem b/tests/Component/KeyManagement/Keys/RSA/rsassa-pss.pem new file mode 100644 index 000000000..0bc959709 --- /dev/null +++ b/tests/Component/KeyManagement/Keys/RSA/rsassa-pss.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +fExebCpblM+ctC+gzK6cJMraZGrXbQ== +-----END PRIVATE KEY----- diff --git a/tests/Component/KeyManagement/Keys/RSAKeysTest.php b/tests/Component/KeyManagement/Keys/RSAKeysTest.php index 0cf1f0a78..7bbdeded8 100644 --- a/tests/Component/KeyManagement/Keys/RSAKeysTest.php +++ b/tests/Component/KeyManagement/Keys/RSAKeysTest.php @@ -313,4 +313,25 @@ public function loadPrivateRSAKeyFromMinimalValues(): void ], $public_key->toArray()); static::assertTrue($public_key->isPublic()); } + + #[Test] + public function loadsRSASSAPSSKey(): void + { + $key = JWKFactory::createFromKeyFile(__DIR__ . '/RSA/rsassa-pss.pem'); + + static::assertSame( + [ + 'kty' => 'RSA', + 'n' => 'AL1gIpgcH5QmcNWbRa3AG6DuKIOQYtcUn-UjmB0GaKudvsLWBDId_GiBMo7CoCTIk30WOt2_YRB8BmNGlJB0jJS-fztLx86gP7m5SfFhJJUcAG10Vj2xpkNQZ9aHUyyeNKZpzMBXmlt6k8d-eF_0qJ6v_CpCzkCK3-SFsw22ntCTluuqyiT2UJs0YXK9cpI_4Np8LJPP2Hqb_ByvG1bEit3-k3UWiiK0bwUFe1Gg49GHIfuSCoOAAYNmoZ8rNHQ0SLmo6htwuqKMa7KdEODeEGB2k8gV1tTjag8_ZbdJ0wfhS8YPs_IBwbuicQJlzpNHHW1DRY5XgsJJym9o5Pm5PrD0Q_cjhjOZkEhQs5Y8_XWBE8onlhKt4h9ce5JdfO3qP1H-PG2GnYdIZEXhwQyjqT4_V1agrPD9DHBFW72aWrYfpU7pTry5FsRLaLQJjNDfEYLumYqOVspWgLrr0Er-B1_03VS93kJnq0Y5xglU_p4wRUBKXUn_ntF9Q6Cy2XnaSvIFF3l20IwPPG9wdtjR8kTd21z1IBMVYI0-WLWK3hNXz5C0perOtH51_6-hNP7bG_IrGbILd3EkkZ7Yd3fxX4T0-ZKAoEgQ_4P1A5aJl-2wzEN0r95S62WUcZEXDwXlfkCsWXo3LSdOW8Aht-2xQoGOl5Cx0bd84kfxYGdzBuyh', + 'e' => 'AQAB', + 'd' => 'A8YQxmnIDiXCdEU89cMztxN2h_b2e0KlqYqkfzk87c-NyQ2RUEDaoj1R2ThYZIdBMM94DT9r2HOKP-FHYwYJikoYrbaFv6YKmGGQefCFlWQ_6hkfgf5NDyoWOaHhIXexGlBWfyONF5h-mE2lPy9C9W-RwDNW2hXSXpgfSxffUWN226Z1KFhRX024yTvXIWzdBumNd1q_faOnr1gkx11mXC8J9_M4KIx31Q3TXmXs_ZnFDqGYl0nTmI9bi45ljru_J8D4PPippW_UJ787bP8L1z-W_rhDBiNr04GKng-I6_nRuVuKf86dvPwV5wD0RVPNVVuEnTCnUhu86UGvOhPhONt2-EPbzJaBb433VC6eO05DJK7JaxrR7vpGn4v4U_xTBUJMTES1-2woPoCjovftMQacNgzoWeuwtFwDdZOkW3rhO5ZEM8msucO3K4AJFRW0MyzGWhUIXqadN_tXKhgKrhgwrQ-M1w4-agBMb_paqIzaePX45YcsT2cd1q_xwr2UM1-8VpfeTouRmiYJINOHiWOsu997H-JTuEpJtpCID6lHDHRoHxpKSEnV4mGSsE74AgdnSvRamDFt8JF2dMdkIOlPrcxXsR8_M0BcQts8vDJ-IQ3RaEbia6vFMSFtTgRK0uV9UuMRp18vQneJXs3GfeDmA7Ej46JCh5m6v0JBNyE', + 'dp' => 'AM0IEiWYWSzSz_YsTGKaubsb0vJlwnnN01Kk8coFqQ-5IBUxGVzBVkdVl6HHDKnP1Is0ImA7kLE9BWgHpMSsI4ohocdwJYqYiK3EKx_LjUweSVKm_01almeSUgok0XxFJGrFEFDO9Fvtt8DRElim6TWM8tViH-HXHGtR90IpvEBUlmdoAR-FNMDzB8h5w3OcZOVnYs3CSAB4wCPo3QO7HzfRgAjUt7t16Kd1bDL4qvRKa-ZePg1mQ697yDidAUheJebAuITxfIcnaoIUGD8QGMB1ugwixzEIYWSrSnOSaPwNESHwZPDAUSrqp0axohhqDc0rMdj9kbWWWFL8i4MKSmE', + 'dq' => 'AM6bvykUO7YnqHyyXw8G1uO74Vm3bjE7LDON3nLD4-FXBJg2IoVqwghiEsK6s8f3QuY0j1PwXS-PlJuGyUSaBrpn2WSbHA2EwkTihbVW33dW7H0dxaovhHvgCx8HnqmVAaagkHl4M1ZJSiKBrFAR8aSy-0vnnpOHOX3tJVM6pL5BrYUa6INY2uhbXZTXxr4EwBHmpiReYQ4zGrE2kptpI8ikSbkQrfBDv4ARqWILp0a1xFea6KeqvjQ3wTx13OhvNPkLrNNcpy4O32ZiuxkDhIlPrzTwUtaQKiB15qFdoe5a-caPc_TcOTWmkqxE6o7yBiwylIJccqMb_j8xnEuyCnE', + 'p' => 'AOCxqqGImEgJgbiHa8bxGICnLq3Aeg1XGhJxW3WBYyhcMLmwUdbu3TeW_wwF_IcWOjbzf4-GtBIbRXtVis9zfPdQpCW2pgVZ77Vl4M0qCJPJz7MVhgzeGoh1KeTSFSba7Da7ZGAgWcWi0HfmZbOv-WjYipIZWQPBFP6u49dsHhO_Icrk7AYWtN07AENnRzIKtENqRp7xItTuDIl4GOqw1_hU9u0XNn7JeMRcPbauqiPT23ZoSCwyPnkKm0ZN74iL2suSTktVW1RFfjIUTQiWt6X-fJ0BgzSb7xqakS65aX9ysAE9SaBAqlIn_fNz3glQziAcNvu5q2htCAuHEdlgufE', + 'q' => 'ANfCvLub-wh4ULifAdqFCAjKL-vNiAyJdZ6KFwitioPge889am3kM7A-T45sislBx_MCcQmSm59GyZmRcrOGHCgVt4vwnagQN9fY6k9omUYSCaKiv3yjLhBxAbzwx3Z2pS7E6roa7zEFykaYJGTQprh5K1hrxFeH_kqafln6vNjtQ2E40WdvMli_rr4fOIAidBjxfYjAAb-OmeTpM1IX6L1GwXNZlG9FmD-K8s1xNT9kL55Kk9Vgtr6-lEffTncStYCLC0JBugk4IcwlOZPFwUXmAEnAIGac6hGMh5tXkvQ-SDuo3JbqcQsCSi4aC49ZuA9Gk9wGbtStVwsVKj7nLbE', + 'qi' => 'AI7uWbGZxN8e6eQIkTm5VjOS5zic6C1zu1cxfZupmsStI_UYfI0UVSYJ6dOCxMvAqtS2Gqm7P2zyCT-xzkU-XcTxlbMshRKtzg0G8BpfFYcCKjEIqCq8MXpK6osp45SKctKcpFC3H-xl5flbasyx5AW5UQriYErUvP-yitVRuIqv2tKVN8Dl5gMmnuQ32vYZsaOagQqy459T42Y42Vw1N_DYMVe8gdDXpwpItp6IhjmHwmZJcOYBFPKPOKEw3LE7AkvaAfzpznSCY_0v6oD9Fvz6tsFxynRtzhPVFSzDAada1kNjop9h91Kd2nxMXmwqW5TPnLQvoMyunCTK2mRq120', + ], + $key->all() + ); + } }