Failed Conditions
Push — ng ( 4e3f89...ea75f5 )
by Florent
05:50
created

theEncryptedClientAssertionSignedAndEncryptedByTheClientIsInvalidBecauseOfMissingClaims()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 13
nc 3
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * The MIT License (MIT)
7
 *
8
 * Copyright (c) 2014-2018 Spomky-Labs
9
 *
10
 * This software may be modified and distributed under the terms
11
 * of the MIT license.  See the LICENSE file for details.
12
 */
13
14
namespace OAuth2Framework\Component\ClientAuthentication\Tests;
15
16
use Http\Message\MessageFactory\DiactorosMessageFactory;
17
use Jose\Component\Checker\ClaimCheckerManager;
18
use Jose\Component\Checker\HeaderCheckerManager;
19
use Jose\Component\Core\AlgorithmManager;
20
use Jose\Component\Core\Converter\StandardConverter;
21
use Jose\Component\Core\JWK;
22
use Jose\Component\Core\JWKSet;
23
use Jose\Component\Encryption\Algorithm\ContentEncryption\A256CBCHS512;
24
use Jose\Component\Encryption\Algorithm\KeyEncryption\RSAOAEP256;
25
use Jose\Component\Encryption\Compression\CompressionMethodManager;
26
use Jose\Component\Encryption\Compression\Deflate;
27
use Jose\Component\Encryption\JWEBuilder;
28
use Jose\Component\Encryption\JWEDecrypter;
29
use Jose\Component\Encryption\JWELoader;
30
use Jose\Component\Encryption\JWETokenSupport;
31
use Jose\Component\Encryption\Serializer\JWESerializerManager;
32
use Jose\Component\KeyManagement\JKUFactory;
33
use Jose\Component\Signature\Algorithm\HS256;
34
use Jose\Component\Signature\Algorithm\RS256;
35
use Jose\Component\Signature\JWSBuilder;
36
use Jose\Component\Signature\JWSTokenSupport;
37
use Jose\Component\Signature\JWSVerifier;
38
use Jose\Component\Signature\Serializer\CompactSerializer;
39
use OAuth2Framework\Component\Core\Client\Client;
40
use OAuth2Framework\Component\Core\Client\ClientId;
41
use OAuth2Framework\Component\Core\DataBag\DataBag;
42
use OAuth2Framework\Component\Core\Exception\OAuth2Exception;
43
use OAuth2Framework\Component\Core\UserAccount\UserAccountId;
44
use OAuth2Framework\Component\ClientAuthentication\AuthenticationMethodManager;
45
use OAuth2Framework\Component\ClientAuthentication\ClientAssertionJwt;
46
use PHPUnit\Framework\TestCase;
47
use Psr\Http\Message\ServerRequestInterface;
48
use Zend\Diactoros\Response;
49
50
/**
51
 * @group TokenEndpoint
52
 * @group ClientAuthentication
53
 */
