Skip to content

Commit 6ee4931

Browse files
committed
On the way the PHPStan level "max"
1 parent 3b736dc commit 6ee4931

File tree

9 files changed

+110
-16
lines changed

9 files changed

+110
-16
lines changed

phpstan.neon

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,7 @@ parameters:
1313
- '#Binary operation "\^" between string and 1 results in an error\.#'
1414
- '#Parameter \#1 \$length of function random_bytes expects int\<1\, max\>.*\.#'
1515
- '#Parameter \#3 \$length of function mb_substr expects int\|null.*\.#'
16+
- '#Parameter \#2 \.\.\.\$values of function sprintf expects bool\|float\|int\|string\|null\, mixed given\.#'
17+
- '#Parameter \#1 \.\.\.\$arrays of function array_merge expects array\, mixed given\.#'
1618
includes:
1719
- vendor/phpstan/phpstan/conf/bleedingEdge.neon

src/Component/Core/Util/ECKey.php

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use function extension_loaded;
88
use InvalidArgumentException;
99
use function is_array;
10+
use function is_string;
1011
use Jose\Component\Core\JWK;
1112
use const OPENSSL_KEYTYPE_EC;
1213
use ParagonIE\ConstantTime\Base64UrlSafe;
@@ -200,7 +201,11 @@ private static function p521PublicKey(): string
200201

