示例#1
0
        internal static XmlNodeList AllDescendantNodes(XmlNode node, bool includeComments)
        {
            CanonicalXmlNodeList nodeList      = new CanonicalXmlNodeList();
            CanonicalXmlNodeList elementList   = new CanonicalXmlNodeList();
            CanonicalXmlNodeList attribList    = new CanonicalXmlNodeList();
            CanonicalXmlNodeList namespaceList = new CanonicalXmlNodeList();

            int index = 0;

            elementList.Add(node);

            do
            {
                XmlNode rootNode = (XmlNode)elementList[index];
                // Add the children nodes
                XmlNodeList childNodes = rootNode.ChildNodes;
                if (childNodes != null)
                {
                    foreach (XmlNode node1 in childNodes)
                    {
                        if (includeComments || (!(node1 is XmlComment)))
                        {
                            elementList.Add(node1);
                        }
                    }
                }
                // Add the attribute nodes
                XmlAttributeCollection attribNodes = rootNode.Attributes;
                if (attribNodes != null)
                {
                    foreach (XmlNode attribNode in rootNode.Attributes)
                    {
                        if (attribNode.LocalName == "xmlns" || attribNode.Prefix == "xmlns")
                        {
                            namespaceList.Add(attribNode);
                        }
                        else
                        {
                            attribList.Add(attribNode);
                        }
                    }
                }
                index++;
            } while (index < elementList.Count);
            foreach (XmlNode elementNode in elementList)
            {
                nodeList.Add(elementNode);
            }
            foreach (XmlNode attribNode in attribList)
            {
                nodeList.Add(attribNode);
            }
            foreach (XmlNode namespaceNode in namespaceList)
            {
                nodeList.Add(namespaceNode);
            }

            return(nodeList);
        }
示例#2
0
        public DataObject(string id, string mimeType, string encoding, XmlElement data)
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            m_id       = id;
            m_mimeType = mimeType;
            m_encoding = encoding;
            m_elData   = new CanonicalXmlNodeList();
            m_elData.Add(data);
            m_cachedXml = null;
        }
示例#3
0
 internal static void AddNamespaces(XmlElement elem, CanonicalXmlNodeList namespaces)
 {
     if (namespaces != null)
     {
         foreach (XmlNode attrib in namespaces)
         {
             string name = ((attrib.Prefix.Length > 0) ? attrib.Prefix + ":" + attrib.LocalName : attrib.LocalName);
             // Skip the attribute if one with the same qualified name already exists
             if (elem.HasAttribute(name) || (name.Equals("xmlns") && elem.Prefix.Length == 0))
             {
                 continue;
             }
             XmlAttribute nsattrib = (XmlAttribute)elem.OwnerDocument.CreateAttribute(name);
             nsattrib.Value = attrib.Value;
             elem.SetAttributeNode(nsattrib);
         }
     }
 }
示例#4
0
        protected void BuildDigestedReferences()
        {
            // Default the DigestMethod and Canonicalization
            ArrayList references = SignedInfo.References;

            // Reset the cache
            m_refProcessed  = new bool[references.Count];
            m_refLevelCache = new int[references.Count];

            ReferenceLevelSortOrder sortOrder = new ReferenceLevelSortOrder();

            sortOrder.References = references;
            // Don't alter the order of the references array list
            ArrayList sortedReferences = new ArrayList();

            foreach (Reference reference in references)
            {
                sortedReferences.Add(reference);
            }
            sortedReferences.Sort(sortOrder);

            CanonicalXmlNodeList nodeList = new CanonicalXmlNodeList();

            foreach (DataObject obj in m_signature.ObjectList)
            {
                nodeList.Add(obj.GetXml());
            }
            foreach (Reference reference in sortedReferences)
            {
                // If no DigestMethod has yet been set, default it to sha1
                if (reference.DigestMethod == null)
                {
                    reference.DigestMethod = XmlDsigSHA1Url;
                }

                reference.UpdateHashValue(m_containingDocument, nodeList);
                // If this reference has an Id attribute, add it
                if (reference.Id != null)
                {
                    nodeList.Add(reference.GetXml());
                }
            }
        }
