Skip to content

Commit 27ee05f

Browse files
authored
test: use keys for testing JWK (#283)
1 parent b0def5f commit 27ee05f

File tree

4 files changed

+141
-127
lines changed

4 files changed

+141
-127
lines changed

tests/JWKTest.php

Lines changed: 70 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -5,155 +5,98 @@
55

66
class JWKTest extends TestCase
77
{
8-
/*
9-
* For compatibility with PHPUnit 4.8 and PHP < 5.6
10-
*/
11-
public function setExpectedException($exceptionName, $message = '', $code = NULL) {
12-
if (method_exists($this, 'expectException')) {
13-
$this->expectException($exceptionName);
14-
} else {
15-
parent::setExpectedException($exceptionName, $message, $code);
16-
}
17-
}
8+
private static $keys;
9+
private static $privKey1;
10+
private static $privKey2;
1811

19-
public function testDecodeByJWKKeySetTokenExpired()
12+
public function testMissingKty()
2013
{
21-
$jsKey = array(
22-
'kty' => 'RSA',
23-
'e' => 'AQAB',
24-
'use' => 'sig',
25-
'kid' => 's1',
26-
'n' => 'kWp2zRA23Z3vTL4uoe8kTFptxBVFunIoP4t_8TDYJrOb7D1iZNDXVeEsYKp6ppmrTZDAgd-cNOTKLd4M39WJc5FN0maTAVKJc7NxklDeKc4dMe1BGvTZNG4MpWBo-taKULlYUu0ltYJuLzOjIrTHfarucrGoRWqM0sl3z2-fv9k',
14+
$this->setExpectedException(
15+
'UnexpectedValueException',
16+
'JWK must contain a "kty" parameter'
2717
);
2818

29-
$key = JWK::parseKeySet(array('keys' => array($jsKey)));
19+
$badJwk = array('kid' => 'foo');
20+
$keys = JWK::parseKeySet(array('keys' => array($badJwk)));
21+
}
3022

31-
$header = array(
32-
'kid' => 's1',
33-
'alg' => 'RS256',
34-
);
35-
$payload = array (
36-
'scp' => array ('openid', 'email', 'profile', 'aas'),
37-
'sub' => 'tUCYtnfIBPWcrSJf4yBfvN1kww4KGcy3LIPk1GVzsE0',
38-
'clm' => array ('!5v8H'),
39-
'iss' => 'http://130.211.243.114:8080/c2id',
40-
'exp' => 1441126539,
41-
'uip' => array('groups' => array('admin', 'audit')),
42-
'cid' => 'pk-oidc-01',
43-
);
44-
$signature = 'PvYrnf3k1Z0wgRwCgq0WXKaoIv1hHtzBFO5cGfCs6bl4suc6ilwCWmJqRxGYkU2fNTGyMOt3OUnnBEwl6v5qN6jv7zbkVAVKVvbQLxhHC2nXe3izvoCiVaMEH6hE7VTWwnPbX_qO72mCwTizHTJTZGLOsyXLYM6ctdOMf7sFPTI';
45-
$msg = sprintf('%s.%s.%s',
46-
JWT::urlsafeB64Encode(json_encode($header)),
47-
JWT::urlsafeB64Encode(json_encode($payload)),
48-
$signature
23+
public function testInvalidAlgorithm()
24+
{
25+
$this->setExpectedException(
26+
'UnexpectedValueException',
27+
'No supported algorithms found in JWK Set'
4928
);
5029

51-
$this->setExpectedException('Firebase\JWT\ExpiredException');
52-
53-
JWT::decode($msg, $key, array('RS256'));
30+
$badJwk = array('kty' => 'BADALG');
31+
$keys = JWK::parseKeySet(array('keys' => array($badJwk)));
5432
}
5533

56-
public function testDecodeByJWKKeySet()
34+
public function testParseJwkKeySet()
5735
{
58-
$jsKey = array(
59-
'kty' => 'RSA',
60-
'e' => 'AQAB',
61-
'use' => 'sig',
62-
'kid' => 's1',
63-
'n' => 'kWp2zRA23Z3vTL4uoe8kTFptxBVFunIoP4t_8TDYJrOb7D1iZNDXVeEsYKp6ppmrTZDAgd-cNOTKLd4M39WJc5FN0maTAVKJc7NxklDeKc4dMe1BGvTZNG4MpWBo-taKULlYUu0ltYJuLzOjIrTHfarucrGoRWqM0sl3z2-fv9k',
36+
$jwkSet = json_decode(
37+
file_get_contents(__DIR__ . '/rsa-jwkset.json'),
38+
true
6439
);
40+
$keys = JWK::parseKeySet($jwkSet);
41+
$this->assertTrue(is_array($keys));
42+
$this->assertArrayHasKey('jwk1', $keys);
43+
self::$keys = $keys;
44+
}
6545

66-
$key = JWK::parseKeySet(array('keys' => array($jsKey)));
67-
68-
$header = array(
69-
'kid' => 's1',
70-
'alg' => 'RS256',
71-
);
72-
$payload = array (
73-
'scp' => array ('openid', 'email', 'profile', 'aas'),
74-
'sub' => 'tUCYtnfIBPWcrSJf4yBfvN1kww4KGcy3LIPk1GVzsE0',
75-
'clm' => array ('!5v8H'),
76-
'iss' => 'http://130.211.243.114:8080/c2id',
77-
'exp' => 1441126539,
78-
'uip' => array('groups' => array('admin', 'audit')),
79-
'cid' => 'pk-oidc-01',
80-
);
81-
$signature = 'PvYrnf3k1Z0wgRwCgq0WXKaoIv1hHtzBFO5cGfCs6bl4suc6ilwCWmJqRxGYkU2fNTGyMOt3OUnnBEwl6v5qN6jv7zbkVAVKVvbQLxhHC2nXe3izvoCiVaMEH6hE7VTWwnPbX_qO72mCwTizHTJTZGLOsyXLYM6ctdOMf7sFPTI';
82-
$msg = sprintf('%s.%s.%s',
83-
JWT::urlsafeB64Encode(json_encode($header)),
84-
JWT::urlsafeB64Encode(json_encode($payload)),
85-
$signature
86-
);
46+
/**
47+
* @depends testParseJwkKeySet
48+
*/
49+
public function testDecodeByJwkKeySetTokenExpired()
50+
{
51+
$privKey1 = file_get_contents(__DIR__ . '/rsa1-private.pem');
52+
$payload = array('exp' => strtotime('-1 hour'));
53+
$msg = JWT::encode($payload, $privKey1, 'RS256', 'jwk1');
8754

8855
$this->setExpectedException('Firebase\JWT\ExpiredException');
8956

90-
$payload = JWT::decode($msg, $key, array('RS256'));
91-
92-
$this->assertEquals("tUCYtnfIBPWcrSJf4yBfvN1kww4KGcy3LIPk1GVzsE0", $payload->sub);
93-
$this->assertEquals(1441126539, $payload->exp);
57+
JWT::decode($msg, self::$keys, array('RS256'));
9458
}
9559

96-
public function testDecodeByMultiJWKKeySet()
60+
/**
61+
* @depends testParseJwkKeySet
62+
*/
63+
public function testDecodeByJwkKeySet()
9764
{
98-
$jsKey1 = array(
99-
'kty' => 'RSA',
100-
'e' => 'AQAB',
101-
'use' => 'sig',
102-
'kid' => 'CXup',
103-
'n' => 'hrwD-lc-IwzwidCANmy4qsiZk11yp9kHykOuP0yOnwi36VomYTQVEzZXgh2sDJpGgAutdQudgwLoV8tVSsTG9SQHgJjH9Pd_9V4Ab6PANyZNG6DSeiq1QfiFlEP6Obt0JbRB3W7X2vkxOVaNoWrYskZodxU2V0ogeVL_LkcCGAyNu2jdx3j0DjJatNVk7ystNxb9RfHhJGgpiIkO5S3QiSIVhbBKaJHcZHPF1vq9g0JMGuUCI-OTSVg6XBkTLEGw1C_R73WD_oVEBfdXbXnLukoLHBS11p3OxU7f4rfxA_f_72_UwmWGJnsqS3iahbms3FkvqoL9x_Vj3GhuJSf97Q',
104-
);
105-
$jsKey2 = array(
106-
'kty' => 'EC',
107-
'use' => 'sig',
108-
'crv' => 'P-256',
109-
'kid' => 'yGvt',
110-
'x' => 'pvgdqM3RCshljmuCF1D2Ez1w5ei5k7-bpimWLPNeEHI',
111-
'y' => 'JSmUhbUTqiFclVLEdw6dz038F7Whw4URobjXbAReDuM',
112-
);
113-
$jsKey3 = array(
114-
'kty' => 'EC',
115-
'use' => 'sig',
116-
'crv' => 'P-384',
117-
'kid' => '9nHY',
118-
'x' => 'JPKhjhE0Bj579Mgj3Cn3ERGA8fKVYoGOaV9BPKhtnEobphf8w4GSeigMesL-038W',
119-
'y' => 'UbJa1QRX7fo9LxSlh7FOH5ABT5lEtiQeQUcX9BW0bpJFlEVGqwec80tYLdOIl59M',
120-
);
121-
$jsKey4 = array(
122-
'kty' => 'EC',
123-
'use' => 'sig',
124-
'crv' => 'P-521',
125-
'kid' => 'tVzS',
126-
'x' => 'AZgkRHlIyNQJlPIwTWdHqouw41k9dS3GJO04BDEnJnd_Dd1owlCn9SMXA-JuXINn4slwbG4wcECbctXb2cvdGtmn',
127-
'y' => 'AdBC6N9lpupzfzcIY3JLIuc8y8MnzV-ItmzHQcC5lYWMTbuM9NU_FlvINeVo8g6i4YZms2xFB-B0VVdaoF9kUswC',
128-
);
65+
$privKey1 = file_get_contents(__DIR__ . '/rsa1-private.pem');
66+
$payload = array('sub' => 'foo', 'exp' => strtotime('+10 seconds'));
67+
$msg = JWT::encode($payload, $privKey1, 'RS256', 'jwk1');
12968

130-
$key = JWK::parseKeySet(array('keys' => array($jsKey1, $jsKey2, $jsKey3, $jsKey4)));
69+
$result = JWT::decode($msg, self::$keys, array('RS256'));
13170

132-
$header = array(
133-
'kid' => 'CXup',
134-
'alg' => 'RS256',
135-
);
136-
$payload = array(
137-
'sub' => 'f8b67cc46030777efd8bce6c1bfe29c6c0f818ec',
138-
'scp' => array('openid', 'name', 'profile', 'picture', 'email', 'rs-pk-main', 'rs-pk-so', 'rs-pk-issue', 'rs-pk-web'),
139-
'clm' => array('!5v8H'),
140-
'iss' => 'https://id.projectkit.net/authenticate',
141-
'exp' => 1492228336,
142-
'iat' => 1491364336,
143-
'cid' => 'cid-pk-web',
144-
);
145-
$signature = 'KW1K-72bMtiNwvyYBgffG6VaG6I59cELGYQR8M2q7HA8dmzliu6QREJrqyPtwW_rDJZbsD3eylvkRinK9tlsMXCOfEJbxLdAC9b4LKOsnsbuXXwsJHWkFG0a7osdW0ZpXJDoMFlO1aosxRGMkaqhf1wIkvQ5PM_EB08LJv7oz64Antn5bYaoajwgvJRl7ChatRDn9Sx5UIElKD1BK4Uw5WdrZwBlWdWZVNCSFhy4F6SdZvi3OBlXzluDwq61RC-pl2iivilJNljYWVrthHDS1xdtaVz4oteHW13-IS7NNEz6PVnzo5nyoPWMAB4JlRnxcfOFTTUqOA2mX5Csg0UpdQ';
146-
$msg = sprintf('%s.%s.%s',
147-
JWT::urlsafeB64Encode(json_encode($header)),
148-
JWT::urlsafeB64Encode(json_encode($payload)),
149-
$signature
150-
);
71+
$this->assertEquals("foo", $result->sub);
72+
}
15173

152-
$this->setExpectedException('Firebase\JWT\ExpiredException');
74+
/**
75+
* @depends testParseJwkKeySet
76+
*/
77+
public function testDecodeByMultiJwkKeySet()
78+
{
79+
$privKey2 = file_get_contents(__DIR__ . '/rsa2-private.pem');
80+
$payload = array('sub' => 'bar', 'exp' => strtotime('+10 seconds'));
81+
$msg = JWT::encode($payload, $privKey2, 'RS256', 'jwk2');
15382

154-
$payload = JWT::decode($msg, $key, array('RS256'));
83+
$result = JWT::decode($msg, self::$keys, array('RS256'));
15584

156-
$this->assertEquals("f8b67cc46030777efd8bce6c1bfe29c6c0f818ec", $payload->sub);
157-
$this->assertEquals(1492228336, $payload->exp);
85+
$this->assertEquals("bar", $result->sub);
86+
}
87+
88+
/*
89+
* For compatibility with PHPUnit 4.8 and PHP < 5.6
90+
*/
91+
public function setExpectedException($exceptionName, $message = '', $code = NULL)
92+
{
93+
if (method_exists($this, 'expectException')) {
94+
$this->expectException($exceptionName);
95+
if ($message) {
96+
$this->expectExceptionMessage($message);
97+
}
98+
} else {
99+
parent::setExpectedException($exceptionName, $message, $code);
100+
}
158101
}
159102
}

tests/rsa-jwkset.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"keys": [
3+
{
4+
"kty": "RSA",
5+
"e": "AQAB",
6+
"kid": "jwk1",
7+
"n": "0Ttga33B1yX4w77NbpKyNYDNSVCo8j-RlZaZ9tI-KfkV1d-tfsvI9ZPAheP11FoN52ceBaY5ltelHW-IKwCfyT0orLdsxLgowaXki9woF1Azvcg2JVxQLv9aVjjAvy3CZFIG_EeN7J3nsyCXGnu1yMEbnvkWxA88__Q6HQ2K9wqfApkQ0LNlsK0YHz_sfjHNvRKxnbAJk7D5fUhZunPZXOPHXFgA5SvLvMaNIXduMKJh4OMfuoLdJowXJAR9j31Mqz_is4FMhm_9Mq7vZZ-uF09htRvIR8tRY28oJuW1gKWyg7cQQpnjHgFyG3XLXWAeXclWqyh_LfjyHQjrYhyeFw"
8+
9+
},
10+
{
11+
"kty": "RSA",
12+
"e": "AQAB",
13+
"kid": "jwk2",
14+
"n": "pXi2o6AnNhwL30MaK_nuDHi2fxZHVen7Xwk0bjLGlHYpq3mSvXm2HBA-zR41vQCbHkYGsDpsyDhIXLBDTbSa7ue7D1ZqYdv5YLIS33zdX9GtUHfFHc6zYgXAU9ziWeyTzVn7icAbjxqcgT2xKNuGK7Zf2ZJ053rr-dxjAE-SjX4SG0WWUhwPjxlr1etF7mEurhHweuSdZYl36g39o9BtTBVfS87io2MwdIRsnL3w8ulgXRVRWjv-vvcuhMS_y6zGbzOC55Yr23sb4h2PSll32bgyglEIsGgHqjOdyjuUzl0t6jh86DHzbu9h-u1iihX8EI8t7CBbizbPPyHQygp-rQ"
15+
}
16+
]
17+
}

tests/rsa1-private.pem

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEowIBAAKCAQEA0Ttga33B1yX4w77NbpKyNYDNSVCo8j+RlZaZ9tI+KfkV1d+t
3+
fsvI9ZPAheP11FoN52ceBaY5ltelHW+IKwCfyT0orLdsxLgowaXki9woF1Azvcg2
4+
JVxQLv9aVjjAvy3CZFIG/EeN7J3nsyCXGnu1yMEbnvkWxA88//Q6HQ2K9wqfApkQ
5+
0LNlsK0YHz/sfjHNvRKxnbAJk7D5fUhZunPZXOPHXFgA5SvLvMaNIXduMKJh4OMf
6+
uoLdJowXJAR9j31Mqz/is4FMhm/9Mq7vZZ+uF09htRvIR8tRY28oJuW1gKWyg7cQ
7+
QpnjHgFyG3XLXWAeXclWqyh/LfjyHQjrYhyeFwIDAQABAoIBAHMqdJsWAGEVNIVB
8+
+792HYNXnydQr32PwemNmLeD59WglgU/9jZJoxaROjI4VLKK0wZg+uRvJ1nA3tCB
9+
+Hh7Anh5Im9XExaAq2ZTkqXtC2AxtBktH6iW1EfaI/Y7jNRuMoaXo+Ku3A62p7cw
10+
JBvepiOXL0Xko0RNguz7mBUvxCLPhYhzn7qCbM8uXLcjsXq/YhWQwQmtMqv0sd3W
11+
Hy+8Jb2c18sqDeZIBne4dWD6qPClPEOsrq9gPTkl0DjbT27oVc2u1p4HMNm5BJIh
12+
u3rMSxnZHUd7Axj1FgyLIOHl63UhaiaA1aPe/fLiVIGOA1jBZrpbnjgqDy9Uxyn6
13+
eydbiwECgYEA9mtRydz22idyUOlBCDXk+vdGBvFAucNYaNNUAXUJ2wfPmdGgFCA7
14+
g5eQG8JC6J/FU+2AfIuz6LGr7SxMBYcsWGjFAzGqs/sJib+zzN1dPUSRn4uJNFit
15+
51yQzPgBqHS6S/XBi6YAODeZDl9jiPl3FxxucqLY5NstqZFXbE0SjIECgYEA2V3r
16+
7xnRAK1krY1+zkPof4kcBmjqOXjnl/oRxlXP65lEXmyNJwm/ulOIko9mElWRs8CG
17+
AxSWKaab9Gk6lc8MHjVRbuW52RGLGKq1mp6ENr4d3IBOfrNsTvD3gtNEN1JFLeF1
18+
jIbSsrbi2txr7VZ06Irac0C/ytro0QDOUoXkvpcCgYA8O0EzmToRWsD7e/g0XJAK
19+
s/Q+8CtE/LWYccc/z+7HxeH9lBqPsM07Pgmwb0xRdfQSrqPQTYl9ICiJAWHXnBG/
20+
zmQRgstZ0MulCuGU+qq2thLuL3oq/F4NhjeykhA9r8J1nK1hSAMXuqdDtxcqPOfa
21+
E03/4UQotFY181uuEiytgQKBgHQT+gjHqptH/XnJFCymiySAXdz2bg6fCF5aht95
22+
t/1C7gXWxlJQnHiuX0KVHZcw5wwtBePjPIWlmaceAtE5rmj7ZC9qsqK/AZ78mtql
23+
SEnLoTq9si1rN624dRUCKW25m4Py4MlYvm/9xovGJkSqZOhCLoJZ05JK8QWb/pKH
24+
Oi6lAoGBAOUN6ICpMQvzMGPgIbgS0H/gvRTnpAEs59vdgrkhlCII4tzfgvBQlVae
25+
hRcdM6GTMq5pekBPKu45eanIzwVc88P6coT4qiWYKk2jYoLBa0UV3xEAuqBMymrj
26+
X4nLcSbZtO0tcDGMfMpWF2JGYOEJQNetPozL/ICGVFyIO8yzXm8U
27+
-----END RSA PRIVATE KEY-----

tests/rsa2-private.pem

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIEowIBAAKCAQEApXi2o6AnNhwL30MaK/nuDHi2fxZHVen7Xwk0bjLGlHYpq3mS
3+
vXm2HBA+zR41vQCbHkYGsDpsyDhIXLBDTbSa7ue7D1ZqYdv5YLIS33zdX9GtUHfF
4+
Hc6zYgXAU9ziWeyTzVn7icAbjxqcgT2xKNuGK7Zf2ZJ053rr+dxjAE+SjX4SG0WW
5+
UhwPjxlr1etF7mEurhHweuSdZYl36g39o9BtTBVfS87io2MwdIRsnL3w8ulgXRVR
6+
Wjv+vvcuhMS/y6zGbzOC55Yr23sb4h2PSll32bgyglEIsGgHqjOdyjuUzl0t6jh8
7+
6DHzbu9h+u1iihX8EI8t7CBbizbPPyHQygp+rQIDAQABAoIBACF25kj1LLjutx/x
8+
7CsUoqX3C8Fr+gVQCrxPmkDnF+4Sb570OU8EfGX0ix7kiy2sH7LhqpydVD6x00Cb
9+
jSD785F5YAVcDqu31xlNKi/0irjEKO7rKfw7P2AFlb3gIA7bn5CaMBrNtUUdtqUU
10+
mu2OZ/YTLhNMYUQnQe4IOiVn8lWW5D4Kje/RlLRRdGn8voXaD5BnOwZNXAxjdXqM
11+
RxyXRG74tLKyfe3W8xTL8uhlKCNHjsdtUg9IZdnKT7I3DJPobpqgC3fUuC/IbfGf
12+
MPK1aiu067/3DdgonC2ZWqFeKLJqtUa7z0pSQaZeDa1iiUuRivfqKYEBovFre6ni
13+
1qHkp8ECgYEA089VnKc74NRGVbIs0VtQGprNhkl47eBq6jhTlG3hfaFF4VuDiZiu
14+
wT8enlbhlbDb/gM0CDr9tkfDs7R4exNnhSVvn2PT8b1mhonOAeE466y/4YBA0d9x
15+
gj0wF2vjH/bsVNBe6MBrIx12R2tBKTZ7tbCzgJRszSZqkrK7sljTlaUCgYEAx/54
16+
G3Yd3ULqGIG/JA7w/QEYitgjwAUSJ+eLU+iqlIjo/njAJwJ/kixqaI3Jzcl+kYmp
17+
yNIXNNaJUz8c0M/QsuqvQjLnHkF0FOZUrdyVseU2mSbI6DhAGsPJEtAOep/61vyz
18+
uJSu0z34gQ6bNrKdqfkA7XIQRNJ1r0qQXrVLRmkCgYB2/UYaIDTaREZTBCp7XnHs
19+
0ERfiUz/TZCijgweGXCQ1BXe2TtXBEhAVcZMq4BFSLr9wyzq5sD7Muu1O9BnS+pe
20+
+T3w6/L4Hi/HqwjpM253r2+ILjW78Wvh/5/RuJE6tsvjhb+bv+UwL+/vhUhw76Ol
21+
2WOt+zP4N/ms+e3J7m7G5QKBgQCmasN65nC3WyT8u4pX8O7rOOw5LN2ivRV8ixnO
22+
+r5m1v46MjSCwXtyIO9yjPmt+csOQ+U6LEgPOa4PzWanAyaAmvS3OzBCZui3M2qn
23+
OfR+kWM7UaDAS35cRyqcMvC5bUIHf0P1hhNryBdvHL5fZ4X2mDMDYnTTL+WptXwo
24+
sucucQKBgAGHzi5+ZRwffhpZiYVR/lA6zvqyekAncJZwGe2UVDL0axTumX1NPdin
25+
2mOnVuvKVvJkisyKTIQzFk6ClQEyiArO4+t7zhUbg5Crh8q6nObRo2R2NcP8o0Iq
26+
BRIwPgaG/WlEvZ6zqlHQ0qH7WoL4HnRG5uyLOuzRIkjasYmZdfR8
27+
-----END RSA PRIVATE KEY-----

0 commit comments

Comments
 (0)