201202
private static function p256PrivateKey(JWK $jwk): string
202203
{
203-
$d = unpack('H*', str_pad(Base64UrlSafe::decode($jwk->get('d')), 32, "\0", STR_PAD_LEFT));
204+
$d = $jwk->get('d');
205+
if (! is_string($d)) {
206+
throw new InvalidArgumentException('Unable to get the private key');
207+
}
208+
$d = unpack('H*', str_pad(Base64UrlSafe::decode($d), 32, "\0", STR_PAD_LEFT));
204209
if (! is_array($d) || ! isset($d[1])) {
205210
throw new InvalidArgumentException('Unable to get the private key');
206211
}
@@ -222,7 +227,11 @@ private static function p256PrivateKey(JWK $jwk): string
222227

223228
private static function p256KPrivateKey(JWK $jwk): string
224229
{
225-
$d = unpack('H*', str_pad(Base64UrlSafe::decode($jwk->get('d')), 32, "\0", STR_PAD_LEFT));
230+
$d = $jwk->get('d');
231+
if (! is_string($d)) {
232+
throw new InvalidArgumentException('Unable to get the private key');
233+
}
234+
$d = unpack('H*', str_pad(Base64UrlSafe::decode($d), 32, "\0", STR_PAD_LEFT));
226235
if (! is_array($d) || ! isset($d[1])) {
227236
throw new InvalidArgumentException('Unable to get the private key');
228237
}
@@ -244,7 +253,11 @@ private static function p256KPrivateKey(JWK $jwk): string
244253

245254
private static function p384PrivateKey(JWK $jwk): string
246255
{
247-
$d = unpack('H*', str_pad(Base64UrlSafe::decode($jwk->get('d')), 48, "\0", STR_PAD_LEFT));
256+
$d = $jwk->get('d');
257+
if (! is_string($d)) {
258+
throw new InvalidArgumentException('Unable to get the private key');
259+
}
260+
$d = unpack('H*', str_pad(Base64UrlSafe::decode($d), 48, "\0", STR_PAD_LEFT));
248261
if (! is_array($d) || ! isset($d[1])) {
249262
throw new InvalidArgumentException('Unable to get the private key');
250263
}
@@ -266,7 +279,11 @@ private static function p384PrivateKey(JWK $jwk): string
266279

267280
private static function p521PrivateKey(JWK $jwk): string
268281
{
269-
$d = unpack('H*', str_pad(Base64UrlSafe::decode($jwk->get('d')), 66, "\0", STR_PAD_LEFT));
282+
$d = $jwk->get('d');
283+
if (! is_string($d)) {
284+
throw new InvalidArgumentException('Unable to get the private key');
285+
}
286+
$d = unpack('H*', str_pad(Base64UrlSafe::decode($d), 66, "\0", STR_PAD_LEFT));
270287
if (! is_array($d) || ! isset($d[1])) {
271288
throw new InvalidArgumentException('Unable to get the private key');
272289
}
@@ -288,12 +305,24 @@ private static function p521PrivateKey(JWK $jwk): string
288305

289306
private static function getKey(JWK $jwk): string
290307
{
291-
$nistCurveSize = self::getNistCurveSize($jwk->get('crv'));
308+
$crv = $jwk->get('crv');
309+
if (! is_string($crv)) {
310+
throw new InvalidArgumentException('Unable to get the curve');
311+
}
312+
$nistCurveSize = self::getNistCurveSize($crv);
292313
$length = (int) ceil($nistCurveSize / 8);
314+
$x = $jwk->get('x');
315+
if (! is_string($x)) {
316+
throw new InvalidArgumentException('Unable to get the public key');
317+
}
318+
$y = $jwk->get('y');
319+
if (! is_string($y)) {
320+
throw new InvalidArgumentException('Unable to get the public key');
321+
}
293322

294323
return
295324
"\04"
296-
. str_pad(Base64UrlSafe::decode($jwk->get('x')), $length, "\0", STR_PAD_LEFT)
297-
. str_pad(Base64UrlSafe::decode($jwk->get('y')), $length, "\0", STR_PAD_LEFT);
325+
. str_pad(Base64UrlSafe::decode($x), $length, "\0", STR_PAD_LEFT)
326+
. str_pad(Base64UrlSafe::decode($y), $length, "\0", STR_PAD_LEFT);
298327
}
299328
}

src/Component/Core/Util/KeyChecker.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use function in_array;
88
use InvalidArgumentException;
99
use function is_array;
10+
use function is_string;
1011
use Jose\Component\Core\JWK;
1112

1213
/**
@@ -29,8 +30,12 @@ public static function checkKeyAlgorithm(JWK $key, string $algorithm): void
2930
if (! $key->has('alg')) {
3031
return;
3132
}
32-
if ($key->get('alg') !== $algorithm) {
33-
throw new InvalidArgumentException(sprintf('Key is only allowed for algorithm "%s".', $key->get('alg')));
33+
$alg = $key->get('alg');
34+
if (! is_string($alg)) {
35+
throw new InvalidArgumentException('Invalid algorithm.');
36+
}
37+
if ($alg !== $algorithm) {
38+
throw new InvalidArgumentException(sprintf('Key is only allowed for algorithm "%s".', $alg));
3439
}
3540
}
3641

src/Component/Encryption/JWEBuilder.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use function array_key_exists;
88
use function count;
99
use InvalidArgumentException;
10+
use function is_string;
1011
use Jose\Component\Core\AlgorithmManager;
1112
use Jose\Component\Core\JWK;
1213
use Jose\Component\Core\Util\JsonConverter;
@@ -450,8 +451,12 @@ private function determineCEK(array &$additionalHeader): string
450451
if ($key->get('kty') !== 'oct') {
451452
throw new RuntimeException('Wrong key type.');
452453
}
454+
$k = $key->get('k');
455+
if (! is_string($k)) {
456+
throw new RuntimeException('Invalid key.');
457+
}
453458

454-
return Base64UrlSafe::decode($key->get('k'));
459+
return Base64UrlSafe::decode($k);
455460

456461
default:
457462
throw new InvalidArgumentException(sprintf(

src/Component/KeyManagement/Analyzer/ES256KeyAnalyzer.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
namespace Jose\Component\KeyManagement\Analyzer;
66

7+
use Jose\Component\Core\Util\Ecc\Curve;
8+
use Jose\Component\Core\Util\Ecc\NistCurve;
9+
710
final class ES256KeyAnalyzer extends ESKeyAnalyzer
811
{
912
protected function getAlgorithmName(): string
@@ -16,6 +19,11 @@ protected function getCurveName(): string
1619
return 'P-256';
1720
}
1821

22+
protected function getCurve(): Curve
23+
{
24+
return NistCurve::curve256();
25+
}
26+
1927
protected function getKeySize(): int
2028
{
2129
return 256;

src/Component/KeyManagement/Analyzer/ES384KeyAnalyzer.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
namespace Jose\Component\KeyManagement\Analyzer;
66

7+
use Jose\Component\Core\Util\Ecc\Curve;
8+
use Jose\Component\Core\Util\Ecc\NistCurve;
9+
710
final class ES384KeyAnalyzer extends ESKeyAnalyzer
811
{
912
protected function getAlgorithmName(): string
@@ -16,6 +19,11 @@ protected function getCurveName(): string
1619
return 'P-384';
1720
}
1821

22+
protected function getCurve(): Curve
23+
{
24+
return NistCurve::curve384();
25+
}
26+
1927
protected function getKeySize(): int
2028
{
2129
return 384;

src/Component/KeyManagement/Analyzer/ES512KeyAnalyzer.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
namespace Jose\Component\KeyManagement\Analyzer;
66

7+
use Jose\Component\Core\Util\Ecc\Curve;
8+
use Jose\Component\Core\Util\Ecc\NistCurve;
9+
710
final class ES512KeyAnalyzer extends ESKeyAnalyzer
811
{
912
protected function getAlgorithmName(): string
@@ -16,8 +19,13 @@ protected function getCurveName(): string
1619
return 'P-521';
1720
}
1821

22+
protected function getCurve(): Curve
23+
{
24+
return NistCurve::curve521();
25+
}
26+
1927
protected function getKeySize(): int
2028
{
21-
return 512; //528
29+
return 528;
2230
}
2331
}

src/Component/KeyManagement/Analyzer/ESKeyAnalyzer.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Brick\Math\BigInteger;
88
use function is_string;
99
use Jose\Component\Core\JWK;
10+
use Jose\Component\Core\Util\Ecc\Curve;
1011
use Jose\Component\Core\Util\Ecc\NistCurve;
1112
use ParagonIE\ConstantTime\Base64UrlSafe;
1213
use RuntimeException;
@@ -22,9 +23,6 @@ public function __construct()
2223

2324
public function analyze(JWK $jwk, MessageBag $bag): void
2425
{
25-
if (! $jwk->has('alg') || $jwk->get('alg') !== $this->getAlgorithmName()) {
26-
return;
27-
}
2826
if ($jwk->get('kty') !== 'EC') {
2927
return;
3028
}
@@ -62,8 +60,7 @@ public function analyze(JWK $jwk, MessageBag $bag): void
6260
}
6361
$xBI = BigInteger::fromBase(bin2hex($x), 16);
6462
$yBI = BigInteger::fromBase(bin2hex($y), 16);
65-
$curve = NistCurve::curve256();
66-
if (! $curve->contains($xBI, $yBI)) {
63+
if (! $this->getCurve()->contains($xBI, $yBI)) {
6764
$bag->add(Message::high('Invalid key. The point is not on the curve.'));
6865
}
6966
}
@@ -72,5 +69,7 @@ abstract protected function getAlgorithmName(): string;
7269

7370
abstract protected function getCurveName(): string;
7471

72+
abstract protected function getCurve(): Curve;
73+
7574
abstract protected function getKeySize(): int;
7675
}

tests/Component/KeyManagement/JWKAnalyzerTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@
66

77
use Jose\Component\Core\JWK;
88
use Jose\Component\KeyManagement\Analyzer\AlgorithmAnalyzer;
9+
use Jose\Component\KeyManagement\Analyzer\ES256KeyAnalyzer;
10+
use Jose\Component\KeyManagement\Analyzer\ES384KeyAnalyzer;
11+
use Jose\Component\KeyManagement\Analyzer\ES512KeyAnalyzer;
12+
use Jose\Component\KeyManagement\Analyzer\HS256KeyAnalyzer;
13+
use Jose\Component\KeyManagement\Analyzer\HS384KeyAnalyzer;
14+
use Jose\Component\KeyManagement\Analyzer\HS512KeyAnalyzer;
915
use Jose\Component\KeyManagement\Analyzer\KeyAnalyzerManager;
1016
use Jose\Component\KeyManagement\Analyzer\KeyIdentifierAnalyzer;
1117
use Jose\Component\KeyManagement\Analyzer\NoneAnalyzer;
1218
use Jose\Component\KeyManagement\Analyzer\OctAnalyzer;
1319
use Jose\Component\KeyManagement\Analyzer\RsaAnalyzer;
1420
use Jose\Component\KeyManagement\Analyzer\UsageAnalyzer;
21+
use Jose\Component\KeyManagement\Analyzer\ZxcvbnKeyAnalyzer;
1522
use Jose\Component\KeyManagement\JWKFactory;
1623
use PHPUnit\Framework\TestCase;
1724

@@ -89,16 +96,39 @@ public function iCanAnalyzeAnOctKeyAndGetMessages(): void
8996
static::assertNotEmpty($messages);
9097
}
9198

99+
/**
100+
* @test
101+
*/
102+
public function iCanAnalyzeAnES521OctKeyAndGetMessages(): void
103+
{
104+
$key = JWKFactory::createECKey('P-521', [
105+
'kid' => '0123456789',
106+
'alg' => 'HS256',
107+
'use' => 'sig',
108+
]);
109+
$messages = $this->getKeyAnalyzer()
110+
->analyze($key)
111+
;
112+
static::assertEmpty($messages);
113+
}
114+
92115
private function getKeyAnalyzer(): KeyAnalyzerManager
93116
{
94117
if ($this->keyAnalyzerManager === null) {
95118
$this->keyAnalyzerManager = new KeyAnalyzerManager();
96119
$this->keyAnalyzerManager->add(new AlgorithmAnalyzer());
120+
$this->keyAnalyzerManager->add(new ES256KeyAnalyzer());
121+
$this->keyAnalyzerManager->add(new ES384KeyAnalyzer());
122+
$this->keyAnalyzerManager->add(new ES512KeyAnalyzer());
123+
$this->keyAnalyzerManager->add(new HS256KeyAnalyzer());
124+
$this->keyAnalyzerManager->add(new HS384KeyAnalyzer());
125+
$this->keyAnalyzerManager->add(new HS512KeyAnalyzer());
97126
$this->keyAnalyzerManager->add(new KeyIdentifierAnalyzer());
98127
$this->keyAnalyzerManager->add(new NoneAnalyzer());
99128
$this->keyAnalyzerManager->add(new OctAnalyzer());
100129
$this->keyAnalyzerManager->add(new RsaAnalyzer());
101130
$this->keyAnalyzerManager->add(new UsageAnalyzer());
131+
$this->keyAnalyzerManager->add(new ZxcvbnKeyAnalyzer());
102132
}
103133

104134
return $this->keyAnalyzerManager;

0 commit comments

Comments
 (0)