/// <summary> /// Create decorator streams implementing the Encrypt-then-MAC scheme (CipherStream bound to a MacStream). /// </summary> /// <param name="item">Item to create resources for.</param> /// <param name="encryptor">Cipher stream (output).</param> /// <param name="authenticator">MAC stream (output).</param> protected void CreateEtMDecorator(PayloadItem item, out CipherStream encryptor, out MacStream authenticator) { byte[] encryptionKey, authenticationKey; if (item.SymmetricCipherKey.IsNullOrZeroLength() == false && item.AuthenticationKey.IsNullOrZeroLength() == false) { encryptionKey = item.SymmetricCipherKey; authenticationKey = item.AuthenticationKey; } else if (PayloadItemPreKeys.ContainsKey(item.Identifier)) { if (item.Authentication.KeySizeBits.HasValue == false) { throw new ConfigurationInvalidException( "Payload item authentication configuration is missing size specification of MAC key."); } KeyStretchingUtility.DeriveWorkingKeys(PayloadItemPreKeys[item.Identifier], item.SymmetricCipher.KeySizeBits / 8, item.Authentication.KeySizeBits.Value / 8, item.KeyDerivation, out encryptionKey, out authenticationKey); } else { throw new ItemKeyMissingException(item); } authenticator = new MacStream(PayloadStream, Writing, item.Authentication, authenticationKey, false); encryptor = new CipherStream(authenticator, Writing, item.SymmetricCipher, encryptionKey, false); }
private void ButSupplementalSaveDefaults_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(textSupplementalBackupCopyNetworkPath.Text) && !Directory.Exists(textSupplementalBackupCopyNetworkPath.Text)) { MsgBox.Show(this, "Invalid or inaccessible " + labelSupplementalBackupCopyNetworkPath.Text + "."); //This label text will rarely change. return; } if (Prefs.UpdateBool(PrefName.SupplementalBackupEnabled, checkSupplementalBackupEnabled.Checked)) { try { //Inform HQ when the supplemental backups are enabled/disabled and which security admin performed the change. PayloadItem pliStatus = new PayloadItem( (int)(checkSupplementalBackupEnabled.Checked?SupplementalBackupStatuses.Enabled:SupplementalBackupStatuses.Disabled), "SupplementalBackupStatus"); PayloadItem pliAdminUserName = new PayloadItem(Security.CurUser.UserName, "AdminUserName"); string officeData = PayloadHelper.CreatePayload(new List <PayloadItem>() { pliStatus, pliAdminUserName }, eServiceCode.SupplementalBackup); WebServiceMainHQProxy.GetWebServiceMainHQInstance().SetSupplementalBackupStatus(officeData); } catch (Exception ex) { ex.DoNothing(); //Internet probably is unavailble right now. } SecurityLogs.MakeLogEntry(Permissions.SupplementalBackup, 0, "Supplemental backup has been " + (checkSupplementalBackupEnabled.Checked?"Enabled":"Disabled") + "."); } if (Prefs.UpdateString(PrefName.SupplementalBackupNetworkPath, textSupplementalBackupCopyNetworkPath.Text)) { SecurityLogs.MakeLogEntry(Permissions.SupplementalBackup, 0, labelSupplementalBackupCopyNetworkPath.Text + " changed to '" + textSupplementalBackupCopyNetworkPath.Text + "'."); } MsgBox.Show(this, "Saved"); }
public static List <PayloadItem> GetItemsBlockExample(List <FileInfo> files) { var items = new List <PayloadItem> (); foreach (var fileInfo in files) { var t = fileInfo; int authOutputSize; var payloadItem = new PayloadItem { Path = t.Name, ExternalLength = t.Length, Type = PayloadItemType.File, SymmetricCipher = CipherConfigurationFactory.CreateBlockCipherConfiguration(BlockCipher.Serpent, BlockCipherMode.Ctr, BlockCipherPadding.None), Authentication = AuthenticationConfigurationFactory.CreateAuthenticationConfiguration(MacFunction.Blake2B256, out authOutputSize) }; payloadItem.SymmetricCipherKey = new byte[payloadItem.SymmetricCipher.KeySizeBits / 8]; StratCom.EntropySupplier.NextBytes(payloadItem.SymmetricCipherKey); payloadItem.AuthenticationKey = new byte[payloadItem.Authentication.KeySizeBits.Value / 8]; StratCom.EntropySupplier.NextBytes(payloadItem.AuthenticationKey); payloadItem.SetStreamBinding(fileInfo.OpenRead); items.Add(payloadItem); } return(items); }
/// <summary> /// Stores an item in the tree structure, building up 'directory' nodes as necessary in the process. /// </summary> /// <param name="item">Payload item to add as content.</param> /// <param name="path">Path of payload item.</param> /// <param name="checkForInvalid">If <c>true</c>, path will be checked for invalid characters.</param> public ContentTreeNode <PayloadItem> AddItem(PayloadItem item, string path, bool checkForInvalid = true) { if (String.IsNullOrWhiteSpace(path)) { throw new ArgumentException("Path is null, empty, or consists only of spaces.", "path"); } var pathSegments = path.Split(PathSeperators, StringSplitOptions.RemoveEmptyEntries); if (pathSegments.Length == 0) { throw new ArgumentException("Path has no valid directory or item names."); } var dirNode = RootNode; for (var i = 0; i < pathSegments.Length; i++) { var segment = pathSegments[i]; // Is this segment of the path already represented by a node? var matchIndex = -1; if (dirNode.HasChildren) { matchIndex = dirNode.FindChildNodeIndex(segment); } if (matchIndex == -1) { // Nope, it isn't! Have to make it. // Maybe check if the path is valid if (checkForInvalid && segment.Any(c => InvalidPathChars.Contains(c)) == false) { throw new ArgumentException("Path contains invalid characters.", "path"); } if (i == pathSegments.Length - 1) { break; } dirNode = dirNode.AddChildDirectory(segment); } else { if (i == pathSegments.Length - 1) { if (dirNode.Children[matchIndex] is DirectoryTreeNode <PayloadItem> ) { throw new InvalidOperationException( "Path terminator (content) is an existing directory name."); } throw new ArgumentException("Content of same name at this path already exists.", "path"); } // Yes, already there, just change the reference. dirNode = dirNode.Children[matchIndex] as DirectoryTreeNode <PayloadItem>; } } return(new ContentTreeNode <PayloadItem>(pathSegments[pathSegments.Length - 1], dirNode, item)); }
public override async Task <bool> WritePacketAsync(PayloadItem packet) { var result = await _gClient.WritePacketAsync(new PacketStorageRequest { API = Common.Constants.API_VERSION, JSON = JsonSerializer.Serialize(packet) }); return(result.Success); }
/// <summary> /// Create and bind Encrypt-then-MAC scheme components for an item. /// Adds finished decorator (cipher/encryptor) and authenticator to mux item resource container. /// </summary> /// <param name="item">Item to prepare resources for.</param> private MuxItemResourceContainer CreateEtMSchemeResources(PayloadItem item) { CipherStream encryptor; MacStream authenticator; CreateEtMDecorator(item, out encryptor, out authenticator); var container = new MuxItemResourceContainer(encryptor, authenticator, _maxStripe + encryptor.OutputBufferSize); return(container); }
protected override ActivityExecutionStatus Execute(ActivityExecutionContext context) { SPFile file = PayloadItem.File; string sFileExtension = Path.GetExtension(file.Name); this.ParentList = PayloadItem.ParentList; if ( (sFileExtension.ToLower() == ".docm") || (sFileExtension.ToLower() == ".xlsm") || (sFileExtension.ToLower() == ".pptm") ) { string sNewFileExtension = string.Empty; switch (sFileExtension.ToLower()) { case ".docm": sNewFileExtension = ".docx"; break; case ".xlsm": sNewFileExtension = ".xlsx"; break; case ".pptm": sNewFileExtension = ".pptx"; break; default: break; } try { this.OriginalDocumentName = file.Name; Stream strmFile = file.OpenBinaryStream(); RemoveMacros(strmFile, sFileExtension); PayloadItem.ParentList.RootFolder.Files.Add(PayloadItem.Url.Replace(sFileExtension, sNewFileExtension), strmFile, PayloadItem.Properties, true); PayloadItem.Delete(); this.FinalDocumentName = Path.GetFileName(file.Name).Replace(sFileExtension, sNewFileExtension); this.IsMacroFree = true; } catch (Exception ex) { this.FinalDocumentName = Path.GetFileName(file.Name); this.IsMacroFree = false; } } else { this.FinalDocumentName = Path.GetFileName(file.Name); this.IsMacroFree = true; } return(ActivityExecutionStatus.Closed); }
public override async Task <bool> WritePacketAsync(PayloadItem packet) { if (packet == null) { Log.Error($"CSVFileDAL::WritePacketAsync - packet was null"); throw new ArgumentNullException(nameof(packet)); } _writer.WriteToFile(packet.ToCSV <PayloadItem>()); return(true); }
protected override void ExecuteOperation() { PayloadItem item = PayloadItems[Index]; bool skip = ItemSkipRegister != null && ItemSkipRegister.Contains(item.Identifier); if (skip == false) { CipherStream itemEncryptor; MacStream itemAuthenticator; CreateEtMDecorator(item, out itemEncryptor, out itemAuthenticator); if (Writing) { EmitHeader(itemAuthenticator); } else { ConsumeHeader(itemAuthenticator); } if (Writing) { int iterIn; do { iterIn = item.StreamBinding.Read(Buffer, 0, BufferSize); itemEncryptor.Write(Buffer, 0, iterIn); } while (iterIn > 0); } else { itemEncryptor.ReadExactly(item.StreamBinding, item.InternalLength, true); } FinishItem(item, itemEncryptor, itemAuthenticator); } else { // Skipping long skipLength = GetHeaderLength() + item.InternalLength + GetTrailerLength(); PayloadStream.Seek(skipLength, SeekOrigin.Current); // Mark the item as completed in the register ItemCompletionRegister[Index] = true; ItemsCompleted++; Debug.Print(DebugUtility.CreateReportString("SimplePayloadMux", "ExecuteOperation", "[*** SKIPPED ITEM", String.Format("{0} ({1}) ***]", Index, item.Identifier))); } }
public override async Task <bool> WritePacketAsync(PayloadItem packet) { if (packet == null) { Log.Error($"MongoDAL::WritePacketAsync - packet was null"); throw new ArgumentNullException(nameof(packet)); } var collection = _db.GetCollection <PayloadItem>(COLLECTION_NAME); await collection.InsertOneAsync(packet); return(true); }
public List <PayloadItem> GetClaims() { List <PayloadItem> items = new List <PayloadItem>(); foreach (var claim in _jwtToken.Claims) { PayloadItem item = new PayloadItem() { Key = claim.Type, Value = claim.Value }; items.Add(item); } return(items); }
public List <PayloadItem> GetPayloads() { List <PayloadItem> items = new List <PayloadItem>(); foreach (var payload in _jwtToken.Payload) { PayloadItem item = new PayloadItem() { Key = payload.Key, Value = payload.Value.ToString() }; items.Add(item); } return(items); }
public override async Task SayHello(HelloRequest request, IServerStreamWriter <HelloReply> responseStream, ServerCallContext context) { for (var i = 0; i < 100; i++) { var item = new PayloadItem() { Id = i, Message = $"Hello {i}" }; var reply = new HelloReply { Message = "Hello " + request.Name }; reply.Items.Add(item); await responseStream.WriteAsync(reply); await Task.Delay(1000); } }
public override async Task <bool> WritePacketAsync(PayloadItem packet) { if (packet == null) { Log.Error($"JsonFileDAL::WritePacketAsync - packet was null"); throw new ArgumentNullException(nameof(packet)); } var data = new List <PayloadItem>(); if (File.Exists(_fileName)) { using var fs = File.OpenRead(_fileName); data = await JsonSerializer.DeserializeAsync <List <PayloadItem> >(fs); } data.Add(packet); await File.WriteAllTextAsync(_fileName, JsonSerializer.Serialize(data)); return(true); }
public override Task <bool> WritePacketAsync(PayloadItem packet) { throw new NotImplementedException(); }
protected void DoMux(PayloadConfiguration payloadConfig, List <PayloadItem> items, List <FileInfo> files, bool outputPayload = false) { var ms = new MemoryStream(); for (var index = 0; index < items.Count; index++) { var index1 = index; items[index].SetStreamBinding(() => new FileStream(files[index1].FullName, FileMode.Open)); items[index].ExternalLength = items[index].StreamBinding.Length; } var itemPreKeys = new Dictionary <Guid, byte[]> (); var mux = PayloadMuxFactory.CreatePayloadMultiplexer(payloadConfig.SchemeName.ToEnum <PayloadLayoutScheme>(), true, ms, items, itemPreKeys, payloadConfig); Assert.DoesNotThrow(mux.Execute); Debug.Print("\n##### END OF MUXING OPERATION #####\n"); foreach (var item in items) { item.StreamBinding.Close(); } // Write out muxed payload - optional if (outputPayload) { if (!DestinationDirectory.Exists) { DestinationDirectory.Create(); } var path = DestinationDirectory.FullName + Path.DirectorySeparatorChar + payloadConfig.SchemeName.ToLower() + IOTestBase.RawPayloadExtension; using (var fs = new FileStream(path, FileMode.Create)) { ms.WriteTo(fs); } } // DEMUX var demuxPath = DestinationDirectory.FullName + Path.DirectorySeparatorChar + DemuxDir; if (!Directory.Exists(demuxPath)) { Directory.CreateDirectory(demuxPath); } foreach (var payloadItem in items) { PayloadItem item = payloadItem; payloadItem.SetStreamBinding(() => new FileStream(demuxPath + Path.DirectorySeparatorChar + item.Path, FileMode.Create)); } ms.Seek(0, SeekOrigin.Begin); mux = PayloadMuxFactory.CreatePayloadMultiplexer(payloadConfig.SchemeName.ToEnum <PayloadLayoutScheme>(), false, ms, items, itemPreKeys, payloadConfig); Assert.DoesNotThrow(mux.Execute); Debug.Print("\n##### END OF DEMUXING OPERATION #####\n"); foreach (var item in items) { item.StreamBinding.Close(); } if (mux is FrameshiftPayloadMux) { Assert.Pass("Overhead: {0} bytes", ((FrameshiftPayloadMux)mux).Overhead); } else { Assert.Pass(); } }
/// <inheritdoc /> protected override void FinishItem(PayloadItem item, CipherStream encryptor, MacStream authenticator) { if (Writing) { if (item.ExternalLength > 0 && encryptor.BytesIn != item.ExternalLength) { throw new InvalidDataException("Length written is not equal to predefined item external length."); } } else { if (encryptor.BytesIn != item.InternalLength) { throw new InvalidDataException("Length read is not equal to item internal length."); } if (encryptor.BytesOut != item.ExternalLength) { throw new InvalidDataException("Demultiplexed and decrypted length is not equal to specified item external length."); } encryptor.Close(); } if (Writing) { // Commit the determined internal length to item in payload manifest item.InternalLength = encryptor.BytesOut; EmitTrailer(authenticator); } else { ConsumeTrailer(authenticator); } // Final stages of Encrypt-then-MAC authentication scheme PayloadItem itemDto = item.CreateAuthenticatibleClone(); byte[] itemDtoAuthBytes = itemDto.SerialiseDto(); Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "FinishItem", "Item DTO length", itemDtoAuthBytes.Length)); if (Writing) { authenticator.Update(itemDtoAuthBytes, 0, itemDtoAuthBytes.Length); authenticator.Close(); // Commit the MAC to item in payload manifest item.AuthenticationVerifiedOutput = authenticator.Mac.DeepCopy(); } else { authenticator.Update(itemDtoAuthBytes, 0, itemDtoAuthBytes.Length); authenticator.Close(); // Verify the authenticity of the item ciphertext and configuration if (authenticator.Mac.SequenceEqual_ConstantTime(item.AuthenticationVerifiedOutput) == false) { // Verification failed! throw new CiphertextAuthenticationException("Payload item not authenticated."); } } // Release the item's resources (implicitly - no references remain) _activeItemResources.Remove(item.Identifier); // Mark the item as completed in the register ItemCompletionRegister[Index] = true; ItemsCompleted++; // Close the source/destination item.StreamBinding.Close(); Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "FinishItem", "[*** END OF ITEM", Index + " ***]")); }
protected override void ExecuteOperation() { Debug.Assert(ItemCompletionRegister[Index] == false); PayloadItem item = PayloadItems[Index]; Guid itemIdentifier = item.Identifier; bool skip = ItemSkipRegister != null && ItemSkipRegister.Contains(itemIdentifier); MuxItemResourceContainer itemContainer; bool activeResource = _activeItemResources.ContainsKey(itemIdentifier); if (activeResource) { itemContainer = _activeItemResources[itemIdentifier]; } else { if (skip == false) { itemContainer = CreateEtMSchemeResources(item); if (Writing) { EmitHeader(itemContainer.Authenticator); } else { ConsumeHeader(itemContainer.Authenticator); } } else { itemContainer = new MuxItemResourceContainer(null, null, null); } _activeItemResources.Add(itemIdentifier, itemContainer); } int opLength = NextOperationLength(); if (skip == false) { CipherStream itemEncryptor = itemContainer.Encryptor; MacStream itemAuthenticator = itemContainer.Authenticator; if (Writing) { // Writing/multiplexing if (itemEncryptor.BytesIn + opLength < item.ExternalLength) { // Normal operation itemEncryptor.WriteExactly(item.StreamBinding, opLength); } else { // Final operation, or just prior to if (itemContainer.Buffer.IsValueCreated == false) { // Redirect final ciphertext to buffer to account for possible expansion itemAuthenticator.ReassignBinding(itemContainer.Buffer.Value, false, finish: false); } var remaining = (int)(item.ExternalLength - itemEncryptor.BytesIn); if (remaining > 0) { while (remaining > 0) { int toRead = Math.Min(remaining, BufferSize); int iterIn = item.StreamBinding.Read(Buffer, 0, toRead); if (iterIn < toRead) { throw new EndOfStreamException(); } itemEncryptor.Write(Buffer, 0, iterIn); // Writing into recently-lazy-inited buffer remaining -= iterIn; } itemEncryptor.Close(); } var toWrite = (int)Math.Min(opLength, itemContainer.Buffer.Value.Length); Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "ExecuteOperation", "Multiplexing item: final stripe length", toWrite)); itemContainer.Buffer.Value.ReadTo(PayloadStream, toWrite); } } else { // Reading/demultiplexing long readRemaining = item.InternalLength - itemEncryptor.BytesIn; bool finalOp = false; if (readRemaining <= opLength) { // Final operation opLength = (int)readRemaining; finalOp = true; Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "ExecuteOperation", "Demultiplexing item: final stripe length", opLength)); } itemEncryptor.ReadExactly(item.StreamBinding, opLength, finalOp); } if ((Writing && itemEncryptor.BytesIn >= item.ExternalLength && itemContainer.Buffer.Value.Length == 0) || (Writing == false && itemEncryptor.BytesIn >= item.InternalLength)) { // Now that we're finished we need to do some extra things, then clean up FinishItem(item, itemEncryptor, itemAuthenticator); } } else { // Skipping Debug.Assert(Writing == false, "Should not be skipping when writing!"); if (itemContainer.SkippedLength == 0) { // Start of item PayloadStream.Seek(opLength, SeekOrigin.Current); itemContainer.SkippedLength += opLength; } else if (itemContainer.SkippedLength + opLength >= item.InternalLength) { int remainingToSkip = (int)(item.InternalLength - itemContainer.SkippedLength); itemContainer.SkippedLength += remainingToSkip; PayloadStream.Seek(remainingToSkip + GetTrailerLength(), SeekOrigin.Current); // "Finish" item _activeItemResources.Remove(item.Identifier); // Mark the item as completed in the register ItemCompletionRegister[Index] = true; ItemsCompleted++; Debug.Print(DebugUtility.CreateReportString("FabricPayloadMux", "ExecuteOperation", "[*** SKIPPED ITEM", Index + " ***]")); } else { PayloadStream.Seek(opLength, SeekOrigin.Current); itemContainer.SkippedLength += opLength; } } }
private PayloadItem[] MapResponseToItem(InternalModels.Response source, PayloadItem[] destinations, ResolutionContext context) { var itemWithBubble = new PayloadItem { Bubble = { Text = source.Text } }; var buttons = source.Buttons?.Where(b => !b.IsQuickReply).ToList(); var cardItems = buttons?.Select(b => { var cardItem = new CardCell { Type = CellTypeValues.GreetingGridItem, TopText = new CardCellText { Type = CellTypeValues.TextCellView, Text = string.Empty, Typeface = TypefaceValues.Caption, TextColor = TextColorValues.Default }, BottomText = new CardCellText { Type = CellTypeValues.LeftRightCellView, Text = b.Text, Typeface = TypefaceValues.Button1, TextColor = TextColorValues.Default, MaxLines = 2, Margins = new Margins { Top = IndentValues.X0 } }, Paddings = new Paddings { Top = IndentValues.X0, Left = IndentValues.X6, Right = IndentValues.X6, Bottom = IndentValues.X16 } }; var action = context.Mapper.Map <SberModels.Action>(b); cardItem.Actions = new[] { action }; return(cardItem); }).ToArray(); var card = new Card { Type = CardTypeValues.GridCard, Items = cardItems, Columns = 2, ItemWidth = ItemWidthValues.Resizable }; var itemWithCard = new PayloadItem { Card = card }; return(new[] { itemWithBubble, itemWithCard }); }
public abstract Task <bool> WritePacketAsync(PayloadItem packet);
public PredictionItem Predict(PayloadItem item) => _predictionEngine.Predict(item);
/// <summary> /// Close the item decorator, check lengths, authenticate the item (emit or verify), /// and if writing, commit the authentication value to the payload item DTO. /// </summary> /// <param name="item">Payload item to finish.</param> /// <param name="encryptor">Item encryptor/cipher.</param> /// <param name="authenticator">Item authenticator/MAC.</param> protected override void FinishItem(PayloadItem item, CipherStream encryptor, MacStream authenticator) { try { encryptor.Close(); } catch (Exception e) { throw new Exception("Unknown error when finalising/closing cipher.", e); } try { if (Writing) { EmitTrailer(authenticator); } else { ConsumeTrailer(authenticator); } } catch (Exception e) { throw new Exception(String.Format("Unknown error when {0} item trailer.", Writing ? "emitting" : "consuming"), e); } // Length checks & commits if (Writing) { // Check if pre-stated length matches what was actually written if (item.ExternalLength > 0 && encryptor.BytesIn != item.ExternalLength) { throw new InvalidDataException( "Mismatch between stated item external length and actual input length."); } // Commit the determined internal length to item in payload manifest item.InternalLength = encryptor.BytesOut; } else { if (encryptor.BytesIn != item.InternalLength) { throw new InvalidOperationException("Probable decorator stack malfunction."); } if (encryptor.BytesOut != item.ExternalLength) { throw new InvalidDataException( "Mismatch between stated item external length and actual output length."); } } // Final stages of Encrypt-then-MAC authentication scheme PayloadItem itemDto = item.CreateAuthenticatibleClone(); byte[] itemDtoAuthBytes = itemDto.SerialiseDto(); #if PRINT_DTO_LENGTH Debug.Print(DebugUtility.CreateReportString("SimplePayloadMux", "FinishItem", "Payload item DTO length", itemDtoAuthBytes.Length)); #endif authenticator.Update(itemDtoAuthBytes, 0, itemDtoAuthBytes.Length); authenticator.Close(); // Authentication if (Writing) { // Commit the MAC to item in payload manifest item.AuthenticationVerifiedOutput = authenticator.Mac.DeepCopy(); } else { // Verify the authenticity of the item ciphertext and configuration if (authenticator.Mac.SequenceEqual_ConstantTime(item.AuthenticationVerifiedOutput) == false) { // Verification failed! throw new CiphertextAuthenticationException("Payload item not authenticated."); } } // Close the source/destination item.StreamBinding.Close(); // Mark the item as completed in the register ItemCompletionRegister[Index] = true; ItemsCompleted++; Debug.Print(DebugUtility.CreateReportString("SimplePayloadMux", "ExecuteOperation", "[*** END OF ITEM", String.Format("{0} ({1}) ***]", Index, item.Identifier))); }
public ItemKeyMissingException(PayloadItem item) : base (String.Format("A cryptographic key for item GUID {0} and relative path \"{1}\" could not be found.", item.Identifier, item.Path)) { }
/// <summary> /// Finish processing the current item. /// </summary> /// <param name="item">Payload item to finish.</param> /// <param name="encryptor">Item encryptor/cipher.</param> /// <param name="authenticator">Item authenticator/MAC.</param> protected abstract void FinishItem(PayloadItem item, CipherStream encryptor, MacStream authenticator);
/// <summary> /// Unpacks/extracts the payload items into a directory. /// </summary> /// <param name="path">Path to write items to.</param> /// <param name="overwrite"></param> /// <param name="payloadKeys">Potential symmetric keys for payload items.</param> /// <exception cref="ConfigurationInvalidException">Package item path includes a relative-up specifier (security risk).</exception> /// <exception cref="NotSupportedException">Package includes a KeyAction payload item type (not implemented).</exception> /// <exception cref="IOException">File already exists and overwrite is not allowed.</exception> public void ReadToDirectory(string path, bool overwrite, IEnumerable <SymmetricKey> payloadKeys = null) { if (path == null) { throw new ArgumentNullException("path"); } try { Directory.CreateDirectory(path); } catch (IOException) { throw new ArgumentException( "Could not create package output directory: Supplied path is a file, not a directory.", "path"); } catch (ArgumentException) { throw new ArgumentException( "Could not create package output directory: Path contains invalid characters.", "path"); } catch (NotSupportedException e) { throw new ArgumentException( "Could not create package output directory: Path contains invalid character.", "path", e); } foreach (PayloadItem item in _manifest.PayloadItems) { if (item.Path == String.Empty) { throw new ConfigurationInvalidException("A payload item has no path/name."); } else if (item.Type != PayloadItemType.KeyAction && item.Path.Contains(Athena.Packaging.PathRelativeUp)) { throw new ConfigurationInvalidException("A payload item specifies a relative path outside that of the package root. " + "This is a potentially dangerous condition."); } // First we correct the directory symbol to match local OS string relativePath = item.Path.Replace(Athena.Packaging.PathDirectorySeperator, Path.DirectorySeparatorChar); string absolutePath = Path.Combine(path, relativePath); switch (item.Type) { case PayloadItemType.Message: if (Path.HasExtension(absolutePath) == false) { absolutePath += ".txt"; } break; case PayloadItemType.KeyAction: throw new NotSupportedException("Key actions not implemented."); } if (File.Exists(absolutePath) && overwrite == false) { throw new IOException("File already exists: " + absolutePath); } PayloadItem itemClosureVar = item; item.SetStreamBinding(() => { try { string directory = Path.GetDirectoryName(absolutePath); Directory.CreateDirectory(directory); const int fileBufferSize = 81920; // 80 KB (Microsoft default) var stream = new FileStream(absolutePath, FileMode.Create, FileAccess.Write, FileShare.None, fileBufferSize, true); stream.SetLength(itemClosureVar.ExternalLength); return(stream); } catch (ArgumentException e) { throw new ConfigurationInvalidException( "Could not create payload item output stream: path contains invalid characters.", e); } catch (NotSupportedException e) { throw new ConfigurationInvalidException( "Could not create payload item output stream: path is invalid.", e); } }); } ReadPayload(payloadKeys); }