TokenDecrypter   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 46
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 23
dl 0
loc 46
ccs 0
cts 33
cp 0
rs 10
c 2
b 0
f 0
wmc 11

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
B decryptToken() 0 32 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TMV\OpenIdClient\Token;
6
7
use function class_exists;
8
use function explode;
9
use Jose\Component\Core\AlgorithmManager;
10
use Jose\Component\Core\JWKSet;
11
use Jose\Component\Encryption\Compression\CompressionMethodManager;
12
use Jose\Component\Encryption\Compression\Deflate;
13
use Jose\Component\Encryption\JWEDecrypter;
14
use Jose\Component\Encryption\JWELoader;
15
use Jose\Component\Encryption\Serializer\CompactSerializer;
16
use Jose\Component\Encryption\Serializer\JWESerializerManager;
17
use function json_decode;
18
use function preg_match;
19
use function sprintf;
20
use function TMV\OpenIdClient\base64url_decode;
21
use TMV\OpenIdClient\Client\ClientInterface;
22
use TMV\OpenIdClient\Exception\LogicException;
23
use TMV\OpenIdClient\Exception\RuntimeException;
24
use function TMV\OpenIdClient\jose_secret_key;
25
26
class TokenDecrypter implements TokenDecrypterInterface
27
{
28
    /** @var JWELoader */
29
    private $jweLoader;
30
31
    public function __construct(?JWELoader $JWELoader = null)
32
    {
33
        $this->jweLoader = $JWELoader ?: new JWELoader(
34
            new JWESerializerManager([new CompactSerializer()]),
35
            new JWEDecrypter(new AlgorithmManager([]), new AlgorithmManager([]), new CompressionMethodManager([new Deflate()])),
36
            null
37
        );
38
    }
39
40
    public function decryptToken(ClientInterface $client, string $token, string $use = 'id_token'): string
41
    {
42
        $metadata = $client->getMetadata();
43
        $expectedAlg = $metadata->get($use . '_encrypted_response_alg');
44
        $expectedEnc = $metadata->get($use . '_encrypted_response_enc');
45
46
        if (null === $expectedAlg) {
47
            return $token;
48
        }
49
50
        $header = json_decode(base64url_decode(explode('.', $token)[0] ?? '{}'), true);
51
52
        if ($expectedAlg !== ($header['alg'] ?? '')) {
53
            throw new RuntimeException(sprintf('Unexpected JWE alg received, expected %s, got: %s', $expectedAlg, $header['alg'] ?? ''));
54
        }
55
56
        if ($expectedEnc !== ($header['enc'] ?? '')) {
57
            throw new RuntimeException(sprintf('Unexpected JWE enc received, expected %s, got: %s', $expectedEnc, $header['enc'] ?? ''));
58
        }
59
60
        if (! class_exists(JWELoader::class)) {
61
            throw new LogicException('In order to decrypt JWT you should install web-token/jwt-encryption package');
62
        }
63
64
        if ((bool) preg_match('/^(?:RSA|ECDH)/', $expectedAlg)) {
65
            $jwks = $client->getJwks();
66
        } else {
67
            $jwk = jose_secret_key($metadata->getClientSecret() ?: '', $expectedAlg === 'dir' ? $expectedEnc : $expectedAlg);
68
            $jwks = new JWKSet([$jwk]);
69
        }
70
71
        return $this->jweLoader->loadAndDecryptWithKeySet($token, $jwks, $recipient)->getPayload() ?: '';
72
    }
73
}
74