axis-java-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Stuart Jensen" <>
Subject Re: AXIS altering XML causing signatures to not validate.
Date Tue, 02 Nov 2004 22:16:56 GMT
I have looked into this problem a little more now and I wanted to give an update.
The bottom line is that I can work around the problem when I am the sender of the XML message.
I do not know, yet, how to work around the problem when I am the receiver of an XML message.
The fix for the problem is to remove lines 210-212 of the file  This removes
the "optimization" that causes the problem.
I have included a discussion of what happens on both the sending and receiving sides to duplicate
this bug.  I believe that this is a serious bug; however, I keep going back to the fact that
someone went to great lengths to make the code "optimize" xml during serialization.  Is there
anyone out there who could comment on why that was done and if  signed XML was considered
during the design/coding process?
These following discussions all assume you are sending/receiving an XML message with the format
described at the bottom of this email.
*-------- Overview of the issue for an XML Sender:  *----------
-- Create a SOAPBodyElement containing the XML.
* Pass that SOAPBodyElement to Call.invoke().
* The Call.invoke() call will eventually create a SOAPPart class that has a currentMessage.
 Since the parameters it receives are SOAPBodyElement objects is creates a SOAPEnvelope message
and sets the "type" of the message to "FORM_SOAPENVELOPE."
* If no other handlers are called, then will be called to output the message
to the server and the XML will NOT be altered. 
* The problem arises when you have a handler, like WSS4J, which executes between the initial
creation of the SOAPPart message and the sending of the XML by What happened
in our case was this:
WSS4J did the following...
     Document doc = SOAPPart.getEnvelope().getAsDocument();
WSS4J applied signatures to this doc. And then replaced the currentMessage with the new signed
     XMLUtils.outputToDOM(doc, outputStream)
     byte[] arBytes = outputStream.toByteArray()
     SOAPPart.setCurrentMessage(arBytes, SOAPPart.FORM_BYTES);
The fact that the new message is in BYTE format is significant because it means that any subsequent
call to SOAPPart.getAsSoapEnvelope() will cause the format to be converted from FORM_BYTES
to FORM_SOAPENVELOPE <-  and that process involves serializing the raw XML into SOAP objects.
Of course, whenever the SerializationContext class is used, the XML namespace prefixes may
be lost, so the resulting XML may be different from what you signed.
It just so happened that we DID HAVE a subsequent handler that caused a call to SOAPPart.getAsSoapEnvelope()
AND we had XML in the format described below SO we saw the bug.
So I can fix it on the sending side by
    1) Reformatting our XML to avoid the problem,
    2) Making sure no subsequent handler calls SOAPPart.getAsSoapEnvelope(). (The Axis api
should be robust enough that this is not a requirement.)
*-------- Overview of the issue for an XML Receiver:  *---------- is initially called with an HTTPServletRequest.  This request eventually
gets down into AxisServer.invoke().  A SOAPPart is built for the XML and a currentMessage
is created of type FORM_INPUTSTREAM where the HTTPServletRequest inputStream is the source.
 But then, in AxisServer.invoke(), an explicit call to msgContext.getRequestMessage().getSOAPEnvelope()
causes SOAPPart.getAsSoapEmvelope() to be called, which detects that the currentMessage type
is NOT FORM_SOAPENVELOPE, so it uses the SerializationContext to convert the XML from the
InputStream to SOAP objects.  Of course, this is the same code with the same bug, and it results
in the same problem.
All of this happens long before the first handler is called.
I have no idea about how to get around this problem when I am the receiver of XML.  I have
no control over the XML that other people will send me (so they could send it in such a way
that this bug shows up), and it appears that I have no control over how Axis serializes XML
from raw bytes to SOAP objects which my Axis operation handlers consume.

>>> 11/02/04 1:44 AM >>>

Samuel Meder wrote:

>On Wed, 2004-10-27 at 11:53 -0600, Stuart Jensen wrote:
>>I was referring to the same document, but a section talking about
>>namespace prefixes. All I was trying to say was that namespace
>>prefixes are deemed an important "signable" thing in the signature.
>>They are not something that can be altered (after signing) with the
>>hopes that  C14N will "clean it all up" at validation time.
>Ok, I misunderstood the problem. In any case shouldn't this only be a
>problem when writing a intermediary that actually
>deserializes/serializes the body and does not reuse the original body?
>Otherwise it would seem to me that if you build the dom tree used for
>canonicalization the same way axis does serialization there should be no
>problem. What is it that I am still missing?
I think the point here goes back to the example Stuart supplied a few 
emails back, copied below. If this is accurate then there's just no way 
*to* reuse the original body with Axis - it actually restructures XML 
when serializing it in a way that's incompatible with C14N. That means 
you could never safely use Axis as an intermediary in a transaction 
using signatures.

  - Dennis

Stuart's example:
If you create a SOAPBodyElement with the following XML:

<soapenv:Body wsu:id="id-23412344" 
<somepfx:SomeTag id="e0sdoaeckrpd"  xmlns="ns:uri:one" 

and then pass that SOAPBodyElement to the Call.invoke(Object[]) method 
as a member of the Object[] parameter.  Then the XML that is sent by 
AXIS is the following:

<soapenv:Body wsu:id="id-23412344" 
<SomeTag id="e0sdoaeckrpd" xmlns="ns:uri:one" 

Note that the only difference is that the namespace prefix "somepfx" has 
been removed from the tag "SomeTag".

View raw message