Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-4451

Provide helpful error message if encryption keystore password missing

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 2.6.1, 2.7
    • 3.0.0-milestone2
    • WS-* Components
    • None
    • Unknown

    Description

      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.

      Attachments

        Activity

          People

            coheigea Colm O hEigeartaigh
            gmazza Glen Mazza
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: