Completed
Push — master ( 507af9...d8c018 )
by Florent
02:29
created

JWTLoader::enableDecryptionSupport()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
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 Assert\Assertion;
15
use Jose\Checker\CheckerManagerInterface;
16
use Jose\Object\JWEInterface;
17
use Jose\Object\JWKSetInterface;
18
use Jose\Object\JWSInterface;
19
use Psr\Log\LoggerInterface;
20
21
final class JWTLoader
22
{
23
    /**
24
     * @var \Jose\LoaderInterface
25
     */
26
    private $loader;
27
28
    /**
29
     * @var \Jose\Checker\CheckerManagerInterface
30
     */
31
    private $checker_manager;
32
33
    /**
34
     * @var \Jose\DecrypterInterface|null
35
     */
36
    private $decrypter = null;
37
38
    /**
39
     * @var \Jose\VerifierInterface
40
     */
41
    private $verifier;
42
43
    /**
44
     * JWTLoader constructor.
45
     *
46
     * @param \Jose\Checker\CheckerManagerInterface $checker_manager
47
     * @param \Jose\VerifierInterface               $verifier
48
     * @param \Psr\Log\LoggerInterface|null         $logger
49
     */
50
    public function __construct(CheckerManagerInterface $checker_manager, VerifierInterface $verifier, LoggerInterface $logger = null)
51
    {
52
        $this->checker_manager = $checker_manager;
53
        $this->verifier = $verifier;
54
        $this->loader = new Loader();
55
        if (null !== $logger) {
56
            $this->loader->enableLogging($logger);
57
        }
58
    }
59
60
    /**
61
     * @param \Jose\DecrypterInterface $decrypter
62
     */
63
    public function enableDecryptionSupport(DecrypterInterface $decrypter)
64
    {
65
        $this->decrypter = $decrypter;
66
    }
67
68
    /**
69
     * @return string[]
70
     */
71
    public function getSupportedSignatureAlgorithms()
72
    {
73
        return $this->verifier->getSupportedSignatureAlgorithms();
74
    }
75
76
    /**
77
     * @return bool
78
     */
79
    public function isDecryptionSupportEnabled()
80
    {
81
        return null !== $this->decrypter;
82
    }
83
84
    /**
85
     * @return string[]
86
     */
87
    public function getSupportedKeyEncryptionAlgorithms()
88
    {
89
        return false === $this->isDecryptionSupportEnabled() ? [] : $this->decrypter->getSupportedKeyEncryptionAlgorithms();
90
    }
91
92
    /**
93
     * @return string[]
94
     */
95
    public function getSupportedContentEncryptionAlgorithms()
96
    {
97
        return false === $this->isDecryptionSupportEnabled() ? [] : $this->decrypter->getSupportedContentEncryptionAlgorithms();
98
    }
99
100
    /**
101
     * @return string[]
102
     */
103
    public function getSupportedCompressionMethods()
104
    {
105
        return false === $this->isDecryptionSupportEnabled() ? [] : $this->decrypter->getSupportedCompressionMethods();
106
    }
107
108
    /**
109
     * @param string                            $assertion
110
     * @param \Jose\Object\JWKSetInterface|null $encryption_key_set
111
     * @param bool                              $is_encryption_required
112
     *
113
     * @return \Jose\Object\JWSInterface
114
     */
115
    public function load($assertion, JWKSetInterface $encryption_key_set = null, $is_encryption_required = false)
116
    {
117
        Assertion::string($assertion);
118
        Assertion::boolean($is_encryption_required);
119
        $jwt = $this->loader->load($assertion);
120
        if ($jwt instanceof JWEInterface) {
121
            Assertion::notNull($encryption_key_set, 'Encryption key set is not available.');
122
            Assertion::true($this->isDecryptionSupportEnabled(), 'Encryption support is not enabled.');
123
            Assertion::inArray($jwt->getSharedProtectedHeader('alg'), $this->getSupportedKeyEncryptionAlgorithms(), sprintf('The key encryption algorithm "%s" is not allowed.', $jwt->getSharedProtectedHeader('alg')));
124
            Assertion::inArray($jwt->getSharedProtectedHeader('enc'), $this->getSupportedContentEncryptionAlgorithms(), sprintf('The content encryption algorithm "%s" is not allowed or not supported.', $jwt->getSharedProtectedHeader('enc')));
125
            $jwt = $this->decryptAssertion($jwt, $encryption_key_set);
0 ignored issues
show
Bug introduced by
It seems like $encryption_key_set defined by parameter $encryption_key_set on line 115 can be null; however, Jose\JWTLoader::decryptAssertion() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
126
        } elseif (true === $is_encryption_required) {
127
            throw new \InvalidArgumentException('The assertion must be encrypted.');
128
        }
129
130
        return $jwt;
131
    }
132
133
    /**
134
     * @param \Jose\Object\JWSInterface    $jws
135
     * @param \Jose\Object\JWKSetInterface $signature_key_set
136
     * @param string|null                  $detached_payload
137
     *
138
     * @return int
139
     */
140
    public function verify(JWSInterface $jws, JWKSetInterface $signature_key_set, $detached_payload = null)
141
    {
142
        Assertion::inArray($jws->getSignature(0)->getProtectedHeader('alg'), $this->getSupportedSignatureAlgorithms(), sprintf('The signature algorithm "%s" is not supported or not allowed.', $jws->getSignature(0)->getProtectedHeader('alg')));
143
144
        $index = null;
145
        $this->verifier->verifyWithKeySet($jws, $signature_key_set, $detached_payload, $index);
146
        Assertion::notNull($index, 'JWS signature(s) verification failed.');
147
        $this->checker_manager->checkJWS($jws, $index);
148
149
        return $index;
150
    }
151
152
    /**
153
     * @param \Jose\Object\JWEInterface    $jwe
154
     * @param \Jose\Object\JWKSetInterface $encryption_key_set
155
     *
156
     * @return \Jose\Object\JWSInterface
157
     */
158
    private function decryptAssertion(JWEInterface $jwe, JWKSetInterface $encryption_key_set)
159
    {
160
        $this->decrypter->decryptUsingKeySet($jwe, $encryption_key_set);
161
162
        $jws = $this->loader->load($jwe->getPayload());
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->loader->load($jwe->getPayload()); of type Jose\Object\JWSInterface|Jose\Object\JWEInterface adds the type Jose\Object\JWEInterface to the return on line 165 which is incompatible with the return type documented by Jose\JWTLoader::decryptAssertion of type Jose\Object\JWSInterface.
Loading history...
163
        Assertion::isInstanceOf($jws, JWSInterface::class, 'The encrypted assertion does not contain a JWS.');
164
165
        return $jws;
166
    }
167
}
168