Completed
Push — v2.0.x ( 11273c...f488cd )
by Florent
04:53 queued 01:28
created

EncrypterTest   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 725
Duplicated Lines 0 %

Coupling/Cohesion

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