protected override async Task<string> ExecuteAsync()
        {
            try
            {
                String sessionKey = TextSecurePreferences.getSignalingKey();
                TextSecureEnvelope envelope = new TextSecureEnvelope(data, sessionKey);

                handle(envelope, true);
            }
            catch (/*IOException | InvalidVersion*/Exception e) {
                Debug.WriteLine($"{this.GetType().Name}: Error: {e.Message}");
            }

            return "";
        }
Beispiel #2
0
        private void handleMessage(TextSecureEnvelope envelope, bool sendExplicitReceipt)
        {
            var worker = App.Current.Worker;
            long messageId = DatabaseFactory.getPushDatabase().Insert(envelope);

            if (sendExplicitReceipt)
            {
                worker.AddTaskActivities(new DeliveryReceiptTask(envelope.getSource(),
                                                      envelope.getTimestamp(),
                                                      envelope.getRelay()));
            }

            worker.AddTaskActivities(new PushDecryptTask(messageId, envelope.getSource()));
            
        }
Beispiel #3
0
        public long Insert(TextSecureEnvelope envelope)
        {
            // TODO check if exists
            var push = new Push()
            {
                Type = envelope.getType(),
                Source = envelope.getSource(),
                DeviceId = envelope.getSourceDevice(),
                LegacyMessage = envelope.hasLegacyMessage() ? Base64.encodeBytes(envelope.getLegacyMessage()) : "",
                Content = envelope.hasContent() ? Base64.encodeBytes(envelope.getContent()) : "",
                Timestamp = TimeUtil.GetDateTime(envelope.getTimestamp())
            };

            try
            {
                conn.Insert(push);
            } catch(Exception e) { Debug.WriteLine(e.Message); }
            

            return push.PushId;
        }
        private void OnMessageReceived(WebSocketConnection sender, WebSocketRequestMessage request)
        {
            WebSocketResponseMessage response = createWebSocketResponse(request);

            Debug.WriteLine($"Verb: {request.Verb}, Path {request.Path}, Body({request.Body.Length}): {request.Body}, Id: {request.Id}");

            try
            {
                if (isTextSecureEnvelope(request))
                {
                    TextSecureEnvelope envelope = new TextSecureEnvelope(request.Body.ToByteArray(),
                                                                         credentialsProvider.GetSignalingKey());

                    MessageReceived(this, envelope);
                }
            }
            //catch (Exception e) { } // ignore for now
            finally
            {
                websocket.sendResponse(response);
            }
        }
Beispiel #5
0
        public void handle(TextSecureEnvelope envelope, bool sendExplicitReceipt)
        {
            if (!isActiveNumber(envelope.getSource()))
            {
                TextSecureDirectory directory = DatabaseFactory.getDirectoryDatabase();
                ContactTokenDetails contactTokenDetails = new ContactTokenDetails();
                contactTokenDetails.setNumber(envelope.getSource());

                directory.setNumber(contactTokenDetails, true);

                // TODO: evtl DirectoryRefresh
            }

            if (envelope.isReceipt()) handleReceipt(envelope);
            else if (envelope.isPreKeyWhisperMessage() || envelope.isWhisperMessage())
            {
                handleMessage(envelope, sendExplicitReceipt);
            }
            else
            {
                Log.Warn($"Received envelope of unknown type: {envelope.GetType()}");
            }
        }
Beispiel #6
0
 private void handleDuplicateMessage(TextSecureEnvelope envelope, May<long> smsMessageId)
 {
     // Let's start ignoring these now
     //    SmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context);
     //
     //    if (smsMessageId <= 0) {
     //      Pair<Long, Long> messageAndThreadId = insertPlaceholder(masterSecret, envelope);
     //      smsDatabase.markAsDecryptDuplicate(messageAndThreadId.first);
     //      MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second);
     //    } else {
     //      smsDatabase.markAsDecryptDuplicate(smsMessageId);
     //    }
 }
