123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373 |
- <?php
- class AuthTest extends BaseTest
- {
- const PRIVATE_KEY_FILE = "testdata/cert.p12";
- const PUBLIC_KEY_FILE_JSON = "testdata/cacert.json";
- const PUBLIC_KEY_FILE = "testdata/cacert.pem";
- const USER_ID = "102102479283111695822";
-
- private $signer;
-
- private $pem;
-
- private $verifier;
- public function setUp()
- {
- $this->signer = new Google_Signer_P12(
- file_get_contents(__DIR__.'/'.self::PRIVATE_KEY_FILE, true),
- "notasecret"
- );
- $this->pem = file_get_contents(__DIR__.'/'.self::PUBLIC_KEY_FILE, true);
- $this->verifier = new Google_Verifier_Pem($this->pem);
- }
- public function testDirectInject()
- {
- $privateKeyString = <<<PK
- -----BEGIN RSA PRIVATE KEY-----
- MIICWwIBAAKBgQC8iqFTYTrSGxddW+Tsx6cdWbQxITdM2anRbMYcohnQpQuPG46B
- HO3WbUA8suC6PXqeIi4JkDrAYbI2+TN6w1FE/fh2H7WczuDVKtosBcfsoL2C5loU
- mOf+4jL1xx4EL6xy8wMntZhNgimVCO9LkWCix/Qh9mpqx2zbC3OV4QsSQQIDAQAB
- AoGASAosRCClifxB/DENko9iwisxV4haiemtIlEOjYg+luNJPGAKHjlAgyrxXX/3
- sBGnlV53+r16RWHO54RmcCTLGwpC6zzVc6C4Or9KItdMDMnqBjmqiYDz3Na7tIPv
- vwzn8k8Uto26HZF8d1bTdoinxHrv7w1OVkDQWnHmWkQRjBUCQQDpNw8F1qiJJoYr
- tkkBmlObmSQRYD3mlEvRwu348e4dFb01oN2cfw/YNhh+Lt2TPHFz2GNn6VwJf1Yb
- qRKBqo/jAkEAzvY91ReYrkBm50pi2nqJc1Hcxm5CVP7MMnHbn8wExKrRG2rCDY9Y
- zOdsw7pP/x6mesdUy3tTrPYVbeWP6YPmiwJANx41Jbsa7/cz5KbbUE6qDe8+sACg
- AJvx42x/k8OR9DvMER2o4rDBDOeUGFZ5NbAmXCu7KrbjcrcuobDu18h44wJAQ2s5
- x0HxjcoS+4Ni4nMKdZOUTNu8Jf3+vOwUNGD8qKhQiBLl9g7dSZqV9sipqJzudI6c
- k9Cv+GcNoggnMlWycwJAHMVgaBmNc+RVCMar/gN6i5sENjN9Itu7U1V4Qj/mG6+4
- MHOXhXSKhtTe0Bqm/MssVvCmc8AraKwBMs0rkMadsA==
- -----END RSA PRIVATE KEY-----
- PK;
- $sign = new Google_Signer_P12($privateKeyString, null);
- }
- public function testCantOpenP12()
- {
- try {
- new Google_Signer_P12(
- file_get_contents(__DIR__.'/'.self::PRIVATE_KEY_FILE, true),
- "badpassword"
- );
- $this->fail("Should have thrown");
- } catch (Google_Auth_Exception $e) {
- $this->assertContains("mac verify failure", $e->getMessage());
- }
- try {
- new Google_Signer_P12(
- file_get_contents(__DIR__.'/'.self::PRIVATE_KEY_FILE, true) . "foo",
- "badpassword"
- );
- $this->fail("Should have thrown");
- } catch (Exception $e) {
- $this->assertContains("Unable to parse", $e->getMessage());
- }
- }
- public function testVerifySignature()
- {
- $binary_data = "\x00\x01\x02\x66\x6f\x6f";
- $signature = $this->signer->sign($binary_data);
- $this->assertTrue($this->verifier->verify($binary_data, $signature));
- $empty_string = "";
- $signature = $this->signer->sign($empty_string);
- $this->assertTrue($this->verifier->verify($empty_string, $signature));
- $text = "foobar";
- $signature = $this->signer->sign($text);
- $this->assertTrue($this->verifier->verify($text, $signature));
- $this->assertFalse($this->verifier->verify($empty_string, $signature));
- }
-
- private function makeSignedJwt($payload)
- {
- $header = array("typ" => "JWT", "alg" => "RS256");
- $segments = array();
- $segments[] = Google_Utils::urlSafeB64Encode(json_encode($header));
- $segments[] = Google_Utils::urlSafeB64Encode(json_encode($payload));
- $signing_input = implode(".", $segments);
- $signature = $this->signer->sign($signing_input);
- $segments[] = Google_Utils::urlSafeB64Encode($signature);
- return implode(".", $segments);
- }
-
- private function getSignonCerts()
- {
- return array("keyid" => $this->pem);
- }
- public function testVerifySignedJwtWithCerts()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "client_id",
- "sub" => self::USER_ID,
- "iat" => time(),
- "exp" => time() + 3600
- )
- );
- $certs = $this->getSignonCerts();
- $oauth2 = new Google_Auth_OAuth2($this->getClient());
- $ticket = $oauth2->verifySignedJwtWithCerts($id_token, $certs, "client_id");
- $this->assertEquals(self::USER_ID, $ticket->getUserId());
-
- $attributes = $ticket->getAttributes();
- $this->assertEquals("JWT", $attributes["envelope"]["typ"]);
- $this->assertEquals("client_id", $attributes["payload"]["aud"]);
- }
-
- private function checkIdTokenFailure($id_token, $msg, $issuer = null)
- {
- $certs = $this->getSignonCerts();
- $oauth2 = new Google_Auth_OAuth2($this->getClient());
- try {
- $oauth2->verifySignedJwtWithCerts($id_token, $certs, "client_id", $issuer);
- $this->fail("Should have thrown for $id_token");
- } catch (Google_Auth_Exception $e) {
- $this->assertContains($msg, $e->getMessage());
- }
- }
- public function testVerifySignedJwtWithMultipleIssuers()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "system.gserviceaccount.com",
- "aud" => "client_id",
- "sub" => self::USER_ID,
- "iat" => time(),
- "exp" => time() + 3600
- )
- );
- $certs = $this->getSignonCerts();
- $oauth2 = new Google_Auth_OAuth2($this->getClient());
- $ticket = $oauth2->verifySignedJwtWithCerts(
- $id_token,
- $certs,
- "client_id",
- array('system.gserviceaccount.com', 'https://system.gserviceaccount.com')
- );
- $this->assertEquals(self::USER_ID, $ticket->getUserId());
-
- $attributes = $ticket->getAttributes();
- $this->assertEquals("JWT", $attributes["envelope"]["typ"]);
- $this->assertEquals("client_id", $attributes["payload"]["aud"]);
- }
- public function testVerifySignedJwtWithBadIssuer()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "fake.gserviceaccount.com",
- "aud" => "client_id",
- "sub" => self::USER_ID,
- "iat" => time(),
- "exp" => time() + 3600
- )
- );
- $issuers = array('system.gserviceaccount.com', 'https://system.gserviceaccount.com');
- $this->checkIdTokenFailure($id_token, 'Invalid issuer', $issuers[0]);
- $this->checkIdTokenFailure($id_token, 'Invalid issuer', $issuers);
- }
- public function testVerifySignedJwtWithBadJwt()
- {
- $this->checkIdTokenFailure("foo", "Wrong number of segments");
- $this->checkIdTokenFailure("foo.bar", "Wrong number of segments");
- $this->checkIdTokenFailure(
- "foo.bar.baz",
- "Can't parse token envelope: foo"
- );
- }
- public function testVerifySignedJwtWithBadSignature()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "client_id",
- "id" => self::USER_ID,
- "iat" => time(),
- "exp" => time() + 3600
- )
- );
- $id_token = $id_token . "a";
- $this->checkIdTokenFailure($id_token, "Invalid token signature");
- }
- public function testVerifySignedJwtWithNoIssueTime()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "client_id",
- "id" => self::USER_ID,
- "exp" => time() + 3600
- )
- );
- $this->checkIdTokenFailure($id_token, "No issue time");
- }
- public function testVerifySignedJwtWithNoExpirationTime()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "client_id",
- "id" => self::USER_ID,
- "iat" => time()
- )
- );
- $this->checkIdTokenFailure($id_token, "No expiration time");
- }
- public function testVerifySignedJwtWithTooEarly()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "client_id",
- "id" => self::USER_ID,
- "iat" => time() + 1800,
- "exp" => time() + 3600
- )
- );
- $this->checkIdTokenFailure($id_token, "Token used too early");
- }
- public function testVerifySignedJwtWithTooLate()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "client_id",
- "id" => self::USER_ID,
- "iat" => time() - 3600,
- "exp" => time() - 1800
- )
- );
- $this->checkIdTokenFailure($id_token, "Token used too late");
- }
- public function testVerifySignedJwtWithLifetimeTooLong()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "client_id",
- "id" => self::USER_ID,
- "iat" => time(),
- "exp" => time() + 3600 * 25
- )
- );
- $this->checkIdTokenFailure($id_token, "Expiration time too far in future");
- }
- public function testVerifySignedJwtWithBadAudience()
- {
- $id_token = $this->makeSignedJwt(
- array(
- "iss" => "federated-signon@system.gserviceaccount.com",
- "aud" => "wrong_client_id",
- "id" => self::USER_ID,
- "iat" => time(),
- "exp" => time() + 3600
- )
- );
- $this->checkIdTokenFailure($id_token, "Wrong recipient");
- }
- public function testNoAuth()
- {
-
- $noAuth = new Google_Auth_Simple($this->getClient());
- $oldAuth = $this->getClient()->getAuth();
- $this->getClient()->setAuth($noAuth);
- $this->getClient()->setDeveloperKey(null);
- $req = new Google_Http_Request("http://example.com");
- $resp = $noAuth->sign($req);
- $this->assertEquals("http://example.com", $resp->getUrl());
- $this->getClient()->setAuth($oldAuth);
- }
- public function testAssertionCredentials()
- {
- $assertion = new Google_Auth_AssertionCredentials(
- 'name',
- 'scope',
- file_get_contents(__DIR__.'/'.self::PRIVATE_KEY_FILE, true)
- );
- $token = explode(".", $assertion->generateAssertion());
- $this->assertEquals('{"typ":"JWT","alg":"RS256"}', base64_decode($token[0]));
- $jwt = json_decode(base64_decode($token[1]), true);
- $this->assertEquals('https://accounts.google.com/o/oauth2/token', $jwt['aud']);
- $this->assertEquals('scope', $jwt['scope']);
- $this->assertEquals('name', $jwt['iss']);
- $key = $assertion->getCacheKey();
- $this->assertTrue($key != false);
- $assertion = new Google_Auth_AssertionCredentials(
- 'name2',
- 'scope',
- file_get_contents(__DIR__.'/'.self::PRIVATE_KEY_FILE, true)
- );
- $this->assertNotEquals($key, $assertion->getCacheKey());
- }
- public function testVerifySignedJWT()
- {
- $assertion = new Google_Auth_AssertionCredentials(
- 'issuer',
- 'scope',
- file_get_contents(__DIR__.'/'.self::PRIVATE_KEY_FILE, true)
- );
- $client = $this->getClient();
- $this->assertInstanceOf(
- 'Google_Auth_LoginTicket',
- $client->verifySignedJwt(
- $assertion->generateAssertion(),
- __DIR__ . DIRECTORY_SEPARATOR . self::PUBLIC_KEY_FILE_JSON,
- 'https://accounts.google.com/o/oauth2/token',
- 'issuer'
- )
- );
- }
- }
|