Ejemplo n.º 1
0
        private OutgoingPushMessageList getEncryptedMessages(PushServiceSocket socket,
                                                             SignalServiceAddress recipient,
                                                             long timestamp,
                                                             byte[] plaintext,
                                                             bool legacy,
                                                             bool silent)
        {
            List <OutgoingPushMessage> messages = new List <OutgoingPushMessage>();

            bool myself = recipient.Equals(localAddress);

            if (!myself || CredentialsProvider.GetDeviceId() != SignalServiceAddress.DEFAULT_DEVICE_ID)
            {
                messages.Add(getEncryptedMessage(socket, recipient, SignalServiceAddress.DEFAULT_DEVICE_ID, plaintext, legacy, silent));
            }

            foreach (uint deviceId in store.GetSubDeviceSessions(recipient.getNumber()))
            {
                if (!myself || deviceId != CredentialsProvider.GetDeviceId())
                {
                    messages.Add(getEncryptedMessage(socket, recipient, deviceId, plaintext, legacy, silent));
                }
            }

            return(new OutgoingPushMessageList(recipient.getNumber(), (ulong)timestamp, recipient.getRelay().HasValue ? recipient.getRelay().ForceGetValue() : null, messages));
        }
        public SignalServiceProfile GetProfile(SignalServiceAddress address)
        {
            WebSocketRequestMessage requestMessage = new WebSocketRequestMessage()
            {
                Id   = BitConverter.ToUInt64(Util.getSecretBytes(sizeof(long)), 0),
                Verb = "GET",
                Path = $"/v1/profile/{address.getNumber()}"
            };

            var t = Websocket.SendRequest(requestMessage);

            t.Wait();
            if (t.IsCompleted)
            {
                var response = t.Result;
                if (response.Item1 < 200 || response.Item1 >= 300)
                {
                    throw new IOException("non-successfull response: " + response.Item1 + " " + response.Item2);
                }
                return(JsonUtil.fromJson <SignalServiceProfile>(response.Item2));
            }
            else
            {
                throw new IOException("timeout reached while waiting for profile");
            }
        }
Ejemplo n.º 3
0
 private void handleStaleDevices(SignalServiceAddress recipient, StaleDevices staleDevices)
 {
     foreach (uint staleDeviceId in staleDevices.getStaleDevices())
     {
         store.DeleteSession(new SignalProtocolAddress(recipient.getNumber(), staleDeviceId));
     }
 }
Ejemplo n.º 4
0
        private void handleMismatchedDevices(PushServiceSocket socket, SignalServiceAddress recipient, MismatchedDevices mismatchedDevices)
        {
            try
            {
                foreach (uint extraDeviceId in mismatchedDevices.getExtraDevices())
                {
                    store.DeleteSession(new SignalProtocolAddress(recipient.getNumber(), extraDeviceId));
                }

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

                    try
                    {
                        SessionBuilder sessionBuilder = new SessionBuilder(store, new SignalProtocolAddress(recipient.getNumber(), missingDeviceId));
                        sessionBuilder.process(preKey);
                    }
                    catch (libsignal.exceptions.UntrustedIdentityException e)
                    {
                        throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey());
                    }
                }
            }
            catch (InvalidKeyException e)
            {
                throw new Exception(e.Message);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Decrypt a received <see cref="SignalServiceEnvelope"/>
        /// </summary>
        /// <param name="envelope">The received SignalServiceEnvelope</param>
        /// <returns>a decrypted SignalServiceContent</returns>
        public SignalServiceContent decrypt(SignalServiceEnvelope envelope)
        {
            try
            {
                SignalServiceContent content = new SignalServiceContent();

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

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

                return(content);
            }
            catch (InvalidProtocolBufferException e)
            {
                throw new InvalidMessageException(e);
            }
        }
Ejemplo n.º 6
0
        private OutgoingPushMessage getEncryptedMessage(PushServiceSocket socket, SignalServiceAddress recipient, uint deviceId, byte[] plaintext, bool legacy, bool silent)
        {
            SignalProtocolAddress signalProtocolAddress = new SignalProtocolAddress(recipient.getNumber(), deviceId);
            SignalServiceCipher   cipher = new SignalServiceCipher(localAddress, store);

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

                    foreach (PreKeyBundle preKey in preKeys)
                    {
                        if (CredentialsProvider.GetUser().Equals(recipient.getNumber()) && CredentialsProvider.GetDeviceId() == preKey.getDeviceId())
                        {
                            continue;
                        }
                        try
                        {
                            SignalProtocolAddress preKeyAddress  = new SignalProtocolAddress(recipient.getNumber(), preKey.getDeviceId());
                            SessionBuilder        sessionBuilder = new SessionBuilder(store, preKeyAddress);
                            sessionBuilder.process(preKey);
                        }
                        catch (libsignal.exceptions.UntrustedIdentityException e)
                        {
                            throw new UntrustedIdentityException("Untrusted identity key!", recipient.getNumber(), preKey.getIdentityKey());
                        }
                    }

                    if (eventListener != null)
                    {
                        eventListener.onSecurityEvent(recipient);
                    }
                }
                catch (InvalidKeyException e)
                {
                    throw new Exception(e.Message);
                }
            }

            return(cipher.encrypt(signalProtocolAddress, plaintext, legacy, silent));
        }