Beispiel #7
0
        private void handleLegacyMessage(TextSecureEnvelope envelope, May<long> smsMessageId)
        {
            var smsDatabase = DatabaseFactory.getTextMessageDatabase(); //getEncryptingSmsDatabase(context);

            if (!smsMessageId.HasValue)
            {
                Pair<long, long> messageAndThreadId = insertPlaceholder(envelope);
                smsDatabase.MarkAsLegacyVersion(messageAndThreadId.first());
                //MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second);
            }
            else {
                smsDatabase.MarkAsLegacyVersion(smsMessageId.ForceGetValue());
            }
        }
 public void onMessage(TextSecureEnvelope envelope) { }
        private TextSecureGroup createGroupInfo(TextSecureEnvelope envelope, DataMessage content)
        {
            if (!content.HasGroup) return null;

            TextSecureGroup.Type type;

            switch (content.Group.Type)
            {
                case GroupContext.Types.Type.DELIVER: type = TextSecureGroup.Type.DELIVER; break;
                case GroupContext.Types.Type.UPDATE: type = TextSecureGroup.Type.UPDATE; break;
                case GroupContext.Types.Type.QUIT: type = TextSecureGroup.Type.QUIT; break;
                default: type = TextSecureGroup.Type.UNKNOWN; break;
            }

            if (content.Group.Type != GroupContext.Types.Type.DELIVER)
            {
                String name = null;
                IList<String> members = null;
                TextSecureAttachmentPointer avatar = null;

                if (content.Group.HasName)
                {
                    name = content.Group.Name;
                }

                if (content.Group.MembersCount > 0)
                {
                    members = content.Group.MembersList;
                }

                if (content.Group.HasAvatar)
                {
                    avatar = new TextSecureAttachmentPointer(content.Group.Avatar.Id,
                                                             content.Group.Avatar.ContentType,
                                                             content.Group.Avatar.Key.ToByteArray(),
                                                             envelope.getRelay());
                }

                return new TextSecureGroup(type, content.Group.Id.ToByteArray(), name, members, avatar);
            }

            return new TextSecureGroup(content.Group.Id.ToByteArray());
        }
        private TextSecureDataMessage createTextSecureMessage(TextSecureEnvelope envelope, DataMessage content)
        {
            TextSecureGroup groupInfo = createGroupInfo(envelope, content);
            LinkedList<TextSecureAttachment> attachments = new LinkedList<TextSecureAttachment>();
            bool endSession = ((content.Flags & (uint)DataMessage.Types.Flags.END_SESSION) != 0);

            foreach (AttachmentPointer pointer in content.AttachmentsList)
            {
                attachments.AddLast(new TextSecureAttachmentPointer(pointer.Id,
                                                                pointer.ContentType,
                                                                pointer.Key.ToByteArray(),
                                                                envelope.getRelay(),
                                                                pointer.HasSize ? new May<uint>(pointer.Size) : May<uint>.NoValue,
                                                                pointer.HasThumbnail ? new May<byte[]>(pointer.Thumbnail.ToByteArray()) : May<byte[]>.NoValue));
            }

            return new TextSecureDataMessage(envelope.getTimestamp(), groupInfo, attachments,
                                             content.Body, endSession);
        }
Beispiel #11
0
        private void handleMessage(TextSecureEnvelope envelope, May<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(envelope, message, smsMessageId);
                    else if (message.isGroupUpdate()) handleGroupMessage(envelope, message, smsMessageId);
                    else if (message.getAttachments().HasValue) handleMediaMessage(envelope, message, smsMessageId);
                    else handleTextMessage(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.Warn(e);
                handleInvalidVersionMessage(envelope, smsMessageId);
            }
            catch (InvalidMessageException e)
            {
                Log.Warn(e);
                handleCorruptMessage(envelope, smsMessageId);
            }
            catch (InvalidKeyIdException e)
            {
                Log.Warn(e);
                handleCorruptMessage(envelope, smsMessageId);
            }
            catch (InvalidKeyException e)
            {
                Log.Warn(e);
                handleCorruptMessage(envelope, smsMessageId);
            }
            catch (NoSessionException e)
            {
                Log.Warn(e);
                handleNoSessionMessage(envelope, smsMessageId);
            }
            catch (LegacyMessageException e)
            {
                Log.Warn(e);
                handleLegacyMessage(envelope, smsMessageId);
            }
            catch (DuplicateMessageException e)
            {
                Log.Warn(e);
                handleDuplicateMessage(envelope, smsMessageId);
            }
            catch (libaxolotl.exceptions.UntrustedIdentityException e)
            {
                Log.Warn(e);
                handleUntrustedIdentityMessage(envelope, smsMessageId);
            }
            catch (Exception e)
            {
                Log.Warn($"Unexpected Exception");
            }
        }
