KeyExchangeMessage::KeyExchangeMessage(int messageVersion, int sequence, int flags, const DjbECPublicKey &baseKey, const QByteArray &baseKeySignature, const DjbECPublicKey &ratchetKey, const IdentityKey &identityKey)
{
    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;

    textsecure::KeyExchangeMessage message;
    message.set_id((sequence << 5) | flags);
    message.set_basekey(baseKey.serialize().constData());
    message.set_ratchetkey(ratchetKey.serialize().constData());
    message.set_identitykey(identityKey.serialize().constData());

    if (messageVersion >= 3) {
        message.set_basekeysignature(baseKeySignature.constData());
    }

    ::std::string serializedMessage = message.SerializeAsString();
    this->serialized = QByteArray(serializedMessage.data(), serializedMessage.length());
    this->serialized.prepend(ByteUtil::intsToByteHighAndLow(this->version, this->supportedVersion));
}
SenderKeyState::SenderKeyState(int id, int iteration, const ByteArray &chainKey, const DjbECPublicKey &signatureKeyPublic, const DjbECPrivateKey &signatureKeyPrivate)
{
    senderKeyStateStructure = textsecure::SenderKeyStateStructure();
    senderKeyStateStructure.set_senderkeyid(id);
    senderKeyStateStructure.mutable_senderchainkey()->set_iteration(iteration);
    senderKeyStateStructure.mutable_senderchainkey()->set_seed(chainKey.c_str(),
                                                               chainKey.size());
    senderKeyStateStructure.mutable_sendersigningkey()->set_public_(signatureKeyPublic.serialize().c_str(),
                                                                    signatureKeyPublic.serialize().size());
    senderKeyStateStructure.mutable_sendersigningkey()->set_private_(signatureKeyPrivate.serialize().c_str(),
                                                                     signatureKeyPrivate.serialize().size());

    /*textsecure::SenderKeyStateStructure::SenderChainKey senderChainKeyStructure;
    senderChainKeyStructure.set_iteration(iteration);
    senderChainKeyStructure.set_seed(chainKey.c_str());

    textsecure::SenderKeyStateStructure::SenderSigningKey signingKeyStructure;
    signingKeyStructure.set_public_(signatureKeyPublic.serialize().c_str());

    signingKeyStructure.set_private_(signatureKeyPrivate.serialize().c_str());

    senderKeyStateStructure = textsecure::SenderKeyStateStructure();
    senderKeyStateStructure.set_senderkeyid(id);
    senderKeyStateStructure.mutable_senderchainkey()->CopyFrom(senderChainKeyStructure);
    senderKeyStateStructure.mutable_sendersigningkey()->CopyFrom(signingKeyStructure);*/
}
Beispiel #3
0
void SessionBuilder::process(const PreKeyBundle &preKey)
{
    if (!identityKeyStore->isTrustedIdentity(recipientId, preKey.getIdentityKey())) {
        throw UntrustedIdentityException(QString("Untrusted identity: %1").arg(recipientId));
    }

    if (!preKey.getSignedPreKey().serialize().isEmpty() &&
        !Curve::verifySignature(preKey.getSignedPreKey(),
                                preKey.getIdentityKey().getPublicKey().serialize(),
                                preKey.getSignedPreKeySignature()))
    {
        qWarning() << preKey.getIdentityKey().getPublicKey().serialize().toHex();
        qWarning() << preKey.getSignedPreKey().serialize().toHex();
        qWarning() << preKey.getSignedPreKeySignature().toHex();
        throw InvalidKeyException("Invalid signature on device key!");
    }

    if (preKey.getSignedPreKey().serialize().isEmpty() && preKey.getPreKey().serialize().isEmpty()) {
        throw InvalidKeyException("Both signed and unsigned prekeys are absent!");
    }

    bool           supportsV3           = !preKey.getSignedPreKey().serialize().isEmpty();
    SessionRecord *sessionRecord        = sessionStore->loadSession(recipientId, deviceId);
    ECKeyPair      ourBaseKey           = Curve::generateKeyPair();
    DjbECPublicKey theirSignedPreKey    = supportsV3 ? preKey.getSignedPreKey() : preKey.getPreKey();
    DjbECPublicKey theirOneTimePreKey   = preKey.getPreKey();
    int            theirOneTimePreKeyId = theirOneTimePreKey.serialize().isEmpty() ? -1 : preKey.getPreKeyId();

    AliceAxolotlParameters parameters;

    parameters.setOurBaseKey(ourBaseKey);
    parameters.setOurIdentityKey(identityKeyStore->getIdentityKeyPair());
    parameters.setTheirIdentityKey(preKey.getIdentityKey());
    parameters.setTheirSignedPreKey(theirSignedPreKey);
    parameters.setTheirRatchetKey(theirSignedPreKey);
    if (supportsV3) {
        parameters.setTheirOneTimePreKey(theirOneTimePreKey);
    }

    if (!sessionRecord->isFresh()) sessionRecord->archiveCurrentState();

    RatchetingSession::initializeSession(sessionRecord->getSessionState(),
                                         supportsV3 ? 3 : 2,
                                         parameters);

    sessionRecord->getSessionState()->setUnacknowledgedPreKeyMessage(theirOneTimePreKeyId, preKey.getSignedPreKeyId(), ourBaseKey.getPublicKey());
    sessionRecord->getSessionState()->setLocalRegistrationId(identityKeyStore->getLocalRegistrationId());
    sessionRecord->getSessionState()->setRemoteRegistrationId(preKey.getRegistrationId());
    sessionRecord->getSessionState()->setAliceBaseKey(ourBaseKey.getPublicKey().serialize());

    sessionStore->storeSession(recipientId, deviceId, sessionRecord);
    identityKeyStore->saveIdentity(recipientId, preKey.getIdentityKey());
}
PreKeyWhisperMessage::PreKeyWhisperMessage(int messageVersion, ulong registrationId, ulong preKeyId, ulong signedPreKeyId, const DjbECPublicKey &baseKey, const IdentityKey &identityKey, QSharedPointer<WhisperMessage> message)
{
    this->version        = messageVersion;
    this->registrationId = registrationId;
    this->preKeyId       = preKeyId;
    this->signedPreKeyId = signedPreKeyId;
    this->baseKey        = baseKey;
    this->identityKey    = identityKey;
    this->message        = message;

    textsecure::PreKeyWhisperMessage preKeyWhisperMessage;
    preKeyWhisperMessage.set_signedprekeyid(signedPreKeyId);
    QByteArray basekey = baseKey.serialize();
    preKeyWhisperMessage.set_basekey(basekey.constData(), basekey.size());
    QByteArray identitykey = identityKey.serialize();
    preKeyWhisperMessage.set_identitykey(identitykey.constData(), identitykey.size());
    QByteArray bytemessage = message->serialize();
    preKeyWhisperMessage.set_message(bytemessage.constData(), bytemessage.size());
    preKeyWhisperMessage.set_registrationid(registrationId);

    if (preKeyId >= 0) {
        preKeyWhisperMessage.set_prekeyid(preKeyId);
    }

    ::std::string serializedmessage = preKeyWhisperMessage.SerializeAsString();
    QByteArray messageBytes = QByteArray(serializedmessage.data(), serializedmessage.length());

    this->serialized = messageBytes;
    this->serialized.prepend(ByteUtil::intsToByteHighAndLow(this->version, CURRENT_VERSION));
}
Beispiel #5
0
WhisperMessage::WhisperMessage(int messageVersion, const QByteArray &macKey, const DjbECPublicKey &senderRatchetKey, uint counter, uint previousCounter, const QByteArray &ciphertext, const IdentityKey &senderIdentityKey, const IdentityKey &receiverIdentityKey)
{
    textsecure::WhisperMessage whisperMessage;
    QByteArray ratchetKey = senderRatchetKey.serialize();
    whisperMessage.set_ratchetkey(ratchetKey.constData(), ratchetKey.size());
    whisperMessage.set_counter(counter);
    whisperMessage.set_previouscounter(previousCounter);
    whisperMessage.set_ciphertext(ciphertext.constData() ,ciphertext.size());
    ::std::string serializedMessage = whisperMessage.SerializeAsString();
    QByteArray message = QByteArray(serializedMessage.data(), serializedMessage.length());
    message.prepend(ByteUtil::intsToByteHighAndLow(messageVersion, CURRENT_VERSION));
    QByteArray mac     = getMac(messageVersion, senderIdentityKey, receiverIdentityKey, macKey, message);

    this->serialized       = message;
    this->serialized.append(mac);
    this->senderRatchetKey = senderRatchetKey;
    this->counter          = counter;
    this->previousCounter  = previousCounter;
    this->ciphertext       = ciphertext;
    this->messageVersion   = messageVersion;
}