public virtual void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } ReferenceType = value.LocalName; string uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl); if (uri == null) { throw new ArgumentNullException(SR.Cryptography_Xml_UriRequired); } Uri = uri; // Transforms XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); XmlNode transformsNode = value.SelectSingleNode("ds:Transforms", nsm); if (transformsNode != null) { TransformChain.LoadXml(transformsNode as XmlElement); } // cache the Xml _cachedXml = value; }
public Reference(Stream stream) { _transformChain = new TransformChain(); _refTarget = stream; _refTargetType = ReferenceTargetType.Stream; _cachedXml = null; _digestMethod = DefaultDigestMethod; }
internal Reference(XmlElement element) { _transformChain = new TransformChain(); _refTarget = element; _refTargetType = ReferenceTargetType.XmlElement; _cachedXml = null; _digestMethod = DefaultDigestMethod; }
// // public constructors // public Reference() { _transformChain = new TransformChain(); _refTarget = null; _refTargetType = ReferenceTargetType.UriReference; _cachedXml = null; _digestMethod = DefaultDigestMethod; }
public void AddTransform(Transform transform) { if (transform == null) { throw new ArgumentNullException(nameof(transform)); } transform.Reference = this; TransformChain.Add(transform); }
internal XmlElement GetXml(XmlDocument document) { // Create the Reference XmlElement referenceElement = document.CreateElement("Reference", SignedXml.XmlDsigNamespaceUrl); if (!string.IsNullOrEmpty(_id)) { referenceElement.SetAttribute("Id", _id); } if (_uri != null) { referenceElement.SetAttribute("URI", _uri); } if (!string.IsNullOrEmpty(_type)) { referenceElement.SetAttribute("Type", _type); } // Add the transforms to the Reference if (TransformChain.Count != 0) { referenceElement.AppendChild(TransformChain.GetXml(document, SignedXml.XmlDsigNamespaceUrl)); } // Add the DigestMethod if (string.IsNullOrEmpty(_digestMethod)) { throw new CryptographicException(SR.Cryptography_Xml_DigestMethodRequired); } XmlElement digestMethodElement = document.CreateElement("DigestMethod", SignedXml.XmlDsigNamespaceUrl); digestMethodElement.SetAttribute("Algorithm", _digestMethod); referenceElement.AppendChild(digestMethodElement); if (DigestValue == null) { if (_hashAlgorithm.Hash == null) { throw new CryptographicException(SR.Cryptography_Xml_DigestValueRequired); } DigestValue = _hashAlgorithm.Hash; } XmlElement digestValueElement = document.CreateElement("DigestValue", SignedXml.XmlDsigNamespaceUrl); digestValueElement.AppendChild(document.CreateTextNode(Convert.ToBase64String(_digestValue))); referenceElement.AppendChild(digestValueElement); return(referenceElement); }
private bool ReferenceUsesSafeTransformMethods(Reference reference) { TransformChain transformChain = reference.TransformChain; int transformCount = transformChain.Count; for (int i = 0; i < transformCount; i++) { Transform transform = transformChain[i]; if (!IsSafeTransform(transform.Algorithm)) { return(false); } } return(true); }
internal XmlElement GetXml(XmlDocument document) { if (ReferenceType == null) { throw new CryptographicException(SR.Cryptography_Xml_ReferenceTypeRequired); } // Create the Reference XmlElement referenceElement = document.CreateElement(ReferenceType, EncryptedXml.XmlEncNamespaceUrl); if (!string.IsNullOrEmpty(_uri)) { referenceElement.SetAttribute("URI", _uri); } // Add the transforms to the CipherReference if (TransformChain.Count > 0) { referenceElement.AppendChild(TransformChain.GetXml(document, SignedXml.XmlDsigNamespaceUrl)); } return(referenceElement); }
public DataReference(string uri, TransformChain transformChain) : base(uri, transformChain) { ReferenceType = "DataReference"; }
// // private methods // private byte[] GetCipherValue(CipherData cipherData) { if (cipherData == null) { throw new ArgumentNullException(nameof(cipherData)); } 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; if (cipherData.CipherReference.Uri == null) { throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported); } // 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; if (tc == null) { throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported); } decInputStream = tc.TransformToOctetStream(_document, _xmlResolver, baseUri); } else if (cipherData.CipherReference.Uri[0] == '#') { string idref = Utils.ExtractIdFromLocalUri(cipherData.CipherReference.Uri); // Serialize XmlElement idElem = GetIdElement(_document, idref); if (idElem == null || idElem.OuterXml == null) { throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported); } inputStream = new MemoryStream(_encoding.GetBytes(idElem.OuterXml)); string baseUri = (_document == null ? null : _document.BaseURI); TransformChain tc = cipherData.CipherReference.TransformChain; if (tc == null) { throw new CryptographicException(SR.Cryptography_Xml_UriNotSupported); } decInputStream = tc.TransformToOctetStream(inputStream, _xmlResolver, baseUri); } else { throw new CryptographicException(SR.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 (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(SR.Cryptography_Xml_MissingCipherData); }
protected EncryptedReference(string uri, TransformChain transformChain) { TransformChain = transformChain; Uri = uri; _cachedXml = null; }
// 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); }
public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } _id = Utils.GetAttribute(value, "Id", SignedXml.XmlDsigNamespaceUrl); _uri = Utils.GetAttribute(value, "URI", SignedXml.XmlDsigNamespaceUrl); _type = Utils.GetAttribute(value, "Type", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(value, new string[] { "Id", "URI", "Type" })) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // Transforms bool hasTransforms = false; TransformChain = new TransformChain(); XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm); if (transformsNodes != null && transformsNodes.Count != 0) { if (transformsNodes.Count > 1) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } hasTransforms = true; XmlElement transformsElement = transformsNodes[0] as XmlElement; if (!Utils.VerifyAttributes(transformsElement, (string[])null)) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm); if (transformNodes != null) { if (transformNodes.Count != transformsElement.SelectNodes("*").Count) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } if (transformNodes.Count > Utils.MaxTransformsPerReference) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/Transforms"); } foreach (XmlNode transformNode in transformNodes) { XmlElement transformElement = transformNode as XmlElement; string algorithm = Utils.GetAttribute(transformElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if (algorithm == null || !Utils.VerifyAttributes(transformElement, "Algorithm")) { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } Transform transform = CryptoHelpers.CreateFromName <Transform>(algorithm); if (transform == null) { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } AddTransform(transform); // let the transform read the children of the transformElement for data transform.LoadInnerXml(transformElement.ChildNodes); // Hack! this is done to get around the lack of here() function support in XPath if (transform is XmlDsigEnvelopedSignatureTransform) { // Walk back to the Signature tag. Find the nearest signature ancestor // Signature-->SignedInfo-->Reference-->Transforms-->Transform XmlNode signatureTag = transformElement.SelectSingleNode("ancestor::ds:Signature[1]", nsm); XmlNodeList signatureList = transformElement.SelectNodes("//ds:Signature", nsm); if (signatureList != null) { int position = 0; foreach (XmlNode node in signatureList) { position++; if (node == signatureTag) { ((XmlDsigEnvelopedSignatureTransform)transform).SignaturePosition = position; break; } } } } } } } // DigestMethod XmlNodeList digestMethodNodes = value.SelectNodes("ds:DigestMethod", nsm); if (digestMethodNodes == null || digestMethodNodes.Count == 0 || digestMethodNodes.Count > 1) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod"); } XmlElement digestMethodElement = digestMethodNodes[0] as XmlElement; _digestMethod = Utils.GetAttribute(digestMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if (_digestMethod == null || !Utils.VerifyAttributes(digestMethodElement, "Algorithm")) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestMethod"); } // DigestValue XmlNodeList digestValueNodes = value.SelectNodes("ds:DigestValue", nsm); if (digestValueNodes == null || digestValueNodes.Count == 0 || digestValueNodes.Count > 1) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue"); } XmlElement digestValueElement = digestValueNodes[0] as XmlElement; _digestValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(digestValueElement.InnerText)); if (!Utils.VerifyAttributes(digestValueElement, (string[])null)) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference/DigestValue"); } // Verify that there aren't any extra nodes that aren't allowed int expectedChildNodeCount = hasTransforms ? 3 : 2; if (value.SelectNodes("*").Count != expectedChildNodeCount) { throw new CryptographicException(SR.Cryptography_Xml_InvalidElement, "Reference"); } // cache the Xml _cachedXml = value; }
public CipherReference(string uri, TransformChain transformChain) : base(uri, transformChain) { ReferenceType = "CipherReference"; }