Search in sources :

Example 1 with SessionBuilder

use of org.whispersystems.libsignal.SessionBuilder in project Conversations by siacs.

the class AxolotlService method buildSessionFromPEP.

private ListenableFuture<XmppAxolotlSession> buildSessionFromPEP(final SignalProtocolAddress address, OnSessionBuildFromPep callback) {
    final SettableFuture<XmppAxolotlSession> sessionSettableFuture = SettableFuture.create();
    Log.i(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Building new session for " + address.toString());
    if (address.equals(getOwnAxolotlAddress())) {
        throw new AssertionError("We should NEVER build a session with ourselves. What happened here?!");
    }
    final Jid jid = Jid.of(address.getName());
    final boolean oneOfOurs = jid.asBareJid().equals(account.getJid().asBareJid());
    IqPacket bundlesPacket = mXmppConnectionService.getIqGenerator().retrieveBundlesForDevice(jid, address.getDeviceId());
    mXmppConnectionService.sendIqPacket(account, bundlesPacket, (account, packet) -> {
        if (packet.getType() == IqPacket.TYPE.TIMEOUT) {
            fetchStatusMap.put(address, FetchStatus.TIMEOUT);
            sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. Timeout"));
        } else if (packet.getType() == IqPacket.TYPE.RESULT) {
            Log.d(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Received preKey IQ packet, processing...");
            final IqParser parser = mXmppConnectionService.getIqParser();
            final List<PreKeyBundle> preKeyBundleList = parser.preKeys(packet);
            final PreKeyBundle bundle = parser.bundle(packet);
            if (preKeyBundleList.isEmpty() || bundle == null) {
                Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "preKey IQ packet invalid: " + packet);
                fetchStatusMap.put(address, FetchStatus.ERROR);
                finishBuildingSessionsFromPEP(address);
                if (callback != null) {
                    callback.onSessionBuildFailed();
                }
                sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. IQ Packet Invalid"));
                return;
            }
            Random random = new Random();
            final PreKeyBundle preKey = preKeyBundleList.get(random.nextInt(preKeyBundleList.size()));
            if (preKey == null) {
                // should never happen
                fetchStatusMap.put(address, FetchStatus.ERROR);
                finishBuildingSessionsFromPEP(address);
                if (callback != null) {
                    callback.onSessionBuildFailed();
                }
                sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. No suitable PreKey found"));
                return;
            }
            final PreKeyBundle preKeyBundle = new PreKeyBundle(0, address.getDeviceId(), preKey.getPreKeyId(), preKey.getPreKey(), bundle.getSignedPreKeyId(), bundle.getSignedPreKey(), bundle.getSignedPreKeySignature(), bundle.getIdentityKey());
            try {
                SessionBuilder builder = new SessionBuilder(axolotlStore, address);
                builder.process(preKeyBundle);
                XmppAxolotlSession session = new XmppAxolotlSession(account, axolotlStore, address, bundle.getIdentityKey());
                sessions.put(address, session);
                if (Config.X509_VERIFICATION) {
                    // TODO; maybe inject callback in here too
                    sessionSettableFuture.setFuture(verifySessionWithPEP(session));
                } else {
                    FingerprintStatus status = getFingerprintTrust(CryptoHelper.bytesToHex(bundle.getIdentityKey().getPublicKey().serialize()));
                    FetchStatus fetchStatus;
                    if (status != null && status.isVerified()) {
                        fetchStatus = FetchStatus.SUCCESS_VERIFIED;
                    } else if (status != null && status.isTrusted()) {
                        fetchStatus = FetchStatus.SUCCESS_TRUSTED;
                    } else {
                        fetchStatus = FetchStatus.SUCCESS;
                    }
                    fetchStatusMap.put(address, fetchStatus);
                    finishBuildingSessionsFromPEP(address);
                    if (callback != null) {
                        callback.onSessionBuildSuccessful();
                    }
                    sessionSettableFuture.set(session);
                }
            } catch (UntrustedIdentityException | InvalidKeyException e) {
                Log.e(Config.LOGTAG, AxolotlService.getLogprefix(account) + "Error building session for " + address + ": " + e.getClass().getName() + ", " + e.getMessage());
                fetchStatusMap.put(address, FetchStatus.ERROR);
                finishBuildingSessionsFromPEP(address);
                if (oneOfOurs && cleanedOwnDeviceIds.add(address.getDeviceId())) {
                    removeFromDeviceAnnouncement(address.getDeviceId());
                }
                if (callback != null) {
                    callback.onSessionBuildFailed();
                }
                sessionSettableFuture.setException(new CryptoFailedException(e));
            }
        } else {
            fetchStatusMap.put(address, FetchStatus.ERROR);
            Element error = packet.findChild("error");
            boolean itemNotFound = error != null && error.hasChild("item-not-found");
            Log.d(Config.LOGTAG, getLogprefix(account) + "Error received while building session:" + packet.findChild("error"));
            finishBuildingSessionsFromPEP(address);
            if (oneOfOurs && itemNotFound && cleanedOwnDeviceIds.add(address.getDeviceId())) {
                removeFromDeviceAnnouncement(address.getDeviceId());
            }
            if (callback != null) {
                callback.onSessionBuildFailed();
            }
            sessionSettableFuture.setException(new CryptoFailedException("Unable to build session. IQ Packet Error"));
        }
    });
    return sessionSettableFuture;
}
Also used : IqParser(eu.siacs.conversations.parser.IqParser) Jid(eu.siacs.conversations.xmpp.Jid) Element(eu.siacs.conversations.xml.Element) SessionBuilder(org.whispersystems.libsignal.SessionBuilder) IqPacket(eu.siacs.conversations.xmpp.stanzas.IqPacket) PreKeyBundle(org.whispersystems.libsignal.state.PreKeyBundle) Random(java.util.Random) List(java.util.List) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList)