54
class ClientAssertionJwtAuthenticationMethodTest extends TestCase
55
{
56
    /**
57
     * @test
58
     */
59
    public function genericCalls()
60
    {
61
        $method = $this->getMethod();
62
63
        self::assertEquals([], $method->getSchemesParameters());
64
        self::assertEquals(['client_secret_jwt', 'private_key_jwt'], $method->getSupportedMethods());
65
        self::assertEquals(['HS256', 'RS256'], $method->getSupportedSignatureAlgorithms());
66
        self::assertEquals(['RSA-OAEP-256'], $method->getSupportedKeyEncryptionAlgorithms());
67
        self::assertEquals(['A256CBC-HS512'], $method->getSupportedContentEncryptionAlgorithms());
68
    }
69
70
    /**
71
     * @test
72
     */
73
    public function theClientIdCannotBeFoundInTheRequest()
74
    {
75
        $method = $this->getMethod();
76
        $request = $this->prophesize(ServerRequestInterface::class);
77
        $request->getHeader('Authorization')->willReturn([]);
78
        $request->getParsedBody()->willReturn([]);
79
80
        $clientId = $method->findClientIdAndCredentials($request->reveal(), $credentials);
81
        self::assertNull($clientId);
82
        self::assertNull($credentials);
83
    }
84
85
    /**
86
     * @test
87
     */
88
    public function theClientAssertionTypeIsNotSupported()
89
    {
90
        $method = $this->getMethod();
91
        $request = $this->prophesize(ServerRequestInterface::class);
92
        $request->getHeader('Authorization')->willReturn([]);
93
        $request->getParsedBody()->willReturn([
94
            'client_assertion_type' => 'foo',
95
        ]);
96
97
        $clientId = $method->findClientIdAndCredentials($request->reveal(), $credentials);
98
        self::assertNull($clientId);
99
        self::assertNull($credentials);
100
    }
101
102
    /**
103
     * @test
104
     */
105
    public function theClientAssertionIsMissing()
106
    {
107
        $method = $this->getMethod();
108
        $request = $this->prophesize(ServerRequestInterface::class);
109
        $request->getHeader('Authorization')->willReturn([]);
110
        $request->getParsedBody()->willReturn([
111
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
112
        ]);
113
114
        try {
115
            $method->findClientIdAndCredentials($request->reveal(), $credentials);
116
            $this->fail('An OAuth2 exception should be thrown.');
117
        } catch (OAuth2Exception $e) {
118
            self::assertEquals('invalid_request', $e->getMessage());
119
            self::assertEquals('Parameter "client_assertion" is missing.', $e->getErrorDescription());
120
        }
121
    }
122
123
    /**
124
     * @test
125
     */
126
    public function theClientAssertionIsInvalid()
127
    {
128
        $method = $this->getMethod();
129
        $request = $this->prophesize(ServerRequestInterface::class);
130
        $request->getHeader('Authorization')->willReturn([]);
131
        $request->getParsedBody()->willReturn([
132
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
133
            'client_assertion' => 'foo',
134
        ]);
135
136
        try {
137
            $method->findClientIdAndCredentials($request->reveal(), $credentials);
138
            $this->fail('An OAuth2 exception should be thrown.');
139
        } catch (OAuth2Exception $e) {
140
            self::assertEquals('invalid_request', $e->getMessage());
141
            self::assertEquals('Unable to load, decrypt or verify the client assertion.', $e->getErrorDescription());
142
        }
143
    }
144
145
    /**
146
     * @test
147
     */
148
    public function theClientAssertionSignedByTheClientIsInvalidBecauseOfMissingClaims()
149
    {
150
        $method = $this->getMethod();
151
        $request = $this->prophesize(ServerRequestInterface::class);
152
        $request->getHeader('Authorization')->willReturn([]);
153
        $request->getParsedBody()->willReturn([
154
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
155
            'client_assertion' => $this->createInvalidClientAssertionSignedByTheClient(),
156
        ]);
157
158
        try {
159
            $method->findClientIdAndCredentials($request->reveal(), $credentials);
160
            $this->fail('An OAuth2 exception should be thrown.');
161
        } catch (OAuth2Exception $e) {
162
            self::assertEquals('invalid_request', $e->getMessage());
163
            self::assertEquals('The following claim(s) is/are mandatory: "iss, sub, aud, exp".', $e->getErrorDescription());
164
        }
165
    }
166
167
    /**
168
     * @test
169
     */
170
    public function theEncryptedClientAssertionSignedAndEncryptedByTheClientIsInvalidBecauseOfMissingClaims()
171
    {
172
        $method = $this->getMethod();
173
        $request = $this->prophesize(ServerRequestInterface::class);
174
        $request->getHeader('Authorization')->willReturn([]);
175
        $request->getParsedBody()->willReturn([
176
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
177
            'client_assertion' => $this->createInvalidClientAssertionSignedAndEncryptedByTheClient(),
178
        ]);
179
180
        try {
181
            $method->findClientIdAndCredentials($request->reveal(), $credentials);
182
            $this->fail('An OAuth2 exception should be thrown.');
183
        } catch (OAuth2Exception $e) {
184
            self::assertEquals('invalid_request', $e->getMessage());
185
            self::assertEquals('The following claim(s) is/are mandatory: "iss, sub, aud, exp".', $e->getErrorDescription());
186
        }
187
    }
188
189
    /**
190
     * @test
191
     */
192
    public function theClientAssertionIsValidAndTheClientIdIsRetrieved()
193
    {
194
        $method = $this->getMethod();
195
        $request = $this->prophesize(ServerRequestInterface::class);
196
        $request->getHeader('Authorization')->willReturn([]);
197
        $request->getParsedBody()->willReturn([
198
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
199
            'client_assertion' => $this->createValidClientAssertionSignedByTheClient(),
200
        ]);
201
202
        $clientId = $method->findClientIdAndCredentials($request->reveal(), $credentials);
203
        self::assertEquals('ClientId', $clientId->getValue());
204
    }
205
206
    /**
207
     * @test
208
     */
209
    public function theEncryptedClientAssertionIsValidAndTheClientIdIsRetrieved()
210
    {
211
        $method = $this->getMethod();
212
        $request = $this->prophesize(ServerRequestInterface::class);
213
        $request->getHeader('Authorization')->willReturn([]);
214
        $request->getParsedBody()->willReturn([
215
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
216
            'client_assertion' => $this->createValidClientAssertionSignedAndEncryptedByTheClient(),
217
        ]);
218
219
        $clientId = $method->findClientIdAndCredentials($request->reveal(), $credentials);
220
        self::assertEquals('ClientId', $clientId->getValue());
221
    }
222
223
    /**
224
     * @test
225
     */
226
    /*public function theClientUsesAnotherAuthenticationMethod()
0 ignored issues
show
Unused Code Comprehensibility introduced by
59% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
227
    {
228
        $method = $this->getMethod();
229
        $manager = new AuthenticationMethodManager();
230
        $method->add($method);
231
        $client = Client::createEmpty();
232
        $client = $client->create(
233
            ClientId::create('CLIENT_ID'),
234
            DataBag::create([
235
                'client_secret' => 'CLIENT_SECRET',
236
                'token_endpoint_auth_method' => 'client_secret_post',
237
            ]),
238
            UserAccountId::create('USER_ACCOUNT_ID')
239
        );
240
        $request = $this->prophesize(ServerRequestInterface::class);
241
        $request->getParsedBody()->willReturn([
242
            'client_assertion_type' => 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer',
243
            'client_assertion'      => 'CLIENT_SECRET',
244
        ]);
245
246
        self::assertFalse($method->isClientAuthenticated($request->reveal(), $client, $method, 'CLIENT_SECRET'));
247
    }*/
248
249
    /**
250
     * @test
251
     */
252
    public function theClientConfigurationCanBeCheckedWithClientSecretJwt()
253
    {
254
        $method = $this->getMethod();
255
        $commandParameters = DataBag::create([
256
            'token_endpoint_auth_method' => 'client_secret_jwt',
257
        ]);
258
        $validatedParameters = $method->checkClientConfiguration($commandParameters, DataBag::create([]));
259
260
        self::assertTrue($validatedParameters->has('client_secret'));
261
        self::assertTrue($validatedParameters->has('client_secret_expires_at'));
262
    }
263
264
    /**
265
     * @test
266
     * @expectedException \InvalidArgumentException
267
     * @expectedExceptionMessage Either the parameter "jwks" or "jwks_uri" must be set.
268
     */
269
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfBothJwksAndJwksUriAreSet()
270
    {
271
        $method = $this->getMethod();
272
        $commandParameters = DataBag::create([
273
            'token_endpoint_auth_method' => 'private_key_jwt',
274
            'jwks' => 'foo',
275
            'jwks_uri' => 'bar',
276
        ]);
277
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
278
    }
279
280
    /**
281
     * @test
282
     * @expectedException \InvalidArgumentException
283
     * @expectedExceptionMessage Either the parameter "jwks" or "jwks_uri" must be set.
284
     */
285
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfNoneOfTheJwksAndJwksUriAreSet()
286
    {
287
        $method = $this->getMethod();
288
        $commandParameters = DataBag::create([
289
            'token_endpoint_auth_method' => 'private_key_jwt',
290
        ]);
291
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
292
    }
293
294
    /**
295
     * @test
296
     * @expectedException \InvalidArgumentException
297
     * @expectedExceptionMessage The parameter "jwks" must be a valid JWKSet object.
298
     */
299
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfJwksIsNotAValidKeySet()
300
    {
301
        $method = $this->getMethod();
302
        $commandParameters = DataBag::create([
303
            'token_endpoint_auth_method' => 'private_key_jwt',
304
            'jwks' => 'foo',
305
        ]);
306
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
307
    }
308
309
    /**
310
     * @test
311
     */
312
    public function theClientConfigurationCanBeCheckedWithPrivateKeyJwtIfJwksIsValid()
313
    {
314
        $method = $this->getMethod();
315
        $commandParameters = DataBag::create([
316
            'token_endpoint_auth_method' => 'private_key_jwt',
317
            'jwks' => '{"keys":[{"kty":"oct","k":"bJzb8RaN7TzPz001PeF0lw0ZoUJqbazGxMvBd_xzfms"},{"kty":"oct","k":"dIx5cdLn-dAgNkvfZSiroJuy5oykHO4hDnYpmwlMq6A"}]}',
318
        ]);
319
        $validatedParameters = $method->checkClientConfiguration($commandParameters, DataBag::create([]));
320
321
        self::assertTrue($validatedParameters->has('jwks'));
322
        self::assertEquals('{"keys":[{"kty":"oct","k":"bJzb8RaN7TzPz001PeF0lw0ZoUJqbazGxMvBd_xzfms"},{"kty":"oct","k":"dIx5cdLn-dAgNkvfZSiroJuy5oykHO4hDnYpmwlMq6A"}]}', $validatedParameters->get('jwks'));
323
    }
324
325
    /**
326
     * @test
327
     * @expectedException \InvalidArgumentException
328
     * @expectedExceptionMessage Distant key sets cannot be used. Please use "jwks" instead of "jwks_uri".
329
     */
330
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfJwksUriFactoryIsNotAvailable()
331
    {
332
        $method = $this->getMethod();
333
        $commandParameters = DataBag::create([
334
            'token_endpoint_auth_method' => 'private_key_jwt',
335
            'jwks_uri' => 'foo',
336
        ]);
337
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
338
    }
339
340
    /**
341
     * @test
342
     * @expectedException \InvalidArgumentException
343
     * @expectedExceptionMessage The parameter "jwks_uri" must be a valid uri to a JWKSet.
344
     */
345
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfJwksUriIsNotValid()
346
    {
347
        $method = clone $this->getMethod();
348
        $httpClient = $this->getHttpClient();
349
        $method->enableJkuSupport(
350
            $this->getJkuFactory($httpClient)
351
        );
352
        $commandParameters = DataBag::create([
353
            'token_endpoint_auth_method' => 'private_key_jwt',
354
            'jwks_uri' => 'foo',
355
        ]);
356
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
357
    }
358
359
    /**
360
     * @test
361
     * @expectedException \InvalidArgumentException
362
     * @expectedExceptionMessage The parameter "jwks_uri" must be a valid uri to a JWKSet.
363
     */
364
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfJwksUriCannotBeReached()
365
    {
366
        $method = clone $this->getMethod();
367
        $httpClient = $this->getHttpClient();
368
        $httpClient->addResponse(new Response('php://memory', 404));
369
        $method->enableJkuSupport(
370
            $this->getJkuFactory($httpClient)
371
        );
372
        $commandParameters = DataBag::create([
373
            'token_endpoint_auth_method' => 'private_key_jwt',
374
            'jwks_uri' => 'https://www.foo.com/bad-url.jwkset',
375
        ]);
376
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
377
    }
378
379
    /**
380
     * @test
381
     * @expectedException \InvalidArgumentException
382
     * @expectedExceptionMessage The parameter "jwks_uri" must be a valid uri to a JWKSet.
383
     */
384
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfJwksUriDoesNotContainAValidKeySet()
385
    {
386
        $method = clone $this->getMethod();
387
        $httpClient = $this->getHttpClient();
388
        $stream = fopen('php://memory', 'w+');
389
        fwrite($stream, 'Hello World!');
390
        rewind($stream);
391
        $httpClient->addResponse(new Response($stream, 200));
392
        $method->enableJkuSupport(
393
            $this->getJkuFactory($httpClient)
394
        );
395
        $commandParameters = DataBag::create([
396
            'token_endpoint_auth_method' => 'private_key_jwt',
397
            'jwks_uri' => 'https://www.foo.com/index.html',
398
        ]);
399
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
400
    }
401
402
    /**
403
     * @test
404
     * @expectedException \InvalidArgumentException
405
     * @expectedExceptionMessage The distant key set is empty.
406
     */
407
    public function theClientConfigurationCannotBeCheckedWithPrivateKeyJwtIfJwksUriDoesContainAnEmptyKeySet()
408
    {
409
        $method = clone $this->getMethod();
410
        $httpClient = $this->getHttpClient();
411
        $stream = fopen('php://memory', 'w+');
412
        fwrite($stream, '{"keys":[]}');
413
        rewind($stream);
414
        $httpClient->addResponse(new Response($stream, 200));
415
        $method->enableJkuSupport(
416
            $this->getJkuFactory($httpClient)
417
        );
418
        $commandParameters = DataBag::create([
419
            'token_endpoint_auth_method' => 'private_key_jwt',
420
            'jwks_uri' => 'https://www.foo.com/index.html',
421
        ]);
422
        $method->checkClientConfiguration($commandParameters, DataBag::create([]));
423
    }
424
425
    /**
426
     * @test
427
     */
428
    public function theClientConfigurationCanBeCheckedWithPrivateKeyJwt()
429
    {
430
        $method = clone $this->getMethod();
431
        $httpClient = $this->getHttpClient();
432
        $stream = fopen('php://memory', 'w+');
433
        fwrite($stream, '{"keys":[{"kty":"oct","k":"bJzb8RaN7TzPz001PeF0lw0ZoUJqbazGxMvBd_xzfms"},{"kty":"oct","k":"dIx5cdLn-dAgNkvfZSiroJuy5oykHO4hDnYpmwlMq6A"}]}');
434
        rewind($stream);
435
        $httpClient->addResponse(new Response($stream, 200));
436
        $method->enableJkuSupport(
437
            $this->getJkuFactory($httpClient)
438
        );
439
        $commandParameters = DataBag::create([
440
            'token_endpoint_auth_method' => 'private_key_jwt',
441
            'jwks_uri' => 'https://www.foo.com/keyset',
442
        ]);
443
        $validatedParameters = $method->checkClientConfiguration($commandParameters, DataBag::create([]));
444
445
        self::assertTrue($validatedParameters->has('jwks_uri'));
446
        self::assertEquals('https://www.foo.com/keyset', $validatedParameters->get('jwks_uri'));
447
    }
448
449
    /**
450
     * @var null|ClientAssertionJwt
451
     */
452
    private $method = null;
453
454
    /**
455
     * @return ClientAssertionJwt
456
     */
457
    private function getMethod(): ClientAssertionJwt
458
    {
459
        if (null === $this->method) {
460
            $this->method = new ClientAssertionJwt(
461
                new StandardConverter(),
462
                new JWSVerifier(AlgorithmManager::create([new HS256(), new RS256()])),
463
                HeaderCheckerManager::create([], [new JWSTokenSupport()]),
464
                ClaimCheckerManager::create([]),
465
                3600
466
            );
467
468
            $this->method->enableEncryptedAssertions(
469
                new JWELoader(
470
                    JWESerializerManager::create([new \Jose\Component\Encryption\Serializer\CompactSerializer(new StandardConverter())]),
471
                    new JWEDecrypter(
472
                        AlgorithmManager::create([new RSAOAEP256()]),
473
                        AlgorithmManager::create([new A256CBCHS512()]),
474
                        CompressionMethodManager::create([new Deflate()])
475
                    ),
476
                    HeaderCheckerManager::create([], [new JWETokenSupport()])
477
                ),
478
                JWKSet::createFromKeys([JWK::create([
479
                    'kty' => 'RSA',
480
                    'kid' => '[email protected]',
481
                    'use' => 'enc',
482
                    'n'   => 'wbdxI55VaanZXPY29Lg5hdmv2XhvqAhoxUkanfzf2-5zVUxa6prHRrI4pP1AhoqJRlZfYtWWd5mmHRG2pAHIlh0ySJ9wi0BioZBl1XP2e-C-FyXJGcTy0HdKQWlrfhTm42EW7Vv04r4gfao6uxjLGwfpGrZLarohiWCPnkNrg71S2CuNZSQBIPGjXfkmIy2tl_VWgGnL22GplyXj5YlBLdxXp3XeStsqo571utNfoUTU8E4qdzJ3U1DItoVkPGsMwlmmnJiwA7sXRItBCivR4M5qnZtdw-7v4WuR4779ubDuJ5nalMv2S66-RPcnFAzWSKxtBDnFJJDGIUe7Tzizjg1nms0Xq_yPub_UOlWn0ec85FCft1hACpWG8schrOBeNqHBODFskYpUc2LC5JA2TaPF2dA67dg1TTsC_FupfQ2kNGcE1LgprxKHcVWYQb86B-HozjHZcqtauBzFNV5tbTuB-TpkcvJfNcFLlH3b8mb-H_ox35FjqBSAjLKyoeqfKTpVjvXhd09knwgJf6VKq6UC418_TOljMVfFTWXUxlnfhOOnzW6HSSzD1c9WrCuVzsUMv54szidQ9wf1cYWf3g5qFDxDQKis99gcDaiCAwM3yEBIzuNeeCa5dartHDb1xEB_HcHSeYbghbMjGfasvKn0aZRsnTyC0xhWBlsolZE',
483
                    'e'   => 'AQAB',
484
                    'alg' => 'RSA-OAEP-256',
485
                    'd'   => 'n7fzJc3_WG59VEOBTkayzuSMM780OJQuZjN_KbH8lOZG25ZoA7T4Bxcc0xQn5oZE5uSCIwg91oCt0JvxPcpmqzaJZg1nirjcWZ-oBtVk7gCAWq-B3qhfF3izlbkosrzjHajIcY33HBhsy4_WerrXg4MDNE4HYojy68TcxT2LYQRxUOCf5TtJXvM8olexlSGtVnQnDRutxEUCwiewfmmrfveEogLx9EA-KMgAjTiISXxqIXQhWUQX1G7v_mV_Hr2YuImYcNcHkRvp9E7ook0876DhkO8v4UOZLwA1OlUX98mkoqwc58A_Y2lBYbVx1_s5lpPsEqbbH-nqIjh1fL0gdNfihLxnclWtW7pCztLnImZAyeCWAG7ZIfv-Rn9fLIv9jZ6r7r-MSH9sqbuziHN2grGjD_jfRluMHa0l84fFKl6bcqN1JWxPVhzNZo01yDF-1LiQnqUYSepPf6X3a2SOdkqBRiquE6EvLuSYIDpJq3jDIsgoL8Mo1LoomgiJxUwL_GWEOGu28gplyzm-9Q0U0nyhEf1uhSR8aJAQWAiFImWH5W_IQT9I7-yrindr_2fWQ_i1UgMsGzA7aOGzZfPljRy6z-tY_KuBG00-28S_aWvjyUc-Alp8AUyKjBZ-7CWH32fGWK48j1t-zomrwjL_mnhsPbGs0c9WsWgRzI-K8gE',
486
                    'p'   => '7_2v3OQZzlPFcHyYfLABQ3XP85Es4hCdwCkbDeltaUXgVy9l9etKghvM4hRkOvbb01kYVuLFmxIkCDtpi-zLCYAdXKrAK3PtSbtzld_XZ9nlsYa_QZWpXB_IrtFjVfdKUdMz94pHUhFGFj7nr6NNxfpiHSHWFE1zD_AC3mY46J961Y2LRnreVwAGNw53p07Db8yD_92pDa97vqcZOdgtybH9q6uma-RFNhO1AoiJhYZj69hjmMRXx-x56HO9cnXNbmzNSCFCKnQmn4GQLmRj9sfbZRqL94bbtE4_e0Zrpo8RNo8vxRLqQNwIy85fc6BRgBJomt8QdQvIgPgWCv5HoQ',
487
                    'q'   => 'zqOHk1P6WN_rHuM7ZF1cXH0x6RuOHq67WuHiSknqQeefGBA9PWs6ZyKQCO-O6mKXtcgE8_Q_hA2kMRcKOcvHil1hqMCNSXlflM7WPRPZu2qCDcqssd_uMbP-DqYthH_EzwL9KnYoH7JQFxxmcv5An8oXUtTwk4knKjkIYGRuUwfQTus0w1NfjFAyxOOiAQ37ussIcE6C6ZSsM3n41UlbJ7TCqewzVJaPJN5cxjySPZPD3Vp01a9YgAD6a3IIaKJdIxJS1ImnfPevSJQBE79-EXe2kSwVgOzvt-gsmM29QQ8veHy4uAqca5dZzMs7hkkHtw1z0jHV90epQJJlXXnH8Q',
488
                    'dp'  => '19oDkBh1AXelMIxQFm2zZTqUhAzCIr4xNIGEPNoDt1jK83_FJA-xnx5kA7-1erdHdms_Ef67HsONNv5A60JaR7w8LHnDiBGnjdaUmmuO8XAxQJ_ia5mxjxNjS6E2yD44USo2JmHvzeeNczq25elqbTPLhUpGo1IZuG72FZQ5gTjXoTXC2-xtCDEUZfaUNh4IeAipfLugbpe0JAFlFfrTDAMUFpC3iXjxqzbEanflwPvj6V9iDSgjj8SozSM0dLtxvu0LIeIQAeEgT_yXcrKGmpKdSO08kLBx8VUjkbv_3Pn20Gyu2YEuwpFlM_H1NikuxJNKFGmnAq9LcnwwT0jvoQ',
489
                    'dq'  => 'S6p59KrlmzGzaQYQM3o0XfHCGvfqHLYjCO557HYQf72O9kLMCfd_1VBEqeD-1jjwELKDjck8kOBl5UvohK1oDfSP1DleAy-cnmL29DqWmhgwM1ip0CCNmkmsmDSlqkUXDi6sAaZuntyukyflI-qSQ3C_BafPyFaKrt1fgdyEwYa08pESKwwWisy7KnmoUvaJ3SaHmohFS78TJ25cfc10wZ9hQNOrIChZlkiOdFCtxDqdmCqNacnhgE3bZQjGp3n83ODSz9zwJcSUvODlXBPc2AycH6Ci5yjbxt4Ppox_5pjm6xnQkiPgj01GpsUssMmBN7iHVsrE7N2iznBNCeOUIQ',
490
                    'qi'  => 'FZhClBMywVVjnuUud-05qd5CYU0dK79akAgy9oX6RX6I3IIIPckCciRrokxglZn-omAY5CnCe4KdrnjFOT5YUZE7G_Pg44XgCXaarLQf4hl80oPEf6-jJ5Iy6wPRx7G2e8qLxnh9cOdf-kRqgOS3F48Ucvw3ma5V6KGMwQqWFeV31XtZ8l5cVI-I3NzBS7qltpUVgz2Ju021eyc7IlqgzR98qKONl27DuEES0aK0WE97jnsyO27Yp88Wa2RiBrEocM89QZI1seJiGDizHRUP4UZxw9zsXww46wy0P6f9grnYp7t8LkyDDk8eoI4KX6SNMNVcyVS9IWjlq8EzqZEKIA',
491
                ])]),
492
                false
493
            );
494
        }
495
496
        return $this->method;
497
    }
498
499
    /**
500
     * @param \Http\Mock\Client $client
501
     *
502
     * @return JKUFactory
503
     */
504
    private function getJkuFactory(\Http\Mock\Client $client): JKUFactory
505
    {
506
        return new JKUFactory(
507
            new StandardConverter(),
508
            $client,
509
            new DiactorosMessageFactory()
510
        );
511
    }
512
513
    /**
514
     * @return \Http\Mock\Client
515
     */
516
    private function getHttpClient(): \Http\Mock\Client
517
    {
518
        return new \Http\Mock\Client(
519
            new DiactorosMessageFactory()
520
        );
521
    }
522
523
    /**
524
     * @return string
525
     */
526
    private function createValidClientAssertionSignedByTheClient(): string
527
    {
528
        $jsonConverter = new StandardConverter();
529
        $jwsBuilder = new JWSBuilder(
530
            $jsonConverter,
531
            AlgorithmManager::create([
532
                new HS256(),
533
            ])
534
        );
535
536
        $jws = $jwsBuilder
537
            ->create()
538
            ->withPayload($jsonConverter->encode([
539
                'iss' => 'ClientId',
540
                'sub' => 'ClientId',
541
                'aud' => 'My Server',
542
                'exp' => time() + 3600,
543
            ]))
544
            ->addSignature(
545
                JWK::createFromJson('{"kty":"oct","k":"bJzb8RaN7TzPz001PeF0lw0ZoUJqbazGxMvBd_xzfms"}'),
546
                ['alg' => 'HS256']
547
            )
548
            ->build();
549
550
        $serializer = new CompactSerializer($jsonConverter);
551
552
        return $serializer->serialize($jws, 0);
553
    }
554
555
    /**
556
     * @return string
557
     *
558
     * @throws \Exception
559
     */
560
    private function createValidClientAssertionSignedAndEncryptedByTheClient(): string
561
    {
562
        $token = $this->createValidClientAssertionSignedByTheClient();
563
564
        return $this->encryptAssertion($token);
565
    }
566
567
    /**
568
     * @return string
569
     *
570
     * @throws \Exception
571
     */
572
    private function createInvalidClientAssertionSignedByTheClient(): string
573
    {
574
        $jsonConverter = new StandardConverter();
575
        $jwsBuilder = new JWSBuilder(
576
            $jsonConverter,
577
            AlgorithmManager::create([
578
                new HS256(),
579
            ])
580
        );
581
582
        $jws = $jwsBuilder
583
            ->create()
584
            ->withPayload($jsonConverter->encode([]))
585
            ->addSignature(
586
                JWK::createFromJson('{"kty":"oct","k":"bJzb8RaN7TzPz001PeF0lw0ZoUJqbazGxMvBd_xzfms"}'),
587
                ['alg' => 'HS256']
588
            )
589
            ->build();
590
591
        $serializer = new CompactSerializer($jsonConverter);
592
593
        return $serializer->serialize($jws, 0);
594
    }
595
596
    /**
597
     * @return string
598
     *
599
     * @throws \Exception
600
     */
601
    private function createInvalidClientAssertionSignedAndEncryptedByTheClient(): string
602
    {
603
        $token = $this->createInvalidClientAssertionSignedByTheClient();
604
605
        return $this->encryptAssertion($token);
606
    }
607
608
    /**
609
     * @param string $assertion
610
     *
611
     * @return string
612
     *
613
     * @throws \Exception
614
     */
615
    private function encryptAssertion(string $assertion): string
616
    {
617
        $jsonConverter = new StandardConverter();
618
        $jweBuilder = new JWEBuilder(
619
            $jsonConverter,
620
            AlgorithmManager::create([new RSAOAEP256()]),
621
            AlgorithmManager::create([new A256CBCHS512()]),
622
            CompressionMethodManager::create([new Deflate()])
623
        );
624
        $jwe = $jweBuilder->create()
625
            ->withPayload($assertion)
626
            ->withSharedProtectedHeader(['alg' => 'RSA-OAEP-256', 'enc' =>'A256CBC-HS512'])
627
            ->addRecipient(JWK::create([
628
                'kty' => 'RSA',
629
                'kid' => '[email protected]',
630
                'use' => 'enc',
631
                'n'   => 'wbdxI55VaanZXPY29Lg5hdmv2XhvqAhoxUkanfzf2-5zVUxa6prHRrI4pP1AhoqJRlZfYtWWd5mmHRG2pAHIlh0ySJ9wi0BioZBl1XP2e-C-FyXJGcTy0HdKQWlrfhTm42EW7Vv04r4gfao6uxjLGwfpGrZLarohiWCPnkNrg71S2CuNZSQBIPGjXfkmIy2tl_VWgGnL22GplyXj5YlBLdxXp3XeStsqo571utNfoUTU8E4qdzJ3U1DItoVkPGsMwlmmnJiwA7sXRItBCivR4M5qnZtdw-7v4WuR4779ubDuJ5nalMv2S66-RPcnFAzWSKxtBDnFJJDGIUe7Tzizjg1nms0Xq_yPub_UOlWn0ec85FCft1hACpWG8schrOBeNqHBODFskYpUc2LC5JA2TaPF2dA67dg1TTsC_FupfQ2kNGcE1LgprxKHcVWYQb86B-HozjHZcqtauBzFNV5tbTuB-TpkcvJfNcFLlH3b8mb-H_ox35FjqBSAjLKyoeqfKTpVjvXhd09knwgJf6VKq6UC418_TOljMVfFTWXUxlnfhOOnzW6HSSzD1c9WrCuVzsUMv54szidQ9wf1cYWf3g5qFDxDQKis99gcDaiCAwM3yEBIzuNeeCa5dartHDb1xEB_HcHSeYbghbMjGfasvKn0aZRsnTyC0xhWBlsolZE',
632
                'e'   => 'AQAB',
633
                'alg' => 'RSA-OAEP-256',
634
            ]))
635
            ->build();
636
637
        $serializer = new \Jose\Component\Encryption\Serializer\CompactSerializer($jsonConverter);
638
639
        return $serializer->serialize($jwe, 0);
640
    }
641
}
642