public override object GetOutput()
        {
            CanonicalXmlNodeList resultNodeList = new CanonicalXmlNodeList();

            if (!string.IsNullOrEmpty(_xpathexpr))
            {
                XPathNavigator    navigator = _document.CreateNavigator();
                XPathNodeIterator it        = navigator.Select("//. | //@*");

                XPathExpression xpathExpr = navigator.Compile("boolean(" + _xpathexpr + ")");
                xpathExpr.SetContext(_nsm);

                while (it.MoveNext())
                {
                    XmlNode node = ((IHasXmlNode)it.Current).GetNode();

                    bool include = (bool)it.Current.Evaluate(xpathExpr);
                    if (include == true)
                    {
                        resultNodeList.Add(node);
                    }
                }

                // keep namespaces
                it = navigator.Select("//namespace::*");
                while (it.MoveNext())
                {
                    XmlNode node = ((IHasXmlNode)it.Current).GetNode();
                    resultNodeList.Add(node);
                }
            }

            return(resultNodeList);
        }
예제 #2
0
        private byte[] GetC14NDigest(HashAlgorithm hash)
        {
            bool isKeyedHashAlgorithm = hash is KeyedHashAlgorithm;

            if (isKeyedHashAlgorithm || !_bCacheValid || !SignedInfo.CacheValid)
            {
                string      baseUri  = (_containingDocument == null ? null : _containingDocument.BaseURI);
                XmlResolver resolver = (_bResolverSet ? _xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));

                XmlDocument doc = Utils.PreProcessElementInput(SignedInfo.GetXml(), resolver, baseUri);

                // Add non default namespaces in scope
                CanonicalXmlNodeList namespaces = (_context == null ? null : Utils.GetPropagatedAttributes(_context));
                SignedXmlDebugLog.LogNamespacePropagation(this, namespaces);
                Utils.AddNamespaces(doc.DocumentElement, namespaces);
                XmlNodeList nodeList = Utils.AllDescendantNodes(doc.DocumentElement.FirstChild, true);

                Transform c14nMethodTransform = SignedInfo.CanonicalizationMethodObject;
                c14nMethodTransform.Resolver = resolver;
                c14nMethodTransform.BaseURI  = baseUri;

                SignedXmlDebugLog.LogBeginCanonicalization(this, c14nMethodTransform);
                c14nMethodTransform.LoadInput(nodeList);
                SignedXmlDebugLog.LogCanonicalizedOutput(this, c14nMethodTransform);
                _digestedSignedInfo = c14nMethodTransform.GetDigestedOutput(hash);

                _bCacheValid = !isKeyedHashAlgorithm;
            }
            return(_digestedSignedInfo);
        }
예제 #3
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);
        }
예제 #4
0
        public DataObject(string id, string mimeType, string encoding, XmlElement data)
        {
            if (data == null)
            {
                throw new ArgumentNullException(nameof(data));
            }

            _id       = id;
            _mimeType = mimeType;
            _encoding = encoding;
            _elData   = new CanonicalXmlNodeList();
            _elData.Add(data);
            _cachedXml = null;
        }
예제 #5
0
        private void BuildDigestedReferences()
        {
            // Default the DigestMethod and Canonicalization
            ArrayList references = SignedInfo.References;

            // Reset the cache
            _refProcessed  = new bool[references.Count];
            _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 = Reference.DefaultDigestMethod;
                }

                SignedXmlDebugLog.LogSigningReference(this, reference);

                reference.UpdateHashValue(_containingDocument, nodeList);
                // If this reference has an Id attribute, add it
                if (reference.Id != null)
                {
                    nodeList.Add(reference.GetXml());
                }
            }
        }
예제 #6
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);
         }
     }
 }
예제 #7
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);
        }
예제 #8
0
        //
        // public constructors
        //

        public DataObject()
        {
            _cachedXml = null;
            _elData    = new CanonicalXmlNodeList();
        }
예제 #9
0
        //
        // public constructors
        //

        public Signature()
        {
            _embeddedObjects = new ArrayList();
            _referencedItems = new CanonicalXmlNodeList();
        }
예제 #10
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;
            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);
        }
예제 #11
0
        public override object GetOutput()
        {
            if (_containingDocument == null)
            {
                throw new CryptographicException(SR.Cryptography_Xml_EnvelopedSignatureRequiresContext);
            }

            // If we have received an XmlNodeList as input
            if (_inputNodeList != null)
            {
                // If the position has not been set, then we don't want to remove any signature tags
                if (_signaturePosition == 0)
                {
                    return(_inputNodeList);
                }
                XmlNodeList signatureList = _containingDocument.SelectNodes("//dsig:Signature", _nsm);
                if (signatureList == null)
                {
                    return(_inputNodeList);
                }

                CanonicalXmlNodeList resultNodeList = new CanonicalXmlNodeList();
                foreach (XmlNode node in _inputNodeList)
                {
                    if (node == null)
                    {
                        continue;
                    }
                    // keep namespaces
                    if (Utils.IsXmlNamespaceNode(node) || Utils.IsNamespaceNode(node))
                    {
                        resultNodeList.Add(node);
                    }
                    else
                    {
                        // SelectSingleNode throws an exception for xmldecl PI for example, so we will just ignore those exceptions
                        try
                        {
                            // Find the nearest signature ancestor tag
                            XmlNode result   = node.SelectSingleNode("ancestor-or-self::dsig:Signature[1]", _nsm);
                            int     position = 0;
                            foreach (XmlNode node1 in signatureList)
                            {
                                position++;
                                if (node1 == result)
                                {
                                    break;
                                }
                            }
                            if (result == null || position != _signaturePosition)
                            {
                                resultNodeList.Add(node);
                            }
                        }
                        catch { }
                    }
                }
                return(resultNodeList);
            }
            // Else we have received either a stream or a document as input
            else
            {
                XmlNodeList signatureList = _containingDocument.SelectNodes("//dsig:Signature", _nsm);
                if (signatureList == null)
                {
                    return(_containingDocument);
                }
                if (signatureList.Count < _signaturePosition || _signaturePosition <= 0)
                {
                    return(_containingDocument);
                }

                // Remove the signature node with all its children nodes
                signatureList[_signaturePosition - 1].ParentNode.RemoveChild(signatureList[_signaturePosition - 1]);
                return(_containingDocument);
            }
        }