Example 2 with SessionBuilder

use of org.whispersystems.libsignal.SessionBuilder in project Signal-Android by WhisperSystems.

the class SignalServiceMessageSender method getEncryptedMessage.

private OutgoingPushMessage getEncryptedMessage(PushServiceSocket socket, SignalServiceAddress recipient, Optional<UnidentifiedAccess> unidentifiedAccess, int deviceId, EnvelopeContent plaintext) throws IOException, InvalidKeyException, UntrustedIdentityException {
    SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.getIdentifier(), deviceId);
    SignalServiceCipher cipher = new SignalServiceCipher(localAddress, localDeviceId, store, sessionLock, null);
    if (!store.containsSession(signalProtocolAddress)) {
        try {
            List<PreKeyBundle> preKeys = socket.getPreKeys(recipient, unidentifiedAccess, deviceId);
            for (PreKeyBundle preKey : preKeys) {
                try {
                    SignalProtocolAddress preKeyAddress = new SignalProtocolAddress(recipient.getIdentifier(), preKey.getDeviceId());
                    SignalSessionBuilder sessionBuilder = new SignalSessionBuilder(sessionLock, new SessionBuilder(store, preKeyAddress));
                    sessionBuilder.process(preKey);
                } catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
                    throw new UntrustedIdentityException("Untrusted identity key!", recipient.getIdentifier(), preKey.getIdentityKey());
                }
            }
            if (eventListener.isPresent()) {
                eventListener.get().onSecurityEvent(recipient);
            }
        } catch (InvalidKeyException e) {
            throw new IOException(e);
        }
    }
    try {
        return cipher.encrypt(signalProtocolAddress, unidentifiedAccess, plaintext);
    } catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
        throw new UntrustedIdentityException("Untrusted on send", recipient.getIdentifier(), e.getUntrustedIdentity());
    }
}
Also used : PreKeyBundle(org.whispersystems.libsignal.state.PreKeyBundle) SignalSessionBuilder(org.whispersystems.signalservice.api.crypto.SignalSessionBuilder) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) SignalServiceCipher(org.whispersystems.signalservice.api.crypto.SignalServiceCipher) SignalGroupSessionBuilder(org.whispersystems.signalservice.api.crypto.SignalGroupSessionBuilder) GroupSessionBuilder(org.whispersystems.libsignal.groups.GroupSessionBuilder) SessionBuilder(org.whispersystems.libsignal.SessionBuilder) SignalSessionBuilder(org.whispersystems.signalservice.api.crypto.SignalSessionBuilder) IOException(java.io.IOException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress)

