Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion src/JWK.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ class JWK
// 'P-521' => '1.3.132.0.35', // Len: 132 (not supported)
];

// Known standard curves from the IANA JOSE registry which are not supported
private const KNOWN_UNSUPPORTED_EC_CURVES = [
'P-521', // RFC 7518
'Ed25519', // RFC 8037
'Ed448', // RFC 8037
'X25519', // RFC 8037
'X448' // RFC 8037
];

// For keys with "kty" equal to "OKP" (Octet Key Pair), the "crv" parameter must contain the key subtype.
// This library supports the following subtypes:
private const OKP_SUBTYPES = [
Expand Down Expand Up @@ -142,7 +151,10 @@ public static function parseKey(#[\SensitiveParameter] array $jwk, ?string $defa
}

if (!isset(self::EC_CURVES[$jwk['crv']])) {
throw new DomainException('Unrecognised or unsupported EC curve');
if (!\in_array($jwk['crv'], self::KNOWN_UNSUPPORTED_EC_CURVES)) {
throw new DomainException('Unrecognised EC curve');
}
return null;
}

if (empty($jwk['x']) || empty($jwk['y'])) {
Expand Down
33 changes: 33 additions & 0 deletions tests/JWKTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Firebase\JWT;

use DomainException;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use UnexpectedValueException;
Expand Down Expand Up @@ -136,6 +137,38 @@ public function testParseJwkKeySet_empty()
JWK::parseKeySet(['keys' => []]);
}

public function testParseJwkKeySetWithValidButUnsupportedCurveDoesNotThrowException()
{
$jwkSet = json_decode(
file_get_contents(__DIR__ . '/data/unsupported-alg-keyset.json'),
true
);

$this->assertCount(3, $jwkSet['keys']);

$keys = JWK::parseKeySet($jwkSet);

$this->assertCount(2, $keys);
$this->assertArrayHasKey('jwk1', $keys);
$this->assertArrayHasKey('jwk2', $keys);
$this->assertArrayNotHasKey('unsupported-ec-curve', $keys);
}

public function testParseJwkKeySetWithInvalidCurveThrowsException()
{
$this->expectException(DomainException::class);
$this->expectExceptionMessage('Unrecognised EC curve');

$jwkSet = json_decode(
file_get_contents(__DIR__ . '/data/unsupported-alg-keyset.json'),
true
);

$jwkSet['keys'][2]['crv'] = 'invalid-curve';

$keys = JWK::parseKeySet($jwkSet);
}

/**
* @depends testParseJwkKeySet
*/
Expand Down
39 changes: 39 additions & 0 deletions tests/data/unsupported-alg-keyset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"keys": [
{
"kid": "jwk1",
"kty": "RSA",
"alg": "RSA-OAEP",
"use": "enc",
"n": "vZi3klbtMtzknokuHuU4WyAs7HFnCG-QUSa2Y-PfbwqONlW7ZruTd9lKv6xVzQKqAldhrF2Ljm1dujMkdMSHYHW7L7WD718k0QX-duH_Z3kediGVgVVIikV5y17wYliHcM9x2lUV1EzVhfI3BQrhu-yHkmzvhuHAosr-kDELD483ReMYbG4f79DHoTl-NAg1ZgKhmUc2aPhut9NrJAIE7Q6mf2EnOeHP9e7KzQPOJW7-_ACnRb2E3iXBqpeX4-uNN5h2zCM1jzgN1m8v3xlqJnz4cydIAJ6Np1fCLief31UK6Tiz84xOgjEhCowjK_i1zrm7ciq-Sgs1heMIfKQ5JQ",
"e": "AQAB",
"x5c": [
"MIICnzCCAYcCBgGEr+Dy7jANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhlbnRyb3BpYTAeFw0yMjExMjUxNzM5MjVaFw0zMjExMjUxNzQxMDVaMBMxETAPBgNVBAMMCGVudHJvcGlhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvZi3klbtMtzknokuHuU4WyAs7HFnCG+QUSa2Y+PfbwqONlW7ZruTd9lKv6xVzQKqAldhrF2Ljm1dujMkdMSHYHW7L7WD718k0QX+duH/Z3kediGVgVVIikV5y17wYliHcM9x2lUV1EzVhfI3BQrhu+yHkmzvhuHAosr+kDELD483ReMYbG4f79DHoTl+NAg1ZgKhmUc2aPhut9NrJAIE7Q6mf2EnOeHP9e7KzQPOJW7+/ACnRb2E3iXBqpeX4+uNN5h2zCM1jzgN1m8v3xlqJnz4cydIAJ6Np1fCLief31UK6Tiz84xOgjEhCowjK/i1zrm7ciq+Sgs1heMIfKQ5JQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAKbEduhsT1yxsCymFBHYDNdSXEtZnCSf/NGan9+wyOZtaDyYYtuAipiX43mahkXP/3RlPyDn6UfMXTsdzeD8tml1sZ1bVqD39VsbPZOr6HSvh1JlX40Bn8mLEU/FoQ4OfgrQzdgSLehFLbZ5P0RWwUcZjV+OpdxkOcC7pSb6y1W+3UfsfVhejTUHncan5ZInMI7GWdMRGVuN4JMuAbgnp2v6XqL1di3gTBJl83vFE8GRdwCoyJJiOzXUqcIjWfUsC6PLeHKtPqPlxtHHyvgJdAuGYVLameBoeDJISu3nxkng/RfSU0iwX1hf/1eHOhva0HG5FjMHQNYGJ+V7wYpxOr"
],
"x5t": "1Nd1lnfuVZjpEjnFppIrEcpJhW4",
"x5t#S256": "8NRLcvxX_jloFTT5EZMkchtgkJylb_v0ZwK1HJSQXW4"
},
{
"kid": "jwk2",
"kty": "RSA",
"alg": "RS256",
"use": "sig",
"n": "tI59R8YidctuCz_3-51aP86L4hGbsF8JeuEuQNmArQ1Xj22jwEUSr-YDPb5u6XViyWzLJI6_z5j3vK7O5XVOQGa09LkcHDdPWeuWq3Twy8ZTTqf8miMgIVLNhNYUmMwTFvvg9tVl-sF4XjcxEUdknvdjgDbkHQgfVEycGcinh-u66ZSXFrYcwD1sGSDPA8RzYDpb9wkedDGQU-s7UZFWRPVbFpg9HiK90f7YNJDbR_xZxwMQftsrTlsArfXptdgx295OrF11BQ_CguftLxUC-6C8W-XxXZb49mzDpznR6ITBo3YfkvWnqL4KplNzG6p9l_3ZVqbCuMUiZYv5dV5iYw",
"e": "AQAB",
"x5c": [
"MIICnzCCAYcCBgGEr+DwPzANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDDAhlbnRyb3BpYTAeFw0yMjExMjUxNzM5MjVaFw0zMjExMjUxNzQxMDVaMBMxETAPBgNVBAMMCGVudHJvcGlhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtI59R8YidctuCz/3+51aP86L4hGbsF8JeuEuQNmArQ1Xj22jwEUSr+YDPb5u6XViyWzLJI6/z5j3vK7O5XVOQGa09LkcHDdPWeuWq3Twy8ZTTqf8miMgIVLNhNYUmMwTFvvg9tVl+sF4XjcxEUdknvdjgDbkHQgfVEycGcinh+u66ZSXFrYcwD1sGSDPA8RzYDpb9wkedDGQU+s7UZFWRPVbFpg9HiK90f7YNJDbR/xZxwMQftsrTlsArfXptdgx295OrF11BQ/CguftLxUC+6C8W+XxXZb49mzDpznR6ITBo3YfkvWnqL4KplNzG6p9l/3ZVqbCuMUiZYv5dV5iYwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQArE6mZeWH4haqOGRjtoPHcjO9J4giO9VR6Cxay4bcgrnJYVuIAn5y6umaLjUaP8IthQMMhDcXh3dkoXkaUvlZFtelB29JXZjwPW66rmrPW/5iVqst6qUghyMI80pQyw4UPZKE09atchMiWwtmJ63BbzAYXizzt4FnWJqX6vcSr5cXRrtcYn4WWxaYVAUqSN5koust3vN7YOKhTk0XBpay+dirfa3ENwLbq4KjhImmHwcZa3RpRgkHInbG2U8u6nZDTsOmyIDgVnG8/LZmBHINQ9vhpiLTiERzk0zRk1WtwojHoe9A5MfEgqC3MW5KMVOYlfE+d0QnvCJ3KKaOj8xwE"
],
"x5t": "GQ1-KNU1SgsG8tFXiqNjTt-x1IQ",
"x5t#S256": "6L5_LevQpy2vP_VUiqOBM3hGIXVIx1EmzsTQPPh0jWc"
},
{
"kid": "unsupported-ec-curve",
"kty": "EC",
"alg": "ES512",
"use": "sig",
"crv": "P-521",
"x": "ANCPjd7cPxRHok4a444BTEa0NjIGBfeXlQK6OtdTUjJojmeWznop8koQh4P9sN4NuU2nm49PglN2Jq7GF3eANSDr",
"y": "Aag3LtKNyL4NJualANsYqnITNQE2H00ZXzogOq_3QbcPwspG8St_dHTFoKEiOSl-Y9776_kJHBPtdlh1H7SY5AbZ"
}
]
}
Loading