Completed
Push — develop ( b5844e...e46df6 )
by Florent
02:33
created

EncrypterTest   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 696
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Importance

Changes 11
Bugs 1 Features 3
Metric Value
wmc 27
c 11
b 1
f 3
lcom 1
cbo 13
dl 0
loc 696
rs 9.7482
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
use Base64Url\Base64Url;
13
use Jose\Factory\DecrypterFactory;
14
use Jose\Factory\EncrypterFactory;
15
use Jose\Factory\JWEFactory;
16
use Jose\Loader;
17
use Jose\Object\JWEInterface;
18
use Jose\Object\JWK;
19
use Jose\Object\JWKSet;
20
use Jose\Test\Stub\FakeLogger;
21
use Jose\Test\TestCase;
22
23
/**
24
 * Class EncrypterTest.
25
 *
26
 * @group Encrypter
27
 * @group Functional
28
 */
29
class EncrypterTest extends TestCase
30
{
31
    public function testEncryptWithJWTInput()
32
    {
33
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
34
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
35
36
        $jwe = JWEFactory::createJWE(
37
            'FOO',
38
            [
39
                'enc' => 'A256CBC-HS512',
40
                'alg' => 'RSA-OAEP-256',
41
                'zip' => 'DEF',
42
            ],
43
            [],
44
            'foo,bar,baz'
45
        );
46
47
        $jwe = $jwe->addRecipient($this->getRSARecipientKey());
48
49
        $encrypter->encrypt($jwe);
50
51
        $encrypted = $jwe->toFlattenedJSON(0);
52
53
        $loaded = Loader::load($encrypted);
54
55
        $this->assertInstanceOf(JWEInterface::class, $loaded);
56
        $this->assertEquals('RSA-OAEP-256', $loaded->getSharedProtectedHeader('alg'));
57
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
58
        $this->assertEquals('DEF', $loaded->getSharedProtectedHeader('zip'));
59
        $this->assertNull($loaded->getPayload());
60
61
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
62
63
        $this->assertEquals(0, $index);
64
        $this->assertEquals('FOO', $loaded->getPayload());
65
    }
66
67
    public function testCreateCompactJWEUsingFactory()
68
    {
69
        $jwe = JWEFactory::createJWEToCompactJSON(
70
            'FOO',
71
            $this->getRSARecipientKey(),
72
            [
73
                'enc' => 'A256CBC-HS512',
74
                'alg' => 'RSA-OAEP-256',
75
                'zip' => 'DEF',
76
            ]
77
        );
78
79
        $loaded = Loader::load($jwe);
80
81
        $this->assertInstanceOf(JWEInterface::class, $loaded);
82
        $this->assertEquals('RSA-OAEP-256', $loaded->getSharedProtectedHeader('alg'));
83
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
84
        $this->assertEquals('DEF', $loaded->getSharedProtectedHeader('zip'));
85
        $this->assertNull($loaded->getPayload());
86
87
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
88
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
89
90
        $this->assertEquals(0, $index);
91
        $this->assertEquals('FOO', $loaded->getPayload());
92
    }
93
94
    public function testCreateFlattenedJWEUsingFactory()
95
    {
96
        $jwe = JWEFactory::createJWEToFlattenedJSON(
97
            'FOO',
98
            $this->getRSARecipientKey(),
99
            [
100
                'enc' => 'A256CBC-HS512',
101
                'alg' => 'RSA-OAEP-256',
102
                'zip' => 'DEF',
103
            ],
104
            [
105
                'foo' => 'bar',
106
            ],
107
            [
108
                'plic' => 'ploc',
109
            ],
110
            'A,B,C,D'
111
        );
112
113
        $loaded = Loader::load($jwe);
114
115
        $this->assertInstanceOf(JWEInterface::class, $loaded);
116
        $this->assertEquals('RSA-OAEP-256', $loaded->getSharedProtectedHeader('alg'));
117
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
118
        $this->assertEquals('DEF', $loaded->getSharedProtectedHeader('zip'));
119
        $this->assertEquals('bar', $loaded->getSharedHeader('foo'));
120
        $this->assertEquals('A,B,C,D', $loaded->getAAD('foo'));
121
        $this->assertEquals('ploc', $loaded->getRecipient(0)->getHeader('plic'));
122
        $this->assertNull($loaded->getPayload());
123
124
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
125
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
126
127
        $this->assertEquals(0, $index);
128
        $this->assertEquals('FOO', $loaded->getPayload());
129
    }
130
131
    public function testEncryptAndLoadFlattenedWithAAD()
132
    {
133
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
134
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
135
136
        $jwe = JWEFactory::createJWE(
137
            $this->getKeyToEncrypt(),
138
            [
139
                'enc' => 'A256CBC-HS512',
140
                'alg' => 'RSA-OAEP-256',
141
                'zip' => 'DEF',
142
            ],
143
            [],
144
            'foo,bar,baz'
145
        );
146
147
        $jwe = $jwe->addRecipient($this->getRSARecipientKey());
148
149
        $encrypter->encrypt($jwe);
150
151
        $encrypted = $jwe->toFlattenedJSON(0);
152
153
        $loaded = Loader::load($encrypted);
154
155
        $this->assertInstanceOf(JWEInterface::class, $loaded);
156
        $this->assertEquals('RSA-OAEP-256', $loaded->getSharedProtectedHeader('alg'));
157
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
158
        $this->assertEquals('DEF', $loaded->getSharedProtectedHeader('zip'));
159
        $this->assertNull($loaded->getPayload());
160
161
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
162
163
        $this->assertEquals(0, $index);
164
        $this->assertTrue(is_array($loaded->getPayload()));
165
        $this->assertEquals($this->getKeyToEncrypt(), new JWK($loaded->getPayload()));
166
    }
167
168
    /**
169
     * @expectedException \InvalidArgumentException
170
     * @expectedExceptionMessage Compression method "FIP" not supported
171
     */
172
    public function testCompressionAlgorithmNotSupported()
173
    {
174
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
175
176
        $jwe = JWEFactory::createJWE(
177
            $this->getKeyToEncrypt(),
178
            [
179
                'enc' => 'A256CBC-HS512',
180
                'alg' => 'RSA-OAEP-256',
181
                'zip' => 'FIP',
182
            ],
183
            [],
184
            'foo,bar,baz'
185
        );
186
187
        $jwe = $jwe->addRecipient($this->getRSARecipientKey());
188
189
        $encrypter->encrypt($jwe);
190
    }
191
192
    public function testMultipleInstructionsNotAllowedWithCompactSerialization()
193
    {
194
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP', 'RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
195
196
        $jwe = JWEFactory::createJWE('Live long and Prosper.');
197
        $jwe = $jwe->withSharedProtectedHeaders([
198
            'enc' => 'A256CBC-HS512',
199
        ]);
200
201
        $jwe = $jwe->addRecipient($this->getRSARecipientKeyWithAlgorithm(), ['alg' => 'RSA-OAEP']);
202
        $jwe = $jwe->addRecipient($this->getRSARecipientKey(), ['alg' => 'RSA-OAEP-256']);
203
204
        $encrypter->encrypt($jwe);
205
206
        $this->assertEquals(2, $jwe->countRecipients());
207
    }
208
209
    public function testMultipleInstructionsNotAllowedWithFlattenedSerialization()
210
    {
211
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
212
213
        $jwe = JWEFactory::createJWE('Live long and Prosper.');
214
        $jwe = $jwe->withSharedProtectedHeaders([
215
            'enc' => 'A256CBC-HS512',
216
        ]);
217
218
        $jwe = $jwe->addRecipient(
219
            $this->getECDHRecipientPublicKey(),
220
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'alg' => 'ECDH-ES+A256KW']
221
        );
222
        $jwe = $jwe->addRecipient(
223
            $this->getRSARecipientKey(),
224
            ['kid' => '123456789', 'alg' => 'RSA-OAEP-256']
225
        );
226
227
        $encrypter->encrypt($jwe);
228
229
        $this->assertEquals(2, $jwe->countRecipients());
230
    }
