Apache CXF - Configure WSS4JInInterceptor

Viewed 7223

I'm using Apache CXF + WS-Security in my project when connecting to the server.

When server's response is received I must validate the signature of SignatureConfirmation, Timestamp, SOAP-body with server's public key, which is included as BinarySecurityToken in SOAP header. After that I need to decrypt the symmetrical key with my own certificate's private key and eventually decrypt the SOAP body.

Here is the diagram with the request-flow:

enter image description here

How should I configure my WSS4JInInterceptor to do that? Here is what I have now:

// for outgoing messages: Signature and Timestamp validation
        outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.TIMESTAMP);
        outProps.put(WSHandlerConstants.USER, "sss");
        outProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientKeystorePasswordCallbackHandler.class.getName());
        outProps.put(WSHandlerConstants.SIG_PROP_FILE, "client_sec.properties");
        outProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
        outProps.put(WSHandlerConstants.SIGNATURE_PARTS, "{}{http://www.w3.org/2003/05/soap-envelope}Body;{}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;{}{http://kontaktinfo.difi.no/wsdl/oppslagstjeneste-16-02}Oppslagstjenesten}");
        outProps.put(WSHandlerConstants.SIG_ALGO, "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
        outProps.put(WSHandlerConstants.SIG_DIGEST_ALGO, "http://www.w3.org/2001/04/xmlenc#sha256");


        // for incoming messages: Signature and Timestamp validation. Response is Encrypted
        inProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE + " " + WSHandlerConstants.TIMESTAMP + " " + WSHandlerConstants.ENCRYPT);
        inProps.put(WSHandlerConstants.SIG_KEY_ID, "DirectReference");
        inProps.put(WSHandlerConstants.PW_CALLBACK_CLASS, ClientKeystorePasswordCallbackHandler.class.getName());
        inProps.put(WSHandlerConstants.SIG_PROP_FILE, "server_sec.properties");
        inProps.put(WSHandlerConstants.DEC_PROP_FILE, "client_sec.properties");

        wss4JInInterceptor = new WSS4JInInterceptor(inProps);
        wss4JOutInterceptor = new WSS4JOutInterceptor(outProps);

server_sec.properties

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=jks
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.keystore.alias=test
org.apache.ws.security.crypto.merlin.file=certs/server.jks

client_sec.properties:

org.apache.ws.security.crypto.provider=org.apache.ws.security.components.crypto.Merlin
org.apache.ws.security.crypto.merlin.keystore.type=PKCS12
org.apache.ws.security.crypto.merlin.keystore.password=changeit
org.apache.ws.security.crypto.merlin.keystore.alias=sss
org.apache.ws.security.crypto.merlin.file=certs/sss_client.p12

After I receive the response I get the error:

SEVERE: Servlet.service() for servlet [rest] in context with path [] threw exception [Request processing failed; nested exception is javax.xml.ws.soap.SOAPFaultException: Error during certificate path validation: No trusted certs found] with root cause
org.apache.wss4j.common.ext.WSSecurityException: Error during certificate path validation: No trusted certs found
    at org.apache.wss4j.common.crypto.Merlin.verifyTrust(Merlin.java:780)
    at org.apache.wss4j.dom.validate.SignatureTrustValidator.verifyTrustInCerts(SignatureTrustValidator.java:108)
    at org.apache.wss4j.dom.validate.SignatureTrustValidator.validate(SignatureTrustValidator.java:64)
    at org.apache.wss4j.dom.processor.SignatureProcessor.handleToken(SignatureProcessor.java:189)
    at org.apache.wss4j.dom.engine.WSSecurityEngine.processSecurityHeader(WSSecurityEngine.java:344)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessageInternal(WSS4JInInterceptor.java:280)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:184)
    at org.apache.cxf.ws.security.wss4j.WSS4JInInterceptor.handleMessage(WSS4JInInterceptor.java:93)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:798)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1670)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1551)
    at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1348)
    at org.apache.cxf.io.CacheAndWriteOutputStream.postClose(CacheAndWriteOutputStream.java:56)
    at org.apache.cxf.io.CachedOutputStream.close(CachedOutputStream.java:216)
    at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
    at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:651)
    at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
    at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:514)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:423)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:324)
    at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:277)
    at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:139)
    at com.sun.proxy.$Proxy74.getPeople(Unknown Source)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