Ejemplo n.º 7
0
        private async Task <OutgoingPushMessageList> getEncryptedMessages(PushServiceSocket socket,
                                                                          SignalServiceAddress recipient,
                                                                          long timestamp,
                                                                          byte[] plaintext,
                                                                          bool legacy,
                                                                          bool silent)
        {
            List <OutgoingPushMessage> messages = new List <OutgoingPushMessage>();

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

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

            return(new OutgoingPushMessageList(recipient.getNumber(), (ulong)timestamp, recipient.getRelay().HasValue ? recipient.getRelay().ForceGetValue() : null, messages));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Send a message to a single recipient.
        /// </summary>
        /// <param name="recipient">The message's destination.</param>
        /// <param name="message">The message.</param>
        public void sendMessage(SignalServiceAddress recipient, SignalServiceDataMessage message)
        {
            byte[] content   = createMessageContent(message);
            long   timestamp = message.Timestamp;
            bool   silent    = message.Group != null && message.Group.Type == SignalServiceGroup.GroupType.REQUEST_INFO;
            var    resp      = sendMessage(recipient, timestamp, content, true, silent);

            if (resp.needsSync)
            {
                byte[] syncMessage = createMultiDeviceSentTranscriptContent(content, new May <SignalServiceAddress>(recipient), (ulong)timestamp);
                sendMessage(localAddress, timestamp, syncMessage, false, false);
            }

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

                if (eventListener != null)
                {
                    eventListener.onSecurityEvent(recipient);
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Send a message to a single recipient.
        /// </summary>
        /// <param name="recipient">The message's destination.</param>
        /// <param name="message">The message.</param>
        public async Task sendMessage(SignalServiceAddress recipient, SignalServiceDataMessage message)
        {
            byte[] content = await createMessageContent(message);

            long timestamp = message.getTimestamp();
            bool silent    = message.getGroupInfo().HasValue&& message.getGroupInfo().ForceGetValue().getType() == SignalServiceGroup.Type.REQUEST_INFO;
            SendMessageResponse response = await sendMessage(recipient, timestamp, content, true, silent);

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

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

                if (eventListener.HasValue)
                {
                    eventListener.ForceGetValue().onSecurityEvent(recipient);
                }
            }
        }
Ejemplo n.º 10
0
 /// <summary>
 /// Send a delivery receipt for a received message.  It is not necessary to call this
 /// when receiving messages through <see cref="SignalServiceMessagePipe"/>
 /// </summary>
 /// <param name="recipient">The sender of the received message you're acknowledging.</param>
 /// <param name="messageId">The message id of the received message you're acknowledging.</param>
 public void sendDeliveryReceipt(SignalServiceAddress recipient, ulong messageId)
 {
     this.socket.sendReceipt(recipient.getNumber(), messageId, recipient.getRelay());
 }