[SWS-378] Wss4jSecurityInterceptor.toDocument(..) causes decryption to fail when using SaajSoapMessageFactory Created: 17/Jun/08  Updated: 21/Jul/08  Resolved: 18/Jun/08

Status: Closed
Project: Spring Web Services
Component/s: Security
Affects Version/s: 1.5.2
Fix Version/s: 1.5.3

Type: Bug Priority: Major
Reporter: Paul Dotsenko Assignee: Arjen Poutsma
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

jdk1.5.0_15, Tomcat 6.0.14, Spring-WS 1.5.2, SaajSoapMessageFactory, message encryption/decryption using Wss4j


Attachments: Text File SWS-378-patch.txt    
Issue Links:
Related
is related to SWS-376 SaajSoapMessage.setSaajMessage() and ... Closed

 Description   

Wss4jSecurityInterceptor.toDocument(..) contains a bug that prevents Wss4jSecurityInterceptor.validateMessage() from replacing encrypted SOAP message parts with decrypted parts when using SaajSoapMessageFactory. Specifically, when the org.w3c.dom.Document returned by toDocument() is modified with decrypted parts, the changes aren't reflected in the original SaajSoapMessage inside MessageContext.

Test case to reproduce the bug uses ws-tutorial sample application.
1. Modify HolidayRequestClient constructor to get wsTemplate bean from Application Context configured inside SpringConfig.xml:
/**

  • Default class constructor
    */
    public HolidayRequestClient() {
    hrNs = Namespace.getNamespace("hr", "http://mycompany.com/hr/schemas");
    fmt = new SimpleDateFormat("yyyy-MM-dd");
    ApplicationContext ac = null;

try
{
ac = new ClassPathXmlApplicationContext(
new String[]

{ "SpringConfig.xml" }

);
}
catch (BeansException e)

{ e.printStackTrace(); ac = new FileSystemXmlApplicationContext("SpringConfig.xml"); }

wsTemplate = (WebServiceTemplate) ac
.getBean("wsTemplate");

}

2. Use the following client SpringConfig.xml to encrypt outgoing HolidayRequest element content using wss4j:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

<bean id="wsTemplate"
class="org.springframework.ws.client.core.WebServiceTemplate">
<constructor-arg>
<bean class="org.springframework.ws.soap.saaj.SaajSoapMessageFactory"/>
</constructor-arg>
<property name="interceptors">
<list>
<ref local="wsEncryptSecurityInterceptor" />
</list>
</property>
</bean>

<bean id="wsEncryptSecurityInterceptor"
class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="securementActions" value="Encrypt" />

<property name="securementEncryptionParts"
value="

