Uploaded image for project: 'WSS4J'
  1. WSS4J
  2. WSS-588

Server-side signature validation on client fail with only certificate CA is in the client truststore

    XMLWordPrintableJSON

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Major
    • Resolution: Not A Problem
    • Affects Version/s: 2.0.4
    • Fix Version/s: None
    • Component/s: WSS4J Core
    • Labels:
    • Environment:
      Servicemix server using cxf+wss4j for WS-Security purpose
    • Flags:
      Important

      Description

      I have a webservices which is secured by WS-Security+Policy.
      I currently use Signature only for server response.
      However I keep having the same error on client side:

      Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: The signature or decryption was invalid
      	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:160)
      	at com.sun.proxy.$Proxy34.submit(Unknown Source)
      	at client.OffresEmploiClientUserToken.doCall(OffresEmploiClientUserToken.java:93)
      	at client.OffresEmploiClientUserToken.main(OffresEmploiClientUserToken.java:63)
      	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:606)
      	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
      Caused by: org.apache.wss4j.common.ext.WSSecurityException: The signature or decryption was invalid
      	at org.apache.wss4j.dom.processor.SignatureProcessor.handleToken(SignatureProcessor.java:194)
      	at org.apache.wss4j.dom.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:428)
      	at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:278)
      	at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:190)
      	at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:129)
      	at org.apache.cxf.ws.security.wss4j.PolicyBasedWSS4JInInterceptor.handleMessage(PolicyBasedWSS4JInInterceptor.java:112)
      	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
      	at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:802)
      	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1645)
      	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1533)
      	at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1336)
      	at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
      	at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:215)
      	at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
      	at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:652)
      	at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
      	at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
      	at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:516)
      	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:425)
      	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:326)
      	at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:279)
      	at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
      	at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:138)
      	... 8 more
      

      My client truststore is set so that I only have the signer CA.
      I have noticed that if I set the signer certificate in the client truststore, it works !
      I did a wireshark snoop and found that in the response part coming from the server:

      <ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>1.2.840.113549.1.9.1=#16107465737473736c40666f72656d2e6265,CN=XXXXX</ds:X509IssuerName><ds:X509SerialNumber>12428414237952637822</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data>
      

      The problem is that 12428414237952637822 isn't the CA(issuer) serial number but the signer serial number !
      I have digged a little bit into the code I have found something that looks weird to me in the WSSecSignature class :

      case WSConstants.ISSUER_SERIAL:
                      String issuer = certs[0].getIssuerX500Principal().getName();
                      java.math.BigInteger serialNumber = certs[0].getSerialNumber();
      

      i'm wondering why in the last line we don't take the issuer serial number ???? ->

       java.math.BigInteger serialNumber = certs[0].getIssuerX500Principal().getSerialNumber();

      I can't see how this can work since the client compare the serial number provided with the serial number of the CA in the Merlin class:

      if (x509cert.getSerialNumber().compareTo(serialNumber) == 0)
      

      Hope I was clear enough.
      I have checked in the latest version of the WSSecSignature and I still see the same line...
      Best Regards,
      Claude

        Attachments

          Activity

            People

            • Assignee:
              coheigea Colm O hEigeartaigh
              Reporter:
              clibois Libois Claude
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: