Completed
Push — v2.0.x ( 255948...c24837 )
by Florent
03:51
created

EncrypterTest   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 788
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 12
Metric Value
wmc 32
lcom 1
cbo 12
dl 0
loc 788
rs 9.6

31 Methods

Rating   Name   Duplication   Size   Complexity  
B testEncryptWithJWTInput() 0 32 1
B testEncryptAndLoadFlattenedWithAAD() 0 33 1
A testCompressionAlgorithmNotSupported() 0 16 1
B testMultipleInstructionsNotAllowedWithCompactSerialization() 0 28 1
B testMultipleInstructionsNotAllowedWithFlattenedSerialization() 0 29 1
B testMultipleInstructionsNotAllowedWithFlattenedSerialization2() 0 26 1
A testOperationNotAllowedForTheKey() 0 16 1
A testAlgorithmNotAllowedForTheKey() 0 16 1
B testEncryptAndLoadFlattenedWithDeflateCompression() 0 35 1
A testAlgParameterIsMissing() 0 14 1
A testEncParameterIsMissing() 0 14 1
A testNotAKeyEncryptionAlgorithm() 0 14 1
A testNotAContentEncryptionAlgorithm() 0 14 1
B testEncryptAndLoadCompactWithDirectKeyEncryption() 0 29 1
B testEncryptAndLoadCompactKeyAgreement() 0 33 1
A testEncryptWithAgreementAlgorithm() 0 16 1
A testEncryptWithAgreementKeyWrapAlgorithm() 0 14 1
A testNoInstruction() 0 12 1
B testEncryptAndLoadCompactKeyAgreementWithWrappingCompact() 0 32 1
B testEncryptAndLoadCompactKeyAgreementWithWrappingFlattened() 0 32 1
B testEncryptAndLoadWithGCMAndAAD() 0 38 2
A testEncryptAndLoadCompactKeyAgreementWithWrapping() 0 56 1
A getKeyToEncrypt() 0 13 1
A getKeySetToEncrypt() 0 16 1
A getRSARecipientKey() 0 11 1
A getRSARecipientKeyWithAlgorithm() 0 12 1
A getSigningKey() 0 13 1
A getECDHRecipientPublicKey() 0 12 1
A getECDHSenderPrivateKey() 0 13 1
A getDirectKey() 0 11 1
A isCryptooExtensionInstalled() 0 4 1
1
<?php
2
3
/*
4
 * The MIT License (MIT)
5
 *
6
 * Copyright (c) 2014-2016 Spomky-Labs
7
 *
8
 * This software may be modified and distributed under the terms
9
 * of the MIT license.  See the LICENSE file for details.
10
 */
11
12
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'));
0 ignored issues
show
Bug introduced by
The method getSharedProtectedHeader does only exist in Jose\Object\JWE, but not in Jose\Object\JWS.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
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());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 50 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
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'));
0 ignored issues
show
Bug introduced by
The method getSharedProtectedHeader does only exist in Jose\Object\JWE, but not in Jose\Object\JWS.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
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());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 86 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
95
96
        $this->assertTrue($result);
97
        $this->assertEquals($this->getKeyToEncrypt(), $loaded->getPayload());
98
        $this->assertInstanceOf('Jose\Object\JWKInterface', $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
        $this->markTestIncomplete('Should be OK now');
128
129
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP', 'A256CBC-HS512'], ['DEF' => 0]);
130
131
        $instruction1 = new EncryptionInstruction(
132
            $this->getRSARecipientKeyWithAlgorithm()
133
        );
134
135
        $instruction2 = new EncryptionInstruction(
136
            $this->getRSARecipientKey()
137
        );
138
139
        $result = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
140
            'Je suis Charlie',
141
            [$instruction1, $instruction2],
142
            JSONSerializationModes::JSON_COMPACT_SERIALIZATION,
143
            [
144
                'enc' => 'A256CBC-HS512',
145
                'alg' => 'RSA-OAEP',
146
            ],
147
            []
148
        );
