https invoke with Remoting
carl-johan.persson Oct 29, 2008 4:35 AMHi,
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