private void handleStaleDevices(TextSecureAddress recipient, StaleDevices staleDevices)
 {
     foreach (uint staleDeviceId in staleDevices.getStaleDevices())
     {
         store.DeleteSession(new AxolotlAddress(recipient.getNumber(), staleDeviceId));
     }
 }
        private async void handleMismatchedDevices(PushServiceSocket socket, TextSecureAddress recipient,
                                                   MismatchedDevices mismatchedDevices)
        {
            try
            {
                foreach (uint extraDeviceId in mismatchedDevices.getExtraDevices())
                {
                    store.DeleteSession(new AxolotlAddress(recipient.getNumber(), extraDeviceId));
                }

                foreach (uint missingDeviceId in mismatchedDevices.getMissingDevices())
                {
                    PreKeyBundle preKey = await socket.getPreKey(recipient, missingDeviceId);

                    try
                    {
                        SessionBuilder sessionBuilder = new SessionBuilder(store, new AxolotlAddress(recipient.getNumber(), missingDeviceId));
                        sessionBuilder.process(preKey);
                    }
                    catch (libaxolotl.exceptions.UntrustedIdentityException e)
                    {
                        throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey());
                    }
                }
            }
            catch (InvalidKeyException e)
            {
                throw new Exception(e.Message);
            }
        }
 /**
  * Construct a TextSecureMessageSender.
  *
  * @param url The URL of the TextSecure server.
  * @param trustStore The trust store containing the TextSecure server's signing TLS certificate.
  * @param user The TextSecure username (eg phone number).
  * @param password The TextSecure user's password.
  * @param store The AxolotlStore.
  * @param eventListener An optional event listener, which fires whenever sessions are
  *                      setup or torn down for a recipient.
  */
 public TextSecureMessageSender(String url, TrustStore trustStore,
                                String user, String password,
                                AxolotlStore store,
                                May <EventListener> eventListener, String userAgent)
 {
     this.socket        = new PushServiceSocket(url, trustStore, new StaticCredentialsProvider(user, password, null), userAgent);
     this.store         = store;
     this.localAddress  = new TextSecureAddress(user);
     this.eventListener = eventListener;
 }
        private async Task <OutgoingPushMessageList> getEncryptedMessages(PushServiceSocket socket,
                                                                          TextSecureAddress recipient,
                                                                          ulong timestamp,
                                                                          byte[] plaintext,
                                                                          bool legacy)
        {
            List <OutgoingPushMessage> messages = new List <OutgoingPushMessage>();

            if (!recipient.Equals(localAddress))
            {
                messages.Add(await getEncryptedMessage(socket, recipient, TextSecureAddress.DEFAULT_DEVICE_ID, plaintext, legacy));
            }

            foreach (uint deviceId in store.GetSubDeviceSessions(recipient.getNumber()))
            {
                messages.Add(await getEncryptedMessage(socket, recipient, deviceId, plaintext, legacy));
            }

            return(new OutgoingPushMessageList(recipient.getNumber(), timestamp, recipient.getRelay().HasValue ? recipient.getRelay().ForceGetValue() : null, messages));
        }
Exemple #5
0
        private void deliver(SmsMessageRecord message)
        {
            try
            {
                TextSecureAddress     address           = getPushAddress(message.getIndividualRecipient().getNumber());
                TextSecureDataMessage textSecureMessage = TextSecureDataMessage.newBuilder()
                                                          .withTimestamp((ulong)TimeUtil.GetUnixTimestampMillis(message.getDateSent()))
                                                          .withBody(message.getBody().getBody())
                                                          .asEndSessionMessage(message.isEndSession())
                                                          .build();

                Debug.WriteLine("TextSendTask deliver");
                messageSender.sendMessage(address, textSecureMessage);
            }
            catch (InvalidNumberException e /*| UnregisteredUserException e*/) {
                //Log.w(TAG, e);
                //throw new InsecureFallbackApprovalException(e);
            } catch (Exception e)
            {
                //Log.w(TAG, e);
                //throw new RetryLaterException(e);
            }
        }
        /**
         * Send a message to a single recipient.
         *
         * @param recipient The message's destination.
         * @param message The message.
         * @throws UntrustedIdentityException
         * @throws IOException
         */
        public async void sendMessage(TextSecureAddress recipient, TextSecureDataMessage message)
        {
            byte[] content = await createMessageContent(message);

            ulong timestamp = message.getTimestamp();
            SendMessageResponse response = await sendMessage(recipient, timestamp, content, true);

            if (response != null && response.getNeedsSync())
            {
                byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, new May <TextSecureAddress>(recipient), timestamp);
                await sendMessage(localAddress, timestamp, syncMessage, false);
            }

            if (message.isEndSession())
            {
                store.DeleteAllSessions(recipient.getNumber());

                if (eventListener.HasValue)
                {
                    eventListener.ForceGetValue().onSecurityEvent(recipient);
                }
            }
        }
        private async Task <SendMessageResponse> sendMessage(TextSecureAddress recipient, ulong timestamp, byte[] content, bool legacy)
        {
            for (int i = 0; i < 3; i++)
            {
                try
                {
                    OutgoingPushMessageList messages = await getEncryptedMessages(socket, recipient, timestamp, content, legacy);

                    return(await socket.sendMessage(messages));
                }
                catch (MismatchedDevicesException mde)
                {
                    Debug.WriteLine(mde.Message, TAG);
                    handleMismatchedDevices(socket, recipient, mde.getMismatchedDevices());
                }
                catch (StaleDevicesException ste)
                {
                    //Log.w(TAG, ste);
                    handleStaleDevices(recipient, ste.getStaleDevices());
                }
            }

            throw new Exception("Failed to resolve conflicts after 3 attempts!");
        }