Example 3 with SessionBuilder

use of org.whispersystems.libsignal.SessionBuilder in project Smack by igniterealtime.

the class SignalOmemoService method processBundle.

@Override
protected void processBundle(OmemoManager omemoManager, PreKeyBundle contactsBundle, OmemoDevice contactsDevice) throws CorruptedOmemoKeyException {
    SignalOmemoStoreConnector connector = new SignalOmemoStoreConnector(omemoManager, getOmemoStoreBackend());
    SessionBuilder builder = new SessionBuilder(connector, connector, connector, connector, SignalOmemoStoreConnector.asAddress(contactsDevice));
    try {
        builder.process(contactsBundle);
        LOGGER.log(Level.FINE, "Session built with " + contactsDevice);
    } catch (org.whispersystems.libsignal.InvalidKeyException e) {
        throw new CorruptedOmemoKeyException(e);
    } catch (UntrustedIdentityException e) {
        // This should never happen.
        throw new AssertionError(e);
    }
}
Also used : UntrustedIdentityException(org.whispersystems.libsignal.UntrustedIdentityException) SessionBuilder(org.whispersystems.libsignal.SessionBuilder) CorruptedOmemoKeyException(org.jivesoftware.smackx.omemo.exceptions.CorruptedOmemoKeyException)

Example 4 with SessionBuilder

use of org.whispersystems.libsignal.SessionBuilder in project libsignal-service-java by signalapp.

the class SignalServiceMessageSender method getEncryptedMessage.

private OutgoingPushMessage getEncryptedMessage(PushServiceSocket socket, SignalServiceAddress recipient, Optional<UnidentifiedAccess> unidentifiedAccess, int deviceId, byte[] plaintext) throws IOException, InvalidKeyException, UntrustedIdentityException {
    SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.getIdentifier(), deviceId);
    SignalServiceCipher cipher = new SignalServiceCipher(localAddress, store, null);
    if (!store.containsSession(signalProtocolAddress)) {
        try {
            List<PreKeyBundle> preKeys = socket.getPreKeys(recipient, unidentifiedAccess, deviceId);
            for (PreKeyBundle preKey : preKeys) {
                try {
                    SignalProtocolAddress preKeyAddress = new SignalProtocolAddress(recipient.getIdentifier(), preKey.getDeviceId());
                    SessionBuilder sessionBuilder = new SessionBuilder(store, preKeyAddress);
                    sessionBuilder.process(preKey);
                } catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
                    throw new UntrustedIdentityException("Untrusted identity key!", recipient.getIdentifier(), preKey.getIdentityKey());
                }
            }
            if (eventListener.isPresent()) {
                eventListener.get().onSecurityEvent(recipient);
            }
        } catch (InvalidKeyException e) {
            throw new IOException(e);
        }
    }
    try {
        return cipher.encrypt(signalProtocolAddress, unidentifiedAccess, plaintext);
    } catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
        throw new UntrustedIdentityException("Untrusted on send", recipient.getIdentifier(), e.getUntrustedIdentity());
    }
}
Also used : PreKeyBundle(org.whispersystems.libsignal.state.PreKeyBundle) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) SignalServiceCipher(org.whispersystems.signalservice.api.crypto.SignalServiceCipher) SessionBuilder(org.whispersystems.libsignal.SessionBuilder) IOException(java.io.IOException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress)