예제 #12
0
        // What we want to do is pump the input throug the TransformChain and then
        // hash the output of the chain document is the document context for resolving relative references
        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
            _hashAlgorithm = CryptoHelpers.CreateFromName <HashAlgorithm>(_digestMethod);
            if (_hashAlgorithm == null)
            {
                throw new CryptographicException(SR.Cryptography_Xml_CreateHashAlgorithmFailed);
            }

            // Let's go get the target.
            string      baseUri         = (document == null ? System.Environment.CurrentDirectory + "\\" : document.BaseURI);
            Stream      hashInputStream = null;
            WebResponse response        = null;
            Stream      inputStream     = null;
            XmlResolver resolver        = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri));

            byte[] hashval = null;

            try
            {
                switch (_refTargetType)
                {
                case ReferenceTargetType.Stream:
                    // This is the easiest case. We already have a stream, so just pump it through the TransformChain
                    hashInputStream = TransformChain.TransformToOctetStream((Stream)_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 (_uri == null)
                    {
                        // 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 = TransformChain.TransformToOctetStream((Stream)null, resolver, baseUri);
                    }
                    else if (_uri.Length == 0 || _uri == "#xpointer(/)")
                    {
                        // 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(SR.Format(SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri));
                        }

                        // Normalize the containing document
                        XmlDocument doc = Utils.PreProcessDocumentInput(document, resolver, baseUri);
                        // Remove comments only if URI is ""
                        if (_uri.Length == 0)
                        {
                            Utils.DiscardComments(doc);
                        }
                        hashInputStream = TransformChain.TransformToOctetStream(doc, resolver, baseUri);
                    }
                    else if (_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(_uri, out discardComments);

                        XmlElement elem = SignedXml.GetIdElement(document, idref);

                        if (elem == null)
                        {
                            // Go throw the referenced items passed in
                            if (refList != null)
                            {
                                foreach (XmlNode node in refList)
                                {
                                    XmlElement tempElem = node.SelectSingleNode("//*[@Id='" + idref + "']") as XmlElement;
                                    //XmlElement tempElem = node as XmlElement;
                                    //if ((tempElem != null) && (Utils.HasAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl))
                                    //    && (Utils.GetAttribute(tempElem, "Id", SignedXml.XmlDsigNamespaceUrl).Equals(idref)))
                                    if (tempElem != null)
                                    {
                                        // copy fragment to document with root, create nodelsit
                                        elem = tempElem;
                                        XmlDocument doc = Utils.PreProcessElementInput(elem, resolver, baseUri);
                                        if (_signedXml._context != null)
                                        {
                                            CanonicalXmlNodeList namespaces = Utils.GetPropagatedAttributes(_signedXml._context);
                                            Utils.AddNamespaces(doc.DocumentElement, namespaces);
                                        }
                                        elem = doc.DocumentElement.FirstChild as XmlElement;
                                        break;
                                    }
                                }
                            }
                            if (elem == null)
                            {
                                throw new CryptographicException(SR.Cryptography_Xml_InvalidReference);
                            }
                        }
                        else
                        {
                            // create node list from document
                            XmlDocument          doc        = Utils.PreProcessElementInput(elem, resolver, baseUri);
                            CanonicalXmlNodeList namespaces = Utils.GetPropagatedAttributes(elem);
                            Utils.AddNamespaces(doc.DocumentElement, namespaces);
                            elem = doc.DocumentElement.FirstChild as XmlElement;
                        }
                        hashInputStream = TransformChain.TransformToOctetStream(Utils.AllDescendantNodes(elem, !discardComments), typeof(XmlNodeList), resolver, baseUri);
                    }
                    else
                    {
                        throw new CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri);
                    }
                    break;

                case ReferenceTargetType.XmlElement:
                    // We need to create a DocumentNavigator out of the XmlElement
                    hashInputStream = TransformChain.TransformToOctetStream(Utils.AllDescendantNodes((XmlNode)_refTarget, true), typeof(XmlNodeList), resolver, baseUri);
                    break;

                default:
                    throw new CryptographicException(SR.Cryptography_Xml_UriNotResolved, _uri);
                }

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

            return(hashval);
        }
예제 #13
0
 internal void UpdateHashValue(XmlDocument document, CanonicalXmlNodeList refList)
 {
     DigestValue = CalculateHashValue(document, refList);
 }