Failed Conditions
Push — v7 ( 858d6a...3f7b5a )
by Florent
02:37
created

JWTLoader::load()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 5
nop 3
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
namespace Jose;
13
14
use Jose\Checker\CheckerManager;
15
use Jose\Object\JWEInterface;
16
use Jose\Object\JWKSetInterface;
17
use Jose\Object\JWSInterface;
18
use Jose\Object\JWTInterface;
19
20
final class JWTLoader
21
{
22
    /**
23
     * @var Loader
24
     */
25
    private $loader;
26
27
    /**
28
     * @var CheckerManager
29
     */
30
    private $checker_manager;
31
32
    /**
33
     * @var Decrypter|null
34
     */
35
    private $decrypter = null;
36
37
    /**
38
     * @var Verifier
39
     */
40
    private $verifier;
41
42
    /**
43
     * JWTLoader constructor.
44
     *
45
     * @param CheckerManager $checker_manager
46
     * @param Verifier       $verifier
47
     */
48
    public function __construct(CheckerManager $checker_manager, Verifier $verifier)
49
    {
50
        $this->checker_manager = $checker_manager;
51
        $this->verifier = $verifier;
52
        $this->loader = new Loader();
53
    }
54
55
    /**
56
     * @param Decrypter $decrypter
57
     */
58
    public function enableDecryptionSupport(Decrypter $decrypter)
59
    {
60
        $this->decrypter = $decrypter;
61
    }
62
63
    /**
64
     * @return string[]
65
     */
66
    public function getSupportedSignatureAlgorithms(): array
67
    {
68
        return $this->verifier->getSupportedSignatureAlgorithms();
69
    }
70
71
    /**
72
     * @return bool
73
     */
74
    public function isDecryptionSupportEnabled(): bool
75
    {
76
        return null !== $this->decrypter;
77
    }
78
79
    /**
80
     * @return string[]
81
     */
82
    public function getSupportedKeyEncryptionAlgorithms(): array
83
    {
84
        return false === $this->isDecryptionSupportEnabled() ? [] : $this->decrypter->getSupportedKeyEncryptionAlgorithms();
85
    }
86
87
    /**
88
     * @return string[]
89
     */
90
    public function getSupportedContentEncryptionAlgorithms(): array
91
    {
92
        return false === $this->isDecryptionSupportEnabled() ? [] : $this->decrypter->getSupportedContentEncryptionAlgorithms();
93
    }
94
95
    /**
96
     * @return string[]
97
     */
98
    public function getSupportedCompressionMethods(): array
99
    {
100
        return false === $this->isDecryptionSupportEnabled() ? [] : $this->decrypter->getSupportedCompressionMethods();
101
    }
102
103
    /**
104
     * @param string               $assertion
105
     * @param JWKSetInterface|null $encryption_key_set
106
     * @param bool                 $is_encryption_required
107
     *
108
     * @return JWTInterface
109
     */
110
    public function load(string $assertion, ?JWKSetInterface $encryption_key_set = null, bool $is_encryption_required = false): JWTInterface
111
    {
112
        $jwt = $this->loader->load($assertion);
113
        if ($jwt instanceof JWEInterface) {
114
            if(false === $this->isDecryptionSupportEnabled()) {
115
                throw new \InvalidArgumentException('Encryption support is not enabled.');
116
            }
117
            if(null === $encryption_key_set) {
118
                throw new \InvalidArgumentException($encryption_key_set, 'Encryption key set is not available.');
119
            }
120
            $jwt = $this->decryptAssertion($jwt, $encryption_key_set);
121
        } elseif (true === $is_encryption_required) {
122
            throw new \InvalidArgumentException('The assertion must be encrypted.');
123
        }
124
125
        return $jwt;
126
    }
127
128
    /**
129
     * @param JWSInterface    $jws
130
     * @param JWKSetInterface $signature_key_set
131
     * @param string|null     $detached_payload
132
     *
133
     * @return int
134
     */
135
    public function verify(JWSInterface $jws, JWKSetInterface $signature_key_set, ?string $detached_payload = null): int
136
    {
137
        $index = null;
138
        $this->verifier->verifyWithKeySet($jws, $signature_key_set, $detached_payload, $index);
139
        if (null === $index) {
140
            throw new \InvalidArgumentException('JWS signature(s) verification failed.');
141
        }
142
        $this->checker_manager->checkJWS($jws, $index);
143
144
        return $index;
145
    }
146
147
    /**
148
     * @param JWEInterface    $jwe
149
     * @param JWKSetInterface $encryption_key_set
150
     *
151
     * @return JWSInterface
152
     */
153
    private function decryptAssertion(JWEInterface $jwe, JWKSetInterface $encryption_key_set): JWSInterface
154
    {
155
        $this->decrypter->decryptUsingKeySet($jwe, $encryption_key_set);
156
157
        $jws = $this->loader->load($jwe->getPayload());
158
        if (!$jws instanceof JWSInterface) {
159
            throw new \InvalidArgumentException('The encrypted assertion does not contain a JWS.');
160
        }
161
162
        return $jws;
163
    }
164
}
165