Пример #1
0
        private byte[] createMultiDeviceSentTranscriptContent(byte[] content, May <SignalServiceAddress> recipient, ulong timestamp)
        {
            try
            {
                Content.Builder                container   = Content.CreateBuilder();
                SyncMessage.Builder            syncMessage = SyncMessage.CreateBuilder();
                SyncMessage.Types.Sent.Builder sentMessage = SyncMessage.Types.Sent.CreateBuilder();
                DataMessage dataMessage = DataMessage.ParseFrom(content);

                sentMessage.SetTimestamp(timestamp);
                sentMessage.SetMessage(dataMessage);

                if (recipient.HasValue)
                {
                    sentMessage.SetDestination(recipient.ForceGetValue().getNumber());
                }

                if (dataMessage.ExpireTimer > 0)
                {
                    sentMessage.SetExpirationStartTimestamp((ulong)Util.CurrentTimeMillis());
                }

                return(container.SetSyncMessage(syncMessage.SetSent(sentMessage)).Build().ToByteArray());
            }
            catch (InvalidProtocolBufferException e)
            {
                throw new Exception(e.Message);
            }
        }
        private SenderKeyState(uint id, uint iteration, byte[] chainKey,
                               IEcPublicKey signatureKeyPublic,
                               May <IEcPrivateKey> signatureKeyPrivate)
        {
            SenderKeyStateStructure.Types.SenderChainKey senderChainKeyStructure = new SenderKeyStateStructure.Types.SenderChainKey
            {
                Iteration = iteration,
                Seed      = ByteString.CopyFrom(chainKey)
            };

            SenderKeyStateStructure.Types.SenderSigningKey signingKeyStructure = new SenderKeyStateStructure.Types.SenderSigningKey
            {
                Public = ByteString.CopyFrom(signatureKeyPublic.Serialize())
            };

            if (signatureKeyPrivate.HasValue)
            {
                signingKeyStructure.Private = ByteString.CopyFrom(signatureKeyPrivate.ForceGetValue().Serialize());
            }

            _senderKeyStateStructure = new SenderKeyStateStructure
            {
                SenderKeyId      = id,
                SenderChainKey   = senderChainKeyStructure,
                SenderSigningKey = signingKeyStructure
            };
        }
Пример #3
0
        private byte[] CreateSentTranscriptMessage(byte[] rawContent, May <SignalServiceAddress> recipient, ulong timestamp)
        {
            {
                try
                {
                    Content content                    = new Content {
                    };
                    SyncMessage syncMessage            = new SyncMessage {
                    };
                    SyncMessage.Types.Sent sentMessage = new SyncMessage.Types.Sent {
                    };

                    sentMessage.Timestamp = timestamp;
                    sentMessage.Message   = DataMessage.Parser.ParseFrom(rawContent);

                    if (recipient.HasValue)
                    {
                        sentMessage.Destination = recipient.ForceGetValue().E164number;
                    }
                    syncMessage.Sent    = sentMessage;
                    content.SyncMessage = syncMessage;
                    return(content.ToByteArray());
                }
                catch (InvalidProtocolBufferException e)
                {
                    throw new Exception(e.Message);
                }
            }
        }
Пример #4
0
        private void handleEndSessionMessage(SignalServiceEnvelope envelope,
                                             SignalServiceDataMessage message,
                                             May <long> smsMessageId)
        {
            var smsDatabase         = DatabaseFactory.getTextMessageDatabase();//getEncryptingSmsDatabase(context);
            var incomingTextMessage = new IncomingTextMessage(envelope.getSource(),
                                                              envelope.getSourceDevice(),
                                                              message.getTimestamp(),
                                                              "", May <SignalServiceGroup> .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);
        }
Пример #5
0
        private byte[] createSentTranscriptMessage(byte[] content, May <SignalServiceAddress> recipient, ulong timestamp)
        {
            {
                try
                {
                    Content.Builder                container   = Content.CreateBuilder();
                    SyncMessage.Builder            syncMessage = SyncMessage.CreateBuilder();
                    SyncMessage.Types.Sent.Builder sentMessage = SyncMessage.Types.Sent.CreateBuilder();

                    sentMessage.SetTimestamp(timestamp);
                    sentMessage.SetMessage(DataMessage.ParseFrom(content));

                    if (recipient.HasValue)
                    {
                        sentMessage.SetDestination(recipient.ForceGetValue().getNumber());
                    }

                    return(container.SetSyncMessage(syncMessage.SetSent(sentMessage)).Build().ToByteArray());;
                }
                catch (InvalidProtocolBufferException e)
                {
                    throw new Exception(e.Message);
                }
            }
        }
        public PreKeySignalMessage(uint messageVersion, uint registrationId, May <uint> preKeyId,
                                   uint signedPreKeyId, ECPublicKey baseKey, IdentityKey identityKey,
                                   SignalMessage message)
        {
            this.version        = messageVersion;
            this.registrationId = registrationId;
            this.preKeyId       = preKeyId;
            this.signedPreKeyId = signedPreKeyId;
            this.baseKey        = baseKey;
            this.identityKey    = identityKey;
            this.message        = message;

            PreKeySignalMessage preKeySignalMessage = new PreKeySignalMessage
            {
                SignedPreKeyId = signedPreKeyId,
                BaseKey        = ByteString.CopyFrom(baseKey.serialize()),
                IdentityKey    = ByteString.CopyFrom(identityKey.serialize()),
                Message        = ByteString.CopyFrom(message.serialize()),
                RegistrationId = registrationId
            };

            if (preKeyId.HasValue)                                       // .isPresent()
            {
                preKeySignalMessage.PreKeyId = preKeyId.ForceGetValue(); // get()
            }

            byte[] versionBytes = { ByteUtil.intsToByteHighAndLow((int)this.version, (int)CURRENT_VERSION) };
            byte[] messageBytes = preKeySignalMessage.ToByteArray();

            this.serialized = ByteUtil.combine(versionBytes, messageBytes);
        }
