Passed
Push — master ( 898cc7...450add )
by Thomas Mauro
03:07
created

TokenDecrypter   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 50
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 23
dl 0
loc 50
ccs 0
cts 32
cp 0
rs 10
c 1
b 0
f 0
wmc 9

2 Methods

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