Example 5 with SessionBuilder

use of org.whispersystems.libsignal.SessionBuilder in project libsignal-service-java by signalapp.

the class SignalServiceMessageSender method getEncryptedMessage.

private OutgoingPushMessage getEncryptedMessage(PushServiceSocket socket, SignalServiceAddress recipient, int deviceId, byte[] plaintext, boolean silent) throws IOException, UntrustedIdentityException {
    SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.getNumber(), deviceId);
    SignalServiceCipher cipher = new SignalServiceCipher(localAddress, store);
    if (!store.containsSession(signalProtocolAddress)) {
        try {
            List<PreKeyBundle> preKeys = socket.getPreKeys(recipient, deviceId);
            for (PreKeyBundle preKey : preKeys) {
                try {
                    SignalProtocolAddress preKeyAddress = new SignalProtocolAddress(recipient.getNumber(), preKey.getDeviceId());
                    SessionBuilder sessionBuilder = new SessionBuilder(store, preKeyAddress);
                    sessionBuilder.process(preKey);
                } catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
                    throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey());
                }
            }
            if (eventListener.isPresent()) {
                eventListener.get().onSecurityEvent(recipient);
            }
        } catch (InvalidKeyException e) {
            throw new IOException(e);
        }
    }
    try {
        return cipher.encrypt(signalProtocolAddress, plaintext, silent);
    } catch (org.whispersystems.libsignal.UntrustedIdentityException e) {
        throw new UntrustedIdentityException("Untrusted on send", recipient.getNumber(), e.getUntrustedIdentity());
    }
}
Also used : PreKeyBundle(org.whispersystems.libsignal.state.PreKeyBundle) UntrustedIdentityException(org.whispersystems.signalservice.api.crypto.UntrustedIdentityException) SignalServiceCipher(org.whispersystems.signalservice.api.crypto.SignalServiceCipher) SessionBuilder(org.whispersystems.libsignal.SessionBuilder) IOException(java.io.IOException) InvalidKeyException(org.whispersystems.libsignal.InvalidKeyException) SignalProtocolAddress(org.whispersystems.libsignal.SignalProtocolAddress)

Aggregations

SessionBuilder (org.whispersystems.libsignal.SessionBuilder)10 PreKeyBundle (org.whispersystems.libsignal.state.PreKeyBundle)9 InvalidKeyException (org.whispersystems.libsignal.InvalidKeyException)8 IOException (java.io.IOException)7 SignalProtocolAddress (org.whispersystems.libsignal.SignalProtocolAddress)7 UntrustedIdentityException (org.whispersystems.signalservice.api.crypto.UntrustedIdentityException)7 GroupSessionBuilder (org.whispersystems.libsignal.groups.GroupSessionBuilder)4 SignalGroupSessionBuilder (org.whispersystems.signalservice.api.crypto.SignalGroupSessionBuilder)4 SignalServiceCipher (org.whispersystems.signalservice.api.crypto.SignalServiceCipher)4 SignalSessionBuilder (org.whispersystems.signalservice.api.crypto.SignalSessionBuilder)4 Random (java.util.Random)2 UntrustedIdentityException (org.whispersystems.libsignal.UntrustedIdentityException)2 ContentHint (org.whispersystems.signalservice.api.crypto.ContentHint)2 ImmutableList (com.google.common.collect.ImmutableList)1 Account (de.pixart.messenger.entities.Account)1 IqParser (de.pixart.messenger.parser.IqParser)1 OnIqPacketReceived (de.pixart.messenger.xmpp.OnIqPacketReceived)1 InvalidJidException (de.pixart.messenger.xmpp.jid.InvalidJidException)1 IqPacket (de.pixart.messenger.xmpp.stanzas.IqPacket)1 IqParser (eu.siacs.conversations.parser.IqParser)1