[ 
https://issues.apache.org/jira/browse/CXF-4451?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Colm O hEigeartaigh resolved CXF-4451.
--------------------------------------

       Resolution: Fixed
    Fix Version/s: 3.0.0-milestone2
         Assignee: Colm O hEigeartaigh


This is working correctly on CXF trunk at the moment.

Colm.

> Provide helpful error message if encryption keystore password missing
> ---------------------------------------------------------------------
>
>                 Key: CXF-4451
>                 URL: https://issues.apache.org/jira/browse/CXF-4451
>             Project: CXF
>          Issue Type: Improvement
>          Components: WS-* Components
>    Affects Versions: 2.6.1, 2.7.0
>            Reporter: Glen Mazza
>            Assignee: Colm O hEigeartaigh
>            Priority: Minor
>             Fix For: 3.0.0-milestone2
>
>
> Given a WS-Security configuration like here: http://tinyurl.com/bv2qpe4 
> except using different properties files for encryption and signature.  If I 
> fail to provide the keystore password for the signature properties file 
> (http://tinyurl.com/cxdjngu) the CXF exception helpfully tells me there's a 
> credential/password problem:
> Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: class 
> org.apache.ws.security.components.crypto.Merlin cannot create instance
>     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
>     at $Proxy25.doubleIt(Unknown Source)
>     at client.WSClient.doubleIt(WSClient.java:27)
>     at client.WSClient.main(WSClient.java:21)
> Caused by: org.apache.ws.security.WSSecurityException: class 
> org.apache.ws.security.components.crypto.Merlin cannot create instance
>     at 
> org.apache.ws.security.components.crypto.CryptoFactory.loadClass(CryptoFactory.java:224)
>     at 
> org.apache.ws.security.components.crypto.CryptoFactory.getInstance(CryptoFactory.java:117)
>     at 
> org.apache.ws.security.components.crypto.CryptoFactory.getInstance(CryptoFactory.java:78)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getCrypto(AbstractBindingBuilder.java:1530)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getSignatureCrypto(AbstractBindingBuilder.java:1437)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.getSignatureBuilder(AbstractBindingBuilder.java:1774)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignature(AsymmetricBindingHandler.java:540)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignBeforeEncrypt(AsymmetricBindingHandler.java:146)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.handleBinding(AsymmetricBindingHandler.java:97)
>     at 
> org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:165)
>     at 
> org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:89)
>     at 
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
>     at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
>     at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
>     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
>     ... 3 more
> Caused by: java.lang.reflect.InvocationTargetException
>     at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
>     at 
> sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
>     at 
> sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
>     at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
>     at 
> org.apache.ws.security.components.crypto.CryptoFactory.loadClass(CryptoFactory.java:219)
>     ... 20 more
> Caused by: org.apache.ws.security.components.crypto.CredentialException: 
> Failed to load credentials.
>     at org.apache.ws.security.components.crypto.Merlin.load(Merlin.java:371)
>     at 
> org.apache.ws.security.components.crypto.Merlin.loadProperties(Merlin.java:190)
>     at org.apache.ws.security.components.crypto.Merlin.<init>(Merlin.java:140)
>     ... 25 more
> Caused by: java.io.IOException: Keystore was tampered with, or password was 
> incorrect
>     at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:772)
>     at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:55)
>     at java.security.KeyStore.load(KeyStore.java:1214)
>     at org.apache.ws.security.components.crypto.Merlin.load(Merlin.java:365)
>     ... 27 more
> Caused by: java.security.UnrecoverableKeyException: Password verification 
> failed
>     at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:770)
>     ... 30 more
> But when I fail to provide the keystore password for the *encryption* 
> properties file, it just tells me it couldn't create a Crypto object:
> org.apache.cxf.interceptor.Fault: class 
> org.apache.ws.security.components.crypto.Merlin cannot create instance
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignBeforeEncrypt(AsymmetricBindingHandler.java:194)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.handleBinding(AsymmetricBindingHandler.java:97)
>     at 
> org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:165)
>     at 
> org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:89)
>     at 
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
>     at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
>     at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
>     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
>     at $Proxy25.doubleIt(Unknown Source)
>     at client.WSClient.doubleIt(WSClient.java:27)
>     at client.WSClient.main(WSClient.java:21)
> Caused by: org.apache.cxf.ws.policy.PolicyException: class 
> org.apache.ws.security.components.crypto.Merlin cannot create instance
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.policyNotAsserted(AbstractBindingBuilder.java:307)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doEncryption(AsymmetricBindingHandler.java:435)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignBeforeEncrypt(AsymmetricBindingHandler.java:189)
>     ... 13 more
> Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: class 
> org.apache.ws.security.components.crypto.Merlin cannot create instance
>     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
>     at $Proxy25.doubleIt(Unknown Source)
>     at client.WSClient.doubleIt(WSClient.java:27)
>     at client.WSClient.main(WSClient.java:21)
> Caused by: org.apache.cxf.ws.policy.PolicyException: class 
> org.apache.ws.security.components.crypto.Merlin cannot create instance
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AbstractBindingBuilder.policyNotAsserted(AbstractBindingBuilder.java:307)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doEncryption(AsymmetricBindingHandler.java:435)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.doSignBeforeEncrypt(AsymmetricBindingHandler.java:189)
>     at 
> org.apache.cxf.ws.security.wss4j.policyhandlers.AsymmetricBindingHandler.handleBinding(AsymmetricBindingHandler.java:97)
>     at 
> org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:165)
>     at 
> org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JOutInterceptor$PolicyBasedWSS4JOutInterceptorInternal.handleMessage(PolicyBasedWSS4JOutInterceptor.java:89)
>     at 
> org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:262)
>     at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:532)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:464)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:367)
>     at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:320)
>     at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:89)
>     at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:134)
> I debugged it and the exception handling for encryption and signatures is 
> different.  For both signature and encryption, the problem is trapped in 
> Merlin.load(InputStream input, String storepass, String provider, String 
> type)--line 368, which throws a CredentialException.  For signature, 
> CryptoFactory.loadClass() throws a WSSecurityException instead, and from 
> that, AsymmetricBindingHandler.doSignBeforeEncrypt()'s exception handler does 
> "throw new Fault(e)", allowing the CredentialException to be shown to the 
> user.  But for encryption, it is handled in method PolicyNotAsserted (line 
> 292 of AbstractBindingBuilder, called from 
> AsymmetricBindingHandler.doEncryption(), line 441), causing the 
> CredentialException to be lost.
> As an added bonus, if the "failed credentials" message could be given more 
> succinctly than a long error trace that would be good but that can be looked 
> at a later date.
> The source code linked to above and described in this blog: 
> http://www.jroller.com/gmazza/entry/cxf_x509_profile_secpol can be used as a 
> test case, just create a separate properties file for the encryption keystore 
> with a missing keystore password.



--
This message was sent by Atlassian JIRA
(v6.1.5#6160)

Reply via email to