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)); } }
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); } } }
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)); }
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); }
/// <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()); }