Пример #7
0
        private SenderKeyState(uint id, uint iteration, byte[] chainKey,
                               ECPublicKey signatureKeyPublic,
                               May <ECPrivateKey> signatureKeyPrivate)
        {
            SenderKeyStateStructure.Types.SenderChainKey senderChainKeyStructure =
                SenderKeyStateStructure.Types.SenderChainKey.CreateBuilder()
                .SetIteration(iteration)
                .SetSeed(ByteString.CopyFrom(chainKey))
                .Build();

            SenderKeyStateStructure.Types.SenderSigningKey.Builder signingKeyStructure =
                SenderKeyStateStructure.Types.SenderSigningKey.CreateBuilder()
                .SetPublic(ByteString.CopyFrom(signatureKeyPublic.Serialize()));

            if (signatureKeyPrivate.HasValue)
            {
                signingKeyStructure.SetPrivate(ByteString.CopyFrom(signatureKeyPrivate.ForceGetValue().Serialize()));
            }

            this.senderKeyStateStructure = SenderKeyStateStructure.CreateBuilder()
                                           .SetSenderKeyId(id)
                                           .SetSenderChainKey(senderChainKeyStructure)
                                           .SetSenderSigningKey(signingKeyStructure)
                                           .Build();
        }
Пример #8
0
        public PreKeySignalMessage(uint messageVersion, uint registrationId, May <uint> preKeyId,
                                   uint signedPreKeyId, ECPublicKey baseKey, IdentityKey identityKey,
                                   SignalMessage message)
        {
            this.version        = messageVersion;
            this.registrationId = registrationId;
            this.preKeyId       = preKeyId;
            this.signedPreKeyId = signedPreKeyId;
            this.baseKey        = baseKey;
            this.identityKey    = identityKey;
            this.message        = message;

            WhisperProtos.PreKeySignalMessage.Builder builder =
                WhisperProtos.PreKeySignalMessage.CreateBuilder()
                .SetSignedPreKeyId(signedPreKeyId)
                .SetBaseKey(ByteString.CopyFrom(baseKey.serialize()))
                .SetIdentityKey(ByteString.CopyFrom(identityKey.serialize()))
                .SetMessage(ByteString.CopyFrom(message.serialize()))
                .SetRegistrationId(registrationId);

            if (preKeyId.HasValue)                             // .isPresent()
            {
                builder.SetPreKeyId(preKeyId.ForceGetValue()); // get()
            }

            byte[] versionBytes = { ByteUtil.intsToByteHighAndLow((int)this.version, (int)CURRENT_VERSION) };
            byte[] messageBytes = builder.Build().ToByteArray();

            this.serialized = ByteUtil.combine(versionBytes, messageBytes);
        }
Пример #9
0
        private byte[] CreateMultiDeviceSentTranscriptContent(byte[] rawContent, May <SignalServiceAddress> recipient, ulong timestamp)
        {
            try
            {
                Content content = new Content {
                };
                SyncMessage            syncMessage = CreateSyncMessage();
                SyncMessage.Types.Sent sentMessage = new SyncMessage.Types.Sent {
                };
                DataMessage dataMessage            = Content.Parser.ParseFrom(rawContent).DataMessage;

                sentMessage.Timestamp = timestamp;
                sentMessage.Message   = dataMessage;

                if (recipient.HasValue)
                {
                    sentMessage.Destination = recipient.ForceGetValue().E164number;
                }

                if (dataMessage.ExpireTimer > 0)
                {
                    sentMessage.ExpirationStartTimestamp = (ulong)Util.CurrentTimeMillis();
                }
                syncMessage.Sent    = sentMessage;
                content.SyncMessage = syncMessage;
                return(content.ToByteArray());
            }
            catch (InvalidProtocolBufferException e)
            {
                throw new Exception(e.Message);
            }
        }
