// 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); }
// 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 void UpdateHashValue(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 = SHA1.Create(); // Let's go get the target. string baseUri = document.BaseURI; Stream hashInputStream = null; byte[] hashval = null; try { // 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[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 = document.GetElementsByTagName(tag)[0] as XmlElement; 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; } } } } XmlDocument normDocument = Utils.PreProcessElementInput(elem); // Add the propagated attributes Utils.AddNamespaces(normDocument.DocumentElement, _namespaces); if (discardComments) { // We should discard comments before going into the transform chain hashInputStream = TransformChain.TransformToOctetStream(normDocument); } else { // This is an XPointer reference, do not discard comments!!! hashInputStream = TransformChain.TransformToOctetStream(normDocument); } } // Compute the new hash value hashval = _hashAlgorithm.ComputeHash(hashInputStream); } finally { if (hashInputStream != null) { hashInputStream.Dispose(); } } DigestValue = hashval; }
// // private methods // private byte[] GetCipherValue(CipherData cipherData) { if (cipherData == null) { throw new ArgumentNullException("cipherData"); } WebResponse response = null; Stream inputStream = null; if (cipherData.CipherValue != null) { return(cipherData.CipherValue); } else if (cipherData.CipherReference != null) { if (cipherData.CipherReference.CipherValue != null) { return(cipherData.CipherReference.CipherValue); } Stream decInputStream = null; // See if the CipherReference is a local URI if (cipherData.CipherReference.Uri.Length == 0) { // self referenced Uri string baseUri = (_document == null ? null : _document.BaseURI); TransformChain tc = cipherData.CipherReference.TransformChain; decInputStream = tc.TransformToOctetStream(_document, _xmlResolver, baseUri); } else if (cipherData.CipherReference.Uri[0] == '#') { string idref = Utils.ExtractIdFromLocalUri(cipherData.CipherReference.Uri); // Serialize inputStream = new MemoryStream(_encoding.GetBytes(GetIdElement(_document, idref).OuterXml)); string baseUri = (_document == null ? null : _document.BaseURI); TransformChain tc = cipherData.CipherReference.TransformChain; decInputStream = tc.TransformToOctetStream(inputStream, _xmlResolver, baseUri); } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_UriNotResolved"), cipherData.CipherReference.Uri); } // read the output stream into a memory stream byte[] cipherValue = null; using (MemoryStream ms = new MemoryStream()) { Utils.Pump(decInputStream, ms); cipherValue = ms.ToArray(); // Close the stream and return if (response != null) { response.Close(); } if (inputStream != null) { inputStream.Close(); } decInputStream.Close(); } // cache the cipher value for Perf reasons in case we call this routine twice cipherData.CipherReference.CipherValue = cipherValue; return(cipherValue); } // Throw a CryptographicException if we were unable to retrieve the cipher data. throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_MissingCipherData")); }
/// <include file='doc\SignedXml.uex' path='docs/doc[@for="SignedXml.ComputeSignature1"]/*' /> public void ComputeSignature(KeyedHashAlgorithm macAlg) { // Do some sanity checks if (macAlg == null) { throw new ArgumentNullException("macAlg"); } if (!(macAlg is HMACSHA1)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_SignatureMethodKeyMismatch")); } int iSignatureLength; if (m_signature.SignedInfo.SignatureLength == null) { iSignatureLength = macAlg.HashSize; } else { iSignatureLength = Convert.ToInt32(m_signature.SignedInfo.SignatureLength); } // iSignatureLength should be less than hash size if (iSignatureLength < 0 || iSignatureLength > macAlg.HashSize) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidSignatureLength")); } if (iSignatureLength % 8 != 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidSignatureLength2")); } BuildDigestedReferences(); SignedInfo.SignatureMethod = XmlDsigHMACSHA1Url; // Compute the hash of the SignedInfo object XmlElement signedInfo = SignedInfo.GetXml().Clone() as XmlElement; // Add non default namespaces in scope if (m_namespaces != null) { foreach (XmlNode attrib in m_namespaces) { string name = ((attrib.Prefix != String.Empty) ? attrib.Prefix + ":" + attrib.LocalName : attrib.LocalName); // Skip the attribute if one with the same qualified name already exists if (signedInfo.HasAttribute(name) || (name.Equals("xmlns") && signedInfo.NamespaceURI != String.Empty)) { continue; } XmlAttribute nsattrib = m_containingDocument.CreateAttribute(name); nsattrib.Value = ((XmlNode)attrib).Value; signedInfo.SetAttributeNode(nsattrib); } } #if _DEBUG if (debug) { Console.WriteLine("computed signedInfo: "); Console.WriteLine(signedInfo.OuterXml); } #endif TransformChain tc = new TransformChain(); Transform c14nMethodTransform = (Transform)CryptoConfig.CreateFromName(SignedInfo.CanonicalizationMethod); if (c14nMethodTransform == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_CreateTransformFailed"), SignedInfo.CanonicalizationMethod)); } tc.Add(c14nMethodTransform); string strBaseUri = (m_containingDocument == null ? null : m_containingDocument.BaseURI); XmlResolver resolver = (m_bResolverSet ? m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); Stream hashInput = tc.TransformToOctetStream(PreProcessElementInput(signedInfo, resolver, strBaseUri), resolver, strBaseUri); byte[] hashValue = macAlg.ComputeHash(hashInput); m_signature.SignatureValue = new byte[iSignatureLength / 8]; Buffer.BlockCopy(hashValue, 0, m_signature.SignatureValue, 0, iSignatureLength / 8); #if _DEBUG if (debug) { Console.WriteLine("computed hash value: " + Convert.ToBase64String(hashValue)); } #endif }
/// <include file='doc\SignedXml.uex' path='docs/doc[@for="SignedXml.ComputeSignature"]/*' /> public void ComputeSignature() { BuildDigestedReferences(); // Load the key AsymmetricAlgorithm key; if (SigningKey != null) { key = SigningKey; } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_LoadKeyFailed")); } if (key == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_LoadKeyFailed")); } // Check the signature algorithm associated with the key so that we can accordingly set // the signature method if (key is DSA) { SignedInfo.SignatureMethod = XmlDsigDSAUrl; } else if (key is RSA) { // Default to RSA-SHA1 if (SignedInfo.SignatureMethod == null) { SignedInfo.SignatureMethod = XmlDsigRSASHA1Url; } } else { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_CreatedKeyFailed")); } // Compute the hash of the SignedInfo object XmlElement signedInfo = SignedInfo.GetXml().Clone() as XmlElement; // Add non default namespaces in scope if (m_namespaces != null) { foreach (XmlNode attrib in m_namespaces) { string name = ((attrib.Prefix != String.Empty) ? attrib.Prefix + ":" + attrib.LocalName : attrib.LocalName); // Skip the attribute if one with the same qualified name already exists if (signedInfo.HasAttribute(name) || (name.Equals("xmlns") && signedInfo.NamespaceURI != String.Empty)) { continue; } XmlAttribute nsattrib = m_containingDocument.CreateAttribute(name); nsattrib.Value = ((XmlNode)attrib).Value; signedInfo.SetAttributeNode(nsattrib); } } #if _DEBUG if (debug) { Console.WriteLine("computed signedInfo: "); Console.WriteLine(signedInfo.OuterXml); } #endif TransformChain tc = new TransformChain(); Transform c14nMethodTransform = (Transform)CryptoConfig.CreateFromName(SignedInfo.CanonicalizationMethod); if (c14nMethodTransform == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_CreateTransformFailed"), SignedInfo.CanonicalizationMethod)); } tc.Add(c14nMethodTransform); string strBaseUri = (m_containingDocument == null ? null : m_containingDocument.BaseURI); XmlResolver resolver = (m_bResolverSet ? m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); Stream hashInput = tc.TransformToOctetStream(PreProcessElementInput(signedInfo, resolver, strBaseUri), resolver, strBaseUri); // See if there is a signature description class defined through the Config file SignatureDescription signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName(SignedInfo.SignatureMethod); if (signatureDescription == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_SignatureDescriptionNotCreated")); } // calculate the hash HashAlgorithm hashAlg = signatureDescription.CreateDigest(); if (hashAlg == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_CreateHashAlgorithmFailed")); } byte[] hashValue = hashAlg.ComputeHash(hashInput); AsymmetricSignatureFormatter asymmetricSignatureFormatter = signatureDescription.CreateFormatter(key); m_signature.SignatureValue = asymmetricSignatureFormatter.CreateSignature(hashAlg); #if _DEBUG if (debug) { Console.WriteLine("computed hash value: " + Convert.ToBase64String(hashValue)); } #endif }
/// <include file='doc\SignedXml.uex' path='docs/doc[@for="SignedXml.CheckSignature2"]/*' /> public bool CheckSignature(KeyedHashAlgorithm macAlg) { // Do some sanity checks if (macAlg == null) { throw new ArgumentNullException("macAlg"); } int iSignatureLength; if (m_signature.SignedInfo.SignatureLength == null) { iSignatureLength = macAlg.HashSize; } else { iSignatureLength = Convert.ToInt32(m_signature.SignedInfo.SignatureLength); } // iSignatureLength should be less than hash size if (iSignatureLength < 0 || iSignatureLength > macAlg.HashSize) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidSignatureLength")); } if (iSignatureLength % 8 != 0) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidSignatureLength2")); } if (m_signature.SignatureValue == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_SignatureValueRequired")); } if (m_signature.SignatureValue.Length != iSignatureLength / 8) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidSignatureLength")); } // set up the canonicalizer & canonicalize SignedInfo TransformChain tc = new TransformChain(); Transform c14nMethodTransform = (Transform)CryptoConfig.CreateFromName(SignedInfo.CanonicalizationMethod); if (c14nMethodTransform == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_CreateTransformFailed"), SignedInfo.CanonicalizationMethod)); } tc.Add(c14nMethodTransform); XmlElement signedInfo = SignedInfo.GetXml().Clone() as XmlElement; // Add non default namespaces in scope if (m_namespaces != null) { foreach (XmlNode attrib in m_namespaces) { string name = ((attrib.Prefix != String.Empty) ? attrib.Prefix + ":" + attrib.LocalName : attrib.LocalName); // Skip the attribute if one with the same qualified name already exists if (signedInfo.HasAttribute(name) || (name.Equals("xmlns") && signedInfo.NamespaceURI != String.Empty)) { continue; } XmlAttribute nsattrib = m_containingDocument.CreateAttribute(name); nsattrib.Value = ((XmlNode)attrib).Value; signedInfo.SetAttributeNode(nsattrib); } } string strBaseUri = (m_containingDocument == null ? null : m_containingDocument.BaseURI); XmlResolver resolver = (m_bResolverSet ? m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); Stream canonicalizedSignedXml = tc.TransformToOctetStream(PreProcessElementInput(signedInfo, resolver, strBaseUri), resolver, strBaseUri); // Calculate the hash byte[] hashValue = macAlg.ComputeHash(canonicalizedSignedXml); #if _DEBUG if (debug) { Console.WriteLine("Computed canonicalized SignedInfo:"); Console.WriteLine(signedInfo.OuterXml); Console.WriteLine("Computed Hash:"); Console.WriteLine(Convert.ToBase64String(hashValue)); Console.WriteLine("m_signature.SignatureValue:"); Console.WriteLine(Convert.ToBase64String(m_signature.SignatureValue)); } #endif for (int i = 0; i < m_signature.SignatureValue.Length; i++) { if (m_signature.SignatureValue[i] != hashValue[i]) { return(false); } } return(CheckDigestedReferences()); }
/// <include file='doc\SignedXml.uex' path='docs/doc[@for="SignedXml.CheckSignature1"]/*' /> public bool CheckSignature(AsymmetricAlgorithm key) { if (key == null) { throw new ArgumentNullException("key"); } SignatureDescription signatureDescription = (SignatureDescription)CryptoConfig.CreateFromName(m_signature.SignedInfo.SignatureMethod); if (signatureDescription == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_SignatureDescriptionNotCreated")); } // Let's see if the key corresponds with the SignatureMethod Type ta = Type.GetType(signatureDescription.KeyAlgorithm); Type tb = key.GetType(); if ((ta != tb) && !ta.IsSubclassOf(tb) && !tb.IsSubclassOf(ta)) { // Signature method key mismatch return(false); } // set up the canonicalizer & canonicalize SignedInfo TransformChain tc = new TransformChain(); Transform c14nMethodTransform = (Transform)CryptoConfig.CreateFromName(SignedInfo.CanonicalizationMethod); if (c14nMethodTransform == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_CreateTransformFailed"), SignedInfo.CanonicalizationMethod)); } tc.Add(c14nMethodTransform); XmlElement signedInfo = SignedInfo.GetXml().Clone() as XmlElement; // Add non default namespaces in scope if (m_namespaces != null) { foreach (XmlNode attrib in m_namespaces) { string name = ((attrib.Prefix != String.Empty) ? attrib.Prefix + ":" + attrib.LocalName : attrib.LocalName); // Skip the attribute if one with the same qualified name already exists if (signedInfo.HasAttribute(name) || (name.Equals("xmlns") && signedInfo.NamespaceURI != String.Empty)) { continue; } XmlAttribute nsattrib = m_containingDocument.CreateAttribute(name); nsattrib.Value = ((XmlNode)attrib).Value; signedInfo.SetAttributeNode(nsattrib); } } string strBaseUri = (m_containingDocument == null ? null : m_containingDocument.BaseURI); XmlResolver resolver = (m_bResolverSet ? m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); Stream canonicalizedSignedXml = tc.TransformToOctetStream(PreProcessElementInput(signedInfo, resolver, strBaseUri), resolver, strBaseUri); // calculate the hash HashAlgorithm hashAlgorithm = signatureDescription.CreateDigest(); if (hashAlgorithm == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_CreateHashAlgorithmFailed")); } byte[] hashval = hashAlgorithm.ComputeHash(canonicalizedSignedXml); // We can FINALLY generate the SignatureValue #if _DEBUG if (debug) { Console.WriteLine("Computed canonicalized SignedInfo:"); Console.WriteLine(signedInfo.OuterXml); Console.WriteLine("Computed Hash:"); Console.WriteLine(Convert.ToBase64String(hashval)); Console.WriteLine("m_signature.SignatureValue:"); Console.WriteLine(Convert.ToBase64String(m_signature.SignatureValue)); } #endif AsymmetricSignatureDeformatter asymmetricSignatureDeformatter = signatureDescription.CreateDeformatter(key); bool bRet = asymmetricSignatureDeformatter.VerifySignature(hashAlgorithm, m_signature.SignatureValue); if (bRet != true) { #if _DEBUG if (debug) { Console.WriteLine("Failed to verify the signature on SignedInfo."); } #endif return(false); } // Now is the time to go through all the references and see if their // DigestValue are good return(CheckDigestedReferences()); }
// 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 m_hashAlgorithm = (HashAlgorithm)CryptoConfig.CreateFromName(DigestMethod); if (m_hashAlgorithm == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_CreateHashAlgorithmFailed")); } string strBaseUri = (document == null ? null : document.BaseURI); // For interop w/ Petteri & IBM -- may not be required by the spec //if (m_transforms.Count == 0) { //if (DataObject != null && DataObject.Data != null) { //AddTransform(new W3cCanonicalization()); //} //} // Let's go get the target. Stream hashInputStream; WebRequest theRequest = null; WebResponse theResponse = null; Stream inputStream = null; XmlResolver resolver = null; switch (m_refTargetType) { case ReferenceTargetType.Stream: // This is the easiest case. We already have a stream, so just pump it through // the TransformChain resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream((Stream)m_refTarget, resolver, strBaseUri); 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_strUri == "") { // This is the self-referential case. // The Enveloped Signature does not discard comments as per spec; those will be omitted during the transform chain process // First, check that we have a document context. if (document == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), m_strUri)); } // Normalize the containing document resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); XmlDocument docWithNoComments = CanonicalXml.DiscardComments(SignedXml.PreProcessDocumentInput(document, resolver, strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(docWithNoComments, resolver, strBaseUri); } else if (m_strUri[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 String idref = m_strUri.Substring(1); bool bDiscardComments = true; // Deal with XPointer of types #xpointer(/) and #xpointer(id("ID")). Other XPointer support isn't handled here and is anyway optional if (idref == "xpointer(/)") { // This is a self referencial case if (document == null) { throw new CryptographicException(String.Format(SecurityResources.GetResourceString("Cryptography_Xml_SelfReferenceRequiresContext"), m_strUri)); } // We should not discard comments here!!! resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(SignedXml.PreProcessDocumentInput(document, resolver, strBaseUri), resolver, strBaseUri); goto end; } else if (idref.StartsWith("xpointer(id(")) { int startId = idref.IndexOf("id("); int endId = idref.IndexOf(")"); if (endId < 0 || endId < startId + 3) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidReference")); } idref = idref.Substring(startId + 3, endId - startId - 3); idref = idref.Replace("\'", ""); idref = idref.Replace("\"", ""); bDiscardComments = false; } XmlElement elem = m_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 as XmlElement; if ((tempElem != null) && (tempElem.HasAttribute("Id")) && (tempElem.GetAttribute("Id").Equals(idref))) { elem = tempElem; break; } } } } if (elem == null) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidReference")); } // Add the propagated attributes, clone the element first XmlElement elemClone = elem.Clone() as XmlElement; if (m_namespaces != null) { foreach (XmlNode attrib in m_namespaces) { string name = ((attrib.Prefix != String.Empty) ? attrib.Prefix + ":" + attrib.LocalName : attrib.LocalName); // Skip the attribute if one with the same qualified name already exists if (elemClone.HasAttribute(name) || (name.Equals("xmlns") && elemClone.NamespaceURI != String.Empty)) { continue; } XmlAttribute nsattrib = (XmlAttribute)elemClone.OwnerDocument.CreateAttribute(name); nsattrib.Value = attrib.Value; elemClone.SetAttributeNode(nsattrib); } } if (bDiscardComments) { // We should discard comments before going into the transform chain resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); XmlDocument docWithNoComments = CanonicalXml.DiscardComments(SignedXml.PreProcessElementInput(elemClone, resolver, strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(docWithNoComments, resolver, strBaseUri); } else { // This is an XPointer reference, do not discard comments!!! resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(SignedXml.PreProcessElementInput(elemClone, resolver, strBaseUri), resolver, strBaseUri); } } else { theRequest = WebRequest.Create(m_strUri); if (theRequest == null) { goto default; } theResponse = theRequest.GetResponse(); if (theResponse == null) { goto default; } inputStream = theResponse.GetResponseStream(); if (inputStream == null) { goto default; } resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), m_strUri)); hashInputStream = m_transformChain.TransformToOctetStream(inputStream, resolver, m_strUri); } break; case ReferenceTargetType.XmlElement: // We need to create a DocumentNavigator out of the XmlElement resolver = (m_signedXml.ResolverSet ? m_signedXml.m_xmlResolver : new XmlSecureResolver(new XmlUrlResolver(), strBaseUri)); hashInputStream = m_transformChain.TransformToOctetStream(SignedXml.PreProcessElementInput((XmlElement)m_refTarget, resolver, strBaseUri), resolver, strBaseUri); break; default: throw new CryptographicException(); } end: // Compute the new hash value byte[] hashval = m_hashAlgorithm.ComputeHash(hashInputStream); // Close the response to free resources, before returning if (theResponse != null) { theResponse.Close(); } if (inputStream != null) { inputStream.Close(); } return(hashval); }