Exemple #1
0
 public function KeyExchangeMessage($messageVersion = null, $sequence = null, $flags = null, $baseKey = null, $baseKeySignature = null, $ratchetKey = null, $identityKey = null, $serialized = null)
 {
     /*
     :type messageVersion: int
     :type  sequence: int
     :type flags:int
     :type baseKey: ECPublicKey
     :type baseKeySignature: bytearray
     :type ratchetKey: ECPublicKey
     :type identityKey: IdentityKey
     :type serialized: bytearray
     */
     if ($serialized == null) {
         $this->supportedVersion = CiphertextMessage::CURRENT_VERSION;
         $this->version = $messageVersion;
         $this->sequence = $sequence;
         $this->flags = $flags;
         $this->baseKey = $baseKey;
         $this->baseKeySignature = $baseKeySignature;
         $this->ratchetKey = $ratchetKey;
         $this->identityKey = $identityKey;
         $version = ByteUtil::intsToByteHighAndLow($this->version, $this->supportedVersion);
         $keyExchangeMessage = new Textsecure_KeyExchangeMessage();
         $keyExchangeMessage->setId($this->sequence << 5 | $this->flags);
         $keyExchangeMessage->setBaseKey($baseKey->serialize());
         $keyExchangeMessage->setRatchetKey($ratchetKey->serialize());
         $keyExchangeMessage->setIdentityKey($identityKey->serialize());
         if ($messageVersion >= 3) {
             $keyExchangeMessage->setBaseKeySignature($baseKeySignature);
         }
         $this->serialized = ByteUtil::combine([chr((int) $version), $keyExchangeMessage->serializeToString()]);
     } else {
         try {
             $parts = ByteUtil::split($serialized, 1, strlen($serialized) - 1);
             $this->version = ByteUtil::highBitsToInt(ord($parts[0][0]));
             $this->supportedVersion = ByteUtil::lowBitsToInt(ord($parts[0][0]));
             if ($this->version <= CiphertextMessage::UNSUPPORTED_VERSION) {
                 throw new LegacyMessageException('Unsupported legacy version: ' . $this->version);
             }
             if ($this->version > CiphertextMessage::CURRENT_VERSION) {
                 throw new InvalidVersionException('Unkown version: ' . $this->version);
             }
             $message = new Textsecure_KeyExchangeMessage();
             $message->parseFromString($parts[1]);
             if ($message->getId() == null || $message->getBaseKey() == null || $message->getRatchetKey() == null || $message->getIdentityKey() == null || $this->version >= 3 && $message->getBaseKeySignature() == null) {
                 throw new InvalidMessageException('Some required fields are missing!');
             }
             $this->sequence = $message->getId() >> 5;
             $this->flags = $message->getId() & 0x1f;
             $this->serialized = $serialized;
             $this->baseKey = Curve::decodePoint($message->getBaseKey(), 0);
             $this->baseKeySignature = $message->getBaseKeySignature();
             $this->ratchetKey = Curve::decodePoint($message->getRatchetKey(), 0);
             $this->identityKey = new IdentityKey($message->getIdentityKey(), 0);
         } catch (InvalidKeyException $ex) {
             throw new InvalidMessageException($ex->getMessage());
         }
     }
 }
