示例#1
0
        public void Encrypt_Decrypt_Stream()
        {
            using (var media = new MemoryStream())
                using (var crypto = new AesStream("abc", media))
                {
                    var input0 = new byte[8192];
                    var input1 = new byte[8192];
                    var input2 = new byte[8192];

                    var output0 = new byte[8192];
                    var output1 = new byte[8192];
                    var output2 = new byte[8192];

                    input0.Fill(100, 0, 8192);
                    input1.Fill(101, 0, 8192);
                    input2.Fill(102, 0, 8192);

                    // write 0, 2, 1 but in order 0, 1, 2
                    crypto.Position = 0 * 8192;
                    crypto.Write(input0, 0, 8192);

                    crypto.Position = 2 * 8192;
                    crypto.Write(input2, 0, 8192);

                    crypto.Position = 1 * 8192;
                    crypto.Write(input1, 0, 8192);

                    // read encrypted data
                    media.Position = 0;
                    media.Read(output0, 0, 8192);
                    media.Read(output1, 0, 8192);
                    media.Read(output2, 0, 8192);

                    Assert.IsFalse(output0.All(x => x == 100));
                    Assert.IsFalse(output1.All(x => x == 101));
                    Assert.IsFalse(output2.All(x => x == 102));

                    // read decrypted data
                    crypto.Position = 0 * 8192;
                    crypto.Read(output0, 0, 8192);

                    crypto.Position = 2 * 8192;
                    crypto.Read(output2, 0, 8192);

                    crypto.Position = 1 * 8192;
                    crypto.Read(output1, 0, 8192);

                    Assert.IsTrue(output0.All(x => x == 100));
                    Assert.IsTrue(output1.All(x => x == 101));
                    Assert.IsTrue(output2.All(x => x == 102));
                }
        }
示例#2
0
        public void AesStreamRead()
        {
            var cryptedData = new byte[] { 238, 75, 117, 248, 55 };
            var password    = SecurityHelper.ToSecureString("MyPassword");

            using (var baseStream = new MemoryStream(cryptedData))
                using (var aesStream = new AesStream(baseStream, password, SecurityHelper.GetSaltKeys(password).GetBytes(16)))
                {
                    var data = new byte[aesStream.Length];
                    aesStream.Read(data, 0, data.Length);

                    Assert.IsTrue(data.ToArray().SequenceEqual(new byte[] { 72, 101, 108, 108, 111 }));
                    Assert.AreEqual(Encoding.ASCII.GetString(data), "Hello");
                }
        }
    /// <summary>
    /// Reads bytes directly from the stream
    /// </summary>
    /// <param name="amount"></param>
    /// <returns></returns>
    private byte[] ReadBytes(int amount)
    {
        if (!Client.Connected)
        {
            throw new UnityException("Client not connected!");
        }

        byte[] buffer    = new byte[amount];
        int    bytesRead = 0;

        lock (_streamReadLock)
        {
            while (bytesRead < amount)
            {
                int i = 0;;
                try
                {
                    if (_encrypted)
                    {
                        i = _aesStream.Read(buffer, bytesRead, amount - bytesRead);
                    }
                    else
                    {
                        i = Client.GetStream().Read(buffer, bytesRead, amount - bytesRead);
                    }
                }
                catch (IOException ex)
                {
                    Disconnect($"Connection closed: {ex.Message}");
                    break;
                }
                catch (Exception ex)
                {
                    Disconnect($"Error reading from socket: {ex.Message}");
                    break;
                }
                if (i == 0)
                {
                    Disconnect("Connection closed");
                    break;
                }

                bytesRead += i;
            }
        }

        return(buffer);
    }
        private void Receive(byte[] buffer, int start, int offset, SocketFlags f)
        {
            int read = 0;

            while (read < offset)
            {
                if (encrypted)
                {
                    read += s.Read(buffer, start + read, offset - read);
                }
                else
                {
                    read += c.Client.Receive(buffer, start + read, offset - read, f);
                }
            }
        }
