Exemplo n.º 1
0
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);
}