Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame^] | 1 | <?php |
| 2 | |
| 3 | namespace OAuth2\Encryption; |
| 4 | |
| 5 | use OAuth2\Storage\Bootstrap; |
| 6 | use PHPUnit\Framework\TestCase; |
| 7 | |
| 8 | class FirebaseJwtTest extends TestCase |
| 9 | { |
| 10 | private $privateKey; |
| 11 | |
| 12 | public function setUp() |
| 13 | { |
| 14 | $this->privateKey = <<<EOD |
| 15 | -----BEGIN RSA PRIVATE KEY----- |
| 16 | MIICXAIBAAKBgQC5/SxVlE8gnpFqCxgl2wjhzY7ucEi00s0kUg3xp7lVEvgLgYcA |
| 17 | nHiWp+gtSjOFfH2zsvpiWm6Lz5f743j/FEzHIO1owR0p4d9pOaJK07d01+RzoQLO |
| 18 | IQAgXrr4T1CCWUesncwwPBVCyy2Mw3Nmhmr9MrF8UlvdRKBxriRnlP3qJQIDAQAB |
| 19 | AoGAVgJJVU4fhYMu1e5JfYAcTGfF+Gf+h3iQm4JCpoUcxMXf5VpB9ztk3K7LRN5y |
| 20 | kwFuFALpnUAarRcUPs0D8FoP4qBluKksbAtgHkO7bMSH9emN+mH4le4qpFlR7+P1 |
| 21 | 3fLE2Y19IBwPwEfClC+TpJvuog6xqUYGPlg6XLq/MxQUB4ECQQDgovP1v+ONSeGS |
| 22 | R+NgJTR47noTkQT3M2izlce/OG7a+O0yw6BOZjNXqH2wx3DshqMcPUFrTjibIClP |
| 23 | l/tEQ3ShAkEA0/TdBYDtXpNNjqg0R9GVH2pw7Kh68ne6mZTuj0kCgFYpUF6L6iMm |
| 24 | zXamIJ51rTDsTyKTAZ1JuAhAsK/M2BbDBQJAKQ5fXEkIA+i+64dsDUR/hKLBeRYG |
| 25 | PFAPENONQGvGBwt7/s02XV3cgGbxIgAxqWkqIp0neb9AJUoJgtyaNe3GQQJANoL4 |
| 26 | QQ0af0NVJAZgg8QEHTNL3aGrFSbzx8IE5Lb7PLRsJa5bP5lQxnDoYuU+EI/Phr62 |
| 27 | niisp/b/ZDGidkTMXQJBALeRsH1I+LmICAvWXpLKa9Gv0zGCwkuIJLiUbV9c6CVh |
| 28 | suocCAteQwL5iW2gA4AnYr5OGeHFsEl7NCQcwfPZpJ0= |
| 29 | -----END RSA PRIVATE KEY----- |
| 30 | EOD; |
| 31 | } |
| 32 | |
| 33 | /** @dataProvider provideClientCredentials */ |
| 34 | public function testJwtUtil($client_id, $client_key) |
| 35 | { |
| 36 | $jwtUtil = new FirebaseJwt(); |
| 37 | |
| 38 | $params = array( |
| 39 | 'iss' => $client_id, |
| 40 | 'exp' => time() + 1000, |
| 41 | 'iat' => time(), |
| 42 | 'sub' => 'testuser@ourdomain.com', |
| 43 | 'aud' => 'http://myapp.com/oauth/auth', |
| 44 | 'scope' => null, |
| 45 | ); |
| 46 | |
| 47 | $encoded = $jwtUtil->encode($params, $this->privateKey, 'RS256'); |
| 48 | |
| 49 | // test BC behaviour of trusting the algorithm in the header |
| 50 | $payload = $jwtUtil->decode($encoded, $client_key, array('RS256')); |
| 51 | $this->assertEquals($params, $payload); |
| 52 | |
| 53 | // test BC behaviour of not verifying by passing false |
| 54 | $payload = $jwtUtil->decode($encoded, $client_key, false); |
| 55 | $this->assertEquals($params, $payload); |
| 56 | |
| 57 | // test the new restricted algorithms header |
| 58 | $payload = $jwtUtil->decode($encoded, $client_key, array('RS256')); |
| 59 | $this->assertEquals($params, $payload); |
| 60 | } |
| 61 | |
| 62 | public function testInvalidJwt() |
| 63 | { |
| 64 | $jwtUtil = new FirebaseJwt(); |
| 65 | |
| 66 | $this->assertFalse($jwtUtil->decode('goob')); |
| 67 | $this->assertFalse($jwtUtil->decode('go.o.b')); |
| 68 | } |
| 69 | |
| 70 | /** @dataProvider provideClientCredentials */ |
| 71 | public function testInvalidJwtHeader($client_id, $client_key) |
| 72 | { |
| 73 | $jwtUtil = new FirebaseJwt(); |
| 74 | |
| 75 | $params = array( |
| 76 | 'iss' => $client_id, |
| 77 | 'exp' => time() + 1000, |
| 78 | 'iat' => time(), |
| 79 | 'sub' => 'testuser@ourdomain.com', |
| 80 | 'aud' => 'http://myapp.com/oauth/auth', |
| 81 | 'scope' => null, |
| 82 | ); |
| 83 | |
| 84 | // testing for algorithm tampering when only RSA256 signing is allowed |
| 85 | // @see https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/ |
| 86 | $tampered = $jwtUtil->encode($params, $client_key, 'HS256'); |
| 87 | |
| 88 | $payload = $jwtUtil->decode($tampered, $client_key, array('RS256')); |
| 89 | |
| 90 | $this->assertFalse($payload); |
| 91 | } |
| 92 | |
| 93 | public function provideClientCredentials() |
| 94 | { |
| 95 | $storage = Bootstrap::getInstance()->getMemoryStorage(); |
| 96 | $client_id = 'Test Client ID'; |
| 97 | $client_key = $storage->getClientKey($client_id, "testuser@ourdomain.com"); |
| 98 | |
| 99 | return array( |
| 100 | array($client_id, $client_key), |
| 101 | ); |
| 102 | } |
| 103 | } |