Beispiel #12
0
 private void handleReceipt(TextSecureEnvelope envelope)
 {
     Log.Debug($"Received receipt: (XXXXX, {envelope.getTimestamp()})");
     DatabaseFactory.getMessageDatabase().incrementDeliveryReceiptCount(envelope.getSource(),
                                                                              (long)envelope.getTimestamp());
 }
Beispiel #13
0
 private void OnMessageRecevied(TextSecureMessagePipe sender, TextSecureEnvelope envelope)
 {
     Log.Debug("Push message recieved");
     var task = new PushContentReceiveTask();
     task.handle(envelope, false);
     //throw new NotImplementedException("OnMessageReceived");
 }
Beispiel #14
0
        private void handleUntrustedIdentityMessage(TextSecureEnvelope envelope, May<long> smsMessageId)
        {
            try
            {
                var database = DatabaseFactory.getTextMessageDatabase(); //getEncryptingSmsDatabase(context);
                Recipients recipients = RecipientFactory.getRecipientsFromString(envelope.getSource(), false);
                long recipientId = recipients.getPrimaryRecipient().getRecipientId();
                PreKeyWhisperMessage whisperMessage = new PreKeyWhisperMessage(envelope.getLegacyMessage());
                IdentityKey identityKey = whisperMessage.getIdentityKey();
                String encoded = Base64.encodeBytes(envelope.getLegacyMessage());
                IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(), envelope.getSourceDevice(),
                                                                               envelope.getTimestamp(), encoded,
                                                                               May<TextSecureGroup>.NoValue);

                if (!smsMessageId.HasValue)
                {
                    IncomingPreKeyBundleMessage bundleMessage = new IncomingPreKeyBundleMessage(textMessage, encoded);
                    Pair<long, long> messageAndThreadId = database.InsertMessageInbox(bundleMessage);

                    database.SetMismatchedIdentity(messageAndThreadId.first(), recipientId, identityKey);
                    //MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second);
                }
                else
                {
                    var messageId = smsMessageId.ForceGetValue();
                    database.UpdateMessageBody(messageId, encoded);
                    database.MarkAsPreKeyBundle(messageId);
                    database.SetMismatchedIdentity(messageId, recipientId, identityKey);
                }
            }
            catch (InvalidMessageException e)
            {
                throw new InvalidOperationException(e.Message);
            }
            catch (InvalidVersionException e)
            {
                throw new InvalidOperationException(e.Message);
            }
        }
Beispiel #15
0
        private void handleEndSessionMessage(TextSecureEnvelope envelope,
                                             TextSecureDataMessage message,
                                             May<long> smsMessageId)
        {
            var smsDatabase = DatabaseFactory.getTextMessageDatabase();//getEncryptingSmsDatabase(context);
            var incomingTextMessage = new IncomingTextMessage(envelope.getSource(),
                                                                                envelope.getSourceDevice(),
                                                                                message.getTimestamp(),
                                                                                "", May<TextSecureGroup>.NoValue);

            long threadId;

            if (!smsMessageId.HasValue)
            {
                IncomingEndSessionMessage incomingEndSessionMessage = new IncomingEndSessionMessage(incomingTextMessage);
                Pair<long, long> messageAndThreadId = smsDatabase.InsertMessageInbox(incomingEndSessionMessage);

                threadId = messageAndThreadId.second();
            }
            else
            {
                var messageId = smsMessageId.ForceGetValue();
                smsDatabase.MarkAsEndSession(messageId);
                threadId = smsDatabase.GetThreadIdForMessage(messageId);
            }

            SessionStore sessionStore = new TextSecureAxolotlStore();
            sessionStore.DeleteAllSessions(envelope.getSource());

            //SecurityEvent.broadcastSecurityUpdateEvent(context, threadId);
            //MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), threadId);
        }
Beispiel #16
0
        private Pair<long, long> insertPlaceholder(TextSecureEnvelope envelope)
        {
            var database = DatabaseFactory.getTextMessageDatabase(); //getEncryptingSmsDatabase(context);
            IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(), envelope.getSourceDevice(),
                                                                        envelope.getTimestamp(), "",
                                                                        May<TextSecureGroup>.NoValue);

            textMessage = new IncomingEncryptedMessage(textMessage, "");
            return database.InsertMessageInbox(textMessage);
        }
