/**
  * @return null|OpenIdDirectGenericErrorResponse|OpenIdAssociationSessionResponse|OpenIdUnencryptedAssociationSessionResponse
  */
 public function handle()
 {
     $response = null;
     try {
         $assoc_type = $this->current_request->getAssocType();
         $session_type = $this->current_request->getSessionType();
         $association = $this->association_service->addAssociation(AssociationFactory::getInstance()->buildSessionAssociation($assoc_type, $this->server_configuration_service->getConfigValue("Session.Association.Lifetime")));
         $response = new OpenIdUnencryptedAssociationSessionResponse($association->getHandle(), $session_type, $assoc_type, $association->getLifetime(), $association->getSecret());
     } catch (InvalidDHParam $exDH) {
         $response = new OpenIdDirectGenericErrorResponse($exDH->getMessage());
         $this->log_service->error($exDH);
     } catch (InvalidArgumentException $exDH1) {
         $response = new OpenIdDirectGenericErrorResponse($exDH1->getMessage());
         $this->log_service->error($exDH1);
     } catch (RuntimeException $exDH2) {
         $response = new OpenIdDirectGenericErrorResponse($exDH2->getMessage());
         $this->log_service->error($exDH2);
     }
     return $response;
 }
 /**
  * @return null|OpenIdDirectGenericErrorResponse|\openid\responses\OpenIdAssociationSessionResponse|OpenIdDiffieHellmanAssociationSessionResponse
  */
 public function handle()
 {
     $response = null;
     try {
         $assoc_type = $this->current_request->getAssocType();
         $session_type = $this->current_request->getSessionType();
         //DH parameters
         $public_prime = $this->current_request->getDHModulus();
         //p
         $public_generator = $this->current_request->getDHGen();
         //g
         //get (g ^ xa mod p) where xa is rp secret key
         $rp_public_key = $this->current_request->getDHConsumerPublic();
         //create association
         $association = $this->association_service->addAssociation(AssociationFactory::getInstance()->buildSessionAssociation($assoc_type, $this->server_configuration_service->getConfigValue("Session.Association.Lifetime")));
         $dh = new DiffieHellman($public_prime, $public_generator);
         $dh->generateKeys();
         //server public key (g ^ xb mod p ), where xb is server private key
         // g ^ (xa * xb) mod p = (g ^ xa) ^ xb mod p = (g ^ xb) ^ xa mod p
         $shared_secret = $dh->computeSecretKey($rp_public_key, DiffieHellman::FORMAT_NUMBER, DiffieHellman::FORMAT_BTWOC);
         $hashed_shared_secret = OpenIdCryptoHelper::digest($session_type, $shared_secret);
         $server_public_key = base64_encode($dh->getPublicKey(DiffieHellman::FORMAT_BTWOC));
         $enc_mac_key = base64_encode($association->getSecret() ^ $hashed_shared_secret);
         $response = new OpenIdDiffieHellmanAssociationSessionResponse($association->getHandle(), $session_type, $assoc_type, $association->getLifetime(), $server_public_key, $enc_mac_key);
     } catch (InvalidDHParam $exDH) {
         $response = new OpenIdDirectGenericErrorResponse($exDH->getMessage());
         $this->log_service->error($exDH);
     } catch (InvalidArgumentException $exDH1) {
         $response = new OpenIdDirectGenericErrorResponse($exDH1->getMessage());
         $this->log_service->error($exDH1);
     } catch (RuntimeException $exDH2) {
         $response = new OpenIdDirectGenericErrorResponse($exDH2->getMessage());
         $this->log_service->error($exDH2);
     }
     return $response;
 }
 /**
  * Create Positive Identity Assertion
  * implements http://openid.net/specs/openid-authentication-2_0.html#positive_assertions
  * @return OpenIdPositiveAssertionResponse
  * @throws InvalidAssociationTypeException
  */
 private function doAssertion()
 {
     $currentUser = $this->auth_service->getCurrentUser();
     $context = new ResponseContext();
     //initial signature params
     $context->addSignParam(OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_OpEndpoint));
     $context->addSignParam(OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Realm));
     $context->addSignParam(OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ReturnTo));
     $context->addSignParam(OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Nonce));
     $context->addSignParam(OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_AssocHandle));
     $context->addSignParam(OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_ClaimedId));
     $context->addSignParam(OpenIdProtocol::param(OpenIdProtocol::OpenIDProtocol_Identity));
     $op_endpoint = $this->server_configuration_service->getOPEndpointURL();
     $identity = $this->server_configuration_service->getUserIdentityEndpointURL($currentUser->getIdentifier());
     $nonce = $this->nonce_service->generateNonce();
     $realm = $this->current_request->getRealm();
     $response = new OpenIdPositiveAssertionResponse($op_endpoint, $identity, $identity, $this->current_request->getReturnTo(), $nonce->getRawFormat(), $realm);
     foreach ($this->extensions as $ext) {
         $ext->prepareResponse($this->current_request, $response, $context);
     }
     //check former assoc handle...
     if (is_null($assoc_handle = $this->current_request->getAssocHandle()) || is_null($association = $this->association_service->getAssociation($assoc_handle))) {
         //create private association ...
         $association = $this->association_service->addAssociation(AssociationFactory::getInstance()->buildPrivateAssociation($realm, $this->server_configuration_service->getConfigValue("Private.Association.Lifetime")));
         $response->setAssocHandle($association->getHandle());
         if (!empty($assoc_handle)) {
             $response->setInvalidateHandle($assoc_handle);
         }
     } else {
         if ($association->getType() != IAssociation::TypeSession) {
             throw new InvalidAssociationTypeException(OpenIdErrorMessages::InvalidAssociationTypeMessage);
         }
         $response->setAssocHandle($assoc_handle);
     }
     //create signature ...
     OpenIdSignatureBuilder::build($context, $association->getMacFunction(), $association->getSecret(), $response);
     /*
      * To prevent replay attacks, the OP MUST NOT issue more than one verification response for each
      * authentication response it had previously issued. An authentication response and its matching
      * verification request may be identified by their "openid.response_nonce" values.
      * so associate $nonce with signature and realm
      */
     $this->nonce_service->associateNonce($nonce, $response->getSig(), $realm);
     //do cleaning ...
     $this->memento_service->clearCurrentRequest();
     $this->auth_service->clearUserAuthorizationResponse();
     return $response;
 }
 /**
  * @expectedException \openid\exceptions\ReplayAttackException
  */
 public function testGetPrivateAssociationMustFail_ReplayAttackException()
 {
     $cache_stub = new CacheServiceStub();
     $this->app->instance(UtilsServiceCatalog::CacheService, $cache_stub);
     $lock_manager_service_mock = Mockery::mock('utils\\services\\ILockManagerService');
     $lock_manager_service_mock->shouldReceive('acquireLock')->times(2);
     $this->app->instance(UtilsServiceCatalog::LockManagerService, $lock_manager_service_mock);
     $service = $this->app[OpenIdServiceCatalog::AssociationService];
     $assoc = AssociationFactory::getInstance()->buildPrivateAssociation('https://www.test.com/', 3600);
     $res = $service->addAssociation($assoc);
     $this->assertTrue(!is_null($res));
     $res2 = $service->getAssociation($res->getHandle(), 'https://www.test.com/');
     $this->assertTrue(!is_null($res2));
     $this->assertTrue($res2->getSecret() === $res->getSecret());
     $lock_manager_service_mock->shouldReceive('acquireLock')->once()->andThrow(new UnacquiredLockException());
     $service->getAssociation($res->getHandle(), 'https://www.test.com/');
 }