示例#5
0
        private static void MarkInclusionStateForNodes(XmlNodeList nodeList, XmlDocument inputRoot, XmlDocument root)
        {
            CanonicalXmlNodeList elementList          = new CanonicalXmlNodeList();
            CanonicalXmlNodeList elementListCanonical = new CanonicalXmlNodeList();

            elementList.Add(inputRoot);
            elementListCanonical.Add(root);
            int index = 0;

            do
            {
                XmlNode     currentNode          = (XmlNode)elementList[index];
                XmlNode     currentNodeCanonical = (XmlNode)elementListCanonical[index];
                XmlNodeList childNodes           = currentNode.ChildNodes;
                XmlNodeList childNodesCanonical  = currentNodeCanonical.ChildNodes;
                for (int i = 0; i < childNodes.Count; i++)
                {
                    elementList.Add(childNodes[i]);
                    elementListCanonical.Add(childNodesCanonical[i]);

                    if (Utils.NodeInList(childNodes[i], nodeList))
                    {
                        MarkNodeAsIncluded(childNodesCanonical[i]);
                    }

                    XmlAttributeCollection attribNodes = childNodes[i].Attributes;
                    if (attribNodes != null)
                    {
                        for (int j = 0; j < attribNodes.Count; j++)
                        {
                            if (Utils.NodeInList(attribNodes[j], nodeList))
                            {
                                MarkNodeAsIncluded(childNodesCanonical[i].Attributes.Item(j));
                            }
                        }
                    }
                }
                index++;
            } while (index < elementList.Count);
        }