231
232
    /**
233
     * @expectedException \InvalidArgumentException
234
     * @expectedExceptionMessage Foreign key management mode forbidden.
235
     */
236
    public function testForeignKeyManagementModeForbidden()
237
    {
238
        $encrypter = EncrypterFactory::createEncrypter(['dir', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
239
240
        $jwe = JWEFactory::createJWE('Live long and Prosper.');
241
        $jwe = $jwe->withSharedProtectedHeaders([
242
            'enc' => 'A256CBC-HS512',
243
        ]);
244
245
        $jwe = $jwe->addRecipient(
246
            $this->getECDHRecipientPublicKey(),
247
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'alg' => 'ECDH-ES+A256KW']
248
        );
249
        $jwe = $jwe->addRecipient(
250
            $this->getDirectKey(),
251
            ['kid' => 'DIR_1', 'alg' => 'dir']
252
        );
253
254
        $encrypter->encrypt($jwe);
255
    }
256
257
    /**
258
     * @expectedException \InvalidArgumentException
259
     * @expectedExceptionMessage Key cannot be used to encrypt
260
     */
261
    public function testOperationNotAllowedForTheKey()
262
    {
263
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
264
265
        $jwe = JWEFactory::createJWE(
266
            'Foo',
267
            [
268
                'enc' => 'A256CBC-HS512',
269
                'alg' => 'RSA-OAEP-256',
270
                'zip' => 'DEF',
271
            ],
272
            [],
273
            'foo,bar,baz'
274
        );
275
        $jwe = $jwe->addRecipient(
276
            $this->getSigningKey()
277
        );
278
279
        $encrypter->encrypt($jwe);
280
    }
281
282
    /**
283
     * @expectedException \InvalidArgumentException
284
     * @expectedExceptionMessage Key is only allowed for algorithm "RSA-OAEP".
285
     */
286
    public function testAlgorithmNotAllowedForTheKey()
287
    {
288
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
289
290
        $jwe = JWEFactory::createJWE(
291
            'FOO',
292
            [
293
                'enc' => 'A256CBC-HS512',
294
                'alg' => 'RSA-OAEP-256',
295
                'zip' => 'DEF',
296
            ],
297
            [],
298
            'foo,bar,baz'
299
        );
300
        $jwe = $jwe->addRecipient(
301
            $this->getRSARecipientKeyWithAlgorithm()
302
        );
303
304
        $encrypter->encrypt($jwe);
305
    }
306
307
    public function testEncryptAndLoadFlattenedWithDeflateCompression()
308
    {
309
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A128CBC-HS256'], ['DEF'], new FakeLogger());
310
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'A128CBC-HS256'], ['DEF'], new FakeLogger());
311
312
        $jwe = JWEFactory::createJWE($this->getKeyToEncrypt());
313
        $jwe = $jwe->withSharedProtectedHeaders([
314
            'kid' => '123456789',
315
            'enc' => 'A128CBC-HS256',
316
            'alg' => 'RSA-OAEP-256',
317
            'zip' => 'DEF',
318
        ]);
319
        $jwe = $jwe->addRecipient(
320
            $this->getRSARecipientKey()
321
        );
322
323
        $encrypter->encrypt($jwe);
324
325
        $encrypted = $jwe->toCompactJSON(0);
326
327
        $loaded = Loader::load($encrypted);
328
329
        $this->assertInstanceOf(JWEInterface::class, $loaded);
330
        $this->assertEquals('RSA-OAEP-256', $loaded->getSharedProtectedHeader('alg'));
331
        $this->assertEquals('A128CBC-HS256', $loaded->getSharedProtectedHeader('enc'));
332
        $this->assertEquals('DEF', $loaded->getSharedProtectedHeader('zip'));
333
        $this->assertNull($loaded->getPayload());
334
335
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
336
337
        $this->assertEquals(0, $index);
338
        $this->assertTrue(is_array($loaded->getPayload()));
339
        $this->assertEquals($this->getKeySetToEncrypt(), new JWKSet($loaded->getPayload()));
340
    }
341
342
    /**
343
     * @expectedException \InvalidArgumentException
344
     * @expectedExceptionMessage Parameter "alg" is missing.
345
     */
