public function processPreKeyBundle($preKey) { /* :type preKey: PreKeyBundle */ if (!$this->identityKeyStore->isTrustedIdentity($this->recipientId, $preKey->getIdentityKey())) { throw new UntrustedIdentityException(); } if ($preKey->getSignedPreKey() != null && !Curve::verifySignature($preKey->getIdentityKey()->getPublicKey(), $preKey->getSignedPreKey()->serialize(), $preKey->getSignedPreKeySignature())) { throw new InvalidKeyException('Invalid signature on device key!'); } if ($preKey->getSignedPreKey() == null && $preKey->getPreKey() == null) { throw new InvalidKeyException('Both signed and unsigned prekeys are absent!'); } $supportsV3 = $preKey->getSignedPreKey() != null; $sessionRecord = $this->sessionStore->loadSession($this->recipientId, $this->deviceId); $ourBaseKey = Curve::generateKeyPair(); $theirSignedPreKey = $supportsV3 ? $preKey->getSignedPreKey() : $preKey->getPreKey(); $theirOneTimePreKey = $preKey->getPreKey(); $theirOneTimePreKeyId = $theirOneTimePreKey != null ? $preKey->getPreKeyId() : null; $parameters = new AliceBuilder(); $parameters->setOurBaseKey($ourBaseKey)->setOurIdentityKey($this->identityKeyStore->getIdentityKeyPair())->setTheirIdentityKey($preKey->getIdentityKey())->setTheirSignedPreKey($theirSignedPreKey)->setTheirRatchetKey($theirSignedPreKey)->setTheirOneTimePreKey($supportsV3 ? $theirOneTimePreKey : null); if (!$sessionRecord->isFresh()) { $sessionRecord->archiveCurrentState(); } RatchetingSession::initializeSessionAsAlice($sessionRecord->getSessionState(), $supportsV3 ? 3 : 2, $parameters->create()); $sessionRecord->getSessionState()->setUnacknowledgedPreKeyMessage($theirOneTimePreKeyId, $preKey->getSignedPreKeyId(), $ourBaseKey->getPublicKey()); $sessionRecord->getSessionState()->setLocalRegistrationId($this->identityKeyStore->getLocalRegistrationId()); $sessionRecord->getSessionState()->setRemoteRegistrationId($preKey->getRegistrationId()); $sessionRecord->getSessionState()->setAliceBaseKey($ourBaseKey->getPublicKey()->serialize()); $this->sessionStore->storeSession($this->recipientId, $this->deviceId, $sessionRecord); $this->identityKeyStore->saveIdentity($this->recipientId, $preKey->getIdentityKey()); }
protected function initializeSessionsV3($aliceSessionState, $bobSessionState) { $aliceIdentityKeyPair = Curve::generateKeyPair(); $aliceIdentityKey = new IdentityKeyPair(new IdentityKey($aliceIdentityKeyPair->getPublicKey()), $aliceIdentityKeyPair->getPrivateKey()); $aliceBaseKey = Curve::generateKeyPair(); $aliceEphemeralKey = Curve::generateKeyPair(); $alicePreKey = $aliceBaseKey; $bobIdentityKeyPair = Curve::generateKeyPair(); $bobIdentityKey = new IdentityKeyPair(new IdentityKey($bobIdentityKeyPair->getPublicKey()), $bobIdentityKeyPair->getPrivateKey()); $bobBaseKey = Curve::generateKeyPair(); $bobEphemeralKey = $bobBaseKey; $bobPreKey = Curve::generateKeyPair(); $aliceParameters = AliceAxolotlParameters::newBuilder()->setOurBaseKey($aliceBaseKey)->setOurIdentityKey($aliceIdentityKey)->setTheirOneTimePreKey(null)->setTheirRatchetKey($bobEphemeralKey->getPublicKey())->setTheirSignedPreKey($bobBaseKey->getPublicKey())->setTheirIdentityKey($bobIdentityKey->getPublicKey())->create(); $bobParameters = BobAxolotlParameters::newBuilder()->setOurRatchetKey($bobEphemeralKey)->setOurSignedPreKey($bobBaseKey)->setOurOneTimePreKey(null)->setOurIdentityKey($bobIdentityKey)->setTheirIdentityKey($aliceIdentityKey->getPublicKey())->setTheirBaseKey($aliceBaseKey->getPublicKey())->create(); RatchetingSession::initializeSessionAsAlice($aliceSessionState, 3, $aliceParameters); RatchetingSession::initializeSessionAsBob($bobSessionState, 3, $bobParameters); }