149
150
        $this->assertTrue(is_array($result));
151
        $this->assertEquals(2, count($result));
152
    }
153
154
    /**
155
     *
156
     */
157
    public function testMultipleInstructionsNotAllowedWithFlattenedSerialization()
158
    {
159
        $this->markTestIncomplete('Should be OK now');
160
161
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF' => 0]);
162
163
        $instruction1 = new EncryptionInstruction(
164
            $this->getECDHRecipientPublicKey(),
165
            $this->getECDHSenderPrivateKey(),
166
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'alg' => 'ECDH-ES+A256KW']
167
        );
168
169
        $instruction2 = new EncryptionInstruction(
170
            $this->getRSARecipientKey(),
171
            null,
172
            ['kid' => '123456789', 'alg' => 'RSA-OAEP-256']
173
        );
174
175
        $result = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
176
            'Je suis Charlie',
177
            [$instruction1, $instruction2],
178
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
179
            ['enc' => 'A256CBC-HS512'],
180
            []
181
        );
182
183
        $this->assertTrue(is_array($result));
184
        $this->assertEquals(2, count($result));
185
    }
186
187
    /**
188
     * @expectedException \RuntimeException
189
     * @expectedExceptionMessage Foreign key management mode forbidden.
190
     */
191
    public function testMultipleInstructionsNotAllowedWithFlattenedSerialization2()
192
    {
193
        $this->markTestIncomplete('Should be OK now');
194
195
        $encrypter = EncrypterFactory::createEncrypter(['dir', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF' => 0]);
196
197
        $instruction1 = new EncryptionInstruction(
198
            $this->getECDHRecipientPublicKey(),
199
            $this->getECDHSenderPrivateKey(),
200
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'alg' => 'ECDH-ES+A256KW']
201
        );
202
203
        $instruction2 = new EncryptionInstruction(
204
            $this->getDirectKey(),
205
            null,
206
            ['kid' => 'DIR_1', 'alg' => 'dir']
207
        );
208
209
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
210
            'Je suis Charlie',
211
            [$instruction1, $instruction2],
212
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
213
            ['enc' => 'A256CBC-HS512'],
214
            []
215
        );
216
    }
217
218
    /**
219
     * @expectedException \InvalidArgumentException
220
     * @expectedExceptionMessage Key cannot be used to encrypt
221
     */
222
    public function testOperationNotAllowedForTheKey()
223
    {
224
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF' => 0]);
225
226
        $jwe = JWEFactory::createJWE('Foo', 'foo,bar,baz');
227
        $jwe = $jwe->withSharedProtectedHeaders([
228
            'enc' => 'A256CBC-HS512',
229
            'alg' => 'RSA-OAEP-256',
230
            'zip' => 'DEF'
231
        ]);
232
233
        $encrypter->addRecipient(
234
            $jwe,
235
            $this->getSigningKey()
236
        );
237
    }
238
239
    /**
240
     * @expectedException \InvalidArgumentException
241
     * @expectedExceptionMessage Key is only allowed for algorithm "RSA-OAEP".
242
     */
243
    public function testAlgorithmNotAllowedForTheKey()
244
    {
245
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A256CBC-HS512'], ['DEF' => 0]);
246
247
        $jwe = JWEFactory::createJWE('FOO', 'foo,bar,baz');
248
        $jwe = $jwe->withSharedProtectedHeaders([
249
            'enc' => 'A256CBC-HS512',
250
            'alg' => 'RSA-OAEP-256',
251
            'zip' => 'DEF'
252
        ]);
253
254
        $encrypter->addRecipient(
255
            $jwe,
256
            $this->getRSARecipientKeyWithAlgorithm()
257
        );
258
    }
259
260
    /**
261
     *
262
     */
263
    public function testEncryptAndLoadFlattenedWithDeflateCompression()