Beispiel #17
0
        private void handleGroupMessage(TextSecureEnvelope envelope, TextSecureDataMessage message, May<long> smsMessageId)
        {
            //GroupMessageProcessor.process(envelope, message, false); // TODO: GROUP enable

            if (smsMessageId.HasValue)
            {
                DatabaseFactory.getTextMessageDatabase().DeleteThread(smsMessageId.ForceGetValue()); //getSmsDatabase(context).deleteMessage(smsMessageId.get());
            }
        }
        private byte[] decrypt(TextSecureEnvelope envelope, byte[] ciphertext)

        {
            AxolotlAddress sourceAddress = new AxolotlAddress(envelope.getSource(), envelope.getSourceDevice());
            SessionCipher sessionCipher = new SessionCipher(axolotlStore, sourceAddress);

            byte[] paddedMessage;

            if (envelope.isPreKeyWhisperMessage())
            {
                paddedMessage = sessionCipher.decrypt(new PreKeyWhisperMessage(ciphertext));
            }
            else if (envelope.isWhisperMessage())
            {
                paddedMessage = sessionCipher.decrypt(new WhisperMessage(ciphertext));
            }
            else
            {
                throw new InvalidMessageException("Unknown type: " + envelope.getType());
            }

            PushTransportDetails transportDetails = new PushTransportDetails(sessionCipher.getSessionVersion());
            return transportDetails.getStrippedPaddingMessageBody(paddedMessage);
        }
Beispiel #19
0
        private void handleSynchronizeSentMessage(TextSecureEnvelope envelope, SentTranscriptMessage message, May<long> smsMessageId) // throws MmsException
        {
            long threadId;

            if (message.getMessage().isGroupUpdate())
            {
                throw new NotImplementedException("GROUP handleSynchronizeSentMessage");
                //threadId = GroupMessageProcessor.process(context, masterSecret, envelope, message.getMessage(), true); // TODO: Group enable
            }
            else if (message.getMessage().getAttachments().HasValue)
            {
                threadId = handleSynchronizeSentMediaMessage(message, smsMessageId);
            }
            else {
                threadId = handleSynchronizeSentTextMessage(message, smsMessageId);
            }

            if (threadId == 0L) return;

            DatabaseFactory.getThreadDatabase().SetRead(threadId);
            //MessageNotifier.updateNotification(getContext(), masterSecret.getMasterSecret().orNull());
        }
        private TextSecureSyncMessage createSynchronizeMessage(TextSecureEnvelope envelope, SyncMessage content)
        {
            if (content.HasSent)
            {
                SyncMessage.Types.Sent sentContent = content.Sent;
                return TextSecureSyncMessage.forSentTranscript(new SentTranscriptMessage(sentContent.Destination,
                                                                           sentContent.Timestamp,
                                                                           createTextSecureMessage(envelope, sentContent.Message)));
            }

            if (content.HasRequest)
            {
                return TextSecureSyncMessage.forRequest(new RequestMessage(content.Request));
            }

            return TextSecureSyncMessage.empty();
        }