示例#5
0
        public void TestAesStream()
        {
            var baseStream = new MemoryStream();
            var key = new byte[]
                { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
            var encryptStream = new AesStream(baseStream, key);
            var plaintext = Encoding.UTF8.GetBytes("Hello, world!");
            encryptStream.Write(plaintext, 0, plaintext.Length);

            baseStream.Seek(0, SeekOrigin.Begin);
            var decryptStream = new AesStream(baseStream, key);
            byte[] buffer = new byte[plaintext.Length];
            decryptStream.Read(buffer, 0, buffer.Length);

            Assert.AreEqual("Hello, world!", Encoding.UTF8.GetString(buffer));
        }
示例#6
0
        public void TestAesStream()
        {
            var baseStream = new MemoryStream();
            var key        = new byte[]
            { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
            var encryptStream = new AesStream(baseStream, key);
            var plaintext     = Encoding.UTF8.GetBytes("Hello, world!");

            encryptStream.Write(plaintext, 0, plaintext.Length);

            baseStream.Seek(0, SeekOrigin.Begin);
            var decryptStream = new AesStream(baseStream, key);

            byte[] buffer = new byte[plaintext.Length];
            decryptStream.Read(buffer, 0, buffer.Length);

            Assert.AreEqual("Hello, world!", Encoding.UTF8.GetString(buffer));
        }
示例#7
0
        private async Task <List <CloudDataEntry> > GetDataEntriesFromServerAsync()
        {
            var cloudStorageProviderMock = GetCloudStorageProviderMock();

            if (Directory.Exists(cloudStorageProviderMock.TemporaryFolder))
            {
                using (var memoryStream = new MemoryStream())
                {
                    await cloudStorageProviderMock.DownloadFileAsync(cloudStorageProviderMock.TemporaryFolder + @"\.clipboard", memoryStream);

                    var cloudDataPassword = await GetCloudDataPasswordAsync();

                    using (var aesStream = new AesStream(memoryStream, cloudDataPassword, SecurityHelper.GetSaltKeys(cloudDataPassword).GetBytes(16)))
                    {
                        var data = new byte[aesStream.Length];
                        aesStream.Read(data, 0, data.Length);
                        return(JsonConvert.DeserializeObject <List <CloudDataEntry> >(Encoding.UTF8.GetString(data)));
                    }
                }
            }

            return(null);
        }
    /// <summary>
    /// Reads bytes directly from the stream
    /// </summary>
    /// <param name="amount"></param>
    /// <returns></returns>
    private byte[] ReadBytes(int amount)
    {
        if (!Client.Connected)
        {
            throw new UnityException("Client not connected!");
        }

        byte[] buffer    = new byte[amount];
        int    bytesRead = 0;

        lock (_streamReadLock)
        {
            while (bytesRead < amount)
            {
                int i = 0;

                if (_encrypted)
                {
                    i = _aesStream.Read(buffer, bytesRead, amount - bytesRead);
                }
                else
                {
                    i = Client.GetStream().Read(buffer, bytesRead, amount - bytesRead);
                }

                if (i == 0)
                {
                    throw new IOException("Connection closed");
                }

                bytesRead += i;
            }
        }

        return(buffer);
    }
示例#9
0
        /// <summary>
        /// Force to synchronize that data with the cloud.
        /// </summary>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        internal async Task SynchronizeAsync()
        {
            if (IsSynchronizing)
            {
                return;
            }

            Logger.Instance.Information("Synchronization with the cloud started.");
            IsSynchronizing = true;

            if (CurrentCloudStorageProvider == null)
            {
                Logger.Instance.Warning("The user is not logged to any cloud storage provider. The synchronization stopped.");
                IsSynchronizing = false;
                return;
            }

            if (!CoreHelper.IsUnitTesting() && !SystemInfoHelper.CheckForInternetConnection())
            {
                Logger.Instance.Warning("There is no internet connection. The synchronization stopped.");
                IsSynchronizing = false;
                return;
            }

            SynchronizationStarted?.Invoke(this, new EventArgs());

            try
            {
                if (!await CurrentCloudStorageProvider.TryAuthenticateAsync())
                {
                    Logger.Instance.Warning("The user is not authenticated correctly. Consider unlink the app and connect again. The synchronization stopped.");
                    IsSynchronizing = false;
                    SynchronizationEnded?.Invoke(this, new EventArgs());
                    return;
                }

                var userId = SecurityHelper.ToSecureString(await CurrentCloudStorageProvider.GetUserIdAsync());

                if (string.IsNullOrWhiteSpace(SecurityHelper.ToUnsecureString(userId)))
                {
                    Logger.Instance.Warning("The user's id from the cloud storage provider has not been found. The synchronization stopped.");
                    IsSynchronizing = false;
                    SynchronizationEnded?.Invoke(this, new EventArgs());
                    SynchronizationFailed?.Invoke(this, new EventArgs());
                    return;
                }

                Logger.Instance.Information("Freezing the data before synchronize.");
                var dataService = ServiceLocator.GetService <DataService>();
                var cloudDataEntryFromServer = new List <CloudDataEntry>();
                var cloudAppFolder           = await CurrentCloudStorageProvider.GetAppFolderAsync();

                var cloudDataEntryFilePath = Path.Combine(cloudAppFolder.FullPath, Consts.DataEntryFileName);
                var cloudDataPassword      = SecurityHelper.ToSecureString(SecurityHelper.EncryptString(userId, SecurityHelper.ToSecureString(await CurrentCloudStorageProvider.GetUserNameAsync())));
                var localFrozenDataEntries = DataHelper.FromByteArray <AsyncObservableCollection <DataEntry> >(DataHelper.ToByteArray(dataService.DataEntries));
                var localFrozenCache       = DataHelper.FromByteArray <List <DataEntryCache> >(DataHelper.ToByteArray(dataService.Cache));

                // Download data from server.
                if (cloudAppFolder.Files.Any(file => file.FullPath == cloudDataEntryFilePath))
                {
                    Logger.Instance.Information("Downloading the data entry file from the server.");
                    try
                    {
                        using (var memoryStream = new MemoryStream())
                        {
                            await CurrentCloudStorageProvider.DownloadFileAsync(cloudDataEntryFilePath, memoryStream);

                            memoryStream.Position = 0;
                            using (var aesStream = new AesStream(memoryStream, cloudDataPassword, SecurityHelper.GetSaltKeys(cloudDataPassword).GetBytes(16)))
                            {
                                var data = new byte[aesStream.Length];
                                aesStream.Read(data, 0, data.Length);
                                cloudDataEntryFromServer = JsonConvert.DeserializeObject <List <CloudDataEntry> >(Encoding.UTF8.GetString(data));
                            }
                        }
                    }
                    catch (Exception exception)
                    {
                        Logger.Instance.Warning($"Unable to download or read the data file entry from the cloud for the following reason : {exception.Message}");
                        IsSynchronizing = false;
                        SynchronizationEnded?.Invoke(this, new EventArgs());
                        SynchronizationFailed?.Invoke(this, new EventArgs());
                        return;
                    }
                }
                else
                {
                    Logger.Instance.Information("There is no data entry file on the server yet.");
                }

                // Synchronize locally the data. The result must corresponds to what we will have locally and on the server at the end of the synchronization process.
                var cloudDataEntryToServer = dataService.DifferenceLocalAndCloudDataEntries(cloudDataEntryFromServer);

                // Download the needed data from the server to the local machine.
                Logger.Instance.Information("Downloading the needed data from the server to the local machine.");
                var dataToDownload = cloudDataEntryFromServer.Cast <DataEntryBase>().Except(localFrozenDataEntries, (item1, item2) => item1.Identifier == item2.Identifier).ToList();
                var taskList       = new List <Task>();
                foreach (var cloudDataEntry in dataToDownload)
                {
                    if (dataToDownload.Any(data => localFrozenCache.Any(item => data.Identifier == item.Identifier && item.Status == DataEntryStatus.Deleted)))
                    {
                        continue;
                    }

                    foreach (var dataEntryDataIdentifier in cloudDataEntry.DataIdentifiers)
                    {
                        var task = DownloadDataFileAsync(dataService.ClipboardDataPath, cloudAppFolder, cloudDataPassword, dataEntryDataIdentifier);
                        taskList.Add(task);
                    }
                }
                await Task.WhenAll(taskList);

                // Delete the needed data from the server
                Logger.Instance.Information("Deleting the needed data from the server.");
                taskList = new List <Task>();
                foreach (var dataServiceDataEntry in localFrozenDataEntries.Where(item => !item.CanSynchronize))
                {
                    foreach (var dataEntryDataIdentifier in dataServiceDataEntry.DataIdentifiers)
                    {
                        var task = DeleteFileAsync(cloudAppFolder, dataEntryDataIdentifier);
                        taskList.Add(task);
                    }
                }
                await Task.WhenAll(taskList);

                taskList = new List <Task>();
                foreach (var cacheEntry in localFrozenCache.Where(item => item.Status == DataEntryStatus.Deleted))
                {
                    var dataEntry = cloudDataEntryFromServer.SingleOrDefault(item => item.Identifier == cacheEntry.Identifier);
                    if (dataEntry != null)
                    {
                        foreach (var dataEntryDataIdentifier in dataEntry.DataIdentifiers)
                        {
                            var task = DeleteFileAsync(cloudAppFolder, dataEntryDataIdentifier);
                            taskList.Add(task);
                        }
                    }
                }
                await Task.WhenAll(taskList);

                await dataService.MakeCacheSynchronized(cloudDataEntryToServer, true, localFrozenCache);

                localFrozenDataEntries = DataHelper.FromByteArray <AsyncObservableCollection <DataEntry> >(DataHelper.ToByteArray(dataService.DataEntries));
                localFrozenCache       = DataHelper.FromByteArray <List <DataEntryCache> >(DataHelper.ToByteArray(dataService.Cache));

                // Upload the needed data from the server to the local machine
                Logger.Instance.Information("Uploading the needed data from the server to the local machine.");
                var dataToUpload = localFrozenDataEntries.Cast <DataEntryBase>().Except(cloudDataEntryFromServer, (item1, item2) => item1.Identifier == item2.Identifier);
                taskList = new List <Task>();
                foreach (var dataEntry in dataToUpload)
                {
                    var localDataEntry = localFrozenDataEntries.Single(item => item.Identifier == dataEntry.Identifier);
                    if (!localDataEntry.CanSynchronize || localDataEntry.Thumbnail.Type == ThumbnailDataType.Files)
                    {
                        continue;
                    }

                    foreach (var dataEntryDataIdentifier in dataEntry.DataIdentifiers)
                    {
                        var task = UploadDataFileAsync(dataService.ClipboardDataPath, cloudAppFolder, cloudDataPassword, dataEntryDataIdentifier);
                        taskList.Add(task);
                    }
                }
                await Task.WhenAll(taskList);

                // Upload the new data to the server.
                Logger.Instance.Information("Uploading the data entry file to the server.");

                using (var memoryStream = new MemoryStream())
                    using (var aesStream = new AesStream(memoryStream, cloudDataPassword, SecurityHelper.GetSaltKeys(cloudDataPassword).GetBytes(16)))
                    {
                        var data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(cloudDataEntryToServer));
                        aesStream.Write(data, 0, data.Length);
                        aesStream.Position = 0;
                        await CurrentCloudStorageProvider.UploadFileAsync(memoryStream, cloudDataEntryFilePath);
                    }

                await dataService.MakeCacheSynchronized(cloudDataEntryToServer, false, localFrozenCache);
            }
            catch (Exception exception)
            {
                Logger.Instance.Warning($"Unable to synchronize for the following reason : {exception.Message}. {exception.InnerException?.Message}");
                SynchronizationFailed?.Invoke(this, new EventArgs());
            }

            _synchronizeTimer.Stop();
            _synchronizeTimer.Start();

            IsSynchronizing = false;
            SynchronizationEnded?.Invoke(this, new EventArgs());
        }