Exemple #2
0
 public function WhisperMessage($messageVersion = null, $macKey = null, $senderRatchetKey = null, $counter = null, $previousCounter = null, $cipherText = null, $senderIdentityKey = null, $receiverIdentityKey = null, $serialized = null)
 {
     if ($serialized == null) {
         $version = ByteUtil::intsToByteHighAndLow($messageVersion, self::CURRENT_VERSION);
         $proto_message = new Textsecure_WhisperMessage();
         $proto_message->setRatchetKey((string) $senderRatchetKey->serialize());
         $proto_message->setCounter($counter);
         $proto_message->setPreviousCounter($previousCounter);
         $proto_message->setCiphertext($cipherText);
         $message = $proto_message->serializeToString();
         $mac = $this->getMac($messageVersion, $senderIdentityKey, $receiverIdentityKey, $macKey, ByteUtil::combine([chr((int) $version), $message]));
         $this->serialized = ByteUtil::combine([chr((int) $version), $message, $mac]);
         $this->senderRatchetKey = $senderRatchetKey;
         $this->counter = $counter;
         $this->previousCounter = $previousCounter;
         $this->cipherText = $cipherText;
         $this->messageVersion = $messageVersion;
     } else {
         try {
             $messageParts = ByteUtil::split($serialized, 1, strlen($serialized) - 1 - self::MAC_LENGTH, self::MAC_LENGTH);
             $version = ord($messageParts[0][0]);
             $message = $messageParts[1];
             $mac = $messageParts[2];
             if (ByteUtil::highBitsToInt($version) <= self::UNSUPPORTED_VERSION) {
                 throw new LegacyMessageException("Legacy message " . ByteUtil::highBitsToInt($version));
             }
             if (ByteUtil::highBitsToInt($version) > self::CURRENT_VERSION) {
                 throw new InvalidMessageException("Unknown version: " . ByteUtil::highBitsToInt($version));
             }
             $proto_message = new Textsecure_WhisperMessage();
             try {
                 $proto_message->parseFromString($message);
             } catch (Exception $ex) {
                 throw new InvalidMessageException("Incomplete message.");
             }
             if ($proto_message->getCiphertext() === null || $proto_message->getCounter() === null || $proto_message->getRatchetKey() == null) {
                 throw new InvalidMessageException("Incomplete message.");
             }
             $this->serialized = $serialized;
             $this->senderRatchetKey = Curve::decodePoint($proto_message->getRatchetKey(), 0);
             $this->messageVersion = ByteUtil::highBitsToInt($version);
             $this->counter = $proto_message->getCounter();
             $this->previousCounter = $proto_message->getPreviousCounter();
             $this->cipherText = $proto_message->getCiphertext();
         } catch (Exception $ex) {
             throw new InvalidMessageException($ex->getMessage());
         }
     }
 }
 public function SenderKeyMessage($keyId = null, $iteration = null, $ciphertext = null, $signatureKey = null, $serialized = null)
 {
     if ($serialized == null) {
         $version = ByteUtil::intsToByteHighAndLow(self::CURRENT_VERSION, self::CURRENT_VERSION);
         $proto_message = new Textsecure_SenderKeyMessage();
         $proto_message->setId($keyId);
         $proto_message->setIteration($iteration);
         $proto_message->setCiphertext($ciphertext);
         $message = $proto_message->serializeToString();
         $signature = $this->getSignature($signatureKey, ByteUtil::combine([chr((int) $version), $message]));
         $this->serialized = ByteUtil::combine([chr((int) $version), $message, $signature]);
         $this->messageVersion = self::CURRENT_VERSION;
         $this->keyId = $keyId;
         $this->iteration = $iteration;
         $this->ciphertext = $ciphertext;
     } else {
         try {
             $messageParts = ByteUtil::split($serialized, 1, strlen($serialized) - 1 - self::SIGNATURE_LENGTH, self::SIGNATURE_LENGTH);
             $version = ord($messageParts[0][0]);
             $message = $messageParts[1];
             $signature = $messageParts[2];
             if (ByteUtil::highBitsToInt($version) < 3) {
                 throw new LegacyMessageException("Legacy message: " . ByteUtil::highBitsToInt($version));
             }
             if (ByteUtil::highBitsToInt($version) > self::CURRENT_VERSION) {
                 throw new InvalidMessageException("Unknown version: " . ByteUtil::highBitsToInt($version));
             }
             $proto_message = new Textsecure_SenderKeyMessage();
             try {
                 $proto_message->parseFromString($message);
             } catch (Exception $ex) {
                 throw new InvalidMessageException("Incomplete message");
             }
             if ($proto_message->getId() === null || $proto_message->getIteration() === null || $proto_message->getCiphertext() == null) {
                 throw new InvalidMessageException("Incomplete message");
             }
             $this->serialized = $serialized;
             $this->messageVersion = ByteUtil::highBitsToInt($version);
             $this->keyId = $proto_message->getId();
             $this->iteration = $proto_message->getIteration();
             $this->ciphertext = $proto_message->getCiphertext();
         } catch (Exception $ex) {
             throw new InvalidMessageException($ex->getMessage());
         }
     }
 }
 public function PreKeyWhisperMessage($messageVersion = null, $registrationId = null, $preKeyId = null, $signedPreKeyId = null, $ecPublicBaseKey = null, $identityKey = null, $whisperMessage = null, $serialized = null)
 {
     if ($serialized != null) {
         $this->version = ByteUtil::highBitsToInt($serialized[0]);
         if ($this->version > self::CURRENT_VERSION) {
             throw new InvalidVersionException("Unknown version " . $this->version);
         }
         $preKeyWhisperMessage = new Textsecure_PreKeyWhisperMessage();
         $preKeyWhisperMessage->parseFromString(substr($serialized, 1));
         if ($this->version == 2 && $preKeyWhisperMessage->getPreKeyId() == null || $this->version == 3 && $preKeyWhisperMessage->getSignedPreKeyId() == null || $preKeyWhisperMessage->getBaseKey() == null || $preKeyWhisperMessage->getIdentityKey() == null || $preKeyWhisperMessage->getMessage() == null) {
             throw new InvalidMessageException("Incomplete message");
         }
         $this->serialized = $serialized;
         $this->registrationId = $preKeyWhisperMessage->getRegistrationId();
         $this->preKeyId = $preKeyWhisperMessage->getPreKeyId();
         $this->signedPreKeyId = $preKeyWhisperMessage->getSignedPreKeyId();
         $this->baseKey = Curve::decodePoint((string) $preKeyWhisperMessage->getBaseKey(), 0);
         $this->identityKey = new IdentityKey(Curve::decodePoint((string) $preKeyWhisperMessage->getIdentityKey(), 0));
         $this->message = new WhisperMessage(null, null, null, null, null, null, null, null, $preKeyWhisperMessage->getMessage());
     } else {
         try {
             $this->version = $messageVersion;
             $this->registrationId = $registrationId;
             $this->preKeyId = $preKeyId;
             $this->signedPreKeyId = $signedPreKeyId;
             $this->baseKey = $ecPublicBaseKey;
             $this->identityKey = $identityKey;
             $this->message = $whisperMessage;
             $builder = new Textsecure_PreKeyWhisperMessage();
             $builder->setSignedPreKeyId($this->signedPreKeyId);
             $builder->setBaseKey($this->baseKey->serialize());
             $builder->setIdentityKey($this->identityKey->serialize());
             $builder->setMessage($whisperMessage->serialize());
             $builder->setRegistrationId($this->registrationId);
             if ($preKeyId != null) {
                 $builder->setPreKeyId($preKeyId);
             }
             $versionBytes = ByteUtil::intsToByteHighAndLow($this->version, self::CURRENT_VERSION);
             $messageBytes = $builder->serializeToString();
             $this->serialized = ByteUtil::combine([chr($versionBytes), $messageBytes]);
         } catch (Exception $ex) {
             throw new InvalidMessageException($ex->getMessage() . " - " . $ex->getLine() . " - " . $ex->getFile());
         }
     }
 }