Пример #10
0
        public PreKeySignalMessage(uint messageVersion, uint registrationId, May <uint> preKeyId,
                                   uint signedPreKeyId, IEcPublicKey baseKey, IdentityKey identityKey,
                                   SignalMessage message)
        {
            _version        = messageVersion;
            _registrationId = registrationId;
            _preKeyId       = preKeyId;
            _signedPreKeyId = signedPreKeyId;
            _baseKey        = baseKey;
            _identityKey    = identityKey;
            _message        = message;

            PreKeySignalMessage preKeySignalMessage = new PreKeySignalMessage
            {
                SignedPreKeyId = signedPreKeyId,
                BaseKey        = ByteString.CopyFrom(baseKey.Serialize()),
                IdentityKey    = ByteString.CopyFrom(identityKey.Serialize()),
                Message        = ByteString.CopyFrom(message.Serialize()),
                RegistrationId = registrationId
            };

            if (preKeyId.HasValue)                                       // .isPresent()
            {
                preKeySignalMessage.PreKeyId = preKeyId.ForceGetValue(); // get()
            }

            byte[] versionBytes = { ByteUtil.IntsToByteHighAndLow((int)_version, (int)CurrentVersion) };
            byte[] messageBytes = preKeySignalMessage.ToByteArray();

            _serialized = ByteUtil.Combine(versionBytes, messageBytes);
        }
Пример #11
0
        private SenderKeyState(uint id, uint iteration, byte[] chainKey,
                              ECPublicKey signatureKeyPublic,
                              May<ECPrivateKey> signatureKeyPrivate)
        {
            SenderKeyStateStructure.Types.SenderChainKey senderChainKeyStructure =
                SenderKeyStateStructure.Types.SenderChainKey.CreateBuilder()
                                                      .SetIteration(iteration)
                                                      .SetSeed(ByteString.CopyFrom(chainKey))
                                                      .Build();

            SenderKeyStateStructure.Types.SenderSigningKey.Builder signingKeyStructure =
                SenderKeyStateStructure.Types.SenderSigningKey.CreateBuilder()
                                                        .SetPublic(ByteString.CopyFrom(signatureKeyPublic.serialize()));

            if (signatureKeyPrivate.HasValue)
            {
                signingKeyStructure.SetPrivate(ByteString.CopyFrom(signatureKeyPrivate.ForceGetValue().serialize()));
            }

            this.senderKeyStateStructure = SenderKeyStateStructure.CreateBuilder()
                                                                  .SetSenderKeyId(id)
                                                                  .SetSenderChainKey(senderChainKeyStructure)
                                                                  .SetSenderSigningKey(signingKeyStructure)
                                                                  .Build();
        }
Пример #12
0
        public PreKeySignalMessage(uint messageVersion, uint registrationId, May <uint> preKeyId,
                                   uint signedPreKeyId, IEcPublicKey baseKey, IdentityKey identityKey,
                                   SignalMessage message)
        {
            _version        = messageVersion;
            _registrationId = registrationId;
            _preKeyId       = preKeyId;
            _signedPreKeyId = signedPreKeyId;
            _baseKey        = baseKey;
            _identityKey    = identityKey;
            _message        = message;

            WhisperProtos.PreKeySignalMessage.Builder builder =
                WhisperProtos.PreKeySignalMessage.CreateBuilder()
                .SetSignedPreKeyId(signedPreKeyId)
                .SetBaseKey(ByteString.CopyFrom(baseKey.Serialize()))
                .SetIdentityKey(ByteString.CopyFrom(identityKey.Serialize()))
                .SetMessage(ByteString.CopyFrom(message.Serialize()))
                .SetRegistrationId(registrationId);

            if (preKeyId.HasValue)                             // .isPresent()
            {
                builder.SetPreKeyId(preKeyId.ForceGetValue()); // get()
            }

            byte[] versionBytes = { ByteUtil.IntsToByteHighAndLow((int)_version, (int)CurrentVersion) };
            byte[] messageBytes = builder.Build().ToByteArray();

            _serialized = ByteUtil.Combine(versionBytes, messageBytes);
        }
Пример #13
0
        private void handleGroupMessage(SignalServiceEnvelope envelope, SignalServiceDataMessage 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());
            }
        }
 /**
  * Register/Unregister a Google Cloud Messaging registration ID.
  *
  * @param gcmRegistrationId The GCM id to register.  A call with an absent value will unregister.
  * @throws IOException
  */
 public async Task<bool> setWnsId(May<String> wnsRegistrationId)// throws IOException
 {
     if (wnsRegistrationId.HasValue)
     {
         return await this.pushServiceSocket.registerWnsId(wnsRegistrationId.ForceGetValue());
     }
     else
     {
         return await this.pushServiceSocket.unregisterWnsId();
     }
 }
Пример #15
0
 /// <summary>
 /// Register/Unregister a Google Cloud Messaging registration ID.
 /// </summary>
 /// <param name="gcmRegistrationId">The GCM id to register.  A call with an absent value will unregister.</param>
 /// <returns></returns>
 public void setGcmId(May <string> gcmRegistrationId)// throws IOException
 {
     if (gcmRegistrationId.HasValue)
     {
         this.pushServiceSocket.registerGcmId(gcmRegistrationId.ForceGetValue());
     }
     else
     {
         this.pushServiceSocket.unregisterGcmId();
     }
 }
