public static SignalMessage IncreaseReceiptCountLocked(SignalServiceEnvelope envelope) { SignalMessage m; bool set_mark = false; lock (DBLock) { using (var ctx = new SignalDBContext()) { m = ctx.Messages.SingleOrDefault(t => t.ComposedTimestamp == envelope.GetTimestamp()); if (m != null) { m.Receipts++; if (m.Status == SignalMessageStatus.Confirmed) { m.Status = SignalMessageStatus.Received; set_mark = true; } } else { ctx.EarlyReceipts.Add(new SignalEarlyReceipt() { DeviceId = (uint)envelope.GetSourceDevice(), Timestamp = envelope.GetTimestamp(), Username = envelope.GetSourceE164() }); } ctx.SaveChanges(); } } return(set_mark ? m : null); }
private async Task HandleSessionResetMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { SignalMessageDirection type; SignalContact author; SignalMessageStatus status; SignalConversation conversation; string prefix; string conversationId; Guid? conversationGuid; long composedTimestamp; if (isSync) { var sent = content.SynchronizeMessage.Sent; type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; composedTimestamp = sent.Timestamp; author = null; prefix = "You have"; conversationId = sent.Destination.E164; conversationGuid = sent.Destination.Uuid; } else { status = 0; type = SignalMessageDirection.Incoming; author = await SignalDBContext.GetOrCreateContactLocked(content.Sender.E164, content.Sender.Uuid); prefix = $"{author.ThreadDisplayName} has"; composedTimestamp = envelope.GetTimestamp(); conversationId = content.Sender.E164; conversationGuid = content.Sender.Uuid; } LibsignalDBContext.DeleteAllSessions(conversationId); conversation = await SignalDBContext.GetOrCreateContactLocked(conversationId, conversationGuid); SignalMessage sm = new SignalMessage() { Direction = type, Type = SignalMessageType.SessionReset, Status = status, Author = author, Content = new SignalMessageContent() { Content = $"{prefix} reset the session." }, ThreadId = conversationId, ThreadGuid = conversationGuid, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, }; await SignalLibHandle.Instance.SaveAndDispatchSignalMessage(sm, null, conversation); }
private async Task HandleSignalMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { SignalMessageDirection type; SignalContact author; SignalMessageStatus status; SignalConversation conversation; long composedTimestamp; string body = dataMessage.Body ?? ""; if (dataMessage.Group != null) { var rawId = dataMessage.Group.GroupId; var threadId = Base64.EncodeBytes(rawId); conversation = await SignalDBContext.GetOrCreateGroupLocked(threadId, timestamp); if (!conversation.CanReceive) { SignalServiceGroup group = new SignalServiceGroup() { Type = SignalServiceGroup.GroupType.REQUEST_INFO, GroupId = rawId }; SignalServiceDataMessage requestInfoMessage = new SignalServiceDataMessage() { Group = group, Timestamp = Util.CurrentTimeMillis() }; SignalLibHandle.Instance.OutgoingQueue.Add(new SignalServiceDataMessageSendable(requestInfoMessage, envelope.GetSourceAddress())); } composedTimestamp = envelope.GetTimestamp(); } else { if (isSync) { var sent = content.SynchronizeMessage.Sent; conversation = await SignalDBContext.GetOrCreateContactLocked(sent.Destination.ForceGetValue(), timestamp); composedTimestamp = sent.Timestamp; } else { conversation = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp); composedTimestamp = envelope.GetTimestamp(); } } if (isSync) { type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; author = null; } else { status = 0; type = SignalMessageDirection.Incoming; author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp); } if (author != null && author.Blocked) { // Don't save blocked messages return; } List <SignalAttachment> attachments = new List <SignalAttachment>(); SignalMessage message = new SignalMessage() { Direction = type, Status = status, Author = author, Content = new SignalMessageContent() { Content = body.Truncate(2000) }, ThreadId = conversation.ThreadId, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, AttachmentsCount = (uint)attachments.Count, Attachments = attachments }; if (dataMessage.Attachments != null) { var receivedAttachments = dataMessage.Attachments; foreach (var receivedAttachment in receivedAttachments) { var pointer = receivedAttachment.AsPointer(); SignalAttachment sa = new SignalAttachment() { Message = message, Status = (uint)SignalAttachmentStatus.Default, SentFileName = pointer.FileName, ContentType = receivedAttachment.ContentType, Key = pointer.Key, Relay = pointer.Relay, StorageId = pointer.Id, Size = (long)pointer.Size, Digest = pointer.Digest }; attachments.Add(sa); } // Make sure to update attachments count message.AttachmentsCount = (uint)attachments.Count; } await SignalLibHandle.Instance.SaveAndDispatchSignalMessage(message, null, conversation); }
private async Task HandleGroupUpdateMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { if (dataMessage.Group != null) //TODO check signal droid: group messages have different types! { SignalServiceGroup group = dataMessage.Group; string groupid = Base64.EncodeBytes(group.GroupId); SignalGroup g = new SignalGroup(); string displayname = "Unknown group"; string avatarfile = null; if (group.Name != null) { displayname = group.Name; } var dbgroup = SignalDBContext.InsertOrUpdateGroupLocked(groupid, displayname, avatarfile, true, timestamp); if (group.Members != null) { foreach (var member in group.Members) { SignalDBContext.InsertOrUpdateGroupMembershipLocked(dbgroup.Id, (await SignalDBContext.GetOrCreateContactLocked(member, 0)).Id); } } /* insert message into conversation */ SignalMessageDirection type; SignalContact author; SignalMessageStatus status; string prefix; long composedTimestamp; if (isSync) { var sent = content.SynchronizeMessage.Sent; type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; composedTimestamp = sent.Timestamp; author = null; prefix = "You have"; } else { status = 0; type = SignalMessageDirection.Incoming; author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp); prefix = $"{author.ThreadDisplayName} has"; composedTimestamp = envelope.GetTimestamp(); } SignalMessage sm = new SignalMessage() { Direction = type, Type = SignalMessageType.GroupUpdate, Status = status, Author = author, Content = new SignalMessageContent() { Content = $"{prefix} updated the group." }, ThreadId = groupid, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, }; SignalDBContext.SaveMessageLocked(sm); dbgroup.MessagesCount += 1; if (sm.Direction == SignalMessageDirection.Incoming) { dbgroup.UnreadCount += 1; } else { dbgroup.UnreadCount = 0; dbgroup.LastSeenMessageIndex = dbgroup.MessagesCount; } dbgroup.LastMessage = sm; await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(dbgroup, sm); } else { Logger.LogError("HandleGroupUpdateMessage() received group update without group info"); } }
private async Task HandleGroupLeaveMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage dataMessage, bool isSync, long timestamp) { SignalServiceGroup sentGroup = dataMessage.Group; if (sentGroup != null) { string groupid = Base64.EncodeBytes(sentGroup.GroupId); SignalGroup group = await SignalDBContext.GetOrCreateGroupLocked(groupid, 0); if (isSync) { SignalContact author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), 0); SignalMessage sm = new SignalMessage() { Direction = SignalMessageDirection.Incoming, Type = SignalMessageType.GroupLeave, Status = SignalMessageStatus.Received, Author = author, Content = new SignalMessageContent() { Content = $"You have left the group." }, ThreadId = groupid, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = envelope.GetTimestamp(), ReceivedTimestamp = timestamp, }; SignalConversation updatedConversation = SignalDBContext.RemoveMemberFromGroup(groupid, author, sm); await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(updatedConversation, sm); } else { SignalContact author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), 0); SignalMessage sm = new SignalMessage() { Direction = SignalMessageDirection.Incoming, Type = SignalMessageType.GroupLeave, Status = SignalMessageStatus.Received, Author = author, Content = new SignalMessageContent() { Content = $"{author.ThreadDisplayName} has left the group." }, ThreadId = groupid, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = envelope.GetTimestamp(), ReceivedTimestamp = timestamp, }; SignalConversation updatedConversation = SignalDBContext.RemoveMemberFromGroup(groupid, author, sm); await SignalLibHandle.Instance.DispatchAddOrUpdateConversation(updatedConversation, sm); } } else { Logger.LogError("HandleGroupLeaveMessage() received group update without group info"); } }
private async Task HandleExpirationUpdateMessage(SignalServiceEnvelope envelope, SignalServiceContent content, SignalServiceDataMessage message, bool isSync, long timestamp) { SignalMessageDirection type; SignalContact author; SignalMessageStatus status; string prefix; SignalConversation conversation; long composedTimestamp; if (isSync) { var sent = content.SynchronizeMessage.Sent; type = SignalMessageDirection.Synced; status = SignalMessageStatus.Confirmed; composedTimestamp = sent.Timestamp; author = null; prefix = "You have"; if (message.Group != null) { conversation = await SignalDBContext.GetOrCreateGroupLocked(Base64.EncodeBytes(message.Group.GroupId), 0); } else { conversation = await SignalDBContext.GetOrCreateContactLocked(sent.Destination.ForceGetValue(), 0); } } else { status = 0; type = SignalMessageDirection.Incoming; author = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), timestamp); prefix = $"{author.ThreadDisplayName} has"; composedTimestamp = envelope.GetTimestamp(); if (message.Group != null) { conversation = await SignalDBContext.GetOrCreateGroupLocked(Base64.EncodeBytes(message.Group.GroupId), 0); } else { conversation = await SignalDBContext.GetOrCreateContactLocked(envelope.GetSource(), 0); } } conversation.ExpiresInSeconds = (uint)message.ExpiresInSeconds; SignalDBContext.UpdateExpiresInLocked(conversation); SignalMessage sm = new SignalMessage() { Direction = type, Type = SignalMessageType.ExpireUpdate, Status = status, Author = author, Content = new SignalMessageContent() { Content = $"{prefix} set the expiration timer to {message.ExpiresInSeconds} seconds." }, ThreadId = conversation.ThreadId, DeviceId = (uint)envelope.GetSourceDevice(), Receipts = 0, ComposedTimestamp = composedTimestamp, ReceivedTimestamp = timestamp, }; await SignalLibHandle.Instance.SaveAndDispatchSignalMessage(sm, null, conversation); }
private async Task HandleMessage(SignalServiceEnvelope envelope) { var cipher = new SignalServiceCipher(new SignalServiceAddress(SignalLibHandle.Instance.Store.Username), new Store()); var content = cipher.Decrypt(envelope); long timestamp = Util.CurrentTimeMillis(); if (content.Message != null) { SignalServiceDataMessage message = content.Message; if (message.EndSession) { await HandleSessionResetMessage(envelope, content, message, false, timestamp); } else if (message.IsGroupUpdate()) { if (message.Group.Type == SignalServiceGroup.GroupType.UPDATE) { await HandleGroupUpdateMessage(envelope, content, message, false, timestamp); } else if (message.Group.Type == SignalServiceGroup.GroupType.QUIT) { await HandleGroupLeaveMessage(envelope, content, message, false, timestamp); } else if (message.Group.Type == SignalServiceGroup.GroupType.REQUEST_INFO) { Logger.LogWarning("Received REQUEST_INFO request"); } } else if (message.ExpirationUpdate) { await HandleExpirationUpdateMessage(envelope, content, message, false, timestamp); } else { await HandleSignalMessage(envelope, content, message, false, timestamp); } } else if (content.SynchronizeMessage != null) { if (content.SynchronizeMessage.Sent != null) { var syncMessage = content.SynchronizeMessage.Sent; var dataMessage = syncMessage.Message; if (dataMessage.EndSession) { await HandleSessionResetMessage(envelope, content, dataMessage, true, timestamp); } else if (dataMessage.IsGroupUpdate()) { if (dataMessage.Group.Type == SignalServiceGroup.GroupType.UPDATE) { await HandleGroupUpdateMessage(envelope, content, dataMessage, true, timestamp); } else if (dataMessage.Group.Type == SignalServiceGroup.GroupType.QUIT) { await HandleGroupLeaveMessage(envelope, content, dataMessage, true, timestamp); } else if (dataMessage.Group.Type == SignalServiceGroup.GroupType.REQUEST_INFO) { Logger.LogWarning("Received synced REQUEST_INFO request"); } } else if (dataMessage.ExpirationUpdate) { await HandleExpirationUpdateMessage(envelope, content, dataMessage, true, timestamp); } else { await HandleSignalMessage(envelope, content, dataMessage, true, timestamp); } } else if (content.SynchronizeMessage.Reads != null) { var readMessages = content.SynchronizeMessage.Reads; foreach (var readMessage in readMessages) { try { await HandleSyncedReadMessage(readMessage); } catch (Exception e) { Logger.LogError("HandleReadMessage failed: {0}\n{1}", e.Message, e.StackTrace); } } } else if (content.SynchronizeMessage.BlockedList != null) { List <string> blockedNumbers = content.SynchronizeMessage.BlockedList.Numbers; await HandleBlockedNumbers(blockedNumbers); } else if (content.SynchronizeMessage.Groups != null) { Logger.LogInformation("HandleMessage() handling groups sync message from device {0}", envelope.GetSourceDevice()); int read; var avatarBuffer = new byte[4096]; var groups = content.SynchronizeMessage.Groups; using (var tmpFile = LibUtils.CreateTmpFile("groups_sync")) { var plaintextStream = await MessageReceiver.RetrieveAttachment(Token, groups.AsPointer(), tmpFile, 10000, null); var deviceGroupsStream = new DeviceGroupsInputStream(plaintextStream); var groupsList = new List <(SignalGroup, IList <string>)>(); DeviceGroup g; while ((g = deviceGroupsStream.Read()) != null) { if (g.Avatar != null) { SignalServiceAttachmentStream ssas = g.Avatar.AsStream(); while ((read = ssas.InputStream.Read(avatarBuffer, 0, avatarBuffer.Length)) > 0) { } } var group = new SignalGroup() { ThreadDisplayName = g.Name, ThreadId = Base64.EncodeBytes(g.Id), GroupMemberships = new List <GroupMembership>(), CanReceive = true, ExpiresInSeconds = g.ExpirationTimer != null ? g.ExpirationTimer.Value : 0 }; groupsList.Add((group, g.Members)); } List <SignalConversation> dbGroups = await SignalDBContext.InsertOrUpdateGroups(groupsList); await SignalLibHandle.Instance.DispatchAddOrUpdateConversations(dbGroups); } } else if (content.SynchronizeMessage.Contacts != null && content.SynchronizeMessage.Contacts.Complete) //TODO incomplete updates { Logger.LogInformation("HandleMessage() handling contacts sync message from device {0}", envelope.GetSourceDevice()); int read; var avatarBuffer = new byte[4096]; ContactsMessage contacts = content.SynchronizeMessage.Contacts; using (var tmpFile = LibUtils.CreateTmpFile("contacts_sync")) { var plaintextStream = await MessageReceiver.RetrieveAttachment(Token, contacts.Contacts.AsPointer(), tmpFile, 10000, null); var deviceContactsStream = new DeviceContactsInputStream(plaintextStream); List <SignalContact> contactsList = new List <SignalContact>(); DeviceContact c; while ((c = deviceContactsStream.Read()) != null) { if (c.Avatar != null) { SignalServiceAttachmentStream ssas = c.Avatar.AsStream(); while ((read = ssas.InputStream.Read(avatarBuffer, 0, avatarBuffer.Length)) > 0) { } } SignalContact contact = new SignalContact() { ThreadDisplayName = c.Name, ThreadId = c.Number, Color = c.Color, CanReceive = true, ExpiresInSeconds = c.ExpirationTimer != null ? c.ExpirationTimer.Value : 0 }; contactsList.Add(contact); } var dbContacts = SignalDBContext.InsertOrUpdateContacts(contactsList); await SignalLibHandle.Instance.DispatchAddOrUpdateConversations(dbContacts); } } } else if (content.ReadMessage != null) { SignalServiceReceiptMessage receiptMessage = content.ReadMessage; Logger.LogTrace("HandleMessage() received ReceiptMessage (type={0}, when={1})", receiptMessage.ReceiptType, receiptMessage.When); } else { //TODO callmessages Logger.LogWarning("HandleMessage() received unrecognized message"); } }
/// <summary> /// /// </summary> /// <param name="envelope"></param> /// <param name="ciphertext"></param> /// <returns></returns> /// <exception cref="InvalidMetadataMessageException"></exception> /// <exception cref="InvalidMetadataVersionException"></exception> /// <exception cref="ProtocolDuplicateMessageException"></exception> /// <exception cref="ProtocolUntrustedIdentityException"></exception> /// <exception cref="ProtocolLegacyMessageException"></exception> /// <exception cref="ProtocolInvalidKeyException"></exception> /// <exception cref="ProtocolInvalidVersionException"></exception> /// <exception cref="ProtocolInvalidMessageException"></exception> /// <exception cref="ProtocolInvalidKeyIdException"></exception> /// <exception cref="ProtocolNoSessionException"></exception> /// <exception cref="SelfSendException"></exception> private Plaintext Decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) { try { byte[] paddedMessage; SignalServiceMetadata metadata; uint sessionVersion; if (!envelope.HasSource() && !envelope.IsUnidentifiedSender()) { throw new ProtocolInvalidMessageException(new InvalidMessageException("Non-UD envelope is missing a source!"), null, 0); } if (envelope.IsPreKeySignalMessage()) { SignalProtocolAddress sourceAddress = GetPreferredProtocolAddress(signalProtocolStore, envelope.GetSourceAddress(), envelope.GetSourceDevice()); SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress); paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext)); metadata = new SignalServiceMetadata(envelope.GetSourceAddress(), envelope.GetSourceDevice(), envelope.GetTimestamp(), false); sessionVersion = sessionCipher.getSessionVersion(); } else if (envelope.IsSignalMessage()) { SignalProtocolAddress sourceAddress = GetPreferredProtocolAddress(signalProtocolStore, envelope.GetSourceAddress(), envelope.GetSourceDevice()); SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress); paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext)); metadata = new SignalServiceMetadata(envelope.GetSourceAddress(), envelope.GetSourceDevice(), envelope.GetTimestamp(), false); sessionVersion = sessionCipher.getSessionVersion(); } else if (envelope.IsUnidentifiedSender()) { SealedSessionCipher sealedSessionCipher = new SealedSessionCipher(signalProtocolStore, localAddress.Uuid, localAddress.GetNumber(), 1); DecryptionResult result = sealedSessionCipher.Decrypt(certificateValidator !, ciphertext, (long)envelope.Envelope.ServerTimestamp); SignalServiceAddress resultAddress = new SignalServiceAddress(UuidUtil.Parse(result.SenderUuid), result.SenderE164); SignalProtocolAddress protocolAddress = GetPreferredProtocolAddress(signalProtocolStore, resultAddress, result.DeviceId); paddedMessage = result.PaddedMessage; metadata = new SignalServiceMetadata(resultAddress, result.DeviceId, envelope.GetTimestamp(), true); sessionVersion = (uint)sealedSessionCipher.GetSessionVersion(protocolAddress); } else { throw new InvalidMessageException($"Unknown type: {envelope.GetType()}"); } PushTransportDetails transportDetails = new PushTransportDetails(sessionVersion); byte[] data = transportDetails.GetStrippedPaddingMessageBody(paddedMessage); return(new Plaintext(metadata, data)); } catch (DuplicateMessageException e) { throw new ProtocolDuplicateMessageException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (LegacyMessageException e) { throw new ProtocolLegacyMessageException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidMessageException e) { throw new ProtocolInvalidMessageException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidKeyIdException e) { throw new ProtocolInvalidKeyIdException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidKeyException e) { throw new ProtocolInvalidKeyException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (libsignal.exceptions.UntrustedIdentityException e) { throw new ProtocolUntrustedIdentityException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (InvalidVersionException e) { throw new ProtocolInvalidVersionException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } catch (NoSessionException e) { throw new ProtocolNoSessionException(e, envelope.GetSourceIdentifier(), envelope.GetSourceDevice()); } }
private Plaintext Decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) { try { SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.GetSource(), (uint)envelope.GetSourceDevice()); SessionCipher sessionCipher = new SessionCipher(SignalProtocolStore, sourceAddress); SealedSessionCipher sealedSessionCipher = new SealedSessionCipher(SignalProtocolStore, new SignalProtocolAddress(LocalAddress.E164number, 1)); byte[] paddedMessage; Metadata metadata; uint sessionVersion; if (envelope.IsPreKeySignalMessage()) { paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext)); metadata = new Metadata(envelope.GetSource(), envelope.GetSourceDevice(), envelope.GetTimestamp(), false); sessionVersion = sessionCipher.getSessionVersion(); } else if (envelope.IsSignalMessage()) { paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext)); metadata = new Metadata(envelope.GetSource(), envelope.GetSourceDevice(), envelope.GetTimestamp(), false); sessionVersion = sessionCipher.getSessionVersion(); } else if (envelope.IsUnidentifiedSender()) { var results = sealedSessionCipher.Decrypt(CertificateValidator, ciphertext, (long)envelope.Envelope.ServerTimestamp); paddedMessage = results.Item2; metadata = new Metadata(results.Item1.Name, (int)results.Item1.DeviceId, (long)envelope.Envelope.Timestamp, true); sessionVersion = (uint)sealedSessionCipher.GetSessionVersion(new SignalProtocolAddress(metadata.Sender, (uint)metadata.SenderDevice)); } else { throw new InvalidMessageException("Unknown type: " + envelope.GetEnvelopeType() + " from " + envelope.GetSource()); } PushTransportDetails transportDetails = new PushTransportDetails(sessionVersion); byte[] data = transportDetails.GetStrippedPaddingMessageBody(paddedMessage); return(new Plaintext(metadata, data)); } catch (DuplicateMessageException e) { throw new ProtocolDuplicateMessageException(e, envelope.GetSource(), envelope.GetSourceDevice()); } catch (LegacyMessageException e) { throw new ProtocolLegacyMessageException(e, envelope.GetSource(), envelope.GetSourceDevice()); } catch (InvalidMessageException e) { throw new ProtocolInvalidMessageException(e, envelope.GetSource(), envelope.GetSourceDevice()); } catch (InvalidKeyIdException e) { throw new ProtocolInvalidKeyIdException(e, envelope.GetSource(), envelope.GetSourceDevice()); } catch (InvalidKeyException e) { throw new ProtocolInvalidKeyException(e, envelope.GetSource(), envelope.GetSourceDevice()); } catch (libsignal.exceptions.UntrustedIdentityException e) { throw new ProtocolUntrustedIdentityException(e, envelope.GetSource(), envelope.GetSourceDevice()); } catch (InvalidVersionException e) { throw new ProtocolInvalidVersionException(e, envelope.GetSource(), envelope.GetSourceDevice()); } catch (NoSessionException e) { throw new ProtocolNoSessionException(e, envelope.GetSource(), envelope.GetSourceDevice()); } }
private byte[] Decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) { SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.GetSource(), (uint)envelope.GetSourceDevice()); SessionCipher sessionCipher = new SessionCipher(SignalProtocolStore, sourceAddress); byte[] paddedMessage; if (envelope.IsPreKeySignalMessage()) { paddedMessage = sessionCipher.decrypt(new PreKeySignalMessage(ciphertext)); } else if (envelope.IsSignalMessage()) { paddedMessage = sessionCipher.decrypt(new SignalMessage(ciphertext)); } else { throw new InvalidMessageException("Unknown type: " + envelope.GetEnvelopeType() + " from " + envelope.GetSource()); } PushTransportDetails transportDetails = new PushTransportDetails(sessionCipher.getSessionVersion()); return(transportDetails.GetStrippedPaddingMessageBody(paddedMessage)); }