3 Replies Latest reply on Nov 14, 2008 12:45 AM by ron_sigal

    https invoke with Remoting

    carl-johan.persson

      Hi,
      Trying to invoke service from Java swing app over https and client certificate is not sent to server.
      Tested scenarios using SSLSocket and HttpsURLConnection.
      SSLSocket works and HttpsURLConnection does not.

      This code using SSLSocket to access the service works, it does not use any JbossRemoting:

       SSLSocket socket = null;
       KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
       ks.load(new FileInputStream("C:/k.jks"), "123456".toCharArray());
       KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
       kmf.init(ks, "123456".toCharArray());
       KeyStore ksT = KeyStore.getInstance(KeyStore.getDefaultType());
       ksT.load(new FileInputStream("C:/Program/Java/jdk1.6.0_06/jre/lib/security/cacerts"), "changeit".toCharArray());
       TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
       tmf.init(ksT);
       SSLContext sc = SSLContext.getInstance("TLS");
       sc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
       socket = (SSLSocket)sc.getSocketFactory().createSocket(TARGET_HTTPS_SERVER, TARGET_HTTPS_PORT);
       String message = "<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Head...</env:Envelope>";
       Writer out = new OutputStreamWriter(socket.getOutputStream(), "ISO-8859-1");
       out.write("POST /KService HTTP/1.1\r\n");
       out.write("SOAPAction: \"\"\r\n");
       out.write("Content-Type: text/xml; charset=UTF-8\r\n");
       out.write("Host: " + TARGET_HTTPS_SERVER + ":" +TARGET_HTTPS_PORT + "\r\n");
       out.write("Agent: SSL-TEST\r\n");
       out.write("Accept: text/xml\r\n");
       out.write("\r\n");
       out.write(message + "\r\n");
       out.flush();
       BufferedReader in = new BufferedReader(
       new InputStreamReader(socket.getInputStream(), "ISO-8859-1"));
       String line = null;
       while ((line = in.readLine()) != null)
       {
       System.out.println(line);
       }
      

      Trace with -Djavax.net.debug=SSL gived Serverhello TLS and client certificate is sent to server (alias is the correct cert):
      main, READ: TLSv1 Handshake, length = 112
      *** CertificateRequest
      Cert Types: RSA, DSS, ECDSA
      Cert Authorities:
      <CN=K Root CA, DC=knet, DC=local>
      *** ServerHelloDone
      matching alias: {b1c7bcaa-7fe4-4ee7-95f7-cc71b211d38c}
      


      This sample using HttpsURLConnection does not send the client certificate to server, does not use any JbossRemoting:
       System.setProperty("javax.net.ssl.keyStore", "C:/k.jks");
       System.setProperty("javax.net.ssl.trustStore", "C:/Program/Java/jdk1.6.0_06/jre/lib/security/cacerts");
       System.setProperty("javax.net.ssl.keyStorePassword", "123456");
       System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
       System.setProperty("javax.net.ssl.keyStoreType", "jks");
       System.setProperty("javax.net.ssl.trustStoreType", "jks");
       String host = "https://test.k.se/KService";
       String keyStorePath = "C:/k.jks";
       String trustStorePath = "C:/Program/Java/jdk1.6.0_06/jre/lib/security/cacerts";
       String password = "123456";
       KeyStore ks = KeyStore.getInstance("JKS");
       FileInputStream keyStoreInput = new FileInputStream(keyStorePath);
       try {
       ks.load(keyStoreInput, password.toCharArray());
       } finally { keyStoreInput.close(); }
       KeyStore ts = KeyStore.getInstance("JKS");
       FileInputStream trustStoreInput = new FileInputStream(trustStorePath);
       try {
       ts.load(trustStoreInput, "changeit".toCharArray());
       } finally { trustStoreInput.close(); }
       TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
       KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
       trustManagerFactory.init(ts);
       keyManagerFactory.init(ks,password.toCharArray());
       SSLContext sslContext = SSLContext.getInstance("TLS");
       sslContext.init(keyManagerFactory.getKeyManagers(),
       trustManagerFactory.getTrustManagers(), null);
       SSLContext.setDefault(sslContext); HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
       HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
       public boolean verify(String arg0, SSLSession arg1) {
       return true;
       }
       });
       java.net.URL url= new java.net.URL(host);
       javax.net.ssl.HttpsURLConnection connection = (javax.net.ssl.HttpsURLConnection)url.openConnection(); org.jboss.invocation.http.interfaces.Util.configureSSLSocketFactory(connection);
       String message = "<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Head...</env:Envelope>";
       connection.setDoOutput(true);
       connection.setDoInput(true);
       connection.setRequestMethod("POST");
       connection.setRequestProperty("SOAPAction", "");
       connection.setRequestProperty("Content-Type","text/xml");
       connection.connect();
       OutputStream outputStream = connection.getOutputStream();
       outputStream.write(message.getBytes());
       BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
       int c;
       while ((c = in.read()) != -1) {
       System.out.write(c);
       }
       in.close();
      


      And when trying to acces server service with SOAP proxy and JbossRemoting client certificate is not sent to server, this use JbossWS and JbossRemoting:
       System.setProperty("org.jboss.wsse.keyStore", "C:/k.jks");
       System.setProperty("org.jboss.wsse.keyStorePassword", "123456");
       System.setProperty("org.jboss.wsse.keyStoreType", "x509v3");
       System.setProperty("org.jboss.wsse.trustStore","C:/Program/Java/jdk1.6.0_06/jre/lib/security/cacerts");
       System.setProperty("org.jboss.wsse.trustStorePassword", "changeit");
       System.setProperty("org.jboss.wsse.trustStoreType", "x509v3");
       System.setProperty("org.jboss.ws.wsse.keyStoreType", "jks");
       System.setProperty("org.jboss.ws.wsse.trustStoreType", "jks");
      
       System.setProperty("javax.net.ssl.keyStore", "C:/k.jks");
       System.setProperty("javax.net.ssl.trustStore", "C:/Program/Java/jdk1.6.0_06/jre/lib/security/cacerts");
       System.setProperty("javax.net.ssl.keyStorePassword", "123456");
       System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
       System.setProperty("javax.net.ssl.keyStoreType", "jks");
       System.setProperty("javax.net.ssl.trustStoreType", "jks");
       String wsdlURLFileName = Resources.getProperty("wsdlURL");
       URL wsdlURL = Resources.findFileAsURL(wsdlURLFileName);
       String namespaceURI = Resources.getProperty("namespaceURI");
       String localpart = Resources.getProperty("localpart");
       service = new KService(wsdlURL, new QName(namespaceURI, localpart));
       port = service.getKPort();
      ((StubExt)port).setConfigName("Standard WSSecurity Client");
       Map<String, Object> reqContext = ((BindingProvider) port).getRequestContext();
       reqContext.put(StubExt.PROPERTY_AUTH_TYPE, StubExt.PROPERTY_AUTH_TYPE_WSSE);
       reqContext.put(StubExt.PROPERTY_KEY_STORE, "C:/k.jks");
       reqContext.put(StubExt.PROPERTY_KEY_STORE_PASSWORD, "123456");
       reqContext.put(StubExt.PROPERTY_TRUST_STORE, "C:/Program/Java/jdk1.6.0_06/jre/lib/security/cacerts");
       reqContext.put(StubExt.PROPERTY_TRUST_STORE_PASSWORD, "changeit");
       String kEnpointAddress = "https://test.k.se/KService";
       ((BindingProvider) port).getRequestContext().put(
       BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
       kEnpointAddress);
      


      If there is a way to configure JbossRemoting to work around this problem?


      Tia/johan



        • 1. Re: https invoke with Remoting
          ron_sigal

          Try setting the property "org.jboss.remoting.clientAuthMode" to "true" on both the client and the server, which you can do by adding it to the InvokerLocator. Setting it to "true" will tell the client to authenticate itself and tell the server to expect the client to authenticate itself. You should also set "UseSSLServerSocketFactory" to false to tell Remoting to respond to the SSL properties.

          See section "5.7.6. SSLSocketBuilder" of the Remoting Guide http://www.jboss.org/jbossremoting/docs/guide/2.2/html/index.html for more information.

          • 2. Re: https invoke with Remoting
            carl-johan.persson

            Thing is our Jboss server is not https aware but we have confirmed
            by enabling https on Jboss that Swing app can talk to Jboss server with:

             // Swing client.
             service = new KService(wsdlURL, new QName(namespaceURI, localpart));
             port = service.getKPort();
             ((StubExt)port).setConfigName("Standard WSSecurity Client");
             Map<String, Object> reqContext = ((BindingProvider) port).getRequestContext();
             reqContext.put(StubExt.PROPERTY_AUTH_TYPE, StubExt.PROPERTY_AUTH_TYPE_WSSE);
             reqContext.put(StubExt.PROPERTY_KEY_STORE, "C:/k/client.keystore");
             reqContext.put(StubExt.PROPERTY_KEY_STORE_PASSWORD, "123456");
             reqContext.put(StubExt.PROPERTY_TRUST_STORE, "C:/k/client.truststore");
             reqContext.put(StubExt.PROPERTY_TRUST_STORE_PASSWORD, "123456");
             String kEnpointAddress = "https://test.k.se/KService";
             ((BindingProvider) port).getRequestContext().put(
             BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
             kassagirotEnpointAddress);
            
             // C:\jboss-4.2.3.GA\server\default\deploy\jboss-web.deployer\server.xml
             <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
             maxThreads="150" scheme="https" secure="true"
             clientAuth="true" sslProtocol="TLS" strategy="ms"
             address="${jboss.bind.address}"
             keystoreFile="C:/k/server.keystore"
             keystorePass="123456"
             truststoreFile="C:/k/server.truststore"
             truststorePass="123456" />
            

            This gives correct certificate exchange and everything works fine.

            Our problem is that a security product Portwise sits between Swing client
            and Jboss server. Portwise is configured to do client cert authentication and after that call Jboss placed in DMZ:
            swing-soap-https--->portwise-https--->jboss-http

            We are looking for a way to work around this problem by configuring JbossWS or JbossRemoting in the Swing client app, would like to try ssl socket factory but not sure how to do this when soap/jax-ws is involved (having ws-security in client with endorsed jboss binaries)?


            • 3. Re: https invoke with Remoting
              ron_sigal

              I know that in some cases JBossWS uses a Remoting client (for SOAP exchanges, I think), but, to be honest, I don't know how JBossWS configures Remoting clients. I suggest you pose the question on the JBossWS forum (http://www.jboss.com/index.html?module=bb&op=viewforum&f=200). If you also post a reference to your JBossWS thread on this thread, I can keep an eye on the proceedings.