346
    public function testAlgParameterIsMissing()
347
    {
348
        $encrypter = EncrypterFactory::createEncrypter(['A256CBC-HS512'], ['DEF'], new FakeLogger());
349
350
        $jwe = JWEFactory::createJWE($this->getKeyToEncrypt());
351
        $jwe = $jwe->withSharedProtectedHeaders([
352
            'kid' => '123456789',
353
            'enc' => 'A256CBC-HS512',
354
            'zip' => 'DEF',
355
        ]);
356
        $jwe = $jwe->addRecipient(
357
            $this->getRSARecipientKey()
358
        );
359
360
        $encrypter->encrypt($jwe);
361
    }
362
363
    /**
364
     * @expectedException \InvalidArgumentException
365
     * @expectedExceptionMessage Parameter "enc" is missing.
366
     */
367
    public function testEncParameterIsMissing()
368
    {
369
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256'], ['DEF'], new FakeLogger());
370
371
        $jwe = JWEFactory::createJWE($this->getKeyToEncrypt());
372
        $jwe = $jwe->withSharedProtectedHeaders([
373
            'kid' => '123456789',
374
            'alg' => 'RSA-OAEP-256',
375
            'zip' => 'DEF',
376
        ]);
377
        $jwe = $jwe->addRecipient(
378
            $this->getRSARecipientKey()
379
        );
380
381
        $encrypter->encrypt($jwe);
382
    }
383
384
    /**
385
     * @expectedException \InvalidArgumentException
386
     * @expectedExceptionMessage The key encryption algorithm "A256CBC-HS512" is not supported or not a key encryption algorithm instance.
387
     */
388
    public function testNotAKeyEncryptionAlgorithm()
389
    {
390
        $encrypter = EncrypterFactory::createEncrypter(['A256CBC-HS512'], ['DEF'], new FakeLogger());
391
392
        $jwe = JWEFactory::createJWE($this->getKeyToEncrypt());
393
        $jwe = $jwe->withSharedProtectedHeaders([
394
            'kid' => '123456789',
395
            'enc' => 'A256CBC-HS512',
396
            'alg' => 'A256CBC-HS512',
397
            'zip' => 'DEF',
398
        ]);
399
        $jwe = $jwe->addRecipient(
400
            $this->getRSARecipientKey()
401
        );
402
403
        $encrypter->encrypt($jwe);
404
    }
405
406
    /**
407
     * @expectedException \InvalidArgumentException
408
     * @expectedExceptionMessage The content encryption algorithm "RSA-OAEP-256" is not supported or not a content encryption algorithm instance.
409
     */
410
    public function testNotAContentEncryptionAlgorithm()
411
    {
412
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256'], ['DEF'], new FakeLogger());
413
414
        $jwe = JWEFactory::createJWE($this->getKeyToEncrypt());
415
        $jwe = $jwe->withSharedProtectedHeaders([
416
            'kid' => '123456789',
417
            'enc' => 'RSA-OAEP-256',
418
            'alg' => 'RSA-OAEP-256',
419
            'zip' => 'DEF',
420
        ]);
421
422
        $jwe = $jwe->addRecipient(
423
            $this->getRSARecipientKey()
424
        );
425
426
        $encrypter->encrypt($jwe);
427
    }
428
429
    public function testEncryptAndLoadCompactWithDirectKeyEncryption()
