public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException("value"); } // SignedInfo XmlElement signedInfoElement = value; if (!signedInfoElement.LocalName.Equals("SignedInfo")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); int expectedChildNodes = 0; // Id attribute -- optional m_id = Utils.GetAttribute(signedInfoElement, "Id", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(signedInfoElement, "Id")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo"); } // CanonicalizationMethod -- must be present XmlNodeList canonicalizationMethodNodes = signedInfoElement.SelectNodes("ds:CanonicalizationMethod", nsm); if (canonicalizationMethodNodes == null || canonicalizationMethodNodes.Count == 0 || (!Utils.GetAllowAdditionalSignatureNodes() && canonicalizationMethodNodes.Count > 1)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/CanonicalizationMethod"); } XmlElement canonicalizationMethodElement = canonicalizationMethodNodes.Item(0) as XmlElement; expectedChildNodes += canonicalizationMethodNodes.Count; m_canonicalizationMethod = Utils.GetAttribute(canonicalizationMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if ((m_canonicalizationMethod == null && !Utils.GetSkipSignatureAttributeEnforcement()) || !Utils.VerifyAttributes(canonicalizationMethodElement, "Algorithm")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/CanonicalizationMethod"); } m_canonicalizationMethodTransform = null; if (canonicalizationMethodElement.ChildNodes.Count > 0) { this.CanonicalizationMethodObject.LoadInnerXml(canonicalizationMethodElement.ChildNodes); } // SignatureMethod -- must be present XmlNodeList signatureMethodNodes = signedInfoElement.SelectNodes("ds:SignatureMethod", nsm); if (signatureMethodNodes == null || signatureMethodNodes.Count == 0 || (!Utils.GetAllowAdditionalSignatureNodes() && signatureMethodNodes.Count > 1)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/SignatureMethod"); } XmlElement signatureMethodElement = signatureMethodNodes.Item(0) as XmlElement; expectedChildNodes += signatureMethodNodes.Count; m_signatureMethod = Utils.GetAttribute(signatureMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if ((m_signatureMethod == null && !Utils.GetSkipSignatureAttributeEnforcement()) || !Utils.VerifyAttributes(signatureMethodElement, "Algorithm")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/SignatureMethod"); } // Now get the output length if we are using a MAC algorithm XmlElement signatureLengthElement = signatureMethodElement.SelectSingleNode("ds:HMACOutputLength", nsm) as XmlElement; if (signatureLengthElement != null) { m_signatureLength = signatureLengthElement.InnerXml; } // flush out any reference that was there m_references.Clear(); // Reference - 0 or more XmlNodeList referenceNodes = signedInfoElement.SelectNodes("ds:Reference", nsm); if (referenceNodes != null) { if (referenceNodes.Count > Utils.GetMaxReferencesPerSignedInfo()) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo/Reference"); } foreach (XmlNode node in referenceNodes) { XmlElement referenceElement = node as XmlElement; Reference reference = new Reference(); AddReference(reference); reference.LoadXml(referenceElement); } expectedChildNodes += referenceNodes.Count; } // Verify that there aren't any extra nodes that aren't allowed if (!Utils.GetAllowAdditionalSignatureNodes() && (signedInfoElement.SelectNodes("*").Count != expectedChildNodes)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo"); } // Save away the cached value m_cachedXml = signedInfoElement; }
public void LoadXml(XmlElement value) { // Make sure we don't get passed null if (value == null) { throw new ArgumentNullException("value"); } // Signature XmlElement signatureElement = value; if (!signatureElement.LocalName.Equals("Signature")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Signature"); } // Attributes m_id = Utils.GetAttribute(signatureElement, "Id", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(signatureElement, "Id")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Signature"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); int expectedChildNodes = 0; // SignedInfo XmlNodeList signedInfoNodes = signatureElement.SelectNodes("ds:SignedInfo", nsm); if (signedInfoNodes == null || signedInfoNodes.Count == 0 || (!Utils.GetAllowAdditionalSignatureNodes() && signedInfoNodes.Count > 1)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignedInfo"); } XmlElement signedInfoElement = signedInfoNodes[0] as XmlElement; expectedChildNodes += signedInfoNodes.Count; this.SignedInfo = new SignedInfo(); this.SignedInfo.LoadXml(signedInfoElement); // SignatureValue XmlNodeList signatureValueNodes = signatureElement.SelectNodes("ds:SignatureValue", nsm); if (signatureValueNodes == null || signatureValueNodes.Count == 0 || (!Utils.GetAllowAdditionalSignatureNodes() && signatureValueNodes.Count > 1)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignatureValue"); } XmlElement signatureValueElement = signatureValueNodes[0] as XmlElement; expectedChildNodes += signatureValueNodes.Count; m_signatureValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(signatureValueElement.InnerText)); m_signatureValueId = Utils.GetAttribute(signatureValueElement, "Id", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(signatureValueElement, "Id")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "SignatureValue"); } // KeyInfo - optional single element XmlNodeList keyInfoNodes = signatureElement.SelectNodes("ds:KeyInfo", nsm); m_keyInfo = new KeyInfo(); if (keyInfoNodes != null) { if (!Utils.GetAllowAdditionalSignatureNodes() && keyInfoNodes.Count > 1) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "KeyInfo"); } foreach (XmlNode node in keyInfoNodes) { XmlElement keyInfoElement = node as XmlElement; if (keyInfoElement != null) { m_keyInfo.LoadXml(keyInfoElement); } } expectedChildNodes += keyInfoNodes.Count; } // Object - zero or more elements allowed XmlNodeList objectNodes = signatureElement.SelectNodes("ds:Object", nsm); m_embeddedObjects.Clear(); if (objectNodes != null) { foreach (XmlNode node in objectNodes) { XmlElement objectElement = node as XmlElement; if (objectElement != null) { DataObject dataObj = new DataObject(); dataObj.LoadXml(objectElement); m_embeddedObjects.Add(dataObj); } } expectedChildNodes += objectNodes.Count; } // Select all elements that have Id attributes XmlNodeList nodeList = signatureElement.SelectNodes("//*[@Id]", nsm); if (nodeList != null) { foreach (XmlNode node in nodeList) { m_referencedItems.Add(node); } } // Verify that there aren't any extra nodes that aren't allowed if (!Utils.GetAllowAdditionalSignatureNodes() && (signatureElement.SelectNodes("*").Count != expectedChildNodes)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Signature"); } }
public void LoadXml(XmlElement value) { if (value == null) { throw new ArgumentNullException("value"); } m_id = Utils.GetAttribute(value, "Id", SignedXml.XmlDsigNamespaceUrl); m_uri = Utils.GetAttribute(value, "URI", SignedXml.XmlDsigNamespaceUrl); m_type = Utils.GetAttribute(value, "Type", SignedXml.XmlDsigNamespaceUrl); if (!Utils.VerifyAttributes(value, new string[] { "Id", "URI", "Type" })) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference"); } XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable); nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl); // Transforms bool hasTransforms = false; this.TransformChain = new TransformChain(); XmlNodeList transformsNodes = value.SelectNodes("ds:Transforms", nsm); if (transformsNodes != null && transformsNodes.Count != 0) { if (!Utils.GetAllowAdditionalSignatureNodes() && transformsNodes.Count > 1) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/Transforms"); } hasTransforms = true; XmlElement transformsElement = transformsNodes[0] as XmlElement; if (!Utils.VerifyAttributes(transformsElement, (string[])null)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/Transforms"); } XmlNodeList transformNodes = transformsElement.SelectNodes("ds:Transform", nsm); if (transformNodes != null) { if (!Utils.GetAllowAdditionalSignatureNodes() && (transformNodes.Count != transformsElement.SelectNodes("*").Count)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/Transforms"); } if (transformNodes.Count > Utils.GetMaxTransformsPerReference()) { throw new CryptographicException(SecurityResources.GetResourceString("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.GetSkipSignatureAttributeEnforcement()) || !Utils.VerifyAttributes(transformElement, "Algorithm")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_UnknownTransform")); } Transform transform = Utils.CreateFromName <Transform>(algorithm); if (transform == null) { throw new CryptographicException(SecurityResources.GetResourceString("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 || (!Utils.GetAllowAdditionalSignatureNodes() && digestMethodNodes.Count > 1)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/DigestMethod"); } XmlElement digestMethodElement = digestMethodNodes[0] as XmlElement; m_digestMethod = Utils.GetAttribute(digestMethodElement, "Algorithm", SignedXml.XmlDsigNamespaceUrl); if ((m_digestMethod == null && !Utils.GetSkipSignatureAttributeEnforcement()) || !Utils.VerifyAttributes(digestMethodElement, "Algorithm")) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/DigestMethod"); } // DigestValue XmlNodeList digestValueNodes = value.SelectNodes("ds:DigestValue", nsm); if (digestValueNodes == null || digestValueNodes.Count == 0 || (!Utils.GetAllowAdditionalSignatureNodes() && digestValueNodes.Count > 1)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/DigestValue"); } XmlElement digestValueElement = digestValueNodes[0] as XmlElement; m_digestValue = Convert.FromBase64String(Utils.DiscardWhiteSpaces(digestValueElement.InnerText)); if (!Utils.VerifyAttributes(digestValueElement, (string[])null)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference/DigestValue"); } // Verify that there aren't any extra nodes that aren't allowed int expectedChildNodeCount = hasTransforms ? 3 : 2; if (!Utils.GetAllowAdditionalSignatureNodes() && (value.SelectNodes("*").Count != expectedChildNodeCount)) { throw new CryptographicException(SecurityResources.GetResourceString("Cryptography_Xml_InvalidElement"), "Reference"); } // cache the Xml m_cachedXml = value; }