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); }
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); }
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); }
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; }
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()); } } }
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); } } }
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); }
// // public constructors // public DataObject() { _cachedXml = null; _elData = new CanonicalXmlNodeList(); }
// // public constructors // public Signature() { _embeddedObjects = new ArrayList(); _referencedItems = new CanonicalXmlNodeList(); }
// 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); }
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); } }
// 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); }
internal void UpdateHashValue(XmlDocument document, CanonicalXmlNodeList refList) { DigestValue = CalculateHashValue(document, refList); }