Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: update return type for JWK methods #392

Merged
merged 8 commits into from Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Expand Up @@ -198,8 +198,8 @@ use Firebase\JWT\JWT;
// this endpoint: https://www.gstatic.com/iap/verify/public_key-jwk
$jwks = ['keys' => []];

// JWK::parseKeySet($jwks) returns an associative array of **kid** to private
// key. Pass this as the second parameter to JWT::decode.
// JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key
// objects. Pass this as the second parameter to JWT::decode.
JWT::decode($payload, JWK::parseKeySet($jwks));
```

Expand All @@ -208,6 +208,7 @@ Changelog

#### 6.0.0 / 2022-01-24

- **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v5.5.1) for more information.
- New Key object to prevent key/algorithm type confusion (#365)
- Add JWK support (#273)
- Add ES256 support (#256)
Expand Down
22 changes: 10 additions & 12 deletions src/JWK.php
Expand Up @@ -25,7 +25,7 @@ class JWK
*
* @param array $jwks The JSON Web Key Set as an associative array
*
* @return array An associative array that represents the set of keys
* @return array<string, Key> An associative array of key IDs (kid) to Key objects
*
* @throws InvalidArgumentException Provided JWK Set is empty
* @throws UnexpectedValueException Provided JWK Set was invalid
Expand All @@ -47,15 +47,7 @@ public static function parseKeySet(array $jwks)
foreach ($jwks['keys'] as $k => $v) {
$kid = isset($v['kid']) ? $v['kid'] : $k;
if ($key = self::parseKey($v)) {
if (isset($v['alg'])) {
$keys[$kid] = new Key($key, $v['alg']);
} else {
// The "alg" parameter is optional in a KTY, but is required
// for parsing in this library. Add it manually to your JWK
// array if it doesn't already exist.
// @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4
throw new InvalidArgumentException('JWK key is missing "alg"');
}
$keys[$kid] = $key;
}
}

Expand All @@ -71,7 +63,7 @@ public static function parseKeySet(array $jwks)
*
* @param array $jwk An individual JWK
*
* @return resource|array An associative array that represents the key
* @return Key The key object for the JWK
*
* @throws InvalidArgumentException Provided JWK is empty
* @throws UnexpectedValueException Provided JWK was invalid
Expand All @@ -87,6 +79,12 @@ public static function parseKey(array $jwk)
if (!isset($jwk['kty'])) {
throw new UnexpectedValueException('JWK must contain a "kty" parameter');
}
if (!isset($jwk['alg'])) {
// The "alg" parameter is optional in a KTY, but is required for parsing in
// this library. Add it manually to your JWK array if it doesn't already exist.
// @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4
throw new UnexpectedValueException('JWK must contain an "alg" parameter');
}

switch ($jwk['kty']) {
case 'RSA':
Expand All @@ -104,7 +102,7 @@ public static function parseKey(array $jwk)
'OpenSSL error: ' . \openssl_error_string()
);
}
return $publicKey;
return new Key($publicKey, $jwk['alg']);
default:
// Currently only RSA is supported
break;
Expand Down
6 changes: 3 additions & 3 deletions src/JWT.php
Expand Up @@ -63,7 +63,7 @@ class JWT
* Decodes a JWT string into a PHP object.
*
* @param string $jwt The JWT
* @param Key|array<Key> $keyOrKeyArray The Key or array of Key objects.
* @param Key|array<string, Key> $keyOrKeyArray The Key or associative array of key IDs (kid) to Key objects.
* If the algorithm used is asymmetric, this is the public key
* Each Key object contains an algorithm and matching key.
* Supported algorithms are 'ES384','ES256', 'HS256', 'HS384',
Expand Down Expand Up @@ -381,8 +381,8 @@ public static function urlsafeB64Encode($input)
/**
* Determine if an algorithm has been provided for each Key
*
* @param Key|array<Key>|mixed $keyOrKeyArray
* @param string|null $kid
* @param Key|array<string, Key> $keyOrKeyArray
* @param string|null $kid
*
* @throws UnexpectedValueException
*
Expand Down
6 changes: 3 additions & 3 deletions tests/JWKTest.php
Expand Up @@ -28,7 +28,7 @@ public function testInvalidAlgorithm()
'No supported algorithms found in JWK Set'
);

$badJwk = array('kty' => 'BADALG');
$badJwk = array('kty' => 'BADALG', 'alg' => 'RSA256');
$keys = JWK::parseKeySet(array('keys' => array($badJwk)));
}

Expand All @@ -51,8 +51,8 @@ public function testParsePrivateKey()
public function testParsePrivateKeyWithoutAlg()
{
$this->setExpectedException(
'InvalidArgumentException',
'JWK key is missing "alg"'
'UnexpectedValueException',
'JWK must contain an "alg" parameter'
);

$jwkSet = json_decode(
Expand Down