コード例 #1
0
        private async void TryJoinConvos()
        {
            if (!appSettings["SaveConvoPasswords", true])
            {
                return;
            }

            var userConvos = (await userService.GetConvos(user.Id, user.Token.Item2))
                             .Select(c => (Convo)c)
                             .Distinct()
                             .Where(convo => !convo.IsExpired()).ToArray();

            foreach (var convo in userConvos)
            {
                string cachedPwSHA512 = convoPasswordProvider.GetPasswordSHA512(convo.Id);

                if (cachedPwSHA512.NullOrEmpty())
                {
                    cachedPwSHA512 = await SecureStorage.GetAsync($"convo:{convo.Id}_pw:SHA512");
                }

                if (cachedPwSHA512.NotNullNotEmpty())
                {
                    var dto = new ConvoJoinRequestDto
                    {
                        ConvoId             = convo.Id,
                        ConvoPasswordSHA512 = cachedPwSHA512
                    };

                    var body = new EpistleRequestBody
                    {
                        UserId = user.Id,
                        Auth   = user.Token.Item2,
                        Body   = JsonSerializer.Serialize(dto)
                    };

                    if (await convoService.JoinConvo(body.Sign(crypto, user.PrivateKeyPem)))
                    {
                        convoPasswordProvider.SetPasswordSHA512(convo.Id, cachedPwSHA512);
                        ConvoMetadataDto metadata = await convoService.GetConvoMetadata(convo.Id, cachedPwSHA512, user.Id, user.Token.Item2);

                        if (metadata != null)
                        {
                            var viewModel = viewModelFactory.Create <ActiveConvoViewModel>();
                            viewModel.ActiveConvo = convo;
                            viewModel.OnAppearing();

                            activeConvos[convo.Id] = viewModel;
                        }
                    }
                }
            }

            eventAggregator.GetEvent <TriggerUpdateConvosListEvent>().Publish();
        }
コード例 #2
0
        /// <summary>
        /// Submits a message to a <see cref="Convo"/>.
        /// </summary>
        /// <param name="convo">The <see cref="Convo"/> to post the message into.</param>
        /// <param name="messageType">The type of message (e.g. "TEXT=UTF8", "FILE=example.png", etc...).</param>
        /// <param name="message">The message body to encrypt and post.</param>
        /// <returns>Whether the message could be submitted successfully or not.</returns>
        private async Task <bool> PostMessageToConvo(Convo convo, string messageType, byte[] message)
        {
            if (message.NullOrEmpty())
            {
                return(false);
            }

            Task <IDictionary <string, string> > publicKeys = userService.GetUserPublicKeys(user.Id, convo.GetParticipantIdsCommaSeparated(), user.Token.Item2);

            byte[] compressedMessage = await compressionUtility.Compress(message, CompressionSettings.Default).ConfigureAwait(false);

            using var encryptionResult = await aes.EncryptAsync(compressedMessage).ConfigureAwait(false);

            byte[] key = new byte[48];

            for (int i = 0; i < 32; i++)
            {
                key[i] = encryptionResult.Key[i];
            }

            for (int i = 0; i < 16; i++)
            {
                key[i + 32] = encryptionResult.IV[i];
            }

            // Encrypt the message decryption key for every convo participant individually.
            var encryptedKeys = new ConcurrentBag <string>();

            Parallel.ForEach(await publicKeys.ConfigureAwait(false), kvp =>
            {
                (string userId, string userPublicKey) = kvp;

                if (userId.NotNullNotEmpty() && userPublicKey.NotNullNotEmpty())
                {
                    string decompressedPublicKey = keyExchange.DecompressPublicKey(userPublicKey);
                    encryptedKeys.Add(userId + ':' + Convert.ToBase64String(rsa.Encrypt(key, decompressedPublicKey)));
                }
            });

            try
            {
                var postParamsDto = new PostMessageParamsDto
                {
                    Type                = messageType,
                    SenderName          = userSettings.Username,
                    ConvoId             = convo.Id,
                    ConvoPasswordSHA512 = convoPasswordProvider.GetPasswordSHA512(convo.Id),
                    EncryptedKeys       = encryptedKeys.ToCommaSeparatedString(),
                    EncryptedBody       = Convert.ToBase64String(encryptionResult.EncryptedData)
                };

                var body = new EpistleRequestBody
                {
                    UserId = user.Id,
                    Auth   = user.Token.Item2,
                    Body   = JsonSerializer.Serialize(postParamsDto)
                };

                return(await convoService.PostMessage(body.Sign(rsa, user.PrivateKeyPem)).ConfigureAwait(false));
            }
            catch
            {
                return(false);
            }
        }