FULL PRODUCT VERSION :
java version "1.8.0_73"
Java(TM) SE Runtime Environment (build 1.8.0_73-b02)
Java HotSpot(TM) Client VM (build 25.73-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Widnows 8.1 Enterprise
A DESCRIPTION OF THE PROBLEM :
We have received a sample XML signature that uses an XSL transformation on a reference element using the xsl:transform synonym element as defined by section 2.2 of https://www.w3.org/TR/1999/REC-xslt-19991116.html
It is my understanding that this is a valid representation of an XSLT.
When the signature is unmarshalled and then validated, the presence of xslt:transform instead of xslt:stylesheet causes the validation to throw a TransformException.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a digital signature with an XSLT transform with an xslt:transform element instead of xslt:stylesheet.
Validate the signature as usual, for example:
DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(), nl.item(0));
XMLSignatureFactory factory = XMLSignatureFactory.getInstance("DOM");
XMLSignature signature = factory.unmarshalXMLSignature(valContext);
boolean coreValidity = signature.validate(valContext);
I can provide XML samples upon request.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The transform should be performed regardless of whether the element name transform or stylesheet is used.
The actual validation of the element should be returned.
ACTUAL -
An exception is thrown.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.dsig.TransformException: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
Original Exception was com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at org.jcp.xml.dsig.internal.dom.DOMReference.transform(DOMReference.java:558)
at org.jcp.xml.dsig.internal.dom.DOMReference.validate(DOMReference.java:399)
at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.validate(DOMXMLSignature.java:278)
at XmlDsigValidation.main(XmlDsigValidation.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: javax.xml.crypto.dsig.TransformException: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
Original Exception was com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transformIt(ApacheTransform.java:210)
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transform(ApacheTransform.java:126)
at org.jcp.xml.dsig.internal.dom.DOMTransform.transform(DOMTransform.java:170)
at org.jcp.xml.dsig.internal.dom.DOMReference.transform(DOMReference.java:473)
... 8 more
Caused by: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
Original Exception was com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT.enginePerformTransform(TransformXSLT.java:156)
at com.sun.org.apache.xml.internal.security.transforms.Transform.performTransform(Transform.java:314)
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transformIt(ApacheTransform.java:197)
... 11 more
Caused by: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT.enginePerformTransform(TransformXSLT.java:91)
... 13 more
javax.xml.crypto.dsig.TransformException: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
Original Exception was com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transformIt(ApacheTransform.java:210)
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transform(ApacheTransform.java:126)
at org.jcp.xml.dsig.internal.dom.DOMTransform.transform(DOMTransform.java:170)
at org.jcp.xml.dsig.internal.dom.DOMReference.transform(DOMReference.java:473)
at org.jcp.xml.dsig.internal.dom.DOMReference.validate(DOMReference.java:399)
at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.validate(DOMXMLSignature.java:278)
at XmlDsigValidation.main(XmlDsigValidation.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
Original Exception was com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT.enginePerformTransform(TransformXSLT.java:156)
at com.sun.org.apache.xml.internal.security.transforms.Transform.performTransform(Transform.java:314)
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transformIt(ApacheTransform.java:197)
... 11 more
Caused by: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT.enginePerformTransform(TransformXSLT.java:91)
... 13 more
com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
Original Exception was com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT.enginePerformTransform(TransformXSLT.java:156)
at com.sun.org.apache.xml.internal.security.transforms.Transform.performTransform(Transform.java:314)
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transformIt(ApacheTransform.java:197)
at org.jcp.xml.dsig.internal.dom.ApacheTransform.transform(ApacheTransform.java:126)
at org.jcp.xml.dsig.internal.dom.DOMTransform.transform(DOMTransform.java:170)
at org.jcp.xml.dsig.internal.dom.DOMReference.transform(DOMReference.java:473)
at org.jcp.xml.dsig.internal.dom.DOMReference.validate(DOMReference.java:399)
at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.validate(DOMXMLSignature.java:278)
at XmlDsigValidation.main(XmlDsigValidation.java:81)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: com.sun.org.apache.xml.internal.security.transforms.TransformationException: Cannot find xslt:stylesheet in Transform
at com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT.enginePerformTransform(TransformXSLT.java:91)
... 13 more
REPRODUCIBILITY :
This bug can be reproduced always.
CUSTOMER SUBMITTED WORKAROUND :
Creating a separate implementation of com.sun.org.apache.xml.internal.security.transforms.implementations.TransformXSLT and replacing the lines
Element _xsltElement =
XMLUtils.selectNode(transformElement.getFirstChild(),
XSLTSpecNS,"stylesheet", 0);
if (_xsltElement == null) {
Object exArgs[] = { "xslt:stylesheet", "Transform" };
throw new TransformationException("xml.WrongContent", exArgs);
}
with
Element _xsltElement =
XMLUtils.selectNode(transformElement.getFirstChild(),
XSLTSpecNS,"stylesheet", 0);
if (_xsltElement == null) {
_xsltElement =
XMLUtils.selectNode(transformElement.getFirstChild(),
XSLTSpecNS,"transform", 0);
}
if (_xsltElement == null) {
Object exArgs[] = { "xslt:stylesheet", "Transform" };
throw new TransformationException("xml.WrongContent", exArgs);
}
and then injecting this implementation into the security framework through:
com.sun.org.apache.xml.internal.security.Init.init();
Field f = com.sun.org.apache.xml.internal.security.transforms.Transform.class.getDeclaredField("transformSpiHash");
f.setAccessible(true);
Map<String, Class<? extends TransformSpi>> transformSpiHash = (Map<String, Class<? extends TransformSpi>>) f.get(null);
transformSpiHash.remove("http://www.w3.org/TR/1999/REC-xslt-19991116");
com.sun.org.apache.xml.internal.security.transforms.Transform.register("http://www.w3.org/TR/1999/REC-xslt-19991116", CustomTransformXSLT.class);
results in signature validation proceeding (and in my case, passing).