示例#6
0
        // Allow machine admins to add additional canonicalization algorithms that should be considered valid when
        // validating XML signatuers by supplying a list in the
        // HKLM\Software\Microsoft\.NETFramework\Security\SafeCanonicalizationMethods
        // key.  Each REG_SZ entry in this key will be considered a canonicalziation algorithm URI that should be
        // allowed by SignedXml instances on this machine.
        //[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
        //[SecuritySafeCritical]
        //private static List<string> ReadAdditionalSafeCanonicalizationMethods() {
        //    List<string> additionalAlgorithms = new List<string>();

        //    try {
        //        using (RegistryKey canonicalizationAlgorithmsKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework\Security\SafeCanonicalizationMethods", false)) {
        //            if (canonicalizationAlgorithmsKey != null) {
        //                foreach (string value in canonicalizationAlgorithmsKey.GetValueNames()) {
        //                    if (canonicalizationAlgorithmsKey.GetValueKind(value) == RegistryValueKind.String) {
        //                        string additionalAlgorithm = canonicalizationAlgorithmsKey.GetValue(value) as string;
        //                        if (!String.IsNullOrWhiteSpace(additionalAlgorithm)) {
        //                            additionalAlgorithms.Add(additionalAlgorithm);
        //                        }
        //                    }
        //                }
        //            }
        //        }
        //    }
        //    catch (SecurityException) { /* we could not open the key - that's fine, we can proceed with no additional algorithms */ }

        //    return additionalAlgorithms;
        //}

        private byte[] GetC14NDigest(HashAlgorithm hash)
        {
            if (!bCacheValid || !this.SignedInfo.CacheValid)
            {
                string      baseUri  = (m_containingDocument == null ? null : m_containingDocument.BaseURI);
                XmlResolver resolver = (m_bResolverSet ? m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                XmlDocument doc      = Utils.PreProcessElementInput(SignedInfo.GetXml(), resolver, baseUri);

                // Add non default namespaces in scope
                CanonicalXmlNodeList namespaces = (m_context == null ? null : Utils.GetPropagatedAttributes(m_context));
                Utils.AddNamespaces(doc.DocumentElement, namespaces);

                Transform c14nMethodTransform = SignedInfo.CanonicalizationMethodObject;
                c14nMethodTransform.Resolver = resolver;
                c14nMethodTransform.BaseURI  = baseUri;
                c14nMethodTransform.LoadInput(doc);
                _digestedSignedInfo = c14nMethodTransform.GetDigestedOutput(hash);

                bCacheValid = true;
            }
            return(_digestedSignedInfo);
        }
示例#7
0
        // This method gets the attributes that should be propagated
        internal static CanonicalXmlNodeList GetPropagatedAttributes(XmlElement elem)
        {
            if (elem == null)
            {
                return(null);
            }

            CanonicalXmlNodeList namespaces = new CanonicalXmlNodeList();
            XmlNode ancestorNode            = elem;

            if (ancestorNode == null)
            {
                return(null);
            }

            bool bDefNamespaceToAdd = true;

            while (ancestorNode != null)
            {
                XmlElement ancestorElement = ancestorNode as XmlElement;
                if (ancestorElement == null)
                {
                    ancestorNode = ancestorNode.ParentNode;
                    continue;
                }
                if (!Utils.IsCommittedNamespace(ancestorElement, ancestorElement.Prefix, ancestorElement.NamespaceURI))
                {
                    // Add the namespace attribute to the collection if needed
                    if (!Utils.IsRedundantNamespace(ancestorElement, ancestorElement.Prefix, ancestorElement.NamespaceURI))
                    {
                        string       name     = ((ancestorElement.Prefix.Length > 0) ? "xmlns:" + ancestorElement.Prefix : "xmlns");
                        XmlAttribute nsattrib = elem.OwnerDocument.CreateAttribute(name);
                        nsattrib.Value = ancestorElement.NamespaceURI;
                        namespaces.Add(nsattrib);
                    }
                }
                if (ancestorElement.HasAttributes)
                {
                    XmlAttributeCollection attribs = ancestorElement.Attributes;
                    foreach (XmlAttribute attrib in attribs)
                    {
                        // Add a default namespace if necessary
                        if (bDefNamespaceToAdd && attrib.LocalName == "xmlns")
                        {
                            XmlAttribute nsattrib = elem.OwnerDocument.CreateAttribute("xmlns");
                            nsattrib.Value = attrib.Value;
                            namespaces.Add(nsattrib);
                            bDefNamespaceToAdd = false;
                            continue;
                        }
                        // retain the declarations of type 'xml:*' as well
                        if (attrib.Prefix == "xmlns" || attrib.Prefix == "xml")
                        {
                            namespaces.Add(attrib);
                            continue;
                        }
                        if (attrib.NamespaceURI.Length > 0)
                        {
                            if (!Utils.IsCommittedNamespace(ancestorElement, attrib.Prefix, attrib.NamespaceURI))
                            {
                                // Add the namespace attribute to the collection if needed
                                if (!Utils.IsRedundantNamespace(ancestorElement, attrib.Prefix, attrib.NamespaceURI))
                                {
                                    string       name     = ((attrib.Prefix.Length > 0) ? "xmlns:" + attrib.Prefix : "xmlns");
                                    XmlAttribute nsattrib = elem.OwnerDocument.CreateAttribute(name);
                                    nsattrib.Value = attrib.NamespaceURI;
                                    namespaces.Add(nsattrib);
                                }
                            }
                        }
                    }
                }
                ancestorNode = ancestorNode.ParentNode;
            }

            return(namespaces);
        }
示例#8
0
        internal byte[] CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
        {
            // refList is a list of elements that might be targets of references
            // Now's the time to create our hashing algorithm
            m_hashAlgorithm = GostCryptoConfig.CreateFromName(m_digestMethod) as HashAlgorithm;
            if (m_hashAlgorithm == null)
            {
                throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_CreateHashAlgorithmFailed"));
            }

            // Let's go get the target.
            string      baseUri         = (document == null ? System.Environment.CurrentDirectory + "\\" : document.BaseURI);
            Stream      hashInputStream = null;
            WebRequest  request         = null;
            WebResponse response        = null;
            Stream      inputStream     = null;
            XmlResolver resolver        = null;

            byte[] hashval = null;

            try {
                switch (m_refTargetType)
                {
                case ReferenceTargetType.Stream:
                    // This is the easiest case. We already have a stream, so just pump it through the TransformChain
                    resolver        = (this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                    hashInputStream = this.TransformChain.TransformToOctetStream((Stream)m_refTarget, resolver, baseUri);
                    break;

                case ReferenceTargetType.UriReference:
                    // Second-easiest case -- dereference the URI & pump through the TransformChain
                    // handle the special cases where the URI is null (meaning whole doc)
                    // or the URI is just a fragment (meaning a reference to an embedded Object)
                    if (m_uri == null)
                    {
                        // We need to create a DocumentNavigator out of the XmlElement
                        resolver = (this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                        // In the case of a Uri-less reference, we will simply pass null to the transform chain.
                        // The first transform in the chain is expected to know how to retrieve the data to hash.
                        hashInputStream = this.TransformChain.TransformToOctetStream((Stream)null, resolver, baseUri);
                    }
                    else if (m_uri.Length == 0)
                    {
                        // This is the self-referential case. First, check that we have a document context.
                        // The Enveloped Signature does not discard comments as per spec; those will be omitted during the transform chain process
                        if (document == null)
                        {
                            throw new CryptographicException(String.Format(CultureInfo.CurrentCulture, SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), m_uri));
                        }

                        // Normalize the containing document
                        resolver = (this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                        XmlDocument docWithNoComments = Utils.DiscardComments(Utils.PreProcessDocumentInput(document, resolver, baseUri));
                        hashInputStream = this.TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri);
                    }
                    else if (m_uri[0] == '#')
                    {
                        // If we get here, then we are constructing a Reference to an embedded DataObject
                        // referenced by an Id = attribute. Go find the relevant object
                        bool   discardComments = true;
                        string idref           = Utils.GetIdFromLocalUri(m_uri, out discardComments);
                        if (idref == "xpointer(/)")
                        {
                            // This is a self referencial case
                            if (document == null)
                            {
                                throw new CryptographicException(String.Format(CultureInfo.CurrentCulture, SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), m_uri));
                            }

                            // We should not discard comments here!!!
                            resolver        = (this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                            hashInputStream = this.TransformChain.TransformToOctetStream(Utils.PreProcessDocumentInput(document, resolver, baseUri), resolver, baseUri);
                            break;
                        }

                        XmlElement elem = this.SignedXml.GetIdElement(document, idref);
                        if (elem != null)
                        {
                            m_namespaces = Utils.GetPropagatedAttributes(elem.ParentNode as XmlElement);
                        }

                        if (elem == null)
                        {
                            // Go throw the referenced items passed in
                            if (refList != null)
                            {
                                foreach (XmlNode node in refList)
                                {
                                    XmlElement tempElem = node as XmlElement;
                                    if ((tempElem != null) && (Utils.HasAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl)) &&
                                        (Utils.GetAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl).Equals(idref)))
                                    {
                                        elem = tempElem;
                                        if (this.m_signedXml.m_context != null)
                                        {
                                            m_namespaces = Utils.GetPropagatedAttributes(this.m_signedXml.m_context);
                                        }
                                        break;
                                    }
                                }
                            }
                        }

                        if (elem == null)
                        {
                            throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidReference"));
                        }

                        XmlDocument normDocument = Utils.PreProcessElementInput(elem, resolver, baseUri);
                        // Add the propagated attributes
                        Utils.AddNamespaces(normDocument.DocumentElement, m_namespaces);

                        resolver = (this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                        if (discardComments)
                        {
                            // We should discard comments before going into the transform chain
                            XmlDocument docWithNoComments = Utils.DiscardComments(normDocument);
                            hashInputStream = this.TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri);
                        }
                        else
                        {
                            // This is an XPointer reference, do not discard comments!!!
                            hashInputStream = this.TransformChain.TransformToOctetStream(normDocument, resolver, baseUri);
                        }
                    }
                    else
                    {
                        // WebRequest always expects an Absolute Uri, so try to resolve if we were passed a relative Uri.
                        System.Uri uri = new System.Uri(m_uri, UriKind.RelativeOrAbsolute);
                        if (!uri.IsAbsoluteUri)
                        {
                            uri = new Uri(new Uri(baseUri), uri);
                        }
                        request = WebRequest.Create(uri);
                        if (request == null)
                        {
                            goto default;
                        }
                        response = request.GetResponse();
                        if (response == null)
                        {
                            goto default;
                        }
                        inputStream = response.GetResponseStream();
                        if (inputStream == null)
                        {
                            goto default;
                        }
                        resolver        = (this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                        hashInputStream = this.TransformChain.TransformToOctetStream(inputStream, resolver, m_uri);
                    }
                    break;

                case ReferenceTargetType.XmlElement:
                    // We need to create a DocumentNavigator out of the XmlElement
                    resolver        = (this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));
                    hashInputStream = this.TransformChain.TransformToOctetStream(Utils.PreProcessElementInput((XmlElement)m_refTarget, resolver, baseUri), resolver, baseUri);
                    break;

                default:
                    throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_UriNotResolved"), m_uri);
                }

                // Compute the new hash value
                //hashInputStream = SignedXmlDebugLog.LogReferenceData(this, hashInputStream);
                hashval = m_hashAlgorithm.ComputeHash(hashInputStream);
            }
            finally {
                if (hashInputStream != null)
                {
                    hashInputStream.Close();
                }
                if (response != null)
                {
                    response.Close();
                }
                if (inputStream != null)
                {
                    inputStream.Close();
                }
            }

            return(hashval);
        }
示例#9
0
 internal void UpdateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
 {
     DigestValue = CalculateHashValue(document, refList);
 }
示例#10
0
        //
        // public constructors
        //

        public Signature()
        {
            m_embeddedObjects = new ArrayList();
            m_referencedItems = new CanonicalXmlNodeList();
        }
示例#11
0
        //
        // public constructors
        //

        public DataObject()
        {
            m_cachedXml = null;
            m_elData    = new CanonicalXmlNodeList();
        }