430
    {
431
        $encrypter = EncrypterFactory::createEncrypter(['dir', 'A192CBC-HS384'], ['DEF'], new FakeLogger());
432
        $decrypter = DecrypterFactory::createDecrypter(['dir', 'A192CBC-HS384'], ['DEF'], new FakeLogger());
433
434
        $jwe = JWEFactory::createJWE($this->getKeyToEncrypt());
435
        $jwe = $jwe->withSharedProtectedHeaders([
436
            'kid' => 'DIR_1',
437
            'enc' => 'A192CBC-HS384',
438
            'alg' => 'dir',
439
        ]);
440
441
        $jwe = $jwe->addRecipient(
442
            $this->getDirectKey()
443
        );
444
445
        $encrypter->encrypt($jwe);
446
447
        $encrypted = $jwe->toFlattenedJSON(0);
448
449
        $loaded = Loader::load($encrypted);
450
451
        $this->assertInstanceOf(JWEInterface::class, $loaded);
452
        $this->assertEquals('dir', $loaded->getSharedProtectedHeader('alg'));
453
        $this->assertEquals('A192CBC-HS384', $loaded->getSharedProtectedHeader('enc'));
454
        $this->assertFalse($loaded->hasSharedHeader('zip'));
455
        $this->assertNull($loaded->getPayload());
456
457
        $decrypter->decryptUsingKeySet($loaded, $this->getSymmetricKeySet(), $index);
458
459
        $this->assertEquals(0, $index);
460
        $this->assertTrue(is_array($loaded->getPayload()));
461
        $this->assertEquals($this->getKeySetToEncrypt(), new JWKSet($loaded->getPayload()));
462
    }
463
464
    public function testEncryptAndLoadCompactKeyAgreement()
465
    {
466
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES', 'A192CBC-HS384'], ['DEF'], new FakeLogger());
467
        $decrypter = DecrypterFactory::createDecrypter(['ECDH-ES', 'A192CBC-HS384'], ['DEF'], new FakeLogger());
468
469
        $jwe = JWEFactory::createJWE(['user_id' => '1234', 'exp' => time() + 3600]);
470
        $jwe = $jwe->withSharedProtectedHeaders([
471
            'kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d',
472
            'enc' => 'A192CBC-HS384',
473
            'alg' => 'ECDH-ES',
474
        ]);
475
476
        $jwe = $jwe->addRecipient(
477
            $this->getECDHRecipientPublicKey()
478
        );
479
480
        $encrypter->encrypt($jwe);
481
482
        $loaded = Loader::load($jwe->toFlattenedJSON(0));
483
484
        $this->assertInstanceOf(JWEInterface::class, $loaded);
485
        $this->assertEquals('ECDH-ES', $loaded->getSharedProtectedHeader('alg'));
486
        $this->assertEquals('A192CBC-HS384', $loaded->getSharedProtectedHeader('enc'));
487
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
488
        $this->assertNull($loaded->getPayload());
489
490
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
491
492
        $this->assertEquals(0, $index);
493
        $this->assertTrue($loaded->hasClaims());
494
        $this->assertTrue($loaded->hasClaim('user_id'));
495
        $this->assertEquals('1234', $loaded->getClaim('user_id'));
496
    }
497
498
    public function testEncryptAndLoadCompactKeyAgreementWithWrappingCompact()
