Completed
Push — v2.0.x ( 59a3d4...b06cab )
by Florent
03:22
created

EncrypterTest::testNoInstruction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 14
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
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->assertTrue(is_array($loaded->getPayload()));
98
        $this->assertEquals($this->getKeyToEncrypt(), new JWK($loaded->getPayload()));
0 ignored issues
show
Documentation introduced by
$loaded->getPayload() is of type string, but the function expects a array.

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...
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'));
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...
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());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($encrypted) on line 272 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...
281
282
        $this->assertTrue($result);
283
        $this->assertTrue(is_array($loaded->getPayload()));
284
        $this->assertEquals($this->getKeySetToEncrypt(), new JWKSet($loaded->getPayload()));
0 ignored issues
show
Documentation introduced by
$loaded->getPayload() is of type string, but the function expects a array.

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...
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'));
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...
399
        $this->assertEquals('A192CBC-HS384', $loaded->getSharedProtectedHeader('enc'));
400
        $this->assertFalse($loaded->hasSharedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedHeader 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...
401
        $this->assertNull($loaded->getPayload());
402
403
        $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 395 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...
404
405
        $this->assertTrue($result);
406
        $this->assertTrue(is_array($loaded->getPayload()));
407
        $this->assertEquals($this->getKeySetToEncrypt(), new JWKSet($loaded->getPayload()));
0 ignored issues
show
Documentation introduced by
$loaded->getPayload() is of type string, but the function expects a array.

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...
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'));
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...
435
        $this->assertEquals('A192CBC-HS384', $loaded->getSharedProtectedHeader('enc'));
436
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedProtectedHeader 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...
437
        $this->assertNull($loaded->getPayload());
438
439
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($jwe->toFlattenedJSON(0)) on line 431 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...
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'));
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...
514
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
515
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedProtectedHeader 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...
516
        $this->assertFalse($loaded->hasSharedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedHeader 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...
517
        $this->assertNull($loaded->getPayload());
518
519
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($jwe->toFlattenedJSON(0)) on line 510 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...
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'));
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...
558
        $this->assertEquals('A256GCM', $loaded->getSharedProtectedHeader('enc'));
559
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedProtectedHeader 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...
560
        $this->assertFalse($loaded->hasSharedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedHeader 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...
561
        $this->assertNull($loaded->getPayload());
562
563
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($jwe->toFlattenedJSON(0)) on line 552 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...
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());
0 ignored issues
show
Bug introduced by
The method countRecipients 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...
597
598
        $this->assertInstanceOf('Jose\Object\JWEInterface', $loaded);
599
        $this->assertEquals('A256CBC-HS512', $loaded->getSharedProtectedHeader('enc'));
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...
600
        $this->assertEquals('ECDH-ES+A256KW', $loaded->getRecipient(0)->getHeader('alg'));
0 ignored issues
show
Bug introduced by
The method getRecipient 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...
601
        $this->assertEquals('RSA-OAEP-256', $loaded->getRecipient(1)->getHeader('alg'));
602
        $this->assertFalse($loaded->hasSharedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedHeader 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...
603
        $this->assertFalse($loaded->hasSharedProtectedHeader('zip'));
0 ignored issues
show
Bug introduced by
The method hasSharedProtectedHeader 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...
604
        $this->assertNull($loaded->getPayload());
605
606
        $result = $decrypter->decryptUsingKeySet($loaded, $this->getPrivateKeySet());
0 ignored issues
show
Bug introduced by
It seems like $loaded defined by \Jose\Loader::load($jwe->toJSON()) on line 594 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...
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