/// <summary> /// Initialize a file for upload /// </summary> /// <returns>Token that is used to append data in chunk</returns> public FileDataInfo SendFileStart(FileInformation block) { if (block == null) { throw new Exception("Fie information not set"); } if (block.TenantID == Guid.Empty) { throw new Exception("Invalid Tenant ID"); } if (string.IsNullOrEmpty(block.Container)) { throw new Exception("Invalid container"); } if (string.IsNullOrEmpty(block.FileName)) { throw new Exception("Invalid file name"); } if (block.Size < 0) { throw new Exception("Invalid file size"); } byte[] tenantKey = null; using (var fm = new FileManager()) { var tenant = fm.GetTenant(block.TenantID); tenantKey = tenant.Key.Decrypt(fm.MasterKey, fm.IV); } lock (_fileUploadCache) { var cache = new FilePartCache { TenantID = block.TenantID, Container = block.Container, FileName = block.FileName, CRC = block.CRC, Size = block.Size, Index = 0, CreatedTime = block.CreatedTime, ModifiedTime = block.ModifiedTime, TenantKey = tenantKey, }; //Add to part cache if (_fileUploadCache.Contains(cache.Key)) { throw new Exception("File concurrency error"); } try { using (var fm = new FileManager()) { fm.RemoveFile(block.TenantID, block.Container, block.FileName); } _fileUploadCache.Add(cache.Key); _fileUploadPartCache.TryAdd(cache.ID, cache); using (var fm = new FileManager()) { var header = new FileHeader { DataKey = cache.OneTimeKey, EncryptedDataKey = cache.OneTimeKey.Encrypt(cache.TenantKey, FileEngine.DefaultIVector), TenantKey = cache.TenantKey, }; //Create the data folder var dataPath = Path.Combine(ConfigHelper.WorkFolder, cache.ID.ToString()); Directory.CreateDirectory(dataPath); cache.TempDataFile = Path.Combine(dataPath, "out"); cache.EncryptStream = Extensions.OpenEncryptStream(cache.TempDataFile, fm.IV, header); } return(new FileDataInfo { Token = cache.ID, Size = cache.Size, CreatedTime = block.CreatedTime, ModifiedTime = block.ModifiedTime, }); } catch (Exception ex) { Logger.LogError(ex); throw; } } }
internal static void DecryptStream(this System.IO.Stream src, System.IO.Stream dest, byte[] iv, FileHeader header) { try { //Get the data key var vv = new byte[FileHeader.FileHeaderSize]; src.Read(vv, 0, vv.Length); header.Load(vv); header.DataKey = header.EncryptedDataKey.Decrypt(header.TenantKey, iv); var aes = FileUtilities.CryptoProvider(header.DataKey, iv); using (var decryptor = aes.CreateDecryptor()) { src.Seek(FileHeader.FileHeaderSize, SeekOrigin.Begin); using (var cryptoStream = new CryptoStream(src, decryptor, CryptoStreamMode.Read)) { cryptoStream.CopyTo(dest); } } } catch (Exception ex) { throw; } }
internal static void EncryptStream(this System.IO.Stream stream, string targetFile, byte[] iv, FileHeader header) { try { var aes = FileUtilities.CryptoProvider(header.DataKey, iv); using (var encryptor = aes.CreateEncryptor()) { using (var newFile = File.Create(targetFile)) { //Write blank header. It will be filled in later var padBytes = header.ToArray(); newFile.Write(padBytes, 0, padBytes.Length); //Write encrypted data using (var cryptoStream = new CryptoStream(newFile, encryptor, CryptoStreamMode.Write)) { stream.CopyTo(cryptoStream); } } } WriteFileHeader(targetFile, header); } catch (Exception ex) { throw; } }
internal static System.IO.Stream OpenEncryptStream(string targetFile, byte[] iv, FileHeader header) { try { var aes = FileUtilities.CryptoProvider(header.DataKey, iv); var encryptor = aes.CreateEncryptor(); var newFile = File.Create(targetFile); //Write blank header. It will be filled in later var padBytes = header.ToArray(); newFile.Write(padBytes, 0, padBytes.Length); //Create encrypted stream var cryptoStream = new CryptoStream(newFile, encryptor, CryptoStreamMode.Write); return(cryptoStream); } catch (Exception ex) { throw; } }
internal static System.IO.Stream GetDecryptStream(this System.IO.Stream src, byte[] iv, FileHeader header) { try { //Get the data key var vv = new byte[FileHeader.FileHeaderSize]; src.Read(vv, 0, vv.Length); header.Load(vv); header.DataKey = header.EncryptedDataKey.Decrypt(header.TenantKey, iv); //Do not use "using" statement as the stream must stay open var aes = FileUtilities.CryptoProvider(header.DataKey, iv); var decryptor = aes.CreateDecryptor(); src.Seek(FileHeader.FileHeaderSize, SeekOrigin.Begin); var cryptoStream = new CryptoStream(src, decryptor, CryptoStreamMode.Read); return(cryptoStream); } catch (Exception ex) { throw; } }