Hess Yvan wrote:
First of all sorry for the delay answering this issue. I recommend you to open a bug report in bugzilla and attach a simple test case that show the error. This way we will not forgot about this problem in the future.Hi,
I am signing a XML document having external references. I created my own Resolver (extending ResourceResolverSpi) that returns a XMLSignatureInput object. My resolver works fine with version 1.1 but not with version 1.2. Here is the code...
Technically, I don't know if is a bug in the XML Signature or the implementation of reset() in BufferedInputStream class(which is the kind of InputStream you got you call getContent() in the unknown for me URIContent class).
In the 1.1 version of the library every inputstream was defensively copied to a ByteArrayInputStream this could be a big amount of memory and a very slow operation, so in the 1.2 we only do this if the InputStream does not support mark(i.e. markSupported() method returns false). If the InputStream supports mark the library just call reset(without previously call mark as we want to position again in the beginning of the Stream), everytime it finish with the InputStream.
Your problem can be happening by two different reasons:
1.- The BufferedInputStream does not support the call to reset without a mark.(Going against the spirit of the explanation in the JavaDoc of reset() in InputStream)
2.- The buffer saved by the BufferInputStream to reset has been overpass and cannot obtain again the lost bytes, and inidicate it with an error.
Anyway I think is better if the application knows what kind of cache it wants to have an create only XMLSignature with ByteArrayInputStreams or just plain bytes, but as we are publishing the API If I don't detected any way to fix this issue I will revert to the previous inefficient behavior.
Regards,
Raul http://r-bg.com
public XMLSignatureInput engineResolve(Attr uri, String baseURI) throws ResourceResolverException { String uriValue = uri.getValue(); XMLSignatureInput result = null;
try { URIContent content = this.resolve(uriValue, baseURI);
// TODO: FOR VERSION 1.2. May be it is a bug !!!
/* java.io.ByteArrayOutputStream bou = new java.io.ByteArrayOutputStream(); imtf.ch.atlas.core.io.Copier.copy(content.getInputStream(), bou); result = new XMLSignatureInput(bou.toByteArray()); */
// TODO: This is the correct code for VERSION 1.1 and should be the
same for VERSION 1.2 result = new XMLSignatureInput(content.getInputStream());
result.setSourceURI(uri.getNodeName());
result.setMIMEType(content.getContentType());
}
catch (Exception e)
{
throw new ResourceResolverException("Could not resolve uri [" + uri
+ "].", e, uri, baseURI);
}
return result; }
When I sign the document using version 1.1 it is ok, when I sign it with
version 1.2, I got the exception bellow. The inputstream given to the
XMLSignatureInput is a FileInputStream. For version 1.2, if I copy it into a
ByteArrayOutputStream it works (see comment code into my Resolver). Can you have a look and give me a feedback, I think it is a bug.
Regards. Yvan
-------- Exception at level 1 -------- Message: Unable to sign the XML document. Class: imtf.ch.atlas.sphinx2.SphinxException
-------- Exception at level 2 --------
Message: Resetting to invalid mark
Class: org.apache.xml.security.signature.XMLSignatureException
Stack trace: org.apache.xml.security.signature.XMLSignatureException: Resetting to
invalid mark
Original Exception was
org.apache.xml.security.signature.ReferenceNotInitializedException:
Resetting to invalid mark
Original Exception was java.io.IOException: Resetting to invalid mark
at org.apache.xml.security.signature.XMLSignature.sign(Unknown
Source)
at imtf.ch.atlas.sphinx2.xmlsig.Signer.sign(Signer.java:480)
at
test.imtf.ch.atlas.sphinx2.xml.XMLSignatureTest.testSignAndVerify_ExternalNo
tSignedCase1(XMLSignatureTest.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRu
nner.java:421)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.
java:305)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner
.java:186)
org.apache.xml.security.signature.ReferenceNotInitializedException:
Resetting to invalid mark
Original Exception was java.io.IOException: Resetting to invalid mark
at
org.apache.xml.security.signature.Reference.calculateDigest(Unknown Source)
at
org.apache.xml.security.signature.Reference.generateDigestValue(Unknown
Source)
at
org.apache.xml.security.signature.Manifest.generateDigestValues(Unknown
Source)
at org.apache.xml.security.signature.XMLSignature.sign(Unknown
Source)
at imtf.ch.atlas.sphinx2.xmlsig.Signer.sign(Signer.java:480)
at
test.imtf.ch.atlas.sphinx2.xml.XMLSignatureTest.testSignAndVerify_ExternalNo
tSignedCase1(XMLSignatureTest.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRu
nner.java:421)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.
java:305)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner
.java:186)
java.io.IOException: Resetting to invalid mark
at java.io.BufferedInputStream.reset(BufferedInputStream.java:370)
at
org.apache.xml.security.signature.XMLSignatureInput.updateOutputStream(Unkno
wn Source)
at
org.apache.xml.security.signature.Reference.calculateDigest(Unknown Source)
at
org.apache.xml.security.signature.Reference.generateDigestValue(Unknown
Source)
at
org.apache.xml.security.signature.Manifest.generateDigestValues(Unknown
Source)
at org.apache.xml.security.signature.XMLSignature.sign(Unknown
Source)
at imtf.ch.atlas.sphinx2.xmlsig.Signer.sign(Signer.java:480)
at
test.imtf.ch.atlas.sphinx2.xml.XMLSignatureTest.testSignAndVerify_ExternalNo
tSignedCase1(XMLSignatureTest.java:98)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39
)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl
.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRu
nner.java:421)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.
java:305)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner
.java:186)