Hi,

without knowing CFXY and how it works I know a bit of WSS4J and
the security behind the OASIS specs.

as for point 1:
If WSS4J does not find the specified element it reports an error.
This is by desing. What else should it do? Silently ignoring this
could mean that a possible typo in the deployment is not detected
and some data goes unencrypted over the wire.

as for point 2:
If the security header contains an encryption key then WSS4j also
throws an error. A missing key could mean that someone tampered
with the security header or it was a problem during transmission.

Anyhow: performing "optional" encryption depending on existent or
missing data is a security problem. Either all mecessary information
is available for encryption/decryption or nothing will happen at all.

Regards,
Werner

Am 26.01.2010 19:46, schrieb Siarhei Kaneuski:
> Hi everyone,
> 
> I'm working on implementation of CXF service managing user profiles (which 
> may contain sensitive data - credit card number, ID number). There are some 
> profiles containing the sensitive data, and some which don't. Even more, the 
> service can work in mode when no sensitive data will be sent to consumer. 
> Naturally, I'd like to make encryption/decryption optional:
> 
> *         Do not encrypt anything if nothing from encryptionParts is found 
> (on service)
> 
> *         Do not decrypt anything if no encryption key found in WS-Security 
> header (on client)
> 
> 
> 1.       Do not encrypt anything if nothing from encryptionParts is found.
> When my endpoint is configured in the following way, and I don't put real 
> value to element from encryptionParts, out processing fails:
>   <bean id="serviceOutSecurityInterceptor" class="com 
> org.apache.cxf.ws.security.wss4j.WSS4JOutInterceptor">
>     <constructor-arg>
>       <map>
>         <entry key="action" value="Encrypt" />
>         <entry key="encryptionPropFile" value="serviceKeystore.properties" />
>         <entry key="encryptionParts" 
> value="{Element}{http://test.com/sample/service}text"; />
>         <entry key="encryptionUser" value="myClientKey" />
>        </map>
>      </constructor-arg>
>    </bean>
> 
> Caused by: org.apache.ws.security.WSSecurityException: General security error 
> (WSEncryptBody/WSSignEnvelope: Element to encrypt/sign not found: 
> {http://test.com/sample/service}text)
>         at 
> org.apache.ws.security.message.WSSecEncrypt.doEncryption(WSSecEncrypt.java:505)
>         at 
> org.apache.ws.security.message.WSSecEncrypt.doEncryption(WSSecEncrypt.java:459)
>         at 
> org.apache.ws.security.message.WSSecEncrypt.encryptForInternalRef(WSSecEncrypt.java:348)
>         at 
> org.apache.ws.security.message.WSSecEncrypt.build(WSSecEncrypt.java:309)
>         at 
> org.apache.ws.security.action.EncryptionAction.execute(EncryptionAction.java:62)
>         ... 10 more
> 
> As I see from code, there is no good way to configure WSS4J to ignore missing 
> encryption parts (at least, in WSS4J 1.5.8 which I use). Is that by design? 
> Do you have any suggestions how to handle such situations? I have workaround 
> for it - when service actually has something to encrypt, it puts a encryption 
> part to ThreadLocal, and then my interceptor overriding WSS4JOutInterceptor 
> decides add Encrypt action or not (see attachment). Looks awkward.
> 
> 
> 2.       Do not decrypt anything if no encryption key found in WS-Security 
> header. Client can get response with encrypted parts, but also can get plain 
> message w/o WS-Security header.
>   <bean id="clientInSecurityInterceptor" 
> class="org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor">
>     <constructor-arg>
>       <map>
>         <entry key="action" value="Encrypt" />
>         <entry key="passwordCallbackRef">
>           <ref bean="clientCallback" />
>         </entry>
>         <entry key="decryptionPropFile" value="clientKeystore.properties" />
>       </map>
>     </constructor-arg>
>   </bean>
> 
> Fails:
> org.apache.ws.security.WSSecurityException: An error was discovered 
> processing the <wsse:Security> header
>         at 
> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:219)
>         at 
> org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:77)
>         at 
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:236)
>         at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:658)
>         at 
> org.apache.cxf.transport.local.LocalDestination$SynchronousConduit$1$1.run(LocalDestination.java:97)
>         at java.lang.Thread.run(Thread.java:619)
> 
> Do I understand correctly the behavior is not configurable? WSS4J just looks 
> for security header and fails when nothing found. To workaround that, I had 
> to override WSS4JInInterceptor, and enable Encrypt action (which actually 
> decrypts) when WS-Security header found. Again, it's weird - see attachment 
> (I like most the part accessing SOAPMessage - instantiating SAAJInInterceptor 
> because of lack of access to private method in WSS4JInInterceptor).
> 
> I'd appreciate if anybody commented: was the behavior described above 
> designed in that way? Are there any good way to implement/workaround that? If 
> not, any suggestions on code attached?
> 
> Thanks,
> Siarhei
> 
> 
> 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to