264
    {
265
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'A128CBC-HS256'], ['DEF' => 0]);
266
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'A128CBC-HS256'], ['DEF'], $this->getCheckers());
267
268
        $jwe = JWEFactory::createJWE($this->getKeyToEncrypt());
269
        $jwe = $jwe->withSharedProtectedHeaders([
270
            'kid' => '123456789',
271
            'enc' => 'A256CBC-HS512',
272
            'alg' => 'RSA-OAEP-256',
273
            'zip' => 'DEF'
274
        ]);
275
276
        $jwe = $encrypter->addRecipient(
277
            $jwe,
278
            $this->getRSARecipientKey()
279
        );
280
281
        $encrypted = $jwe->toFlattenedJSON(0);
282
283
        $loaded = Loader::load($encrypted);
284
285
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded);
286
        $this->assertEquals('RSA-OAEP-256', $loaded->getSharedProtectedHeader('alg'));
0 ignored issues
show
Bug introduced by
The method getSharedProtectedHeader does only exist in Jose\Object\JWE, but not in Jose\Object\JWS.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
287
        $this->assertEquals('A128CBC-HS256', $loaded->getSharedProtectedHeader('enc'));
288
        $this->assertEquals('DEF', $loaded->getSharedProtectedHeader('zip'));
289
        $this->assertNull($loaded->getPayload());
290
291
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 283 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
292
293
        $this->assertTrue($result);
294
        $this->assertEquals($this->getKeyToEncrypt(), $loaded->getPayload());
295
        $this->assertEquals($encrypted, $loaded->getInput());
0 ignored issues
show
Bug introduced by
The method getInput() does not seem to exist on object<Jose\Object\JWEInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
296
        $this->assertInstanceOf('Jose\Object\JWKInterface', $loaded->getPayload());
297
    }
298
299
    /**
300
     * @expectedException \InvalidArgumentException
301
     * @expectedExceptionMessage Parameter "alg" is missing.
302
     */
303
    public function testAlgParameterIsMissing()
304
    {
305
        $encrypter = EncrypterFactory::createEncrypter(['A128CBC-HS256'], ['DEF' => 0]);
306
307
        $instruction = new EncryptionInstruction($this->getRSARecipientKey());
308
309
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
310
            $this->getKeyToEncrypt(),
311
            [$instruction],
312
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
313
            ['kid' => '123456789', 'enc' => 'A128CBC-HS256', 'zip' => 'DEF'],
314
            []
315
        );
316
    }
317
318
    /**
319
     * @expectedException \InvalidArgumentException
320
     * @expectedExceptionMessage Parameter "enc" is missing.
321
     */
322
    public function testEncParameterIsMissing()
323
    {
324
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256'], ['DEF' => 0]);
325
326
        $instruction = new EncryptionInstruction($this->getRSARecipientKey());
327
328
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
329
            $this->getKeyToEncrypt(),
330
            [$instruction],
331
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
332
            ['kid' => '123456789', 'alg' => 'RSA-OAEP-256', 'zip' => 'DEF'],
333
            []
334
        );
335
    }
336
337
    /**
338
     * @expectedException \RuntimeException
339
     * @expectedExceptionMessage The key encryption algorithm "A128CBC-HS256" is not supported or not a key encryption algorithm instance.
340
     */
341
    public function testNotAKeyEncryptionAlgorithm()
342
    {
343
        $encrypter = EncrypterFactory::createEncrypter(['A128CBC-HS256'], ['DEF' => 0]);
344
345
        $instruction = new EncryptionInstruction($this->getRSARecipientKey());
346
347
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
348
            $this->getKeyToEncrypt(),
349
            [$instruction],
350
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
351
            ['kid' => '123456789', 'alg' => 'A128CBC-HS256', 'enc' => 'A128CBC-HS256', 'zip' => 'DEF'],
352
            []
353
        );
354
    }
355
356
    /**
357
     * @expectedException \RuntimeException
358
     * @expectedExceptionMessage The algorithm "RSA-OAEP-256" is not enabled or does not implement ContentEncryptionInterface.
359
     */
