5 Replies Latest reply on Oct 24, 2008 5:10 PM by yhrn

    Full control of client and server certificates with a JBossW

    yhrn

      Hi,
      I want to invoke a web service over https with client certificate authentication. The problem is that I need to control exactly which client certificate/key is used and what server certificates to trust per invocation. All examples i can find involves setting global properties and that is not good enough for me.

      My application is an EJB3 application running in in JBoss AS 4.2.2 with JBossWS as JAX-WS provider. In JAX-WS 2.1 RI there is a simple way of doing what I want by setting a passing a SSLSocketFactory in the RequestContext of the SEI proxy (see my example below).

      package org.acme.ejb3;
      
      import java.net.Socket;
      import java.security.Principal;
      import java.security.PrivateKey;
      import java.security.SecureRandom;
      import java.security.cert.CertificateException;
      import java.security.cert.X509Certificate;
      import java.util.Map;
      
      import javax.ejb.Remote;
      import javax.ejb.Stateless;import javax.net.ssl.KeyManager;
      import javax.net.ssl.SSLContext;
      import javax.net.ssl.TrustManager;
      import javax.net.ssl.X509KeyManager;
      import javax.net.ssl.X509TrustManager;
      import javax.xml.ws.BindingProvider;
      import javax.xml.ws.WebServiceRef;
      
      @Stateless
      @Remote(MyTestClient.class)
      public class MyTestClientBean implements MyTestClient {
      
       @WebServiceRef(SomeWebService.class)
       private SomeWebServicePortType sei;
      
      
       @Override
       public String saySometing(String message, String endpointAddress,
       X509Certificate[] clientCertChain, PrivateKey clientKey,
       X509Certificate trustedCaCert) throws Exception {
      
       Map<String, Object> reqCtx = ((BindingProvider)sei).getRequestContext();
      
       // Standard JAX-WS method to set the endpoint address.
       reqCtx.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointAddress);
      
       // My custom key manager
       KeyManager[] keyMgrs = { new MyClientKeyManager(clientCertChain, clientKey) };
       // My custom trust manager
       TrustManager[] trustMgrs = { new MyClientTrustManager(trustedCaCert) };
      
       // Get an SSL context and initialize it with my custom key and trust managers.
       SSLContext sslCtx = SSLContext.getInstance("TLS");
       sslCtx.init(keyMgrs, trustMgrs, SecureRandom.getInstance("SHA1PRNG"));
      
       // Use the JAX-WS 2.1 RI specific property to ensure that
       // my custom managers are used.
       reqCtx.put(com.sun.xml.ws.developer.JAXWSProperties.SSL_SOCKET_FACTORY,
       sslCtx.getSocketFactory());
      
       // Finally invoke the web service.
       return sei.saySometing(message);
       }
      }
      
      class MyClientKeyManager implements X509KeyManager {
       private X509Certificate[] clientCertChain;
       private PrivateKey clientKey;
      
       public MyClientKeyManager(X509Certificate[] clientCertChain,
       PrivateKey clientKey) {
       this.clientCertChain = clientCertChain;
       this.clientKey = clientKey;
       }
      
       // Here comes my custom KeyManager implementation
      }
      
      class MyClientTrustManager implements X509TrustManager {
      
       private X509Certificate trustedCaCertificate;
      
       public MyClientTrustManager(X509Certificate trustedCaCertificate) {
       this.trustedCaCertificate = trustedCaCertificate;
       }
      
       // Here comes my custom TrustManager implementation
      }
      


      Is there any way of doing something similar in JBossWS?

        • 1. Re: Full control of client and server certificates with a JB
          yhrn

          Sorry about the title. It should, of course, be "Full control of client and server certificates with JBossWS". I can't edit the post but if a moderator sees this I'd appreciate if it was corrected

          • 2. Re: Full control of client and server certificates with a JB

            Hello,

            I have exactly the same requirements... did you make it working ?

            Cheers

            Vincent

            • 3. Re: Full control of client and server certificates with a JB
              yhrn

              Hi Vincent,
              No, I haven't solved this yet. I was working on some other stuff hoping that I'd get a hint from the forum. But soon I have to come up with a solution so I guess the only thing left to do is to get down and dirty with the JBossWS source code...

              I think the documentation on JBossWS client configuration (both for the stub objects and for standard-jaxws-client-config.xml) is very poor so I put another forum post for this (http://www.jboss.com/index.html?module=bb&op=viewtopic&t=128758) but that didn't do much good either.

              When I solve this I'll share it here and if you beat me to it I'd appreciate if you did the same.

              Cheers,
              Mattias

              • 4. Re: Full control of client and server certificates with a JB
                jeckles933

                Trying to do the same thing. I can't understand what other people are doing to get around this problem. We have multiple keystores, so i have to override the default behavior for the SSLContext...
                This is what i need to do, but i can't figure out how/when to call this to set the socket factory.



                KeyStore ts = KeyStore.getInstance("JKS");
                 ts.load(new FileInputStream(trustStoreFullName), trustStorePassword.toCharArray());
                 TrustManager[] tm;
                 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
                 tmf.init(ts);
                 tm = tmf.getTrustManagers();
                
                 SSLContext sslContext = SSLContext.getInstance("SSL");
                 sslContext.init(kmf.getKeyManagers(), tm, null);
                
                 SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
                
                 HttpsURLConnection urlc = (HttpsURLConnection) url.openConnection();
                 urlc.setSSLSocketFactory(sslSocketFactory);
                


                • 5. Re: Full control of client and server certificates with a JB
                  yhrn

                  Hi,
                  When I posted this JBossWS did not yet support multiple JAX-WS implementations. When this feature came I solved the problem by switching to the Metro flavor of JBossWS instead and then implement it as described in the initial post of this thread.

                  This of course resulted in a set of other problems (which I can't even remember now) but I think they were all caused by bugs in an immature feature and are probably solved by now...