Пример #16
0
 private bool equals(May <String> one, May <String> two)
 {
     if (one.HasValue)
     {
         return(two.HasValue && one.ForceGetValue().Equals(two.ForceGetValue()));
     }
     else
     {
         return(!two.HasValue);
     }
 }
 /// <summary>
 /// Register/Unregister a Google Cloud Messaging registration ID.
 /// </summary>
 /// <param name="wnsRegistrationId">The GCM id to register.  A call with an absent value will unregister.</param>
 /// <returns></returns>
 public async Task <bool> setWnsId(May <string> wnsRegistrationId)// throws IOException
 {
     if (wnsRegistrationId.HasValue)
     {
         return(await this.pushServiceSocket.registerWnsId(wnsRegistrationId.ForceGetValue()));
     }
     else
     {
         return(await this.pushServiceSocket.unregisterWnsId());
     }
 }
        public bool sendReceipt(string destination, ulong messageId, May <string> relay)// throws IOException
        {
            string path = string.Format(RECEIPT_PATH, destination, messageId);

            if (relay.HasValue)
            {
                path += "?relay=" + relay.ForceGetValue();
            }

            makeRequest(path, "PUT", null);
            return(true);
        }
Пример #19
0
        private async Task <IList <AttachmentPointer> > createAttachmentPointers(May <List <SignalServiceAttachment> > attachments)
        {
            IList <AttachmentPointer> pointers = new List <AttachmentPointer>();

            if (!attachments.HasValue || attachments.ForceGetValue().Count == 0)
            {
                Debug.WriteLine("No attachments present...", TAG);
                return(pointers);
            }

            foreach (SignalServiceAttachment attachment in attachments.ForceGetValue())
            {
                if (attachment.isStream())
                {
                    Debug.WriteLine("Found attachment, creating pointer...", TAG);
                    pointers.Add(await createAttachmentPointer(attachment.asStream()));
                }
            }

            return(pointers);
        }
