// 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 = null; 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 resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); 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) { // We need to create a DocumentNavigator out of the XmlElement resolver = (SignedXml.ResolverSet ? SignedXml._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 = TransformChain.TransformToOctetStream((Stream)null, resolver, baseUri); } else if (_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(SR.Format(SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } // Normalize the containing document resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); XmlDocument docWithNoComments = Utils.DiscardComments(Utils.PreProcessDocumentInput(document, resolver, baseUri)); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, 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); if (idref == "xpointer(/)") { // This is a self referencial case if (document == null) { throw new CryptographicException(SR.Format(SR.Cryptography_Xml_SelfReferenceRequiresContext, _uri)); } // We should not discard comments here!!! resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(Utils.PreProcessDocumentInput(document, resolver, baseUri), resolver, baseUri); break; } XmlElement elem = SignedXml.GetIdElement(document, idref); if (elem != null) { _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 (_signedXml._context != null) { _namespaces = Utils.GetPropagatedAttributes(_signedXml._context); } break; } } } } if (elem == null) { throw new CryptographicException(SR.Cryptography_Xml_InvalidReference); } XmlDocument normDocument = Utils.PreProcessElementInput(elem, resolver, baseUri); // Add the propagated attributes Utils.AddNamespaces(normDocument.DocumentElement, _namespaces); resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); if (discardComments) { // We should discard comments before going into the transform chain XmlDocument docWithNoComments = Utils.DiscardComments(normDocument); hashInputStream = TransformChain.TransformToOctetStream(docWithNoComments, resolver, baseUri); } else { // This is an XPointer reference, do not discard comments!!! hashInputStream = TransformChain.TransformToOctetStream(normDocument, 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 resolver = (SignedXml.ResolverSet ? SignedXml._xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), baseUri)); hashInputStream = TransformChain.TransformToOctetStream(Utils.PreProcessElementInput((XmlElement)_refTarget, resolver, baseUri), 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 byte[] CalculateHashValue(XmlDocument document, CanonicalXmlNodeList refList) { this.m_hashAlgorithm = CryptoConfig.CreateFromName(this.m_digestMethod) as HashAlgorithm; if (this.m_hashAlgorithm == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_CreateHashAlgorithmFailed")); } string securityUrl = (document == null) ? (Environment.CurrentDirectory + @"\") : document.BaseURI; Stream data = null; WebRequest request = null; WebResponse response = null; Stream input = null; XmlResolver resolver = null; byte[] buffer = null; try { switch (this.m_refTargetType) { case System.Security.Cryptography.Xml.ReferenceTargetType.Stream: resolver = this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl); data = this.TransformChain.TransformToOctetStream((Stream)this.m_refTarget, resolver, securityUrl); goto Label_048A; case System.Security.Cryptography.Xml.ReferenceTargetType.XmlElement: resolver = this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl); data = this.TransformChain.TransformToOctetStream(System.Security.Cryptography.Xml.Utils.PreProcessElementInput((XmlElement)this.m_refTarget, resolver, securityUrl), resolver, securityUrl); goto Label_048A; case System.Security.Cryptography.Xml.ReferenceTargetType.UriReference: if (this.m_uri != null) { break; } resolver = this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl); data = this.TransformChain.TransformToOctetStream((Stream)null, resolver, securityUrl); goto Label_048A; default: goto Label_0474; } if (this.m_uri.Length == 0) { if (document == null) { throw new CryptographicException(string.Format(CultureInfo.CurrentCulture, SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), new object[] { this.m_uri })); } resolver = this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl); XmlDocument document2 = System.Security.Cryptography.Xml.Utils.DiscardComments(System.Security.Cryptography.Xml.Utils.PreProcessDocumentInput(document, resolver, securityUrl)); data = this.TransformChain.TransformToOctetStream(document2, resolver, securityUrl); goto Label_048A; } if (this.m_uri[0] == '#') { bool discardComments = true; string idFromLocalUri = System.Security.Cryptography.Xml.Utils.GetIdFromLocalUri(this.m_uri, out discardComments); if (idFromLocalUri == "xpointer(/)") { if (document == null) { throw new CryptographicException(string.Format(CultureInfo.CurrentCulture, SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), new object[] { this.m_uri })); } resolver = this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl); data = this.TransformChain.TransformToOctetStream(System.Security.Cryptography.Xml.Utils.PreProcessDocumentInput(document, resolver, securityUrl), resolver, securityUrl); } else { XmlElement idElement = this.SignedXml.GetIdElement(document, idFromLocalUri); if (idElement != null) { this.m_namespaces = System.Security.Cryptography.Xml.Utils.GetPropagatedAttributes(idElement.ParentNode as XmlElement); } if ((idElement == null) && (refList != null)) { foreach (XmlNode node in refList) { XmlElement element = node as XmlElement; if (((element != null) && System.Security.Cryptography.Xml.Utils.HasAttribute(element, "Id", "http://www.w3.org/2000/09/xmldsig#")) && System.Security.Cryptography.Xml.Utils.GetAttribute(element, "Id", "http://www.w3.org/2000/09/xmldsig#").Equals(idFromLocalUri)) { idElement = element; if (this.m_signedXml.m_context != null) { this.m_namespaces = System.Security.Cryptography.Xml.Utils.GetPropagatedAttributes(this.m_signedXml.m_context); } break; } } } if (idElement == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidReference")); } XmlDocument document3 = System.Security.Cryptography.Xml.Utils.PreProcessElementInput(idElement, resolver, securityUrl); System.Security.Cryptography.Xml.Utils.AddNamespaces(document3.DocumentElement, this.m_namespaces); resolver = this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl); if (discardComments) { XmlDocument document4 = System.Security.Cryptography.Xml.Utils.DiscardComments(document3); data = this.TransformChain.TransformToOctetStream(document4, resolver, securityUrl); } else { data = this.TransformChain.TransformToOctetStream(document3, resolver, securityUrl); } } goto Label_048A; } System.Uri relativeUri = new System.Uri(this.m_uri, UriKind.RelativeOrAbsolute); if (!relativeUri.IsAbsoluteUri) { relativeUri = new System.Uri(new System.Uri(securityUrl), relativeUri); } request = WebRequest.Create(relativeUri); if (request != null) { response = request.GetResponse(); if (response != null) { input = response.GetResponseStream(); if (input != null) { resolver = this.SignedXml.ResolverSet ? this.SignedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), securityUrl); data = this.TransformChain.TransformToOctetStream(input, resolver, this.m_uri); goto Label_048A; } } } Label_0474: throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_UriNotResolved"), this.m_uri); Label_048A: data = SignedXmlDebugLog.LogReferenceData(this, data); buffer = this.m_hashAlgorithm.ComputeHash(data); } finally { if (data != null) { data.Close(); } if (response != null) { response.Close(); } if (input != null) { input.Close(); } } return(buffer); }