/** * "associate" mode request * * @param $server to make association with (usually obtained from OpenIdCredentials) * @param $manager - dao-like association manager * @return OpenIdConsumerAssociation **/ public function associate(HttpUrl $server, OpenIdConsumerAssociationManager $manager) { Assert::isTrue($server->isValid()); if ($association = $manager->findByServer($server)) { return $association; } $dhParameters = new DiffieHellmanParameters($this->numberFactory->makeNumber(self::DIFFIE_HELLMAN_G), $this->numberFactory->makeNumber(self::DIFFIE_HELLMAN_P)); $keyPair = DiffieHellmanKeyPair::generate($dhParameters, $this->randomSource); $request = HttpRequest::create()->setMethod(HttpMethod::post())->setUrl($server)->setPostVar('openid.ns', self::NAMESPACE_2_0)->setPostVar('openid.mode', 'associate')->setPostVar('openid.assoc_type', self::ASSOCIATION_TYPE)->setPostVar('openid.session_type', 'DH-SHA1')->setPostVar('openid.dh_modulus', base64_encode($dhParameters->getModulus()->toBinary()))->setPostVar('openid.dh_gen', base64_encode($dhParameters->getGen()->toBinary()))->setPostVar('openid.dh_consumer_public', base64_encode($keyPair->getPublic()->toBinary())); $response = $this->httpClient->setFollowLocation(true)->send($request); if ($response->getStatus()->getId() != HttpStatus::CODE_200) { throw new OpenIdException('bad response code from server'); } $result = $this->parseKeyValueFormat($response->getBody()); if (empty($result['assoc_handle'])) { throw new OpenIdException('can\\t live without handle'); } if (!isset($result['assoc_type']) || $result['assoc_type'] !== self::ASSOCIATION_TYPE) { throw new OpenIdException('bad association type'); } if (!isset($result['expires_in']) || !is_numeric($result['expires_in'])) { throw new OpenIdException('bad expires'); } if (isset($result['session_type']) && $result['session_type'] == 'DH-SHA1' && isset($result['dh_server_public'])) { $secret = sha1($keyPair->makeSharedKey($this->numberFactory->makeFromBinary(base64_decode($result['dh_server_public'])))->toBinary(), true) ^ base64_decode($result['enc_mac_key']); } elseif (empty($result['session_type']) && isset($result['mac_key'])) { $secret = base64_decode($result['mac_key']); } else { throw new OpenIdException('no secret in answer'); } return $manager->makeAndSave($result['assoc_handle'], $result['assoc_type'], $secret, Timestamp::makeNow()->modify('+ ' . $result['expires_in'] . ' seconds'), $server); }
public function runDiffieHellmanGeneration(BigNumberFactory $factory) { $parameters = DiffieHellmanParameters::create($factory->makeNumber(2), $factory->makeNumber(126)); $sourceA = new RandomSourceStub(""); $pairA = DiffieHellmanKeyPair::generate($parameters, $sourceA); $this->assertEquals($pairA->getPublic()->toString(), '4'); $this->assertEquals($pairA->getPrivate()->toString(), '2'); $sourceB = new RandomSourceStub(""); $pairB = DiffieHellmanKeyPair::generate($parameters, $sourceB); $this->assertEquals($pairB->getPublic()->toString(), '8'); $this->assertEquals($pairB->getPrivate()->toString(), '3'); $this->assertEquals($pairA->makeSharedKey($pairB->getPublic())->toString(), '64'); $this->assertEquals($pairB->makeSharedKey($pairA->getPublic())->toString(), '64'); $bigSource = new RandomSourceStub($factory->makeNumber('17620208266278770330305877401674539709763945430177869257076175454731875847774962345544017639615825508394434743684629375358533661943819685038381342979593382253449035990153308416178843539244884579493167694072720167536494654808080865723281709878280854033940718446755086284684724942649928096406688489109561821711')->toBinary()); $bigPair = DiffieHellmanKeyPair::generate(DiffieHellmanParameters::create($factory->makeNumber(2), $factory->makeNumber('155172898181473697471232257763715539915724801966915404479707795314057629378541917580651227423698188993727816152646631438561595825688188889951272158842675419950341258706556549803580104870537681476726513255747040765857479291291572334510643245094715007229621094194349783925984760375594985848253359305585439638443')), $bigSource); $this->assertEquals($bigPair->getPrivate()->toString(), '17620208266278770330305877401674539709763945430177869257076175454731875847774962345544017639615825508394434743684629375358533661943819685038381342979593382253449035990153308416178843539244884579493167694072720167536494654808080865723281709878280854033940718446755086284684724942649928096406688489109561821711'); $this->assertEquals($bigPair->getPublic()->toString(), '93611077906724276144355642962486685180052418906604011044062651816823973443710236445918597792417855982839842862368107478409559670530180271906446567838772164434838441509602151691228515001241179534817267036102715381057132924139174991783818894647585751956892566340543905490069919079555140420098531372841096272473'); $this->assertEquals($bigPair->makeSharedKey($factory->makeFromBinary(base64_decode('ALOlru0GPBCbWulLlZPjRFCVPQDOnmQ+bUaowbHvgA4D1TEDlHA0WgX+HnQuq3KleYWK8jgY0nH/l02gdE93OCMq1Kitat+I8PE1HGVkAQ1J7pfM6f3WISSCa88xm63CLVg4MPTCP+0ONh6A5XUkN+D+LwS4ff9zUoF9GVRRKN6K')))->toString(), '130574307951871152424428936775752636435856388421474727121158044023326117405721624660812283811910707382094169797795608545580344115985070696700827335362669644864287947205210570090276035970957788252377653229959968013235712431298868299742980604595915492149293770517689028200287095518234357514745938567136863374034'); }