Пример #20
0
        private void handleLegacyMessage(SignalServiceEnvelope 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 SetUnacknowledgedPreKeyMessage(May <uint> preKeyId, uint signedPreKeyId, IEcPublicKey baseKey)
        {
            SessionStructure.Types.PendingPreKey pending = new SessionStructure.Types.PendingPreKey
            {
                SignedPreKeyId = (int)signedPreKeyId,
                BaseKey        = ByteString.CopyFrom(baseKey.Serialize())
            };

            if (preKeyId.HasValue)
            {
                pending.PreKeyId = preKeyId.ForceGetValue();
            }

            _sessionStructure.PendingPreKey = pending;
        }
Пример #22
0
        private async static Task <bool> isPushDestination(String destination)
        {
            TextSecureDirectory directory = DatabaseFactory.getDirectoryDatabase();

            try
            {
                return(directory.isActiveNumber(destination));
            }
            catch (/*NotInDirectory*/ Exception e)
            {
                try
                {
                    TextSecureAccountManager  accountManager = TextSecureCommunicationFactory.createManager();
                    May <ContactTokenDetails> registeredUser = await App.Current.accountManager.getContact(destination);

                    if (!registeredUser.HasValue)
                    {
                        registeredUser = new May <ContactTokenDetails>(new ContactTokenDetails());
                        registeredUser.ForceGetValue().setNumber(destination);
                        directory.setNumber(registeredUser.ForceGetValue(), false);
                        return(false);
                    }
                    else
                    {
                        registeredUser.ForceGetValue().setNumber(destination);
                        directory.setNumber(registeredUser.ForceGetValue(), true);
                        return(true);
                    }
                }
                catch (Exception e1)
                {
                    //Log.w(TAG, e1);
                    return(false);
                }
            }
        }
Пример #23
0
        public void SetUnacknowledgedPreKeyMessage(May <uint> preKeyId, uint signedPreKeyId, IEcPublicKey baseKey)
        {
            StorageProtos.SessionStructure.Types.PendingPreKey.Builder pending = StorageProtos.SessionStructure.Types.PendingPreKey.CreateBuilder()
                                                                                 .SetSignedPreKeyId((int)signedPreKeyId)
                                                                                 .SetBaseKey(ByteString.CopyFrom(baseKey.Serialize()));

            if (preKeyId.HasValue)
            {
                pending.SetPreKeyId(preKeyId.ForceGetValue());
            }

            _sessionStructure = _sessionStructure.ToBuilder()
                                .SetPendingPreKey(pending.Build())
                                .Build();
        }
Пример #24
0
        public void setUnacknowledgedPreKeyMessage(May <uint> preKeyId, uint signedPreKeyId, ECPublicKey baseKey)
        {
            PendingPreKey.Builder pending = PendingPreKey.CreateBuilder()
                                            .SetSignedPreKeyId(signedPreKeyId)
                                            .SetBaseKey(ByteString.CopyFrom(baseKey.serialize()));

            if (preKeyId.HasValue)
            {
                pending.SetPreKeyId(preKeyId.ForceGetValue());
            }

            this.sessionStructure = this.sessionStructure.ToBuilder()
                                    .SetPendingPreKey(pending.Build())
                                    .Build();
        }
Пример #25
0
        public static Recipients getRecipientsFromString(String rawText, bool asynchronous)
        {
            var           tokens = rawText.Split(',');
            List <String> ids    = new List <string>();

            foreach (var token in tokens)
            {
                May <long> id = getRecipientIdFromNumber(token);

                if (id.HasValue)
                {
                    ids.Add(Convert.ToString(id.ForceGetValue()));
                }
            }

            return(getRecipientsForIds(ids, asynchronous));
        }
Пример #26
0
        /**
         * Decrypt a message.
         *
         * @param  ciphertext The {@link PreKeyWhisperMessage} to decrypt.
         * @param  callback   A callback that is triggered after decryption is complete,
         *                    but before the updated session state has been committed to the session
         *                    DB.  This allows some implementations to store the committed plaintext
         *                    to a DB first, in case they are concerned with a crash happening between
         *                    the time the session state is updated but before they're able to store
         *                    the plaintext to disk.
         *
         * @return The plaintext.
         * @throws InvalidMessageException if the input is not valid ciphertext.
         * @throws DuplicateMessageException if the input is a message that has already been received.
         * @throws LegacyMessageException if the input is a message formatted by a protocol version that
         *                                is no longer supported.
         * @throws InvalidKeyIdException when there is no local {@link org.whispersystems.libaxolotl.state.PreKeyRecord}
         *                               that corresponds to the PreKey ID in the message.
         * @throws InvalidKeyException when the message is formatted incorrectly.
         * @throws UntrustedIdentityException when the {@link IdentityKey} of the sender is untrusted.
         */
        public byte[] decrypt(PreKeyWhisperMessage ciphertext, DecryptionCallback callback)

        {
            lock (SESSION_LOCK)
            {
                SessionRecord sessionRecord    = sessionStore.loadSession(remoteAddress);
                May <uint>    unsignedPreKeyId = sessionBuilder.process(sessionRecord, ciphertext);
                byte[]        plaintext        = decrypt(sessionRecord, ciphertext.getWhisperMessage());

                callback.handlePlaintext(plaintext);

                sessionStore.storeSession(remoteAddress, sessionRecord);

                if (unsignedPreKeyId.HasValue)
                {
                    preKeyStore.removePreKey(unsignedPreKeyId.ForceGetValue());
                }

                return(plaintext);
            }
        }
Пример #27
0
        /**
         * Decrypt a message.
         *
         * @param  ciphertext The {@link PreKeySignalMessage} to decrypt.
         * @param  callback   A callback that is triggered after decryption is complete,
         *                    but before the updated session state has been committed to the session
         *                    DB.  This allows some implementations to store the committed plaintext
         *                    to a DB first, in case they are concerned with a crash happening between
         *                    the time the session state is updated but before they're able to store
         *                    the plaintext to disk.
         *
         * @return The plaintext.
         * @throws InvalidMessageException if the input is not valid ciphertext.
         * @throws DuplicateMessageException if the input is a message that has already been received.
         * @throws LegacyMessageException if the input is a message formatted by a protocol version that
         *                                is no longer supported.
         * @throws InvalidKeyIdException when there is no local {@link org.whispersystems.libsignal.state.PreKeyRecord}
         *                               that corresponds to the PreKey ID in the message.
         * @throws InvalidKeyException when the message is formatted incorrectly.
         * @throws UntrustedIdentityException when the {@link IdentityKey} of the sender is untrusted.
         */
        public byte[] Decrypt(PreKeySignalMessage ciphertext, IDecryptionCallback callback)

        {
            lock (SessionLock)
            {
                SessionRecord sessionRecord    = _sessionStore.LoadSession(_remoteAddress);
                May <uint>    unsignedPreKeyId = _sessionBuilder.Process(sessionRecord, ciphertext);
                byte[]        plaintext        = Decrypt(sessionRecord, ciphertext.GetSignalMessage());

                callback.HandlePlaintext(plaintext);

                _sessionStore.StoreSession(_remoteAddress, sessionRecord);

                if (unsignedPreKeyId.HasValue)
                {
                    _preKeyStore.RemovePreKey(unsignedPreKeyId.ForceGetValue());
                }

                return(plaintext);
            }
        }
Пример #28
0
        private long handleSynchronizeSentTextMessage(SentTranscriptMessage message,
                                                      May <long> smsMessageId)
        {
            var                 textMessageDatabase = DatabaseFactory.getTextMessageDatabase();//getEncryptingSmsDatabase(context);
            Recipients          recipients          = getSyncMessageDestination(message);
            String              body = message.getMessage().getBody().HasValue ? message.getMessage().getBody().ForceGetValue() : "";
            OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipients, body);

            long threadId  = DatabaseFactory.getThreadDatabase().GetThreadIdForRecipients(recipients);
            long messageId = textMessageDatabase.InsertMessageOutbox(threadId, outgoingTextMessage, TimeUtil.GetDateTime(message.getTimestamp()));

            textMessageDatabase.MarkAsSent(messageId);
            textMessageDatabase.MarkAsPush(messageId);
            textMessageDatabase.MarkAsSecure(messageId);

            if (smsMessageId.HasValue)
            {
                textMessageDatabase.Delete(smsMessageId.ForceGetValue());
            }

            return(threadId);
        }
        /**
         * Decrypt a message.
         *
         * @param  ciphertext The {@link PreKeySignalMessage} to decrypt.
         * @param  callback   A callback that is triggered after decryption is complete,
         *                    but before the updated session state has been committed to the session
         *                    DB.  This allows some implementations to store the committed plaintext
         *                    to a DB first, in case they are concerned with a crash happening between
         *                    the time the session state is updated but before they're able to store
         *                    the plaintext to disk.
         *
         * @return The plaintext.
         * @throws InvalidMessageException if the input is not valid ciphertext.
         * @throws DuplicateMessageException if the input is a message that has already been received.
         * @throws LegacyMessageException if the input is a message formatted by a protocol version that
         *                                is no longer supported.
         * @throws InvalidKeyIdException when there is no local {@link org.whispersystems.libsignal.state.PreKeyRecord}
         *                               that corresponds to the PreKey ID in the message.
         * @throws InvalidKeyException when the message is formatted incorrectly.
         * @throws UntrustedIdentityException when the {@link IdentityKey} of the sender is untrusted.
         */
        public byte[] decrypt(PreKeySignalMessage ciphertext, DecryptionCallback callback)
        {
            lock (SESSION_LOCK)
            {
                SessionRecord sessionRecord    = sessionStore.LoadSession(remoteAddress);
                May <uint>    unsignedPreKeyId = sessionBuilder.process(sessionRecord, ciphertext);
                byte[]        plaintext        = decrypt(sessionRecord, ciphertext.getSignalMessage());

                identityKeyStore.SaveIdentity(remoteAddress, sessionRecord.getSessionState().getRemoteIdentityKey());

                callback.handlePlaintext(plaintext);

                sessionStore.StoreSession(remoteAddress, sessionRecord);

                if (unsignedPreKeyId.HasValue)
                {
                    preKeyStore.RemovePreKey(unsignedPreKeyId.ForceGetValue());
                }

                return(plaintext);
            }
        }