360
    public function testNotAContentEncryptionAlgorithm()
361
    {
362
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256'], ['DEF' => 0]);
363
364
        $instruction = new EncryptionInstruction($this->getRSARecipientKey());
365
366
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
367
            $this->getKeyToEncrypt(),
368
            [$instruction],
369
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
370
            ['kid' => '123456789', 'alg' => 'RSA-OAEP-256', 'enc' => 'RSA-OAEP-256', 'zip' => 'DEF'],
371
            []
372
        );
373
    }
374
375
    /**
376
     *
377
     */
378
    public function testEncryptAndLoadCompactWithDirectKeyEncryption()
379
    {
380
        $encrypter = EncrypterFactory::createEncrypter(['dir', 'A192CBC-HS384'], ['DEF' => 0]);
381
        $decrypter = DecrypterFactory::createDecrypter(['dir', 'A192CBC-HS384'], ['DEF'], $this->getCheckers());
382
383
        $instruction = new EncryptionInstruction($this->getDirectKey());
384
385
        $encrypted = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
386
            $this->getKeySetToEncrypt(),
387
            [$instruction],
388
            JSONSerializationModes::JSON_COMPACT_SERIALIZATION,
389
            ['kid' => 'DIR_1', 'enc' => 'A192CBC-HS384', 'alg' => 'dir'],
390
            []
391
        );
392
393
        $loaded = Loader::load($encrypted);
394
395
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded);
396
        $this->assertEquals('dir', $loaded->getHeader('alg'));
397
        $this->assertEquals('A192CBC-HS384', $loaded->getHeader('enc'));
398
        $this->assertFalse($loaded->hasHeader('zip'));
399
        $this->assertNull($loaded->getPayload());
400
401
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getSymmetricKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 393 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
402
403
        $this->assertTrue($result);
404
        $this->assertEquals($this->getKeySetToEncrypt(), $loaded->getPayload());
405
        $this->assertInstanceOf('Jose\Object\JWKSetInterface', $loaded->getPayload());
406
    }
407
408
    /**
409
     *
410
     */
411
    public function testEncryptAndLoadCompactKeyAgreement()
412
    {
413
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES', 'A192CBC-HS384'], ['DEF' => 0]);
414
        $decrypter = DecrypterFactory::createDecrypter(['ECDH-ES', 'A192CBC-HS384'], ['DEF'], $this->getCheckers());
415
416
        $instruction = new EncryptionInstruction(
417
            $this->getECDHRecipientPublicKey(),
418
            $this->getECDHSenderPrivateKey()
419
        );
420
421
        $encrypted = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
422
            ['user_id' => '1234', 'exp' => time() + 3600],
423
            [$instruction],
424
            JSONSerializationModes::JSON_COMPACT_SERIALIZATION,
425
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'enc' => 'A192CBC-HS384', 'alg' => 'ECDH-ES'],
426
            []
427
        );
428
429
        $loaded = Loader::load($encrypted);
430
431
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded);
432
        $this->assertEquals('ECDH-ES', $loaded->getHeader('alg'));
433
        $this->assertEquals('A192CBC-HS384', $loaded->getHeader('enc'));
434
        $this->assertFalse($loaded->hasHeader('zip'));
435
        $this->assertNull($loaded->getPayload());
436
437
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 429 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
438
439
        $this->assertTrue($result);
440
        $this->assertTrue($loaded->hasClaims());
441
        $this->assertTrue($loaded->hasClaim('user_id'));
442
        $this->assertEquals('1234', $loaded->getClaim('user_id'));
443
    }
444
445
    /**
446
     * @expectedException \RuntimeException
447
     * @expectedExceptionMessage The sender key must be set using Key Agreement or Key Agreement with Wrapping algorithms.
448
     */
449
    public function testEncryptWithAgreementAlgorithm()
