public override void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator) { SecurityAppliedMessage message = this.SecurityAppliedMessage; EncryptedData encryptedData; HashStream hashStream; switch (message.BodyProtectionMode) { case MessagePartProtectionMode.None: return; case MessagePartProtectionMode.Sign: hashStream = TakeHashStream(); if (CanCanonicalizeAndFragment(writer)) { message.WriteBodyToSignWithFragments(hashStream, false, null, writer); } else { message.WriteBodyToSign(hashStream); } this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue()); return; case MessagePartProtectionMode.SignThenEncrypt: hashStream = TakeHashStream(); encryptedData = CreateEncryptedDataForBody(); if (CanCanonicalizeAndFragment(writer)) { message.WriteBodyToSignThenEncryptWithFragments(hashStream, false, null, encryptedData, this.encryptingSymmetricAlgorithm, writer); } else { message.WriteBodyToSignThenEncrypt(hashStream, encryptedData, this.encryptingSymmetricAlgorithm); } this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue()); this.referenceList.AddReferredId(encryptedData.Id); this.hasSignedEncryptedMessagePart = true; return; case MessagePartProtectionMode.Encrypt: encryptedData = CreateEncryptedDataForBody(); message.WriteBodyToEncrypt(encryptedData, this.encryptingSymmetricAlgorithm); this.referenceList.AddReferredId(encryptedData.Id); return; case MessagePartProtectionMode.EncryptThenSign: hashStream = TakeHashStream(); encryptedData = CreateEncryptedDataForBody(); message.WriteBodyToEncryptThenSign(hashStream, encryptedData, this.encryptingSymmetricAlgorithm); this.signedInfo.AddReference(message.BodyId, hashStream.FlushHashAndGetValue()); this.referenceList.AddReferredId(encryptedData.Id); return; default: Fx.Assert("Invalid MessagePartProtectionMode"); return; } }
void AddEncryptionReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, bool sign, out MemoryStream plainTextStream, out string encryptedDataId) { plainTextStream = new MemoryStream(); XmlDictionaryWriter encryptingWriter = XmlDictionaryWriter.CreateTextWriter(plainTextStream); if (sign) { AddSignatureReference(header, headerId, prefixGenerator, encryptingWriter); } else { header.WriteHeader(encryptingWriter, this.Version); encryptingWriter.Flush(); } encryptedDataId = this.GenerateId(); referenceList.AddReferredId(encryptedDataId); }
string GetSignatureHash(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer, out byte[] hash) { HashStream hashStream = TakeHashStream(); XmlDictionaryWriter effectiveWriter; XmlBuffer canonicalBuffer = null; if (writer.CanCanonicalize) { effectiveWriter = writer; } else { canonicalBuffer = new XmlBuffer(int.MaxValue); effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max); } effectiveWriter.StartCanonicalization(hashStream, false, null); header.WriteStartHeader(effectiveWriter, this.Version); if (headerId == null) { headerId = GenerateId(); this.StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId); } header.WriteHeaderContents(effectiveWriter, this.Version); effectiveWriter.WriteEndElement(); effectiveWriter.EndCanonicalization(); effectiveWriter.Flush(); if (!ReferenceEquals(effectiveWriter, writer)) { Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null."); canonicalBuffer.CloseSection(); canonicalBuffer.Close(); XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0); writer.WriteNode(dicReader, false); dicReader.Close(); } hash = hashStream.FlushHashAndGetValue(); return(headerId); }
public override void ApplySecurityAndWriteHeaders(MessageHeaders headers, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator) { string[] headerIds; if (this.RequireMessageProtection || this.ShouldSignToHeader) { headerIds = headers.GetHeaderAttributes(UtilityStrings.IdAttribute, this.StandardsManager.IdManager.DefaultIdNamespaceUri); } else { headerIds = null; } for (int i = 0; i < headers.Count; i++) { MessageHeader header = headers.GetMessageHeader(i); if (this.Version.Addressing == AddressingVersion.None && header.Namespace == AddressingVersion.None.Namespace) { continue; } if (header != this) { ApplySecurityAndWriteHeader(header, headerIds == null ? null : headerIds[i], writer, prefixGenerator); } } }
void ApplySecurityAndWriteHeader(MessageHeader header, string headerId, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator) { if (!this.RequireMessageProtection && this.ShouldSignToHeader) { if ((header.Name == XD.AddressingDictionary.To.Value) && (header.Namespace == this.Message.Version.Addressing.Namespace)) { if (this.toHeaderHash == null) { byte[] headerHash; headerId = GetSignatureHash(header, headerId, prefixGenerator, writer, out headerHash); this.toHeaderHash = headerHash; this.toHeaderId = headerId; } else // More than one 'To' header is specified in the message. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageHasMoreThanOneToHeader))); return; } } MessagePartProtectionMode protectionMode = GetProtectionMode(header); MemoryStream plainTextStream; string encryptedDataId; switch (protectionMode) { case MessagePartProtectionMode.None: header.WriteHeader(writer, this.Version); return; case MessagePartProtectionMode.Sign: AddSignatureReference(header, headerId, prefixGenerator, writer); return; case MessagePartProtectionMode.SignThenEncrypt: AddEncryptionReference(header, headerId, prefixGenerator, true, out plainTextStream, out encryptedDataId); EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer); this.hasSignedEncryptedMessagePart = true; return; case MessagePartProtectionMode.Encrypt: AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId); EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer); return; case MessagePartProtectionMode.EncryptThenSign: AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId); EncryptedHeader encryptedHeader = EncryptHeader( header, this.encryptingSymmetricAlgorithm, this.encryptionKeyIdentifier, this.Version, encryptedDataId, plainTextStream); AddSignatureReference(encryptedHeader, encryptedDataId, prefixGenerator, writer); return; default: Fx.Assert("Invalid MessagePartProtectionMode"); return; } }
void AddSignatureReference(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer) { byte[] hashValue; headerId = GetSignatureHash(header, headerId, prefixGenerator, writer, out hashValue); this.signedInfo.AddReference(headerId, hashValue); }
string GetSignatureHash(MessageHeader header, string headerId, IPrefixGenerator prefixGenerator, XmlDictionaryWriter writer, out byte[] hash) { HashStream hashStream = TakeHashStream(); XmlDictionaryWriter effectiveWriter; XmlBuffer canonicalBuffer = null; if (writer.CanCanonicalize) { effectiveWriter = writer; } else { canonicalBuffer = new XmlBuffer(int.MaxValue); effectiveWriter = canonicalBuffer.OpenSection(XmlDictionaryReaderQuotas.Max); } effectiveWriter.StartCanonicalization(hashStream, false, null); header.WriteStartHeader(effectiveWriter, this.Version); if (headerId == null) { headerId = GenerateId(); this.StandardsManager.IdManager.WriteIdAttribute(effectiveWriter, headerId); } header.WriteHeaderContents(effectiveWriter, this.Version); effectiveWriter.WriteEndElement(); effectiveWriter.EndCanonicalization(); effectiveWriter.Flush(); if (!ReferenceEquals(effectiveWriter, writer)) { Fx.Assert(canonicalBuffer != null, "Canonical buffer cannot be null."); canonicalBuffer.CloseSection(); canonicalBuffer.Close(); XmlDictionaryReader dicReader = canonicalBuffer.GetReader(0); writer.WriteNode(dicReader, false); dicReader.Close(); } hash = hashStream.FlushHashAndGetValue(); return headerId; }
void ApplySecurityAndWriteHeader(MessageHeader header, string headerId, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator) { if (!this.RequireMessageProtection && this.ShouldSignToHeader) { if ((header.Name == XD.AddressingDictionary.To.Value) && (header.Namespace == this.Message.Version.Addressing.Namespace)) { if (this.toHeaderHash == null) { byte[] headerHash; headerId = GetSignatureHash(header, headerId, prefixGenerator, writer, out headerHash); this.toHeaderHash = headerHash; this.toHeaderId = headerId; } else { // More than one 'To' header is specified in the message. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.TransportSecuredMessageHasMoreThanOneToHeader))); } return; } } MessagePartProtectionMode protectionMode = GetProtectionMode(header); MemoryStream plainTextStream; string encryptedDataId; switch (protectionMode) { case MessagePartProtectionMode.None: header.WriteHeader(writer, this.Version); return; case MessagePartProtectionMode.Sign: AddSignatureReference(header, headerId, prefixGenerator, writer); return; case MessagePartProtectionMode.SignThenEncrypt: AddEncryptionReference(header, headerId, prefixGenerator, true, out plainTextStream, out encryptedDataId); EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer); this.hasSignedEncryptedMessagePart = true; return; case MessagePartProtectionMode.Encrypt: AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId); EncryptAndWriteHeader(header, encryptedDataId, plainTextStream, writer); return; case MessagePartProtectionMode.EncryptThenSign: AddEncryptionReference(header, headerId, prefixGenerator, false, out plainTextStream, out encryptedDataId); EncryptedHeader encryptedHeader = EncryptHeader( header, this.encryptingSymmetricAlgorithm, this.encryptionKeyIdentifier, this.Version, encryptedDataId, plainTextStream); AddSignatureReference(encryptedHeader, encryptedDataId, prefixGenerator, writer); return; default: Fx.Assert("Invalid MessagePartProtectionMode"); return; } }
public abstract void ApplySecurityAndWriteHeaders(MessageHeaders headers, XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator);
public abstract void ApplyBodySecurity(XmlDictionaryWriter writer, IPrefixGenerator prefixGenerator);