499
    {
500
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
501
        $decrypter = DecrypterFactory::createDecrypter(['ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
502
503
        $jwe = JWEFactory::createJWE('Live long and Prosper.');
504
        $jwe = $jwe->withSharedProtectedHeaders([
505
            'kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d',
506
            'enc' => 'A256CBC-HS512',
507
            'alg' => 'ECDH-ES+A256KW',
508
        ]);
509
510
        $jwe = $jwe->addRecipient(
511
            $this->getECDHRecipientPublicKey()
512
        );
513
514
        $encrypter->encrypt($jwe);
515
516
        $loaded = Loader::load($jwe->toFlattenedJSON(0));
517
518
        $this->assertInstanceOf(JWEInterface::class, $loaded);
519
        $this->assertEquals('ECDH-ES+A256KW', $loaded->getSharedProtectedHeader('alg'));
520
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
521
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
522
        $this->assertFalse($loaded->hasSharedHeader('zip'));
523
        $this->assertNull($loaded->getPayload());
524
525
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
526
527
        $this->assertEquals(0, $index);
528
        $this->assertTrue(is_string($loaded->getPayload()));
529
        $this->assertEquals('Live long and Prosper.', $loaded->getPayload());
530
    }
531
532
    public function testEncryptAndLoadWithGCMAndAAD()
533
    {
534
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES+A256KW', 'A256GCM'], ['DEF'], new FakeLogger());
535
536
        $jwe = JWEFactory::createJWE(
537
            'Live long and Prosper.',
538
            [
539
                'kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d',
540
                'enc' => 'A256GCM',
541
                'alg' => 'ECDH-ES+A256KW',
542
            ],
543
            [],
544
            'foo,bar,baz'
545
        );
546
547
        $jwe = $jwe->addRecipient(
548
            $this->getECDHRecipientPublicKey()
549
        );
550
551
        $encrypter->encrypt($jwe);
552
553
        $loaded = Loader::load($jwe->toFlattenedJSON(0));
554
555
        $decrypter = DecrypterFactory::createDecrypter(['A256GCM', 'ECDH-ES+A256KW'], ['DEF'], new FakeLogger());
556
557
        $this->assertInstanceOf(JWEInterface::class, $loaded);
558
        $this->assertEquals('ECDH-ES+A256KW', $loaded->getSharedProtectedHeader('alg'));
559
        $this->assertEquals('A256GCM', $loaded->getSharedProtectedHeader('enc'));
560
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
561
        $this->assertFalse($loaded->hasSharedHeader('zip'));
562
        $this->assertNull($loaded->getPayload());
563
564
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
565
566
        $this->assertEquals(0, $index);
567
        $this->assertTrue(is_string($loaded->getPayload()));
568
        $this->assertEquals('Live long and Prosper.', $loaded->getPayload());
569
    }
570
571
    public function testEncryptAndLoadCompactKeyAgreementWithWrapping()
572
    {
573
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
574
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], new FakeLogger());
575
576
        $jwe = JWEFactory::createJWE('Live long and Prosper.');
577
        $jwe = $jwe->withSharedProtectedHeaders(['enc' => 'A256CBC-HS512']);
578
579
        $jwe = $jwe->addRecipient(
580
            $this->getECDHRecipientPublicKey(),
581
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'alg' => 'ECDH-ES+A256KW']
582
        );
583
        $jwe = $jwe->addRecipient(
584
            $this->getRSARecipientKey(),
585
            ['kid' => '123456789', 'alg' => 'RSA-OAEP-256']
586
        );
587
588
        $encrypter->encrypt($jwe);
589
590
        $loaded = Loader::load($jwe->toJSON());
591
592
        $this->assertEquals(2, $loaded->countRecipients());
593
594
        $this->assertInstanceOf(JWEInterface::class, $loaded);
595
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
596
        $this->assertEquals('ECDH-ES+A256KW', $loaded->getRecipient(0)->getHeader('alg'));
597
        $this->assertEquals('RSA-OAEP-256', $loaded->getRecipient(1)->getHeader('alg'));
598
        $this->assertFalse($loaded->hasSharedHeader('zip'));
599
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
600
        $this->assertNull($loaded->getPayload());
601
602
        $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet(), $index);
603
604
        $this->assertEquals(0, $index);
605
        $this->assertTrue(is_string($loaded->getPayload()));
606
        $this->assertEquals('Live long and Prosper.', $loaded->getPayload());
607
    }
608
609
    /**
610
     * @return JWK
611
     */
612
    private function getKeyToEncrypt()
613
    {
614
        $key = new JWK([
615
            'kty' => 'EC',
616
            'use' => 'enc',
617
            'crv' => 'P-256',
618
            'x'   => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
619
            'y'   => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
620
            'd'   => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
621
        ]);
622
623
        return $key;
624
    }
625
626
    /**
627
     * @return JWKSet
628
     */
629
    private function getKeySetToEncrypt()