450
    {
451
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES', 'A192CBC-HS384'], ['DEF' => 0]);
452
453
        $instruction = new EncryptionInstruction(
454
            $this->getECDHRecipientPublicKey()
455
        );
456
457
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
458
            ['user_id' => '1234', 'exp' => time() + 3600],
459
            [$instruction],
460
            JSONSerializationModes::JSON_COMPACT_SERIALIZATION,
461
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'enc' => 'A192CBC-HS384', 'alg' => 'ECDH-ES'],
462
            []
463
        );
464
    }
465
466
    /**
467
     * @expectedException \RuntimeException
468
     * @expectedExceptionMessage The sender key must be set using Key Agreement or Key Agreement with Wrapping algorithms.
469
     */
470
    public function testEncryptWithAgreementKeyWrapAlgorithm()
471
    {
472
        $encrypter = EncrypterFactory::createEncrypter(['A192CBC-HS384', 'ECDH-ES+A128KW'], ['DEF' => 0]);
473
474
        $instruction = new EncryptionInstruction($this->getECDHRecipientPublicKey());
475
476
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
477
            ['user_id' => '1234', 'exp' => 3600],
478
            [$instruction],
479
            JSONSerializationModes::JSON_COMPACT_SERIALIZATION,
480
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'enc' => 'A192CBC-HS384', 'alg' => 'ECDH-ES+A128KW'],
481
            []
482
        );
483
    }
484
485
    /**
486
     * @expectedException \InvalidArgumentException
487
     * @expectedExceptionMessage No instruction
488
     */
489
    public function testNoInstruction()
490
    {
491
        $encrypter = EncrypterFactory::createEncrypter(['A192CBC-HS384', 'ECDH-ES+A128KW'], ['DEF' => 0]);
492
493
        $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
494
            ['user_id' => '1234', 'exp' => 3600],
495
            [],
496
            JSONSerializationModes::JSON_COMPACT_SERIALIZATION,
497
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'enc' => 'A192CBC-HS384', 'alg' => 'ECDH-ES+A128KW'],
498
            []
499
        );
500
    }
501
502
    /**
503
     *
504
     */
505
    public function testEncryptAndLoadCompactKeyAgreementWithWrappingCompact()
506
    {
507
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF' => 0]);
508
        $decrypter = DecrypterFactory::createDecrypter(['ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], $this->getCheckers());
509
510
        $instruction = new EncryptionInstruction(
511
            $this->getECDHRecipientPublicKey(),
512
            $this->getECDHSenderPrivateKey()
513
        );
514
515
        $encrypted = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
516
            'Je suis Charlie',
517
            [$instruction],
518
            JSONSerializationModes::JSON_COMPACT_SERIALIZATION,
519
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'enc' => 'A256CBC-HS512', 'alg' => 'ECDH-ES+A256KW'],
520
            []
521
        );
522
523
        $loaded = Loader::load($encrypted);
524
525
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded);
526
        $this->assertEquals('ECDH-ES+A256KW', $loaded->getHeader('alg'));
527
        $this->assertEquals('A256CBC-HS512', $loaded->getHeader('enc'));
528
        $this->assertFalse($loaded->hasHeader('zip'));
529
        $this->assertNull($loaded->getPayload());
530
531
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 523 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
532
533
        $this->assertTrue($result);
534
        $this->assertTrue(is_string($loaded->getPayload()));
535
        $this->assertEquals('Je suis Charlie', $loaded->getPayload());
536
    }
537
538
    /**
539
     *
540
     */
541
    public function testEncryptAndLoadCompactKeyAgreementWithWrappingFlattened()
542
    {
543
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF' => 0]);
544
        $decrypter = DecrypterFactory::createDecrypter(['ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], $this->getCheckers());
545
546
        $instruction = new EncryptionInstruction(
547
            $this->getECDHRecipientPublicKey(),
548
            $this->getECDHSenderPrivateKey()
549
        );
550
551
        $encrypted = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
552
            'Je suis Charlie',
553
            [$instruction],
554
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
555
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'enc' => 'A256CBC-HS512', 'alg' => 'ECDH-ES+A256KW'],
556
            []
557
        );
558
559
        $loaded = Loader::load($encrypted);
560
561
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded);
562
        $this->assertEquals('ECDH-ES+A256KW', $loaded->getHeader('alg'));