Exemple #8
0
        private void handleMessage(/*MasterSecretUnion masterSecret, */ TextSecureEnvelope envelope /*, Optional<Long> smsMessageId*/)
        {
            try
            {
                AxolotlStore      axolotlStore = new TextSecureAxolotlStore();
                TextSecureAddress localAddress = new TextSecureAddress(TextSecurePreferences.getLocalNumber());
                TextSecureCipher  cipher       = new TextSecureCipher(localAddress, axolotlStore);

                TextSecureContent content = cipher.decrypt(envelope);

                if (content.getDataMessage().HasValue)
                {
                    TextSecureDataMessage message = content.getDataMessage().ForceGetValue();

                    if (message.isEndSession())
                    {
                        handleEndSessionMessage(/*masterSecret, */ envelope, message /*, smsMessageId*/);
                    }
                    //else if (message.isGroupUpdate()) handleGroupMessage(masterSecret, envelope, message, smsMessageId);
                    //else if (message.getAttachments().isPresent()) handleMediaMessage(masterSecret, envelope, message, smsMessageId);
                    else
                    {
                        handleTextMessage(/*masterSecret, */ envelope, message /*, smsMessageId*/);
                    }
                }

                /*else if (content.getSyncMessage().HasValue) TODO: SYNC enable
                 * {
                 *  TextSecureSyncMessage syncMessage = content.getSyncMessage().ForceGetValue();
                 *
                 *  if (syncMessage.getSent().HasValue) handleSynchronizeSentMessage(masterSecret, syncMessage.getSent().ForceGetValue(), smsMessageId);
                 *  else if (syncMessage.getRequest().HasValue) handleSynchronizeRequestMessage(masterSecret, syncMessage.getRequest().ForceGetValue());
                 * }*/

                if (envelope.isPreKeyWhisperMessage())
                {
                    App.Current.Worker.AddTaskActivities(new RefreshPreKeysTask());
                    //ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob(context));
                }
            }
            catch (InvalidVersionException e)
            {
                //Log.w(TAG, e);
                //handleInvalidVersionMessage(masterSecret, envelope, smsMessageId);
            }

            /* catch (InvalidMessageException | InvalidKeyIdException | InvalidKeyException | MmsException e) {
             *   Log.w(TAG, e);
             *   handleCorruptMessage(masterSecret, envelope, smsMessageId);
             * } catch (NoSessionException e)
             * {
             *   Log.w(TAG, e);
             *   handleNoSessionMessage(masterSecret, envelope, smsMessageId);
             * }
             * catch (LegacyMessageException e)
             * {
             *   Log.w(TAG, e);
             *   handleLegacyMessage(masterSecret, envelope, smsMessageId);
             * }
             * catch (DuplicateMessageException e)
             * {
             *   Log.w(TAG, e);
             *   handleDuplicateMessage(masterSecret, envelope, smsMessageId);
             * }
             * catch (UntrustedIdentityException e)
             * {
             *   Log.w(TAG, e);
             *   handleUntrustedIdentityMessage(masterSecret, envelope, smsMessageId);
             * }*/
        }
 public TextSecureCipher(TextSecureAddress localAddress, AxolotlStore axolotlStore)
 {
     this.axolotlStore = axolotlStore;
     this.localAddress = localAddress;
 }
 /**
  * Send a delivery receipt for a received message.  It is not necessary to call this
  * when receiving messages through {@link org.whispersystems.textsecure.api.TextSecureMessagePipe}.
  * @param recipient The sender of the received message you're acknowledging.
  * @param messageId The message id of the received message you're acknowledging.
  * @throws IOException
  */
 public void sendDeliveryReceipt(TextSecureAddress recipient, ulong messageId)
 {
     this.socket.sendReceipt(recipient.getNumber(), messageId, recipient.getRelay());
 }
        private async Task <OutgoingPushMessage> getEncryptedMessage(PushServiceSocket socket, TextSecureAddress recipient, uint deviceId, byte[] plaintext, bool legacy)
        {
            AxolotlAddress   axolotlAddress = new AxolotlAddress(recipient.getNumber(), deviceId);
            TextSecureCipher cipher         = new TextSecureCipher(localAddress, store);

            if (!store.ContainsSession(axolotlAddress))
            {
                try
                {
                    List <PreKeyBundle> preKeys = await socket.getPreKeys(recipient, deviceId);

                    foreach (PreKeyBundle preKey in preKeys)
                    {
                        try
                        {
                            AxolotlAddress preKeyAddress  = new AxolotlAddress(recipient.getNumber(), preKey.getDeviceId());
                            SessionBuilder sessionBuilder = new SessionBuilder(store, preKeyAddress);
                            sessionBuilder.process(preKey);
                        }
                        catch (libaxolotl.exceptions.UntrustedIdentityException e)
                        {
                            throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey());
                        }
                    }

                    if (eventListener.HasValue)
                    {
                        eventListener.ForceGetValue().onSecurityEvent(recipient);
                    }
                }
                catch (InvalidKeyException e)
                {
                    throw new Exception(e.Message);
                }
            }

            return(cipher.encrypt(axolotlAddress, plaintext, legacy));
        }