Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / IO / Packaging / XmlDigitalSignatureProcessor.cs / 1305600 / XmlDigitalSignatureProcessor.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // Implementation of the W3C Digital Signature Handler. // Generates and consumes XmlDSig-compliant digital signatures based on the subset // specified by the Opc file format. // // History: // 05/13/2002: BruceMac: Initial implementation. // 05/31/2003: LGolding: Ported to WCP tree. // 01/25/2004: BruceMac: Ported to address Security Mitigation and API changes for Opc // 11/10/2005: BruceMac: // - Rename GetManifest to ParseManifest, rename AssembleManifest // to GenerateManifest to match pattern of other methods. // - Tighten up parsing logic to throw in more cases when spec is violated. // - Require at least a singleobject in the tag as // specified by the w3c digsig spec. //----------------------------------------------------------------------------- using System; using System.Diagnostics; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Security; // for SecurityCritical and SecurityTreatAsSafe using System.Security.Cryptography; using System.Security.Cryptography.Xml; using System.Security.Cryptography.X509Certificates; using System.Security.Permissions; using System.Xml; using System.IO; using System.Windows; using System.IO.Packaging; using MS.Internal; using MS.Internal.WindowsBase; namespace MS.Internal.IO.Packaging { /// /// Signature Handler implementation that follows the Feb 12, 2002 W3C DigSig Recommendation /// ///See: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/ for details internal class XmlDigitalSignatureProcessor { //----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- ////// Constructor - called from PackageDigitalSignatureManager when opening an existing signature /// /// current DigitalSignatureManager /// public signature object /// the part that will/does house the associated XML signature internal XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, PackagePart signaturePart, PackageDigitalSignature packageSignature) : this(manager, signaturePart) { _signature = packageSignature; } ////// Factory method that creates a new PackageDigitalSignature /// internal static PackageDigitalSignature Sign( PackageDigitalSignatureManager manager, PackagePart signaturePart, IEnumerableparts, IEnumerable relationshipSelectors, X509Certificate2 signer, String signatureId, bool embedCertificate, IEnumerable signatureObjects, IEnumerable objectReferences) { // create XmlDigitalSignatureProcessor p = new XmlDigitalSignatureProcessor(manager, signaturePart); // and sign return p.Sign(parts, relationshipSelectors, signer, signatureId, embedCertificate, signatureObjects, objectReferences); } /// /// Verify the given signature /// ///throws if no certificate found in the signature ///true if the data stream has not been altered since it was signed internal bool Verify() { return Verify(Signer); } ////// Verify the given signature /// /// certificate to use (ignores any embedded cert) ///true if the data stream has not been altered since it was signed ////// Critical - 1) Elevate to unrestricted to work around a feature in the .NET XML libraries. /// - 2) We are calling GenerateDigestValueNode which is SecurityCritical due to the Transform parameter. /// TreatAsSafe - 1) This is to work around a feature in the Xml layer. The assert makes it possible for the XML /// layer to perform a transform on the data "under the covers". /// (http://bugcheck/default.asp?URL=/bugs/SQLBUDefectTracking/392346.asp) /// 2) The one parameter of concern (Transform) is trusted. The reasoning is that we get the /// instance from trusted sources. The Transform is obtained from a trusted method /// (DigitalSignatureProcessor.StringToTranform) that only creates built-in .NET Transform /// instances which are safe XML Transforms. /// [SecurityCritical, SecurityTreatAsSafe] internal bool Verify(X509Certificate2 signer) { Invariant.Assert(signer != null); // Create a SignedXml to do the dirty work SignedXml xmlSig = EnsureXmlSignatureParsed(); bool result = false; // Validate the Reference tags in the SignedInfo as per the // restrictions imposed by the OPC spec ValidateReferences(xmlSig.SignedInfo.References, true /*allowPackageSpecificReference*/); (new PermissionSet(PermissionState.Unrestricted)).Assert(); try { // verify "standard" XmlSignature portions result = xmlSig.CheckSignature(signer, true); } finally { PermissionSet.RevertAssert(); } if (result) { HashAlgorithm hashAlgorithm = null; // optimize - generally only need to create and re-use one of these String currentHashAlgorithmName = String.Empty; // guaranteed not to match try { try { // if that succeeds, verify the Manifest including Part/Relationship content and ContentTypes ParsePackageDataObject(); } catch (XmlException) { // parsing exception - means this is a bad signature return false; } foreach (PartManifestEntry partEntry in _partEntryManifest) { // compare the content Stream s = null; // Relationship requires special handling if (partEntry.IsRelationshipEntry) { // This behaves correctely even if the Relationship Part is missing entirely s = GetRelationshipStream(partEntry); } else // Part entry - inspect raw stream { // part is guaranteed to exist at this point because we fail early in PackageDigitalSignature.Verify() Debug.Assert(_manager.Package.PartExists(partEntry.Uri)); // Compare the content type first so we can fail early if it doesn't match // (faster than hashing the content itself). // Compare ordinal case-sensitive which is more strict than normal ContentType // comparision because this is manadated by the OPC specification. PackagePart part = _manager.Package.GetPart(partEntry.Uri); if (String.CompareOrdinal( partEntry.ContentType.OriginalString, part.ValidatedContentType.OriginalString) != 0) { result = false; // content type mismatch break; } s = part.GetStream(FileMode.Open, FileAccess.Read); } using (s) { // ensure hash algorithm object is available - re-use if possible if (((hashAlgorithm != null) && (!hashAlgorithm.CanReuseTransform)) || String.CompareOrdinal(partEntry.HashAlgorithm, currentHashAlgorithmName) != 0) { if (hashAlgorithm != null) ((IDisposable)hashAlgorithm).Dispose(); currentHashAlgorithmName = partEntry.HashAlgorithm; hashAlgorithm = GetHashAlgorithm(currentHashAlgorithmName); // not a supported or recognized algorithm? if (hashAlgorithm == null) { // return invalid result instead of throwing exception result = false; break; } } // calculate hash String base64EncodedHashValue = GenerateDigestValue(s, partEntry.Transforms, hashAlgorithm); // now compare the hash - must be identical if (String.CompareOrdinal(base64EncodedHashValue, partEntry.HashValue) != 0) { result = false; // hash mismatch break; } } } } finally { if (hashAlgorithm != null) ((IDisposable)hashAlgorithm).Dispose(); } } return result; } ////// Get the list of transforms applied to the given part (works for Relationship parts too) /// /// part to get transforms for ///possibly empty, ordered list of transforms applied to the given part (never null) ///This method only returns transform names. Transform-specific properties can be obtained by parsing the actual /// signature contents which conform to the W3C XmlDSig spec. internal ListGetPartTransformList(Uri partName) { // query the parsed manifest ParsePackageDataObject(); List transformList = null; // look through the manifest for the requested part foreach (PartManifestEntry entry in _partEntryManifest) { if (PackUriHelper.ComparePartUri(entry.Uri, partName) == 0) { transformList = entry.Transforms; break; } } // never return null - an empty list is better form if (transformList == null) transformList = new List (); return transformList; } //------------------------------------------------------ // // Internal Properties // //----------------------------------------------------- /// /// Content type of signature parts created by this processor /// internal static ContentType ContentType { get { return _xmlSignaturePartType; } } ////// Associated signature part /// internal PackagePart SignaturePart { get { return _signaturePart; } } ////// Obtain the list of signed parts /// ///Authors identity in handler-proprietary format ///if signature xml is malformed internal ListPartManifest { get { ParsePackageDataObject(); return _partManifest; } } /// /// Obtain the author's identity as a byte stream /// ///Authors identity in handler-proprietary format ///if signature xml is malformed internal ListRelationshipManifest { get { ParsePackageDataObject(); return _relationshipManifest; } } /// /// Obtain the author's identity in X509 Certificate form /// ///Authors identity as a certificate in X509 form, or null if none found internal X509Certificate2 Signer { get { // lazy init when loading existing cert - Sign may have assigned this for us if (_certificate == null) { // first look for cert part if (PackageSignature.GetCertificatePart() != null) _certificate = PackageSignature.GetCertificatePart().GetCertificate(); else { // look in signature if (_lookForEmbeddedCert) { IEnumerator keyInfoClauseEnum = EnsureXmlSignatureParsed().KeyInfo.GetEnumerator(typeof(KeyInfoX509Data)); while (keyInfoClauseEnum.MoveNext()) { KeyInfoX509Data x509Data = (KeyInfoX509Data)keyInfoClauseEnum.Current; foreach (X509Certificate2 cert in x509Data.Certificates) { // just take the first one for now _certificate = cert; break; } // just need one for now if (_certificate != null) break; } // only need to do this once _lookForEmbeddedCert = false; } } } return _certificate; // may be null } } ////// encrypted hash value /// ///internal byte[] SignatureValue { get { return EnsureXmlSignatureParsed().SignatureValue; } } /// /// The object that actually creates the signature /// Note: This API is exposed to the public API surface through the /// PackageDigitalSignature.Signature property. Through this API it is /// possible to create Signatures that are not OPC compliant. However, /// at verify time, we will throw exceptions for non-conforming signatures. /// ///object of type System.Security.Cryptography.Xml.Signature internal Signature Signature { get { return EnsureXmlSignatureParsed().Signature; } set { UpdatePartFromSignature(value); } } ////// Get the given signature /// internal PackageDigitalSignature PackageSignature { get { return _signature; } } ////// Time that the signature was created /// ///Time of signing if available, or DateTime.MinValue if signature was not time-stamped internal DateTime SigningTime { get { // lazy init ParsePackageDataObject(); return _signingTime; } } internal String TimeFormat { get { // lazy init ParsePackageDataObject(); return _signingTimeFormat; } } //------------------------------------------------------ // // Digest Helper Functions // //------------------------------------------------------ ////// Generate digest value tag /// /// /// name of the single transform to use - may be null /// hash algorithm to use ////// /// Critical - We are calling the TransformXml method which is Critical due to the Transform parameter. /// TreatAsSafe - It is safe because we are creating only built-in Transform instances. /// [SecurityCritical, SecurityTreatAsSafe] internal static String GenerateDigestValue( Stream s, String transformName, HashAlgorithm hashAlgorithm) { Listtransforms = null; if (transformName != null) { transforms = new List (1); transforms.Add(transformName); } return GenerateDigestValue(s, transforms, hashAlgorithm); } /// /// Generate digest value tag /// /// transforms to apply - may be null and list may contain empty strings /// stream to hash /// algorithm to use ////// Critical - We are calling the TransformXml method which is Critical due to the Transform parameter. /// TreatAsSafe - It is safe because we are creating only built-in Transform instances. /// [SecurityCritical, SecurityTreatAsSafe] internal static String GenerateDigestValue( Stream s, Listtransforms, HashAlgorithm hashAlgorithm) { s.Seek(0, SeekOrigin.Begin); // We need to be able to dispose streams generated by the // Transform object but we don't want to dispose the stream // passed to us so we insert this to block any propagated Dispose() calls. Stream transformStream = new IgnoreFlushAndCloseStream(s); List transformStreams = null; // canonicalize the part content if asked if (transforms != null) { transformStreams = new List (transforms.Count); transformStreams.Add(transformStream); foreach (String transformName in transforms) { // ignore empty strings at this point (as well as Relationship Transforms) - these are legal if ((transformName.Length == 0) || (String.CompareOrdinal(transformName, XTable.Get(XTable.ID.RelationshipsTransformName)) == 0)) { continue; } // convert the transform names into objects (if defined) Transform transform = StringToTransform(transformName); if (transform == null) { // throw XmlException so the outer loop knows the signature is invalid throw new XmlException(SR.Get(SRID.UnsupportedTransformAlgorithm)); } transformStream = TransformXml(transform, transformStream); transformStreams.Add(transformStream); } } // hash it and encode to Base64 String hashValueString = System.Convert.ToBase64String(HashStream(hashAlgorithm, transformStream)); // dispose of any generated streams if (transformStreams != null) { foreach (Stream stream in transformStreams) stream.Close(); } return hashValueString; } /// /// Synthesizes a NodeList of Reference tags to hash /// /// ///internal static Stream GenerateRelationshipNodeStream(IEnumerable relationships) { // create a NodeList containing valid Relationship XML and serialize it to the stream Stream s = new MemoryStream(); // Wrap in a stream that ignores Flush and Close so the XmlTextWriter // will not close it. // use UTF-8 encoding by default using (XmlTextWriter writer = new XmlTextWriter(new IgnoreFlushAndCloseStream(s), System.Text.Encoding.UTF8)) { // start outer Relationships tag writer.WriteStartElement(XTable.Get(XTable.ID.RelationshipsTagName), PackagingUtilities.RelationshipNamespaceUri); // generate a valid Relationship tag according to the Opc schema InternalRelationshipCollection.WriteRelationshipsAsXml(writer, relationships, true, /* systematically write target mode */ false /* not in streaming production */ ); // end of Relationships tag writer.WriteEndElement(); } return s; } /// /// Convert algorithm name to object /// /// fully specified name ///HashAlgorithm object or null if it does not map to a supported hash type ///Caller is responsible for calling Dispose() on returned object internal static HashAlgorithm GetHashAlgorithm(String hashAlgorithmName) { Object o = CryptoConfig.CreateFromName(hashAlgorithmName); HashAlgorithm algorithm = o as HashAlgorithm; // In the case that we get a valid crypto object that is not a hash algorithm // we should attempt to dispose it if it offers IDisposable. if (algorithm == null && o != null) { IDisposable disposable = o as IDisposable; if (disposable != null) disposable.Dispose(); } return algorithm; } ////// Critical - We are marking this function critical since we want to know the types /// of Transform instances that are being created. If new types of transforms /// are created in this method other than build-in .NET ones, then we should /// probably know about it. /// TreatAsSafe - It is safe because we are creating only built-in Transform instances. /// ////// IMPORTANT NOTE: /// 1. In the XmlDigitalSignatureProcessor.IsValidXmlCanonicalizationTransform method, /// we have similar logic regarding these two transforms.So both these methods must be updated /// in [....]. /// [SecurityCritical, SecurityTreatAsSafe] private static Transform StringToTransform(String transformName) { Invariant.Assert(transformName != null); if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NTransformUrl) == 0) { return new XmlDsigC14NTransform(); } else if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NWithCommentsTransformUrl) == 0) { return new XmlDsigC14NWithCommentsTransform(); } else return null; } // As per the OPC spec, only two tranforms are valid. Also, both of these happen to be // XML canonicalization transforms. // In the XmlSignatureManifest.ParseTransformsTag method we make use this method to // validate the transforms to make sure that they are supported by the OPC spec and // we also take advantage of the fact that both of them are XML canonicalization transforms // IMPORTANT NOTE: // 1. In the XmlDigitalSignatureProcessor.StringToTransform method, we have similar logic // regarding these two transforms.So both these methods must be updated in [....]. // 2. If ever this method is updated to add other transforms, careful review must be done to // make sure that methods calling this method are updated as required. internal static bool IsValidXmlCanonicalizationTransform(String transformName) { Invariant.Assert(transformName != null); if (String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NTransformUrl) == 0 || String.CompareOrdinal(transformName, SignedXml.XmlDsigC14NWithCommentsTransformUrl) == 0) { return true; } else return false; } //----------------------------------------------------- // // Private Properties // //------------------------------------------------------ ////// Helper class /// private SignedXml EnsureXmlSignatureParsed() { // lazy init if (_signedXml == null) { _signedXml = new CustomSignedXml(); // Load the XML XmlDocument xmlDocument = new XmlDocument(); xmlDocument.PreserveWhitespace = true; using (Stream s = SignaturePart.GetStream()) { using (XmlTextReader xmlReader = new XmlTextReader(s)) { //Prohibit DTD from the markup as per the OPC spec xmlReader.ProhibitDtd = true; //This method expects the reader to be in ReadState.Initial. //It will make the first read call. PackagingUtilities.PerformInitailReadAndVerifyEncoding(xmlReader); //If the reader.ReadState is ReadState.Initial, then XmlDocument with perform the //first xmlReader.Read() and start loading from that node/tag. //If the reader.ReadState is ReadState.Intermediate, then XmlDocument, will start //loading from that location itself. //Note: Since in the above method we perform only the first read and will have not //moved the reader state further down in the markup, we should be okay, and //xmlDocument.Load will load from the very begining as intended. xmlDocument.Load(xmlReader); // W3C spec allows for Signature tag to appear as an island and inherently allows // for multiple Signature tags within the same XML document. // OPC restricts this to a single, root-level Signature tag. However, Signature // tags are allowed to exist within the non-OPC Object tags within an OPC signature. // This is common for XAdES signatures and must be explicitly allowed. XmlNodeList nodeList = xmlDocument.ChildNodes; if (nodeList == null || nodeList.Count == 0 || nodeList.Count > 2) throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); XmlNode node = nodeList[0]; if (nodeList.Count == 2) { // First node must be the XmlDeclaration if (nodeList[0].NodeType != XmlNodeType.XmlDeclaration) throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); // Second node must be in the w3c namespace, and must be thetag node = nodeList[1]; } if ((node.NodeType != XmlNodeType.Element) || (String.CompareOrdinal(node.NamespaceURI, SignedXml.XmlDsigNamespaceUrl) != 0) || (String.CompareOrdinal(node.LocalName, XTable.Get(XTable.ID.SignatureTagName)) != 0)) { throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } // instantiate the SignedXml from the xmlDoc _signedXml.LoadXml((XmlElement)node); } } } // As per the OPC spec, only two Canonicalization methods can be specified if (!IsValidXmlCanonicalizationTransform(_signedXml.SignedInfo.CanonicalizationMethod)) throw new XmlException(SR.Get(SRID.UnsupportedCanonicalizationMethod)); // As per OPC spec, signature ID must be NCName if (_signedXml.Signature.Id != null) { try { System.Xml.XmlConvert.VerifyNCName(_signedXml.Signature.Id); } catch (System.Xml.XmlException) { throw new XmlException(SR.Get(SRID.PackageSignatureCorruption)); } } return _signedXml; } //----------------------------------------------------- // // Private Methods // //----------------------------------------------------- /// /// Constructor - called from public constructor as well as static Sign() method /// /// current DigitalSignatureManager /// the part that will/does house the associated XML signature private XmlDigitalSignatureProcessor(PackageDigitalSignatureManager manager, PackagePart signaturePart) { Invariant.Assert(manager != null); Invariant.Assert(signaturePart != null); _signaturePart = signaturePart; _manager = manager; _lookForEmbeddedCert = true; } ////// Create a new PackageDigitalSignature /// /// the data being protected by this signature /// possibly null collection of relationshipSelectors that represent the /// relationships that are to be signed /// Identity of the author /// Id attribute of the new Xml Signature /// true if caller wants certificate embedded in the signature itself /// references /// objects to sign ////// Critical - Elevating for unrestricted permissions to call into .NET XML code. This is due to a feature in /// the CLR code (http://bugcheck/default.asp?URL=/bugs/SQLBUDefectTracking/392346.asp). /// TreatAsSafe - The elevation is causing a transform of data at the CLR level. The transforms being used /// are built in .NET XML transforms. Since we using built in .NET transforms the transform on /// the XML data is not a security threat. The only data we supply is data from the package. /// [SecurityCritical, SecurityTreatAsSafe] private PackageDigitalSignature Sign( IEnumerableparts, IEnumerable relationshipSelectors, X509Certificate2 signer, String signatureId, bool embedCertificate, IEnumerable signatureObjects, IEnumerable objectReferences) { // don't overwrite Debug.Assert(SignaturePart.GetStream().Length == 0, "Logic Error: Can't sign when signature already exists"); // grab hash algorithm as this may change in the future _hashAlgorithmName = _manager.HashAlgorithm; // keep the signer if indicated if (_manager.CertificateOption == CertificateEmbeddingOption.NotEmbedded) _lookForEmbeddedCert = false; // don't bother parsing else _certificate = signer; // save some parsing // we only release this key if we obtain it AsymmetricAlgorithm key = null; bool ownKey = false; if (signer.HasPrivateKey) { key = signer.PrivateKey; } else { ownKey = true; key = GetPrivateKeyForSigning(signer); } try { _signedXml = new CustomSignedXml(); _signedXml.SigningKey = key; _signedXml.Signature.Id = signatureId; // put it in the XML if (embedCertificate) { _signedXml.KeyInfo = GenerateKeyInfo(key, signer); } // Package object tag // convert from string to class and ensure we dispose using (HashAlgorithm hashAlgorithm = GetHashAlgorithm(_hashAlgorithmName)) { // inform caller if hash algorithm is unknown if (hashAlgorithm == null) throw new InvalidOperationException(SR.Get(SRID.UnsupportedHashAlgorithm)); _signedXml.AddObject(GenerateObjectTag(hashAlgorithm, parts, relationshipSelectors, signatureId)); } // add reference from SignedInfo to Package object tag Reference objectReference = new Reference(XTable.Get(XTable.ID.OpcLinkAttrValue)); objectReference.Type = XTable.Get(XTable.ID.W3CSignatureNamespaceRoot) + "Object"; objectReference.DigestMethod = _hashAlgorithmName; _signedXml.AddReference(objectReference); // add any custom object tags AddCustomObjectTags(signatureObjects, objectReferences); // compute the signature SignedXml xmlSig = _signedXml; (new PermissionSet(PermissionState.Unrestricted)).Assert(); try { xmlSig.ComputeSignature(); } finally { PermissionSet.RevertAssert(); } // persist UpdatePartFromSignature(_signedXml.Signature); } finally { if (key != null && ownKey) ((IDisposable)key).Dispose(); } // create the PackageDigitalSignature object _signature = new PackageDigitalSignature(_manager, this); return _signature; } /// /// Assembles the sorted list of relationships for this part entry and /// generates a stream with the Xml-equivalent as defined in the Opc spec /// /// relationship-type part entry ///private Stream GetRelationshipStream(PartManifestEntry partEntry) { Debug.Assert(partEntry.IsRelationshipEntry); //Get the list of relationships from the RelationshipSelectors for this part SortedDictionary partRelationships = new SortedDictionary (StringComparer.Ordinal); foreach (PackageRelationshipSelector relationshipSelector in partEntry.RelationshipSelectors) { foreach (PackageRelationship r in relationshipSelector.Select(_manager.Package)) { if(!partRelationships.ContainsKey(r.Id)) partRelationships.Add(r.Id, r); } } return GenerateRelationshipNodeStream(partRelationships.Values); } private void AddCustomObjectTags(IEnumerable signatureObjects, IEnumerable objectReferences) { Invariant.Assert(_signedXml != null); // add any references if (objectReferences != null) { // Validate the Reference tags in the SignedInfo as per the // restrictions imposed by the OPC spec ValidateReferences(objectReferences, false /*allowPackageSpecificReference*/); foreach (Reference reference in objectReferences) { // consistent hash algorithm for entire signature reference.DigestMethod = _hashAlgorithmName; _signedXml.AddReference(reference); } } // any object tags if (signatureObjects != null) { // thes have been pre-screened for matches against reserved OpcAttrValue and duplicates foreach (DataObject obj in signatureObjects) { _signedXml.AddObject(obj); } } } private void UpdatePartFromSignature(Signature sig) { // write to stream using (Stream s = SignaturePart.GetStream(FileMode.Create, FileAccess.Write)) { using (XmlTextWriter xWriter = new XmlTextWriter(s, System.Text.Encoding.UTF8)) { xWriter.WriteStartDocument(true); sig.GetXml().WriteTo(xWriter); xWriter.WriteEndDocument(); } } _signedXml = null; // force a re-parse } private static byte[] HashStream(HashAlgorithm hashAlgorithm, Stream s) { s.Seek(0, SeekOrigin.Begin); // reset algorithm hashAlgorithm.Initialize(); return hashAlgorithm.ComputeHash(s); } /// /// Critical - Elevates for FULL unrestricted permissions due to a feature in the XmlDocument class. /// The XmlDocument class demands for unrestricted permissions when setting the XmlResolver. /// This permission is overboard but we are really only transforming the stream from one form /// to another via a supplied Transform instance. Callers should ensure the Transform is /// trusted. /// NOTE: This elevation is due to the feature in the CLR XML code that demands for "full trust". /// (http://bugcheck/default.asp?URL=/bugs/SQLBUDefectTracking/392346.asp) /// [SecurityCritical] private static Stream TransformXml(Transform xForm, Object source) { (new PermissionSet(PermissionState.Unrestricted)).Assert(); // Blessed try { // transform xForm.LoadInput(source); } finally { PermissionSet.RevertAssert(); } return (Stream)xForm.GetOutput(); } ////// Full parse of the Package-specific Object tag /// ///Side effect of updating _signingTime, _signingTimeFormat, /// _partManifest, _partEntryManifest and _relationshipManifest ///throws if markup does not match OPC spec private void ParsePackageDataObject() { if (!_dataObjectParsed) { EnsureXmlSignatureParsed(); // find the package-specific Object tag XmlNodeList nodeList = GetPackageDataObject().Data; // The legal parent is a "Package" Object tag with 2 children //and if (nodeList.Count != 2) throw new XmlException(SR.Get(SRID.XmlSignatureParseError)); // get a NodeReader that allows us to easily and correctly skip comments XmlReader reader = new XmlNodeReader(nodeList[0].ParentNode); // parse the
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SystemIPInterfaceProperties.cs
- ControlPropertyNameConverter.cs
- LoginUtil.cs
- Point3DCollection.cs
- IgnoreSectionHandler.cs
- SqlLiftWhereClauses.cs
- LinkConverter.cs
- LoadWorkflowByKeyAsyncResult.cs
- SerializationSectionGroup.cs
- FragmentQuery.cs
- AuthenticationModulesSection.cs
- WebConfigurationHostFileChange.cs
- ComboBoxRenderer.cs
- NotImplementedException.cs
- WebPartDisplayModeCollection.cs
- FolderBrowserDialog.cs
- EntityProviderServices.cs
- ExitEventArgs.cs
- XamlRtfConverter.cs
- IBuiltInEvidence.cs
- DataBindingCollectionEditor.cs
- StringArrayEditor.cs
- Hyperlink.cs
- PrtCap_Public.cs
- EditBehavior.cs
- TemplateField.cs
- OpenFileDialog.cs
- GuidConverter.cs
- CheckBoxList.cs
- ListViewUpdatedEventArgs.cs
- HttpChannelHelper.cs
- TreeViewItemAutomationPeer.cs
- TransactionInterop.cs
- InkCanvas.cs
- HealthMonitoringSectionHelper.cs
- METAHEADER.cs
- PermissionToken.cs
- TreeView.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- XmlSchemaExporter.cs
- WebException.cs
- DataListComponentEditor.cs
- ScriptControlManager.cs
- Label.cs
- XpsManager.cs
- HierarchicalDataTemplate.cs
- FrameworkReadOnlyPropertyMetadata.cs
- InputBuffer.cs
- DecoderBestFitFallback.cs
- TypedElement.cs
- WSFederationHttpSecurityElement.cs
- WebPartConnectVerb.cs
- DictionaryItemsCollection.cs
- BitStack.cs
- QuaternionRotation3D.cs
- SamlAttributeStatement.cs
- DetailsViewPagerRow.cs
- WebDescriptionAttribute.cs
- WebDisplayNameAttribute.cs
- COM2PropertyBuilderUITypeEditor.cs
- DetailsViewPagerRow.cs
- xdrvalidator.cs
- _HeaderInfo.cs
- DataGridPageChangedEventArgs.cs
- ObjectDisposedException.cs
- Hyperlink.cs
- figurelengthconverter.cs
- FixedTextBuilder.cs
- GeneralTransform3DGroup.cs
- CmsInterop.cs
- PeerPresenceInfo.cs
- StylusButtonCollection.cs
- ObjRef.cs
- Scripts.cs
- RegexCompiler.cs
- WebDisplayNameAttribute.cs
- NetStream.cs
- GeneralTransform.cs
- HttpStreamXmlDictionaryReader.cs
- MimeObjectFactory.cs
- PrintControllerWithStatusDialog.cs
- KnownColorTable.cs
- EdmError.cs
- CardSpaceSelector.cs
- DataGridBoolColumn.cs
- EndPoint.cs
- HtmlSelect.cs
- Message.cs
- XmlArrayAttribute.cs
- LinqDataSourceSelectEventArgs.cs
- PkcsUtils.cs
- MetabaseSettings.cs
- StylusButtonCollection.cs
- LassoSelectionBehavior.cs
- XMLUtil.cs
- PolicyException.cs
- WebPartConnectionsEventArgs.cs
- DllNotFoundException.cs
- TextServicesManager.cs
- CodeAttributeDeclaration.cs