563
        $this->assertEquals('A256CBC-HS512', $loaded->getHeader('enc'));
564
        $this->assertFalse($loaded->hasHeader('zip'));
565
        $this->assertNull($loaded->getPayload());
566
567
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 559 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
568
569
        $this->assertTrue($result);
570
        $this->assertTrue(is_string($loaded->getPayload()));
571
        $this->assertEquals('Je suis Charlie', $loaded->getPayload());
572
    }
573
574
    /**
575
     *
576
     */
577
    public function testEncryptAndLoadWithGCMAndAAD()
578
    {
579
        if (!$this->isCryptooExtensionInstalled()) {
580
            $this->markTestSkipped('Crypto extension not available');
581
582
            return;
583
        }
584
585
        $encrypter = EncrypterFactory::createEncrypter(['ECDH-ES+A256KW', 'A256GCM'], ['DEF' => 0]);
586
587
        $instruction = new EncryptionInstruction(
588
            $this->getECDHRecipientPublicKey(),
589
            $this->getECDHSenderPrivateKey()
590
        );
591
592
        $encrypted = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
593
            'Je suis Charlie',
594
            [$instruction],
595
            JSONSerializationModes::JSON_FLATTENED_SERIALIZATION,
596
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'enc' => 'A256GCM', 'alg' => 'ECDH-ES+A256KW'],
597
            [],
598
            'foo,bar,baz');
599
600
        $loaded = Loader::load($encrypted);
601
        $decrypter = DecrypterFactory::createDecrypter(['A256GCM', 'ECDH-ES+A256KW'], ['DEF'], $this->getCheckers());
602
603
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded);
604
        $this->assertEquals('ECDH-ES+A256KW', $loaded->getHeader('alg'));
605
        $this->assertEquals('A256GCM', $loaded->getHeader('enc'));
606
        $this->assertFalse($loaded->hasHeader('zip'));
607
        $this->assertNull($loaded->getPayload());
608
609
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 600 can also be of type object<Jose\Object\JWS>; however, Jose\Decrypter::decryptUsingKeySet() does only seem to accept object<Jose\Object\JWEInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
610
611
        $this->assertTrue($result);
612
        $this->assertTrue(is_string($loaded->getPayload()));
613
        $this->assertEquals('Je suis Charlie', $loaded->getPayload());
614
    }
615
616
    /**
617
     *
618
     */
619
    public function testEncryptAndLoadCompactKeyAgreementWithWrapping()
