This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php namespace jws\impl; |
||
2 | /** |
||
3 | * Copyright 2015 OpenStack Foundation |
||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
5 | * you may not use this file except in compliance with the License. |
||
6 | * You may obtain a copy of the License at |
||
7 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
8 | * Unless required by applicable law or agreed to in writing, software |
||
9 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
11 | * See the License for the specific language governing permissions and |
||
12 | * limitations under the License. |
||
13 | **/ |
||
14 | use jwa\cryptographic_algorithms\digital_signatures\DigitalSignatureAlgorithm; |
||
15 | use jwa\cryptographic_algorithms\DigitalSignatures_MACs_Registry; |
||
16 | use jwa\cryptographic_algorithms\macs\MAC_Algorithm; |
||
17 | use jwk\exceptions\InvalidJWKAlgorithm; |
||
18 | use jwk\IAsymmetricJWK; |
||
19 | use jwk\IJWK; |
||
20 | use jwk\JSONWebKeyKeyOperationsValues; |
||
21 | use jwk\JSONWebKeyPublicKeyUseValues; |
||
22 | use jwk\JSONWebKeyVisibility; |
||
23 | use jws\exceptions\JWSInvalidJWKException; |
||
24 | use jws\exceptions\JWSInvalidPayloadException; |
||
25 | use jws\exceptions\JWSNotSupportedAlgorithm; |
||
26 | use jws\IJWS; |
||
27 | use jws\IJWSPayloadClaimSetSpec; |
||
28 | use jws\IJWSPayloadRawSpec; |
||
29 | use jws\IJWSPayloadSpec; |
||
30 | use jws\payloads\JWSPayloadFactory; |
||
31 | use jwt\IBasicJWT; |
||
32 | use jwt\IJOSEHeader; |
||
33 | use jwt\impl\JWT; |
||
34 | use jwt\impl\JWTSerializer; |
||
35 | use jwt\JOSEHeaderParam; |
||
36 | use jwt\RegisteredJOSEHeaderNames; |
||
37 | use jwt\utils\JOSEHeaderSerializer; |
||
38 | use jwt\utils\JWTClaimSetSerializer; |
||
39 | use jwt\utils\JWTRawSerializer; |
||
40 | use utils\json_types\JsonValue; |
||
41 | use utils\json_types\StringOrURI; |
||
42 | /** |
||
43 | * Class JWS |
||
44 | * @package jws\impl |
||
45 | * @access private |
||
46 | */ |
||
47 | final class JWS extends JWT implements IJWS |
||
48 | { |
||
49 | |||
50 | /** |
||
51 | * @var IJWK |
||
52 | */ |
||
53 | private $jwk = null; |
||
54 | |||
55 | /** |
||
56 | * @var IJWSPayloadSpec |
||
57 | */ |
||
58 | private $payload = null; |
||
59 | |||
60 | /** |
||
61 | * @param IJOSEHeader $header |
||
62 | * @param IJWSPayloadSpec $payload |
||
63 | * @param string $signature |
||
64 | * @throws JWSNotSupportedAlgorithm |
||
65 | */ |
||
66 | protected function __construct(IJOSEHeader $header, IJWSPayloadSpec $payload = null, $signature = '') |
||
67 | { |
||
68 | |||
69 | $claim_set = null; |
||
70 | |||
71 | if(!is_null($payload) && $payload->isClaimSet() && $payload instanceof IJWSPayloadClaimSetSpec) { |
||
72 | $header->addHeader(new JOSEHeaderParam(RegisteredJOSEHeaderNames::Type, new StringOrURI('JWT'))); |
||
73 | $claim_set = $payload->getClaimSet(); |
||
74 | } |
||
75 | |||
76 | parent::__construct($header, $claim_set); |
||
77 | |||
78 | if(!is_null($payload)) |
||
79 | $this->setPayload($payload); |
||
80 | |||
81 | $this->signature = $signature; |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * @param IJWSPayloadSpec $payload |
||
86 | * @return IJWS |
||
87 | */ |
||
88 | public function setPayload(IJWSPayloadSpec $payload) |
||
89 | { |
||
90 | $this->payload = $payload; |
||
91 | return $this; |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * @return string |
||
96 | */ |
||
97 | public function toCompactSerialization() |
||
98 | { |
||
99 | if(!is_null($this->jwk->getId())) |
||
100 | $this->header->addHeader(new JOSEHeaderParam(RegisteredJOSEHeaderNames::KeyID, $this->jwk->getId())); |
||
101 | |||
102 | if($this->jwk instanceof IAsymmetricJWK) |
||
103 | { |
||
104 | // we should add the public key on the header |
||
105 | $public_key = clone $this->jwk; |
||
106 | |||
107 | $this->header->addHeader |
||
108 | ( |
||
109 | new JOSEHeaderParam |
||
110 | ( |
||
111 | RegisteredJOSEHeaderNames::JSONWebKey, |
||
112 | new JsonValue |
||
113 | ( |
||
114 | $public_key->setVisibility(JSONWebKeyVisibility::PublicOnly) |
||
115 | ) |
||
116 | ) |
||
117 | ); |
||
118 | } |
||
119 | |||
120 | $this->sign(); |
||
121 | return parent::toCompactSerialization(); |
||
122 | } |
||
123 | |||
124 | /** |
||
125 | * @return $this |
||
126 | * @throws JWSInvalidJWKException |
||
127 | * @throws JWSInvalidPayloadException |
||
128 | * @throws JWSNotSupportedAlgorithm |
||
129 | */ |
||
130 | public function sign() |
||
131 | { |
||
132 | |||
133 | if(is_null($this->jwk)) |
||
134 | throw new JWSInvalidJWKException; |
||
135 | |||
136 | View Code Duplication | if($this->jwk->getKeyUse()->getString() !== JSONWebKeyPublicKeyUseValues::Signature) |
|
0 ignored issues
–
show
|
|||
137 | throw new JWSInvalidJWKException(sprintf('use %s not supported.', $this->jwk->getKeyUse()->getString())); |
||
138 | |||
139 | $alg = DigitalSignatures_MACs_Registry::getInstance()->get($this->header->getAlgorithm()->getString()); |
||
140 | |||
141 | if(is_null($alg)) |
||
142 | throw new JWSNotSupportedAlgorithm(sprintf('alg %s.',$this->header->getAlgorithm()->getString())); |
||
143 | |||
144 | $secured_input_bytes = JOSEHeaderSerializer::serialize($this->header) . IBasicJWT::SegmentSeparator .$this->getEncodedPayload(); |
||
145 | |||
146 | $key = $this->jwk->getKey(JSONWebKeyKeyOperationsValues::ComputeDigitalSignatureOrMAC); |
||
147 | |||
148 | if($alg instanceof DigitalSignatureAlgorithm) |
||
149 | { |
||
150 | $this->signature = $alg->sign($key, $secured_input_bytes); |
||
0 ignored issues
–
show
$key of type object<security\Key> is not a sub-type of object<security\PrivateKey> . It seems like you assume a child interface of the interface security\Key to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.
Loading history...
|
|||
151 | } |
||
152 | else if($alg instanceof MAC_Algorithm ) |
||
153 | { |
||
154 | $this->signature = $alg->digest($key, $secured_input_bytes); |
||
0 ignored issues
–
show
$key of type object<security\Key> is not a sub-type of object<security\SharedKey> . It seems like you assume a child interface of the interface security\Key to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.
Loading history...
|
|||
155 | } |
||
156 | else |
||
157 | { |
||
158 | throw new JWSNotSupportedAlgorithm(sprintf('alg %s.',$this->header->getAlgorithm()->getString())); |
||
159 | } |
||
160 | |||
161 | return $this; |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * @return string |
||
166 | * @throws JWSInvalidPayloadException |
||
167 | */ |
||
168 | public function getEncodedPayload() |
||
169 | { |
||
170 | if(is_null($this->payload)) |
||
171 | throw new JWSInvalidPayloadException('payload is not set!'); |
||
172 | |||
173 | $enc_payload = ''; |
||
174 | |||
175 | if($this->payload instanceof IJWSPayloadClaimSetSpec) |
||
176 | { |
||
177 | $enc_payload = JWTClaimSetSerializer::serialize($this->payload->getClaimSet()); |
||
178 | } |
||
179 | else if($this->payload instanceof IJWSPayloadRawSpec) |
||
180 | { |
||
181 | $enc_payload = JWTRawSerializer::serialize($this->payload->getRaw()); |
||
182 | } |
||
183 | return $enc_payload; |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * @param IJWK $key |
||
188 | * @return $this |
||
189 | */ |
||
190 | public function setKey(IJWK $key) |
||
191 | { |
||
192 | $this->jwk = $key; |
||
193 | return $this; |
||
194 | } |
||
195 | |||
196 | /** |
||
197 | * @param string $compact_serialization |
||
198 | * @return IJWS |
||
199 | * @access private |
||
200 | */ |
||
201 | static public function fromCompactSerialization($compact_serialization) |
||
202 | { |
||
203 | list($header, $payload, $signature) = JWTSerializer::deserialize($compact_serialization); |
||
204 | return new JWS($header, JWSPayloadFactory::build($payload), $signature); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * @return StringOrURI |
||
209 | */ |
||
210 | public function getSigningAlgorithm() |
||
211 | { |
||
212 | return $this->header->getAlgorithm(); |
||
213 | } |
||
214 | |||
215 | /** |
||
216 | * @return StringOrURI |
||
217 | */ |
||
218 | public function getType() |
||
219 | { |
||
220 | return $this->header->getType(); |
||
221 | } |
||
222 | |||
223 | /** |
||
224 | * @param string $original_alg |
||
225 | * @return bool |
||
226 | * @throws InvalidJWKAlgorithm |
||
227 | * @throws JWSInvalidJWKException |
||
228 | * @throws JWSInvalidPayloadException |
||
229 | * @throws JWSNotSupportedAlgorithm |
||
230 | */ |
||
231 | public function verify($original_alg) |
||
232 | { |
||
233 | if(is_null($this->jwk)) |
||
234 | throw new JWSInvalidJWKException; |
||
235 | |||
236 | View Code Duplication | if($this->jwk->getKeyUse()->getString() !== JSONWebKeyPublicKeyUseValues::Signature) |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository.
Loading history...
|
|||
237 | throw new JWSInvalidJWKException |
||
238 | ( |
||
239 | sprintf |
||
240 | ( |
||
241 | 'use %s not supported ', |
||
242 | $this->jwk->getKeyUse()->getString() |
||
243 | ) |
||
244 | ); |
||
245 | |||
246 | if(is_null($this->jwk->getAlgorithm())) |
||
247 | throw new InvalidJWKAlgorithm('algorithm intended for use with the key is not set! '); |
||
248 | |||
249 | if(!is_null($this->jwk->getId()) && !is_null($this->header->getKeyID()) && $this->header->getKeyID()->getValue() != $this->jwk->getId()->getValue()) |
||
250 | throw new JWSInvalidJWKException |
||
251 | ( |
||
252 | sprintf |
||
253 | ( |
||
254 | 'original kid %s - current kid %s', |
||
255 | $this->header->getKeyID()->getValue(), |
||
256 | $this->jwk->getId()->getValue() |
||
257 | ) |
||
258 | ); |
||
259 | |||
260 | $alg = DigitalSignatures_MACs_Registry::getInstance()->get($original_alg); |
||
261 | |||
262 | if(is_null($alg)) |
||
263 | throw new JWSNotSupportedAlgorithm(sprintf('algo %s', $original_alg)); |
||
264 | |||
265 | $former_alg = $this->header->getAlgorithm()->getString(); |
||
266 | |||
267 | if($former_alg != $original_alg) |
||
268 | throw new JWSNotSupportedAlgorithm |
||
269 | ( |
||
270 | sprintf |
||
271 | ( |
||
272 | 'former alg %s - original alg %s', |
||
273 | $former_alg, |
||
274 | $original_alg |
||
275 | ) |
||
276 | ); |
||
277 | |||
278 | if($this->jwk->getAlgorithm()->getValue() !== $original_alg) |
||
279 | throw new InvalidJWKAlgorithm |
||
280 | ( |
||
281 | sprintf |
||
282 | ( |
||
283 | 'mismatch between algorithm intended for use with the key %s and the cryptographic algorithm used to secure the JWS %s', |
||
284 | $this->jwk->getAlgorithm()->getValue(), |
||
285 | $original_alg |
||
286 | ) |
||
287 | ); |
||
288 | |||
289 | $secured_input_bytes = JOSEHeaderSerializer::serialize($this->header) . IBasicJWT::SegmentSeparator .$this->getEncodedPayload(); |
||
290 | |||
291 | // use public key / secret |
||
292 | $key = $this->jwk->getKey(JSONWebKeyKeyOperationsValues::VerifyDigitalSignatureOrMAC); |
||
293 | return $alg->verify($key, $secured_input_bytes, $this->signature); |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * @return IJWSPayloadSpec |
||
298 | */ |
||
299 | public function getPayload() |
||
300 | { |
||
301 | return $this->payload; |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * @param IJOSEHeader $header |
||
306 | * @param IJWSPayloadSpec $payload |
||
307 | * @param string $signature |
||
308 | * @return IJWS |
||
309 | */ |
||
310 | static public function fromHeaderClaimsAndSignature(IJOSEHeader $header, IJWSPayloadSpec $payload = null , $signature = '') |
||
311 | { |
||
312 | return new JWS($header, $payload, $signature ); |
||
313 | } |
||
314 | |||
315 | /** |
||
316 | * @return array |
||
317 | */ |
||
318 | public function take() |
||
319 | { |
||
320 | $payload = ($this->payload instanceof IJWSPayloadRawSpec) ? $this->payload->getRaw() : $this->claim_set; |
||
321 | return array |
||
322 | ( |
||
323 | $this->header, |
||
324 | $payload, |
||
325 | $this->signature |
||
326 | ); |
||
327 | } |
||
328 | } |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.