Beispiel #21
0
        private void handleMediaMessage(TextSecureEnvelope envelope, TextSecureDataMessage message, May<long> smsMessageId) // throws MmsException
        {
            throw new NotImplementedException("handleMediaMessage");
            /*
            var database = DatabaseFactory.getMediaMessageDatabase(); //getMmsDatabase(context);
            String localNumber = TextSecurePreferences.getLocalNumber(context);
            IncomingMediaMessage mediaMessage = new IncomingMediaMessage(masterSecret, envelope.getSource(),
                                                                 localNumber, message.getTimestamp(),
                                                                 Optional.fromNullable(envelope.getRelay()),
                                                                 message.getBody(),
                                                                 message.getGroupInfo(),
                                                                 message.getAttachments());

            Pair<long, long> messageAndThreadId = database.insertSecureDecryptedMessageInbox(mediaMessage, -1);
            List<DatabaseAttachment> attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachmentsForMessage(messageAndThreadId.first);

            for (DatabaseAttachment attachment : attachments)
            {
                ApplicationContext.getInstance(context)
                                  .getJobManager()
                                  .add(new AttachmentDownloadJob(context, messageAndThreadId.first,
                                                                 attachment.getAttachmentId()));
            }

            if (smsMessageId.isPresent())
            {
                DatabaseFactory.getSmsDatabase(context).deleteMessage(smsMessageId.get());
            }

            MessageNotifier.updateNotification(context, masterSecret.getMasterSecret().orNull(), messageAndThreadId.second);*/
        }
        /**
         * Decrypt a received {@link org.whispersystems.textsecure.api.messages.TextSecureEnvelope}
         *
         * @param envelope The received TextSecureEnvelope
         * @return a decrypted TextSecureMessage
         * @throws InvalidVersionException
         * @throws InvalidMessageException
         * @throws InvalidKeyException
         * @throws DuplicateMessageException
         * @throws InvalidKeyIdException
         * @throws UntrustedIdentityException
         * @throws LegacyMessageException
         * @throws NoSessionException
         */
        public TextSecureContent decrypt(TextSecureEnvelope envelope)
        {
            try
            {
                TextSecureContent content = new TextSecureContent();

                if (envelope.hasLegacyMessage())
                {
                    DataMessage message = DataMessage.ParseFrom(decrypt(envelope, envelope.getLegacyMessage()));
                    content = new TextSecureContent(createTextSecureMessage(envelope, message));
                }
                else if (envelope.hasContent())
                {
                    Content message = Content.ParseFrom(decrypt(envelope, envelope.getContent()));

                    if (message.HasDataMessage)
                    {
                        content = new TextSecureContent(createTextSecureMessage(envelope, message.DataMessage));
                    }
                    else if (message.HasSyncMessage && localAddress.getNumber().Equals(envelope.getSource()))
                    {
                        content = new TextSecureContent(createSynchronizeMessage(envelope, message.SyncMessage));
                    }
                }

                return content;
            }
            catch (InvalidProtocolBufferException e)
            {
                throw new InvalidMessageException(e);
            }
        }
Beispiel #23
0
        private void handleTextMessage(/*@NonNull MasterSecretUnion masterSecret,*/
                                       TextSecureEnvelope envelope,
                                       TextSecureDataMessage message,
                                       May<long> smsMessageId)
        {
            var textMessageDatabase = DatabaseFactory.getTextMessageDatabase();
            String body = message.getBody().HasValue ? message.getBody().ForceGetValue() : "";


            IncomingTextMessage textMessage = new IncomingTextMessage(envelope.getSource(),
                                                                      envelope.getSourceDevice(),
                                                                      message.getTimestamp(), body,
                                                                      message.getGroupInfo());

            textMessage = new IncomingEncryptedMessage(textMessage, body);
            var messageAndThreadId = textMessageDatabase.InsertMessageInbox(textMessage);
            
            ToastHelper.NotifyNewMessage(messageAndThreadId.second());
        }
        private void processIncomingMessageRecord(MessageRecord record)
        {
            try
            {
                PushDatabase pushDatabase = DatabaseFactory.getPushDatabase();
                var messageDatabase = DatabaseFactory.getMessageDatabase();

                messageDatabase.RemoveMismatchedIdentity(record.MessageId,
                                                     mismatch.RecipientId,
                                                     mismatch.IdentityKey);

                TextSecureEnvelope envelope = new TextSecureEnvelope((uint)TextSecureProtos.Envelope.Types.Type.PREKEY_BUNDLE,
                                                                     record.IndividualRecipient.getNumber(),
                                                                     (uint)record.RecipientDeviceId, "",
                                                                     (ulong)TimeUtil.GetUnixTimestamp(record.DateSent),
                                                                     Base64.decode(record.Body.Body),
                                                                     null);

                long pushId = pushDatabase.Insert(envelope);

                var task = new PushDecryptTask(pushId, record.MessageId, record.IndividualRecipient.getNumber());
                App.Current.Worker.AddTaskActivities(task);
            }
            catch (IOException e)
            {
                throw new Exception();
            }
        }
        public async Task<List<TextSecureEnvelope>> retrieveMessages(MessageReceivedCallback callback)
        {
            List<TextSecureEnvelope> results = new List<TextSecureEnvelope>();
            List<TextSecureEnvelopeEntity> entities = await socket.getMessages();

            foreach (TextSecureEnvelopeEntity entity in entities)
            {
                TextSecureEnvelope envelope = new TextSecureEnvelope(entity.getType(), entity.getSource(),
                                                                      entity.getSourceDevice(), entity.getRelay(),
                                                                      entity.getTimestamp(), entity.getMessage(),
                                                                      entity.getContent());

                callback.onMessage(envelope);
                results.Add(envelope);

                socket.acknowledgeMessage(entity.getSource(), entity.getTimestamp());
            }

            return results;
        }