Пример #30
0
        private void handleUntrustedIdentityMessage(SignalServiceEnvelope envelope, May <long> smsMessageId)
        {
            try
            {
                var                 database       = DatabaseFactory.getTextMessageDatabase(); //getEncryptingSmsDatabase(context);
                Recipients          recipients     = RecipientFactory.getRecipientsFromString(envelope.getSource(), false);
                long                recipientId    = recipients.getPrimaryRecipient().getRecipientId();
                PreKeySignalMessage whisperMessage = new PreKeySignalMessage(envelope.getLegacyMessage());
                IdentityKey         identityKey    = whisperMessage.getIdentityKey();
                String              encoded        = Base64.encodeBytes(envelope.getLegacyMessage());
                IncomingTextMessage textMessage    = new IncomingTextMessage(envelope.getSource(), envelope.getSourceDevice(),
                                                                             envelope.getTimestamp(), encoded,
                                                                             May <SignalServiceGroup> .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);
            }
        }
Пример #31
0
        /*public IncomingTextMessage(SmsMessage message)
         * {
         *  this.message = message.getDisplayMessageBody();
         *  this.sender = message.getDisplayOriginatingAddress();
         *  this.senderDeviceId = TextSecureAddress.DEFAULT_DEVICE_ID;
         *  this.protocol = message.getProtocolIdentifier();
         *  this.serviceCenterAddress = message.getServiceCenterAddress();
         *  this.replyPathPresent = message.isReplyPathPresent();
         *  this.pseudoSubject = message.getPseudoSubject();
         *  this.sentTimestampMillis = message.getTimestampMillis();
         *  this.groupId = null;
         *  this.push = false;
         * }*/

        public IncomingTextMessage(String sender, int senderDeviceId, long sentTimestampMillis,
                                   String encodedBody, May <SignalServiceGroup> group)
        {
            this.Message              = encodedBody;
            this.Sender               = sender;
            this.SenderDeviceId       = senderDeviceId;
            this.Protocol             = 31337;
            this.ServiceCenterAddress = "GCM";
            this.ReplyPathPresent     = true;
            this.PseudoSubject        = "";
            this.SentTimestampMillis  = sentTimestampMillis;
            this.Push = true;

            if (group.HasValue)
            {
                this.GroupId = GroupUtil.getEncodedId(group.ForceGetValue().getGroupId());
            }
            else
            {
                this.GroupId = null;
            }
        }
