WhisperMessage::WhisperMessage(const QByteArray &serialized) { try { //QList<QByteArray> messageParts = ByteUtil::split(serialized, 1, serialized.size() - 1 - MAC_LENGTH, MAC_LENGTH); qint8 version = serialized[0]; QByteArray message = serialized.mid(1, serialized.size() - MAC_LENGTH - 1); QByteArray mac = serialized.right(MAC_LENGTH); //qDebug() << "serialized size:" << serialized.size() << "message size:" << message.size(); if (ByteUtil::highBitsToInt(version) <= UNSUPPORTED_VERSION) { throw LegacyMessageException("Legacy message: " + ByteUtil::highBitsToInt(version)); } if (ByteUtil::highBitsToInt(version) > CURRENT_VERSION) { throw InvalidMessageException("Unknown version: " + ByteUtil::highBitsToInt(version)); } textsecure::WhisperMessage whisperMessage; whisperMessage.ParsePartialFromArray(message.constData(), message.size()); if (!whisperMessage.has_ciphertext() || !whisperMessage.has_counter() || !whisperMessage.has_ratchetkey()) { qDebug() << "has_ciphertext" << whisperMessage.has_ciphertext(); qDebug() << "has_counter" << whisperMessage.has_counter(); qDebug() << "has_ratchetkey" << whisperMessage.has_ratchetkey(); throw InvalidMessageException("Incomplete message."); } this->serialized = serialized; ::std::string whisperratchetkey = whisperMessage.ratchetkey(); QByteArray whisperratchetkeybytes(whisperratchetkey.data(), whisperratchetkey.length()); this->senderRatchetKey = Curve::decodePoint(whisperratchetkeybytes, 0); this->messageVersion = ByteUtil::highBitsToInt(version); this->counter = whisperMessage.counter(); this->previousCounter = whisperMessage.previouscounter(); ::std::string whisperciphertext = whisperMessage.ciphertext(); this->ciphertext = QByteArray(whisperciphertext.data(), whisperciphertext.length()); } catch (const InvalidKeyException &e) { throw InvalidMessageException(__PRETTY_FUNCTION__, QList<WhisperException>() << e); } }
KeyExchangeMessage::KeyExchangeMessage(const QByteArray &serialized) { QList<QByteArray> parts = ByteUtil::split(serialized, 1, serialized.size() - 1); this->version = ByteUtil::highBitsToInt(parts[0][0]); this->supportedVersion = ByteUtil::lowBitsToInt(parts[0][0]); if (this->version <= CiphertextMessage::UNSUPPORTED_VERSION) { throw LegacyMessageException(QString("Unsupported legacy version: %1").arg(this->version)); } if (this->version > CiphertextMessage::CURRENT_VERSION) { throw InvalidVersionException(QString("Unknown version: %1").arg(this->version)); } textsecure::KeyExchangeMessage message; message.ParseFromArray(parts[1].constData(), parts[1].size()); if (!message.has_id() || !message.has_basekey() || !message.has_ratchetkey() || !message.has_identitykey() || (this->version >=3 && !message.has_basekeysignature())) { throw InvalidMessageException("Some required fields missing!"); } this->sequence = message.id() >> 5; this->flags = message.id() & 0x1f; this->serialized = serialized; ::std::string messagebasekey = message.basekey(); this->baseKey = Curve::decodePoint(QByteArray(messagebasekey.data(), messagebasekey.length()), 0); ::std::string messagebasekeysignature = message.basekeysignature(); this->baseKeySignature = QByteArray(messagebasekeysignature.data(), messagebasekeysignature.length()); ::std::string messageratchetkey = message.ratchetkey(); this->ratchetKey = Curve::decodePoint(QByteArray(messageratchetkey.data(), messageratchetkey.length()), 0); ::std::string messageidentitykey = message.identitykey(); this->identityKey = IdentityKey(QByteArray(messageidentitykey.data(), messageidentitykey.length()), 0); }