630
    {
631
        $key = new JWK([
632
            'kty' => 'EC',
633
            'use' => 'enc',
634
            'crv' => 'P-256',
635
            'x'   => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
636
            'y'   => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
637
            'd'   => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
638
        ]);
639
640
        $key_set = new JWKSet();
641
        $key_set->addKey($key);
642
643
        return $key_set;
644
    }
645
646
    /**
647
     * @return JWK
648
     */
649
    private function getRSARecipientKey()
650
    {
651
        $key = new JWK([
652
            'kty' => 'RSA',
653
            'use' => 'enc',
654
            'n'   => 'tpS1ZmfVKVP5KofIhMBP0tSWc4qlh6fm2lrZSkuKxUjEaWjzZSzs72gEIGxraWusMdoRuV54xsWRyf5KeZT0S-I5Prle3Idi3gICiO4NwvMk6JwSBcJWwmSLFEKyUSnB2CtfiGc0_5rQCpcEt_Dn5iM-BNn7fqpoLIbks8rXKUIj8-qMVqkTXsEKeKinE23t1ykMldsNaaOH-hvGti5Jt2DMnH1JjoXdDXfxvSP_0gjUYb0ektudYFXoA6wekmQyJeImvgx4Myz1I4iHtkY_Cp7J4Mn1ejZ6HNmyvoTE_4OuY1uCeYv4UyXFc1s1uUyYtj4z57qsHGsS4dQ3A2MJsw',
655
            'e'   => 'AQAB',
656
        ]);
657
658
        return $key;
659
    }
660
661
    /**
662
     * @return JWK
663
     */
664
    private function getRSARecipientKeyWithAlgorithm()
665
    {
666
        $key = new JWK([
667
            'kty' => 'RSA',
668
            'use' => 'enc',
669
            'alg' => 'RSA-OAEP',
670
            'n'   => 'tpS1ZmfVKVP5KofIhMBP0tSWc4qlh6fm2lrZSkuKxUjEaWjzZSzs72gEIGxraWusMdoRuV54xsWRyf5KeZT0S-I5Prle3Idi3gICiO4NwvMk6JwSBcJWwmSLFEKyUSnB2CtfiGc0_5rQCpcEt_Dn5iM-BNn7fqpoLIbks8rXKUIj8-qMVqkTXsEKeKinE23t1ykMldsNaaOH-hvGti5Jt2DMnH1JjoXdDXfxvSP_0gjUYb0ektudYFXoA6wekmQyJeImvgx4Myz1I4iHtkY_Cp7J4Mn1ejZ6HNmyvoTE_4OuY1uCeYv4UyXFc1s1uUyYtj4z57qsHGsS4dQ3A2MJsw',
671
            'e'   => 'AQAB',
672
        ]);
673
674
        return $key;
675
    }
676
677
    /**
678
     * @return JWK
679
     */
680
    private function getSigningKey()
681
    {
682
        $key = new JWK([
683
            'kty'     => 'EC',
684
            'key_ops' => ['sign', 'verify'],
685
            'crv'     => 'P-256',
686
            'x'       => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
687
            'y'       => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
688
            'd'       => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
689
        ]);
690
691
        return $key;
692
    }
693
694
    /**
695
     * @return JWK
696
     */
697
    private function getECDHRecipientPublicKey()
698
    {
699
        $key = new JWK([
700
            'kty'     => 'EC',
701
            'key_ops' => ['encrypt', 'decrypt'],
702
            'crv'     => 'P-256',
703
            'x'       => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
704
            'y'       => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
705
        ]);
706
707
        return $key;
708
    }
709
710
    /**
711
     * @return JWK
712
     */
713
    private function getDirectKey()
714
    {
715
        $key = new JWK([
716
            'kid'     => 'DIR_1',
717
            'key_ops' => ['encrypt', 'decrypt'],
718
            'kty'     => 'oct',
719
            'k'       => Base64Url::encode(hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F')),
720
        ]);
721
722
        return $key;
723
    }
724
}
725