The first problem I see is CXF expects server certificate to be a keystone file, but I have it as Binary Security Token included in the response. Extracting it into a file is not an option, of course.

How should I configure my InInterceptor so it can verify and decrypt server's response?

UPDATE 1:

  • root CA certificate is added to JRE/lib/security/cacerts

  • Intermediate certificate is in the keystore used by the in-interceptor

Here is the server response I'm trying to verify and decrypt:

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
   <env:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" env:mustUnderstand="true">
         <xenc:EncryptedKey xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="EK-66D388AF0DD8D8AE061458643455700833237">
            <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" />
            <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
               <wsse:SecurityTokenReference>
                  <ds:X509Data>
                     <ds:X509IssuerSerial>
                        <ds:X509IssuerName>CN=Buypass Class 3 Test4 CA 3,O=Buypass AS-983163327,C=NO</ds:X509IssuerName>
                        <ds:X509SerialNumber>1111111111111111111</ds:X509SerialNumber>
                     </ds:X509IssuerSerial>
                  </ds:X509Data>
               </wsse:SecurityTokenReference>
            </ds:KeyInfo>
            <xenc:CipherData>
               <xenc:CipherValue>VSZMFYsHgVWPhhhBjcmITh2ElsViaRhmyVcLlyC9/iAh/gpIT1mhqocYRr3uDUZUVjNZba8wfRbVYTPAz/Kxix7faZ8+F23ANyhhKmrwxgn2SJdOVjYRYiVZZ/lgufYO4jFDnbkDjHeNxY6FZ/nxdB25OX18v5sWPkXtJQLKm3wQS6gQ8xc7K48lnIZDiKDGs0AyY4wCQ8rd0sI/odFma9h7661rs9Ei0WtzWU8reuhd/YGcaShY7qNnG/EguItnd4H4uEpgH09tCCge3R3vIw7LYK+qa5n97UVKe6ZZcRENZgyDR0PYx7bA+wcmGbHgZUivbc3FhJGwvXjGUu+3Xw==</xenc:CipherValue>
            </xenc:CipherData>
            <xenc:ReferenceList>
               <xenc:DataReference URI="#ED-66D388AF0DD8D8AE061458643455700833238" />
            </xenc:ReferenceList>
         </xenc:EncryptedKey>
         <wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="X509-66D388AF0DD8D8AE061458643455693833232">MIIFDzCCA/egAwIBAgILCDNWTvJPbvLPzFQwDQYJKoZIhvcNAQELBQAwSzELMAu390STHWF1hjeDUZ8ep4u3cO0bwKHsdkrp/JIWQ6q8PpIJHcCDrz/tIKn2JLpxbQe9AR6KWDDzgfyRxoCyulOcnXoVH+CeSfieQ3WapR5VymxpPDA+jC6fccPfBDpKrOso4WpFFvwJbyEhxDAgJAXzwx1R3CrTFAfku8cck0h3v5E4</wsse:BinarySecurityToken>
         <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="SIG-66D388AF0DD8D8AE061458643455696833236">
            <ds:SignedInfo>
               <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
               <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
               <ds:Reference URI="#TS-66D388AF0DD8D8AE061458643455693833231">
                  <ds:Transforms>
                     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                  </ds:Transforms>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                  <ds:DigestValue>vUNvEQQFUqrUScQTwDrfVl+SEd/T5f/8RegkbE/Hcig=</ds:DigestValue>
               </ds:Reference>
               <ds:Reference URI="#id-66D388AF0DD8D8AE061458643455693833235">
                  <ds:Transforms>
                     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                  </ds:Transforms>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                  <ds:DigestValue>dv6BjR/TX8x1eYnlLyHCZQCQcdpOQ8o8CDE5mmCEYCw=</ds:DigestValue>
               </ds:Reference>
               <ds:Reference URI="#SC-66D388AF0DD8D8AE061458643455693833230">
                  <ds:Transforms>
                     <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                  </ds:Transforms>
                  <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                  <ds:DigestValue>+F0GP7N7OlRpKR1yMRHn7F8ZYhCoPqDeDvjNMiQ5bHU=</ds:DigestValue>
               </ds:Reference>
            </ds:SignedInfo>
            <ds:SignatureValue>EAclVc0VHMFZtPFGCzwGrvMhp4W4Rmzf2Jke0oZeRcVKNpx88FSCfiCaEx5EaSs8zisbm8dQ7tDSWGnOWgVw1i6S0BXrq5g7Vn2+YZxmKJdJVxwtFAvCl9mXWF7gSgPVX8OYPmSFQ7I9cGaUr8/Sh5o3qClmNez/H4jOSgGXx6zXHqqG3FSkgaXaf0dfY6CgybTff2WG5dfnIdP4tfvllbNfzJa6Lgx8gsGZfG6J1c71mhBSo4ogejW64D0yjWBSGIdsrnAvgZZpXUs3ecR1za+GGUb9UhKLYoaiZZ1XO5fwOZM9TwXkmOwIG8mLbiXMnbsVmC5lyI5ARyZzrDRTmg==</ds:SignatureValue>
            <ds:KeyInfo Id="KI-66D388AF0DD8D8AE061458643455693833233">
               <wsse:SecurityTokenReference wsu:Id="STR-66D388AF0DD8D8AE061458643455693833234">
                  <wsse:Reference URI="#X509-66D388AF0DD8D8AE061458643455693833232" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" />
               </wsse:SecurityTokenReference>
            </ds:KeyInfo>
         </ds:Signature>
         <wsu:Timestamp wsu:Id="TS-66D388AF0DD8D8AE061458643455693833231">
            <wsu:Created>2016-03-22T10:44:15.693Z</wsu:Created>
            <wsu:Expires>2016-03-22T10:45:15.693Z</wsu:Expires>
         </wsu:Timestamp>
         <wsse11:SignatureConfirmation xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" Value="1uzncWE+stuYWDjMt6dPyFpt1UAiyFjvWlA/sSV+2y2dqJ+GmE9/izZqgZ07Nhz1+TFnjX8h/ZvjbSpZEk9H280zJXYP8mVk87rz5qOD8ivt2T1m4zOIMNIvtvCwAGSN+ozTA7HWuzRELbMjiHbFwsLsBXtmmO0hngytyMyFvcnxThKcfb2wAsyhW6pnVX9Fu9OHKLIoktdYKX5ofXWxu8aH6OjfnbexKIa6URATpQIuLjPmQFh6t9YZcBnpHJuKcydIZBQGKEd9h41crVDrVQJ1YEGGmX4XKhLaEOFx/i+kMMjFfrowzodLxMx0vKW73vvhydv3BIWyWROo6X4JDg==" wsu:Id="SC-66D388AF0DD8D8AE061458643455693833230" />
      </wsse:Security>
   </env:Header>
   <env:Body xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="id-66D388AF0DD8D8AE061458643455693833235">
      <xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="ED-66D388AF0DD8D8AE061458643455700833238" Type="http://www.w3.org/2001/04/xmlenc#Content">
         <xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc" />
         <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
            <wsse:SecurityTokenReference xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsse11="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" wsse11:TokenType="http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey">
               <wsse:Reference URI="#EK-66D388AF0DD8D8AE061458643455700833237" />
            </wsse:SecurityTokenReference>
         </ds:KeyInfo>
         <xenc:CipherData>
            <xenc:CipherValue>Zl4kpoGYlFRXJ453SZIHxR4VVdzMCfnfTQogResKRu1PO8vHt6Azkc3/q0R0duPdUuttwQDGOUls+jw==</xenc:CipherValue>
         </xenc:CipherData>
      </xenc:EncryptedData>
   </env:Body>
</env:Envelope>
0 Answers
Related