CustomSignedXml.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / MS / Internal / IO / Packaging / CustomSignedXml.cs / 1305600 / CustomSignedXml.cs

                            //------------------------------------------------------------------------------ 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
// Description: 
//  Wrapper class for existing SignedXml class that works around 
//  DevDiv Schedule bug: 39530 (mdownen PM)
// 
// History:
//  07/08/2005: BruceMac: Initial implementation.
//
//----------------------------------------------------------------------------- 

using System; 
using System.Xml; 
using System.Windows;                          // for SR
using System.Security.Cryptography.Xml; 
using MS.Internal.WindowsBase;

namespace MS.Internal.IO.Packaging
{ 
    /// 
    /// SignedXml wrapper that supports reference targeting of internal ID's 
    ///  
    /// See: http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/ for details
    internal class CustomSignedXml : SignedXml 
    {
        /// 
        /// Returns the XmlElement that matches the given id
        ///  
        /// 
        ///  
        /// element if found, otherwise return null 
        public override XmlElement GetIdElement(XmlDocument document, string idValue)
        { 
            // Always let the base class have a first try at finding the element
            XmlElement elem = base.GetIdElement(document, idValue);

            // If not found then we will try to find it ourselves 
            if (elem == null)
            { 
                elem = SelectNodeByIdFromObjects(m_signature, idValue); 
            }
 
            return elem;
        }

        ///  
        /// Locate and return the node identified by idValue
        ///  
        ///  
        /// 
        /// node if found - else null 
        /// Tries to match each object in the Object list.
        private static XmlElement SelectNodeByIdFromObjects(Signature signature, string idValue)
        {
            XmlElement node = null; 

            // enumerate the objects 
            foreach (DataObject dataObject in signature.ObjectList) 
            {
                // direct reference to Object id - supported for all reference typs 
                if (String.CompareOrdinal(idValue, dataObject.Id) == 0)
                {
                    // anticipate duplicate ID's and throw if any found
                    if (node != null) 
                        throw new XmlException(SR.Get(SRID.DuplicateObjectId));
 
                    node = dataObject.GetXml(); 
                }
            } 

            // now search for XAdES specific references
            if (node == null)
            { 
                // For XAdES we implement special case where the reference may
                // be to an internal tag with matching "Id" attribute. 
                node = SelectSubObjectNodeForXAdES(signature, idValue); 
            }
 
            return node;
        }

        ///  
        /// Locate any signed Object tag that matches the XAdES "target type"
        ///  
        ///  
        /// 
        /// element if found; null if not found 
        /// Special purpose code to support Sub-Object signing required by XAdES signatures
        private static XmlElement SelectSubObjectNodeForXAdES(Signature signature, string idValue)
        {
            XmlElement node = null; 

            // enumerate the References to determine if any are of type XAdES 
            foreach (Reference reference in signature.SignedInfo.References) 
            {
                // if we get a match by Type? 
                if (String.CompareOrdinal(reference.Type, _XAdESTargetType) == 0)
                {
                    // now try to match by Uri
                    // strip off any preceding # mark to facilitate matching 
                    string uri;
                    if ((reference.Uri.Length > 0) && (reference.Uri[0] == '#')) 
                        uri = reference.Uri.Substring(1); 
                    else
                        continue;   // ignore non-local references 

                    // if we have a XAdES type reference and the ID matches the requested one
                    // search all object tags for the XML with this ID
                    if (String.CompareOrdinal(uri, idValue) == 0) 
                    {
                        node = SelectSubObjectNodeForXAdESInDataObjects(signature, idValue); 
                        break; 
                    }
                } 
            }

            return node;
        } 

        ///  
        /// Locates and selects the target XmlElement from all available Object tags 
        /// 
        ///  
        /// 
        /// element if found; null if not found
        /// relies on XPath query to search the Xml in each Object tag
        private static XmlElement SelectSubObjectNodeForXAdESInDataObjects(Signature signature, string idValue) 
        {
            XmlElement node = null; 
 
            // now find an object tag that includes an element that matches
            foreach (DataObject dataObject in signature.ObjectList) 
            {
                // skip the package object
                if (String.CompareOrdinal(dataObject.Id, XTable.Get(XTable.ID.OpcAttrValue)) != 0)
                { 
                    XmlElement element = dataObject.GetXml();
 
                    // NOTE: this is executing an XPath query 
                    XmlElement local = element.SelectSingleNode("//*[@Id='" + idValue + "']") as XmlElement;
                    if (local == null) 
                        continue;

                    // node found?
                    if (local != null) 
                    {
                        XmlNode temp = local; 
 
                        // climb the tree towards the root until we find our namespace
                        while ((temp != null) && (temp.NamespaceURI.Length == 0)) 
                            temp = temp.ParentNode;

                        // only match if the target is in the XAdES namespace
                        if ((temp != null) && (String.CompareOrdinal(temp.NamespaceURI, _XAdESNameSpace) == 0)) 
                        {
                            node = local as XmlElement; 
                            break; 
                        }
                    } 
                }
            }

            return node; 
        }
 
        private const string _XAdESNameSpace = @"http://uri.etsi.org/01903/v1.2.2#"; 
        private const string _XAdESTargetType = _XAdESNameSpace + @"SignedProperties";
    } 
}


// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK