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"); } }
private void handleStaleDevices(SignalServiceAddress recipient, StaleDevices staleDevices) { foreach (uint staleDeviceId in staleDevices.getStaleDevices()) { store.DeleteSession(new SignalProtocolAddress(recipient.getNumber(), staleDeviceId)); } }
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); } }
/// <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); } }
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)); }
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)); }
/// <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); } } }
/// <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); } } }
/// <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()); }