Пример #32
0
        public async Task<bool> sendReceipt(String destination, ulong messageId, May<string> relay)// throws IOException
        {
            String path = string.Format(RECEIPT_PATH, destination, messageId);

            if (relay.HasValue)
            {
                path += "?relay=" + relay.ForceGetValue();
            }

            await makeRequest(path, "PUT", null);
            return true;
        }
Пример #33
0
        /*public IncomingTextMessage(SmsMessage message)
        {
            this.message = message.getDisplayMessageBody();
            this.sender = message.getDisplayOriginatingAddress();
            this.senderDeviceId = TextSecureAddress.DEFAULT_DEVICE_ID;
            this.protocol = message.getProtocolIdentifier();
            this.serviceCenterAddress = message.getServiceCenterAddress();
            this.replyPathPresent = message.isReplyPathPresent();
            this.pseudoSubject = message.getPseudoSubject();
            this.sentTimestampMillis = message.getTimestampMillis();
            this.groupId = null;
            this.push = false;
        }*/

        public IncomingTextMessage(String sender, uint senderDeviceId, ulong sentTimestampMillis,
                                   String encodedBody, May<TextSecureGroup> group)
        {
            this.Message = encodedBody;
            this.Sender = sender;
            this.SenderDeviceId = senderDeviceId;
            this.Protocol = 31337;
            this.ServiceCenterAddress = "GCM";
            this.ReplyPathPresent = true;
            this.PseudoSubject = "";
            this.SentTimestampMillis = sentTimestampMillis;
            this.Push = true;

            if (group.HasValue)
            {
                this.GroupId = GroupUtil.getEncodedId(group.ForceGetValue().getGroupId());
            }
            else
            {
                this.GroupId = null;
            }
        }
Пример #34
0
        private long handleSynchronizeSentTextMessage(SentTranscriptMessage message,
                                                May<long> smsMessageId)
        {
            var textMessageDatabase = DatabaseFactory.getTextMessageDatabase();//getEncryptingSmsDatabase(context);
            Recipients recipients = getSyncMessageDestination(message);
            String body = message.getMessage().getBody().HasValue ? message.getMessage().getBody().ForceGetValue() : "";
            OutgoingTextMessage outgoingTextMessage = new OutgoingTextMessage(recipients, body);

            long threadId = DatabaseFactory.getThreadDatabase().GetThreadIdForRecipients(recipients);
            long messageId = textMessageDatabase.InsertMessageOutbox(threadId, outgoingTextMessage, TimeUtil.GetDateTime(message.getTimestamp()));

            textMessageDatabase.MarkAsSent(messageId);
            textMessageDatabase.MarkAsPush(messageId);
            textMessageDatabase.MarkAsSecure(messageId);

            if (smsMessageId.HasValue)
            {
                textMessageDatabase.Delete(smsMessageId.ForceGetValue());
            }

            return threadId;
        }