{Content}{http://mycompany.com/hr/schemas}HolidayRequest"/>

<property name="securementEncryptionUser" value="alias" />
<property name="securementEncryptionCrypto">
<bean
class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
<property name="keyStorePassword" value="storepass" />
<property name="keyStoreLocation" value="classpath:/clientKeystore.jks" />
</bean>
</property>
</bean>

</beans>

3. Configure server security interceptor bean wsEncryptSecurityInterceptor inside spring-ws-servlet.xml for decrypting HollidayRequest element content:
...
<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootQNameEndpointMapping">
<property name="mappings">
<props>
<prop key="{http://mycompany.com/hr/schemas}HolidayRequest">holidayEndpoint</prop>
</props>
</property>
<property name="interceptors">
<list>
<ref local="wsEncryptSecurityInterceptor"/>
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
</list>
</property>
</bean>

<bean id="wsEncryptSecurityInterceptor"
class="org.springframework.ws.soap.security.wss4j.Wss4jSecurityInterceptor">
<property name="validationActions" value="Encrypt" />
<property name="securementEncryptionParts"
value="{Content} {http://mycompany.com/hr/schemas}

HolidayRequest" />
<property name="validationDecryptionCrypto">
<bean
class="org.springframework.ws.soap.security.wss4j.support.CryptoFactoryBean">
<property name="keyStorePassword" value="storepass" />
<property name="keyStoreLocation"
value="classpath:/serverKeystore.jks" />
</bean>
</property>
<property name="validationCallbackHandler">
<bean
class="org.springframework.ws.soap.security.wss4j.callback.KeyStoreCallbackHandler">
<property name="privateKeyPassword" value="keypass" />
</bean>
</property>
</bean>
...

4. Generate server and client keystore files using these commands and place the generated files on the classpath:
create server keystore:
keytool -v -genkey -alias alias -keypass keypass -keystore serverKeystore.jks -storepass storepass -keyalg RSA -sigalg SHA1withRSA
export PEM file for client keystore:
keytool -export -alias alias -file alias.pem -sigalg SHA1withRSA -keystore serverKeystore.jks -storepass storepass -rfc
import PEM into client store:
keytool -v -import -trustcacerts -alias alias -file alias.pem -keystore clientKeystore.jks -keypass storepass -noprompt

5. Run com.mycompany.hr.client.Main as Java Application, and see SoapFault response as logged by the client since the server was unable to decrypt the encrypted parts:

2008-06-17 11:36:55,625 DEBUG [org.springframework.ws.client.core.WebServiceTemplate] - Received Fault message for request [SaajSoapMessage

{http://mycompany.com/hr/schemas}

HolidayRequest]
Exception in thread "main" org.springframework.ws.soap.client.SoapFaultClientException: Unparseable date: ""
at org.springframework.ws.soap.client.core.SoapFaultMessageResolver.resolveFault(SoapFaultMessageResolver.java:37)
at org.springframework.ws.client.core.WebServiceTemplate.handleFault(WebServiceTemplate.java:699)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:527)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:465)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:420)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:366)
at org.springframework.ws.client.core.WebServiceTemplate.sendSourceAndReceiveToResult(WebServiceTemplate.java:351)
at com.mycompany.hr.client.HolidayRequestClient.bookHoliday(HolidayRequestClient.java:63)
at com.mycompany.hr.client.Main.main(Main.java:18)

------------------------------
Proposed fix is to modify Wss4jSecurityInterceptor.toDocument(..) as follows, essentially rolling back an earlier fix for SWS-345:

/** Converts the given

{@link SoapMessage}

into a

{@link Document}

. */
private Document toDocument(SoapMessage soapMessage, MessageContext messageContext) {
if (soapMessage instanceof SaajSoapMessage)

{ SaajSoapMessage saajSoapMessage = (SaajSoapMessage) soapMessage; return saajSoapMessage.getSaajMessage().getSOAPPart();// works now since SWS-345 is fixed }

else if (soapMessage instanceof AxiomSoapMessage)

{ AxiomSoapMessage axiomMessage = (AxiomSoapMessage) soapMessage; return AxiomUtils.toDocument(axiomMessage.getAxiomMessage().getSOAPEnvelope()); }

else

{ throw new IllegalArgumentException("Message type not supported [" + soapMessage + "]"); }

}



 Comments   
Comment by Paul Dotsenko [ 17/Jun/08 ]

This is a patch file I created for the proposed fix for this bug.

Comment by Tareq Abedrabbo [ 17/Jun/08 ]

Thanks for the detailed description Paul.
Regarding the proposed fix, I'm afraid it's not the best way to do it since it will break the signature generation. What should be done probably is to replace the Saaj message as it is done for Axiom messages.

Comment by Paul Dotsenko [ 18/Jun/08 ]

Tareq,

Thanks for pointing this out. Looks like Arjen's fixes for SWS-376 also fixed the problem that this issue was supposed to fix! After I saw your comment I got latest SaajMessageFactory from trunk and ran the test case I described in this issue, and decryption worked. So like you suggested this is fixed in the Saaj message now.

Comment by Arjen Poutsma [ 18/Jun/08 ]

Ok, so this issue can be resolved?

Comment by Paul Dotsenko [ 18/Jun/08 ]

Yes, I would call this issue resolved by fixes for SWS-376. Thanks.

Comment by Arjen Poutsma [ 21/Jul/08 ]

Closing issues in 1.5.3

Generated at Tue Dec 12 02:34:23 UTC 2017 using JIRA 6.4.14#64029-sha1:ae256fe0fbb912241490ff1cecfb323ea0905ca5.