620
    {
621
        $encrypter = EncrypterFactory::createEncrypter(['RSA-OAEP-256', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF' => 0]);
622
        $decrypter = DecrypterFactory::createDecrypter(['RSA-OAEP-256', 'ECDH-ES+A256KW', 'A256CBC-HS512'], ['DEF'], $this->getCheckers());
623
624
        $instruction1 = new EncryptionInstruction(
625
            $this->getECDHRecipientPublicKey(),
626
            $this->getECDHSenderPrivateKey(),
627
            ['kid' => 'e9bc097a-ce51-4036-9562-d2ade882db0d', 'alg' => 'ECDH-ES+A256KW']
628
        );
629
630
        $instruction2 = new EncryptionInstruction(
631
            $this->getRSARecipientKey(),
632
            null,
633
            ['kid' => '123456789', 'alg' => 'RSA-OAEP-256']
634
        );
635
636
        $encrypted = $encrypter->encrypt(
0 ignored issues
show
Bug introduced by
The method encrypt() does not exist on Jose\Encrypter. Did you maybe mean getEncryptedKey()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
637
            'Je suis Charlie',
638
            [$instruction1, $instruction2],
639
            JSONSerializationModes::JSON_SERIALIZATION,
640
            ['enc' => 'A256CBC-HS512'],
641
            []
642
        );
643
644
        $loaded = Loader::load($encrypted);
645
646
        /*
647
         * @var \Jose\Object\JWEInterface[] $loaded
648
         */
649
        $this->assertEquals(2, count($loaded));
650
651
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded[0]);
652
        $this->assertEquals('ECDH-ES+A256KW', $loaded[0]->getHeader('alg'));
0 ignored issues
show
Bug introduced by
The method getHeader() does not seem to exist on object<Jose\Object\JWEInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
653
        $this->assertEquals('A256CBC-HS512', $loaded[0]->getHeader('enc'));
0 ignored issues
show
Bug introduced by
The method getHeader() does not seem to exist on object<Jose\Object\JWEInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
654
        $this->assertFalse($loaded[0]->hasHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasHeader() does not seem to exist on object<Jose\Object\JWEInterface>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
655
        $this->assertNull($loaded[0]->getPayload());
656
657
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Documentation introduced by
$loaded is of type array<integer,object<Jose\Object\JWEInterface>>, but the function expects a object<Jose\Object\JWEInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
658
659
        $this->assertTrue($result);
660
        $this->assertTrue(is_string($loaded[0]->getPayload()));
661
        $this->assertEquals('Je suis Charlie', $loaded[0]->getPayload());
662
663
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded[1]);
664
        $this->assertEquals('RSA-OAEP-256', $loaded[1]->getHeader('alg'));
665
        $this->assertEquals('A256CBC-HS512', $loaded[1]->getHeader('enc'));
666
        $this->assertFalse($loaded[1]->hasHeader('zip'));
667
        $this->assertNull($loaded[1]->getPayload());
668
669
        $this->assertFalse($decrypter->decryptUsingKeySet($loaded[1], new JWKSet()));
670
        $this->assertFalse($decrypter->decryptUsingKeySet($loaded[1], $this->getSymmetricKeySet()));
671
        $this->assertTrue($decrypter->decryptUsingKeySet($loaded[1], $this->getPrivateKeySet()));
672
        $this->assertTrue(is_string($loaded[1]->getPayload()));
673
        $this->assertEquals('Je suis Charlie', $loaded[1]->getPayload());
674
    }
675
676
    /**
677
     * @return JWK
678
     */
679
    protected function getKeyToEncrypt()
680
    {
681
        $key = new JWK([
682
            'kty' => 'EC',
683
            'use' => 'enc',
684
            'crv' => 'P-256',
685
            'x'   => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
686
            'y'   => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
687
            'd'   => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
688
        ]);
689
690
        return $key;
691
    }
692
693
    /**
694
     * @return JWKSet
695
     */
696
    protected function getKeySetToEncrypt()
697
    {
698
        $key = new JWK([
699
            'kty' => 'EC',
700
            'use' => 'enc',
701
            'crv' => 'P-256',
702
            'x'   => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
703
            'y'   => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
704
            'd'   => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
705
        ]);
706
707
        $key_set = new JWKSet();
708
        $key_set->addKey($key);
709
710
        return $key_set;
711
    }
712
713
    /**
714
     * @return JWK
715
     */
716
    protected function getRSARecipientKey()
717
    {
718
        $key = new JWK([
719
            'kty' => 'RSA',
720
            'use' => 'enc',
721
            'n'   => 'tpS1ZmfVKVP5KofIhMBP0tSWc4qlh6fm2lrZSkuKxUjEaWjzZSzs72gEIGxraWusMdoRuV54xsWRyf5KeZT0S-I5Prle3Idi3gICiO4NwvMk6JwSBcJWwmSLFEKyUSnB2CtfiGc0_5rQCpcEt_Dn5iM-BNn7fqpoLIbks8rXKUIj8-qMVqkTXsEKeKinE23t1ykMldsNaaOH-hvGti5Jt2DMnH1JjoXdDXfxvSP_0gjUYb0ektudYFXoA6wekmQyJeImvgx4Myz1I4iHtkY_Cp7J4Mn1ejZ6HNmyvoTE_4OuY1uCeYv4UyXFc1s1uUyYtj4z57qsHGsS4dQ3A2MJsw',
722
            'e'   => 'AQAB',
723
        ]);
724
725
        return $key;
726
    }
727
728
    /**
729
     * @return JWK
730
     */
731
    protected function getRSARecipientKeyWithAlgorithm()
732
    {
733
        $key = new JWK([
734
            'kty' => 'RSA',
735
            'use' => 'enc',
736
            'alg' => 'RSA-OAEP',
737
            'n'   => 'tpS1ZmfVKVP5KofIhMBP0tSWc4qlh6fm2lrZSkuKxUjEaWjzZSzs72gEIGxraWusMdoRuV54xsWRyf5KeZT0S-I5Prle3Idi3gICiO4NwvMk6JwSBcJWwmSLFEKyUSnB2CtfiGc0_5rQCpcEt_Dn5iM-BNn7fqpoLIbks8rXKUIj8-qMVqkTXsEKeKinE23t1ykMldsNaaOH-hvGti5Jt2DMnH1JjoXdDXfxvSP_0gjUYb0ektudYFXoA6wekmQyJeImvgx4Myz1I4iHtkY_Cp7J4Mn1ejZ6HNmyvoTE_4OuY1uCeYv4UyXFc1s1uUyYtj4z57qsHGsS4dQ3A2MJsw',
738
            'e'   => 'AQAB',
739
        ]);
740
741
        return $key;
742
    }
743
744
    /**
745
     * @return JWK
746
     */
747
    protected function getSigningKey()
748
    {
749
        $key = new JWK([
750
            'kty'     => 'EC',
751
            'key_ops' => ['sign', 'verify'],
752
            'crv'     => 'P-256',
753
            'x'       => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
754
            'y'       => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
755
            'd'       => 'jpsQnnGQmL-YBIffH1136cspYG6-0iY7X1fCE9-E9LI',
756
        ]);
757
758
        return $key;
759
    }
760
761
    /**
762
     * @return JWK
763
     */
764
    protected function getECDHRecipientPublicKey()
765
    {
766
        $key = new JWK([
767
            'kty'     => 'EC',
768
            'key_ops' => ['encrypt', 'decrypt'],
769
            'crv'     => 'P-256',
770
            'x'       => 'f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU',
771
            'y'       => 'x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0',
772
        ]);
773
774
        return $key;
775
    }
776
777
    /**
778
     * @return JWK
779
     */
780
    protected function getECDHSenderPrivateKey()
781
    {
782
        $key = new JWK([
783
            'kty'     => 'EC',
784
            'key_ops' => ['encrypt', 'decrypt'],
785
            'crv'     => 'P-256',
786
            'x'       => 'gI0GAILBdu7T53akrFmMyGcsF3n5dO7MmwNBHKW5SV0',
787
            'y'       => 'SLW_xSffzlPWrHEVI30DHM_4egVwt3NQqeUD7nMFpps',
788
            'd'       => '0_NxaRPUMQoAJt50Gz8YiTr8gRTwyEaCumd-MToTmIo',
789
        ]);
790
791
        return $key;
792
    }
793
794
    /**
795
     * @return JWK
796
     */
797
    protected function getDirectKey()
798
    {
799
        $key = new JWK([
800
            'kid'     => 'DIR_1',
801
            'key_ops' => ['encrypt', 'decrypt'],
802
            'kty'     => 'dir',
803
            'dir'     => Base64Url::encode(hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F')),
804
        ]);
805
806
        return $key;
807
    }
808
809
    private function isCryptooExtensionInstalled()
810
    {
811
        return class_exists('\Crypto\Cipher');
812
    }
813
}
814