Exemplo n.º 1
0
 public function onMasterRequest(Oxygen_Event_MasterRequestEvent $event)
 {
     $request = $event->getRequest();
     $data = $event->getRequestData();
     $existingPublicKey = $this->state->get('oxygen_public_key');
     $providedPublicKey = $data->publicKey;
     $signature = $data->signature;
     $requestId = $data->oxygenRequestId;
     $requestExpiresAt = $data->requestExpiresAt;
     if (empty($existingPublicKey)) {
         // There is no public key set, use the provided one to verify SSL implementation.
         $verifyPublicKey = $providedPublicKey;
     } else {
         $verifyPublicKey = $existingPublicKey;
     }
     $verified = $this->rsaVerifier->verify($verifyPublicKey, sprintf('%s|%d', $requestId, $requestExpiresAt), $signature);
     if (!$verified) {
         if (empty($existingPublicKey)) {
             // A public key is not set, but the handshake failed. There might be a problem with the OpenSSL implementation.
             throw new Oxygen_Exception(Oxygen_Exception::HANDSHAKE_VERIFY_TEST_FAILED);
         } else {
             throw new Oxygen_Exception(Oxygen_Exception::HANDSHAKE_VERIFY_FAILED);
         }
     }
     if (!empty($existingPublicKey)) {
         // We validated against an existing key.
         $this->nonceManager->useNonce($requestId, $requestExpiresAt);
         $request->setAuthenticated(true);
         return;
     }
     $handshakeKey = @file_get_contents($this->modulePath . '/keys/' . $data->handshakeKey . '.pub');
     if ($handshakeKey === false) {
         $lastError = error_get_last();
         throw new Oxygen_Exception(Oxygen_Exception::HANDSHAKE_LOCAL_KEY_NOT_FOUND, array('lastError' => $lastError['message'], 'keyPath' => $this->modulePath . '/' . $data->handshakeKey));
     }
     $urlSlug = Oxygen_Util::getUrlSlug($this->baseUrl);
     $verifiedHandshake = $this->rsaVerifier->verify($handshakeKey, $urlSlug, $data->handshakeSignature);
     if (!$verifiedHandshake) {
         throw new Oxygen_Exception(Oxygen_Exception::HANDSHAKE_LOCAL_VERIFY_FAILED);
     }
     $this->nonceManager->useNonce($requestId, $requestExpiresAt);
     $this->state->set('oxygen_public_key', $providedPublicKey);
     $request->setAuthenticated(true);
 }
Exemplo n.º 2
0
 public function onPublicRequest(Oxygen_Event_PublicRequestEvent $event)
 {
     $params = $event->getRequest()->query;
     // @TODO: Move the logic below to kernel? We need at least one more action for that, or else it's an overkill.
     if (!isset($params['oxygenRequestId'])) {
         return;
     }
     if (!is_string($params['oxygenRequestId'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_REQUEST_ID_NOT_VALID);
     }
     if (!isset($params['actionName'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_ACTION_NAME_NOT_PROVIDED);
     }
     if (!is_string($params['actionName'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_ACTION_NAME_NOT_VALID);
     }
     if ($params['actionName'] !== 'site.login') {
         return;
     }
     if (!isset($params['requestExpiresAt'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_EXPIRATION_NOT_PROVIDED);
     }
     // The "is_numeric" check with more predictable behavior.
     if ((string) (int) $params['requestExpiresAt'] !== (string) $params['requestExpiresAt']) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_EXPIRATION_NOT_VALID);
     }
     if (!isset($params['signature'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_SIGNATURE_NOT_PROVIDED);
     }
     if (!is_string($params['signature'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_SIGNATURE_NOT_VALID);
     }
     if (!isset($params['userName'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_NAME_NOT_PROVIDED);
     }
     if (!is_string($params['userName'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_NAME_NOT_VALID);
     }
     if (!isset($params['userUid'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_UID_NOT_PROVIDED);
     }
     if (!is_string($params['userUid']) || !preg_match('{^U\\d{10}$}', $params['userUid'])) {
         throw new Oxygen_Exception(Oxygen_Exception::PROTOCOL_USER_UID_NOT_VALID);
     }
     $params['requestExpiresAt'] = (int) $params['requestExpiresAt'];
     $publicKey = $this->state->get('oxygen_public_key');
     if (!$publicKey) {
         throw new Oxygen_Exception(Oxygen_Exception::PUBLIC_KEY_MISSING);
     }
     if (!$this->rsaVerifier->verify($publicKey, sprintf('%s|%d|%s|%s', $params['oxygenRequestId'], $params['requestExpiresAt'], $params['userUid'], $params['userName']), $params['signature'])) {
         throw new Oxygen_Exception(Oxygen_Exception::HANDSHAKE_VERIFY_FAILED);
     }
     $this->nonceManager->useNonce($params['oxygenRequestId'], $params['requestExpiresAt']);
     $closure = new Oxygen_Util_Closure(array($this, 'loginUser'), $params['userUid'], $params['userName']);
     $event->setDeferredResponse(new Oxygen_Util_HookedClosure('init', $closure->getCallable()));
 }
Exemplo n.º 3
0
 /**
  * @dataProvider signerProvider
  */
 public function testVerifierVerifiesSignature(\Oxygen_Security_Rsa_RsaVerifierInterface $verifier)
 {
     $data = self::MESSAGE;
     $keyResource = openssl_pkey_new();
     openssl_pkey_export($keyResource, $otherPrivateKey);
     openssl_sign($data, $signature1, self::$privateKey);
     openssl_sign($data . $data, $signature2, self::$privateKey);
     openssl_sign($data, $signature3, $otherPrivateKey);
     openssl_sign($data . $data, $signature4, $otherPrivateKey);
     $this->assertGreaterThan(0, strlen($signature1));
     $this->assertGreaterThan(0, strlen($signature2));
     $this->assertGreaterThan(0, strlen($signature3));
     $this->assertGreaterThan(0, strlen($signature4));
     $this->assertTrue($verifier->verify(self::$publicKey, $data, base64_encode($signature1)));
     $this->assertFalse($verifier->verify(self::$publicKey, $data, base64_encode($signature2)));
     $this->assertFalse($verifier->verify(self::$publicKey, $data, base64_encode($signature3)));
     $this->assertFalse($verifier->verify(self::$publicKey, $data, base64_encode($signature4)));
     $this->assertFalse($verifier->verify(self::$publicKey, $data, 'foobar'));
 }