Пример #35
0
 private bool equals(May<String> one, May<String> two)
 {
     if (one.HasValue) {
         return two.HasValue && one.ForceGetValue().Equals(two.ForceGetValue());
     }
     else return !two.HasValue;
 }
        private HttpResponseMessage getConnection(string urlFragment, string method, string body)
        {
            try
            {
                SignalConnectionInformation connectionInformation = getRandom(signalConnectionInformation);
                string       url        = connectionInformation.getUrl();
                May <string> hostHeader = connectionInformation.getHostHeader();
                Uri          uri        = new Uri(string.Format("{0}{1}", url, urlFragment));
                Debug.WriteLine("{0}: Uri {1}", TAG, uri);
                HttpClient connection = new HttpClient();

                var headers = connection.DefaultRequestHeaders;

                if (credentialsProvider.GetPassword() != null)
                {
                    string authHeader = getAuthorizationHeader();
                    Debug.WriteLine(String.Format("Authorization: {0}", authHeader), TAG);
                    headers.Add("Authorization", authHeader);
                }

                if (userAgent != null)
                {
                    headers.Add("X-Signal-Agent", userAgent);
                }

                if (hostHeader.HasValue)
                {
                    headers.Host = hostHeader.ForceGetValue();
                }

                StringContent content;
                if (body != null)
                {
                    content = new StringContent(body, Encoding.UTF8, "application/json");
                    Debug.WriteLine(body);
                }
                else
                {
                    content = new StringContent("");
                }
                switch (method)
                {
                case "POST":
                    return(connection.PostAsync(uri, content).Result);

                case "PUT":
                    return(connection.PutAsync(uri, content).Result);

                case "DELETE":
                    return(connection.DeleteAsync(uri).Result);

                case "GET":
                    return(connection.GetAsync(uri).Result);

                default:
                    throw new Exception("Unknown method: " + method);
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("getConnection() failed:", TAG);
                Debug.WriteLine(e.Message);
                Debug.WriteLine(e.StackTrace);
                throw new PushNetworkException(e);
            }
        }
        public PreKeyWhisperMessage(uint messageVersion, uint registrationId, May<uint> preKeyId,
                                    uint signedPreKeyId, ECPublicKey baseKey, IdentityKey identityKey,
                                    WhisperMessage message)
        {
            this.version = messageVersion;
            this.registrationId = registrationId;
            this.preKeyId = preKeyId;
            this.signedPreKeyId = signedPreKeyId;
            this.baseKey = baseKey;
            this.identityKey = identityKey;
            this.message = message;

            WhisperProtos.PreKeyWhisperMessage.Builder builder =
                WhisperProtos.PreKeyWhisperMessage.CreateBuilder()
                                                  .SetSignedPreKeyId(signedPreKeyId)
                                                  .SetBaseKey(ByteString.CopyFrom(baseKey.serialize()))
                                                  .SetIdentityKey(ByteString.CopyFrom(identityKey.serialize()))
                                                  .SetMessage(ByteString.CopyFrom(message.serialize()))
                                                  .SetRegistrationId(registrationId);

            if (preKeyId.HasValue) // .isPresent()
            {
                builder.SetPreKeyId(preKeyId.ForceGetValue()); // get()
            }

            byte[] versionBytes = { ByteUtil.intsToByteHighAndLow((int)this.version, (int)CURRENT_VERSION) };
            byte[] messageBytes = builder.Build().ToByteArray();

            this.serialized = ByteUtil.combine(versionBytes, messageBytes);
        }
Пример #38
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);
            }
        }
        private IList<AttachmentPointer> createAttachmentPointers(May<LinkedList<TextSecureAttachment>> attachments)
        {
            IList<AttachmentPointer> pointers = new List<AttachmentPointer>();

            if (!attachments.HasValue || attachments.ForceGetValue().Count == 0)
            {
                Debug.WriteLine("No attachments present...", TAG);
                return pointers;
            }

            foreach (TextSecureAttachment attachment in attachments.ForceGetValue())
            {
                if (attachment.isStream())
                {
                    Debug.WriteLine("Found attachment, creating pointer...", TAG);
                    pointers.Add(createAttachmentPointer(attachment.asStream()));
                }
            }

            return pointers;
        }
Пример #40
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());
            }
        }
Пример #41
0
        private async static Task<bool> isPushDestination(String destination)
        {
            TextSecureDirectory directory = DatabaseFactory.getDirectoryDatabase();

            try
            {
                return directory.isActiveNumber(destination);
            }
            catch (/*NotInDirectory*/Exception e)
            {
                try
                {
                    TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager();
                    May<ContactTokenDetails> registeredUser = await App.Current.accountManager.getContact(destination);

                    if (!registeredUser.HasValue)
                    {
                        registeredUser = new May<ContactTokenDetails>(new ContactTokenDetails());
                        registeredUser.ForceGetValue().setNumber(destination);
                        directory.setNumber(registeredUser.ForceGetValue(), false);
                        return false;
                    }
                    else
                    {
                        registeredUser.ForceGetValue().setNumber(destination);
                        directory.setNumber(registeredUser.ForceGetValue(), true);
                        return true;
                    }
                }
                catch (Exception e1)
                {
                    //Log.w(TAG, e1);
                    return false;
                }
            }
        }
Пример #42
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());
            }
        }
Пример #43
0
		public void setUnacknowledgedPreKeyMessage(May<uint> preKeyId, uint signedPreKeyId, ECPublicKey baseKey)
		{
			PendingPreKey.Builder pending = PendingPreKey.CreateBuilder()
														 .SetSignedPreKeyId(signedPreKeyId)
														 .SetBaseKey(ByteString.CopyFrom(baseKey.serialize()));

			if (preKeyId.HasValue)
			{
				pending.SetPreKeyId(preKeyId.ForceGetValue());
			}

			this.sessionStructure = this.sessionStructure.ToBuilder()
														 .SetPendingPreKey(pending.Build())
														 .Build();
		}
Пример #44
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);
        }
        private byte[] createSentTranscriptMessage(byte[] content, May<TextSecureAddress> recipient, ulong timestamp)
        {
            {
                try
                {
                    Content.Builder container = Content.CreateBuilder();
                    SyncMessage.Builder syncMessage = SyncMessage.CreateBuilder();
                    SyncMessage.Types.Sent.Builder sentMessage = SyncMessage.Types.Sent.CreateBuilder();

                    sentMessage.SetTimestamp(timestamp);
                    sentMessage.SetMessage(DataMessage.ParseFrom(content));

                    if (recipient.HasValue)
                    {
                        sentMessage.SetDestination(recipient.ForceGetValue().getNumber());
                    }

                    return container.SetSyncMessage(syncMessage.SetSent(sentMessage)).Build().ToByteArray(); ;
                }
                catch (InvalidProtocolBufferException e)
                {
                    throw new Exception(e.Message);
                }
            }
        }