{"record":{"id":"b91bc0f91e7f3225","repo":"dotnet/wpf","slug":"sr-unsupportedtransformalgorithm","errorCode":null,"errorMessage":"SR.UnsupportedTransformAlgorithm","messagePattern":"SR\\.UnsupportedTransformAlgorithm","errorType":"exception","errorClass":"XmlException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs","lineNumber":458,"sourceCode":"            {\n                transformStreams = new List<Stream>(transforms.Count);\n                transformStreams.Add(transformStream);\n                foreach (String transformName in transforms)\n                {\n                    // ignore empty strings at this point (as well as Relationship Transforms) - these are legal\n                    if ((transformName.Length == 0)\n                        || (string.Equals(transformName, XTable.Get(XTable.ID.RelationshipsTransformName), StringComparison.Ordinal)))\n                    {\n                        continue;\n                    }\n\n                    // convert the transform names into objects (if defined)\n                    Transform transform = StringToTransform(transformName);\n\n                    if (transform == null)\n                    {\n                        // throw XmlException so the outer loop knows the signature is invalid\n                        throw new XmlException(SR.UnsupportedTransformAlgorithm);\n                    }\n\n                    transformStream = TransformXml(transform, transformStream);\n                    transformStreams.Add(transformStream);\n                }\n            }\n\n            // hash it and encode to Base64\n            String hashValueString = System.Convert.ToBase64String(HashStream(hashAlgorithm, transformStream));\n\n            // dispose of any generated streams\n            if (transformStreams != null)\n            {\n                foreach (Stream stream in transformStreams)\n                    stream.Close();\n            }\n\n            return hashValueString;","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/XmlDigitalSignatureProcessor.cs#L440-L476","documentation":"GenerateDigestValue converts each ds:Transform name in a signature reference into a transform object; if StringToTransform returns null the algorithm name is not supported by the OPC/WPF XML digital signature implementation and an XmlException is thrown, marking the signature invalid.","triggerScenarios":"Verifying an OPC digital signature whose ds:Reference contains a ds:TransformAlgorithm attribute naming an algorithm outside those supported (e.g. XSLT, XPath, or newer canonicalization transforms not in the supported set).","commonSituations":"Signatures produced by other stacks (XAdES toolkits, Java/.NET Core signing tools, custom signing services) that apply transforms WPF's XmlDigitalSignatureProcessor doesn't recognize; verifying documents signed outside the OPC signing APIs.","solutions":["Re-sign the package using the supported transforms only (e.g. the OPC-required canonicalization transforms) via PackageDigitalSignatureManager.Sign.","Inspect the signature XML and remove/replace unsupported ds:Transform elements.","Verify signatures with a more complete XML-DSig implementation (System.Security.Cryptography.Xml directly, or a third-party library) instead of WPF's package signature verification.","If you control the signer, restrict transforms to the OPC-supported set."],"exampleFix":"// before: signer applies an unsupported transform\nref.AddTransform(new XmlDsigXPathTransform(xpath));\n// after: keep only supported transforms\nref.AddTransform(new XmlDsigC14NTransform());","handlingStrategy":"validation","validationCode":"var doc = XDocument.Load(signaturePartXml);\nvar supported = new[] { \"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\", \"http://www.w3.org/2001/10/xml-exc-c14n#\" };\nbool transformsOk = doc.Descendants(ds + \"Transform\")\n    .All(t => supported.Contains((string)t.Attribute(\"Algorithm\")));","typeGuard":null,"tryCatchPattern":"try { status = dsm.VerifySignatures(); }\ncatch (XmlException ex) when (ex.Message.Contains(\"transform\")) { /* signature uses unsupported transform - treat as invalid */ }","preventionTips":["Restrict signing to OPC-supported transforms (canonicalization only)","Pre-scan signature XML transform algorithms before verification","Use WPF's own PackageDigitalSignatureManager for signing"],"tags":["wpf","xml-dsig","signatures","packaging"],"backgroundTag":"unsupported-operation","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}