{"record":{"id":"ff791709da3bf2db","repo":"dotnet/wpf","slug":"sr-xmlsignatureparseerror","errorCode":null,"errorMessage":"SR.XmlSignatureParseError","messagePattern":"SR\\.XmlSignatureParseError","errorType":"exception","errorClass":"XmlException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs","lineNumber":979,"sourceCode":"        /// <summary>\n        /// Full parse of the Package-specific Object tag\n        /// </summary>\n        /// <remarks>Side effect of updating _signingTime, _signingTimeFormat, \n        /// _partManifest, _partEntryManifest and _relationshipManifest</remarks>\n        /// <exception cref=\"XmlException\">throws if markup does not match OPC spec</exception>\n        private void ParsePackageDataObject()\n        {\n            if (!_dataObjectParsed)\n            {\n                EnsureXmlSignatureParsed();\n\n                // find the package-specific Object tag\n                XmlNodeList nodeList = GetPackageDataObject().Data;\n\n                // The legal parent is a \"Package\" Object tag with 2 children\n                // <Manifest> and <SignatureProperties>\n                if (nodeList.Count != 2)\n                    throw new XmlException(SR.XmlSignatureParseError);\n\n                // get a NodeReader that allows us to easily and correctly skip comments\n                XmlReader reader = new XmlNodeReader(nodeList[0].ParentNode);\n\n                // parse the <Object> tag - ensure that it is in the correct namespace\n                reader.Read();  // enter the Object tag\n                if (!string.Equals(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl, StringComparison.Ordinal))\n                    throw new XmlException(SR.XmlSignatureParseError);\n\n                string signaturePropertiesTagName = XTable.Get(XTable.ID.SignaturePropertiesTagName);\n                string manifestTagName = XTable.Get(XTable.ID.ManifestTagName);\n                bool signaturePropertiesTagFound = false;\n                bool manifestTagFound = false;\n                while (reader.Read() && (reader.NodeType == XmlNodeType.Element))\n                {\n                    if (reader.MoveToContent() == XmlNodeType.Element\n                        && (string.Equals(reader.NamespaceURI, SignedXml.XmlDsigNamespaceUrl, StringComparison.Ordinal))\n                        && reader.Depth == 1)","sourceCodeStart":961,"sourceCodeEnd":997,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs#L961-L997","documentation":"ParsePackageDataObject parses the OPC-specific <Object> element of an XML digital signature. The WPF packaging code requires that the package <Object> tag contain exactly two children: a <Manifest> and <SignatureProperties>. If the child node count is anything other than 2, the signature XML is considered structurally invalid and an XmlException(SR.XmlSignatureParseError) is thrown.","triggerScenarios":"Calling PackageDigitalSignatureManager.Verify, VerifySignatures, or any accessor (SigningTime, TimeFormat, PartManifest, RelationshipManifest) on a PackageSignature whose embedded <Object> element has children other than exactly one <Manifest> plus one <SignatureProperties> — e.g. comments processed as nodes, extra elements, or a missing child.","commonSituations":"Hand-editing or post-processing the signature XML with a tool that rewrites/normalizes the Object element; signatures produced by non-.NET OPC signers that emit extra property elements inside the package Object; XML documents mangled by template or encoding round-trips.","solutions":["Re-sign the package with PackageDigitalSignatureManager.Sign so a conformant package Object element is generated.","Compare the <Object> element of the failing signature against one produced by Sign; remove or merge extra children so exactly <Manifest> and <SignatureProperties> remain.","If signatures come from a third-party signer, ensure it follows the OPC digital-signature profile (Object with exactly two children).","Load the package from a known-good copy or from source control instead of the corrupted one."],"exampleFix":"// before: signature Object rewritten by an external tool\n<Object Id=\"idPackageObject\">...\n  <extra:Property/> <!-- third child → throws -->\n</Object>\n// after: re-sign in C#\nusing (Package pkg = Package.Open(path, FileMode.Open, FileAccess.ReadWrite))\n{\n    var dsm = new PackageDigitalSignatureManager(pkg);\n    dsm.Sign(toSign, cert);\n}","handlingStrategy":"validation","validationCode":"// Pre-check the signature XML's package Object child count\nvar doc = new XmlDocument(); doc.Load(signaturePartStream);\nvar obj = doc.GetElementById(\"idPackageObject\") ??\n          doc.SelectSingleNode(\"//*[local-name()='Object' and @Id='idPackageObject']\");\nbool valid = obj != null &&\n             obj.ChildNodes.Cast<XmlNode>().Count(n => n.NodeType == XmlNodeType.Element) == 2;","typeGuard":"static bool HasExactlyTwoElementChildren(XmlElement obj) =>\n    obj != null && obj.ChildNodes.Cast<XmlNode>().Count(n => n.NodeType == XmlNodeType.Element) == 2;","tryCatchPattern":"try { var manifest = signature.PartManifest; }\ncatch (XmlException ex) { /* log malformed signature; treat package as untrusted */ }","preventionTips":["Never hand-edit or post-process signature XML with tools that alter the Object element.","Re-sign rather than repair when a signature's structure is in doubt.","Validate third-party signers against the OPC digital-signature profile.","Keep original packages under version control for recovery."],"tags":["wpf","xml-signature","packaging","opc"],"backgroundTag":"schema-validation-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}