I was learning socket programming in Java and had written a simple program for connecting a client server to a socket server on a local host. But every time when I run the ClientServer program it gives an error stating connection :refused.
I am enclosing both the client code and server code that i wrote and also enclosing the console output.
package Classes;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class ClientSer {
/**
* #param args
* #throws IOException
* #throws UnknownHostException
*/
public static void main(String[] args) throws UnknownHostException, IOException {
// TODO Auto-generated method stub
Socket s = new Socket("localhost",1029);
OutputStreamWriter os = new OutputStreamWriter(s.getOutputStream());
String str = "tEST mESSAGE";
os.write(str);
os.flush();
}
}
This is the server code:
package Classes;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketSer {
public static void main(String args[]) throws Exception{
ServerSocket ss = new ServerSocket(1029);
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String str = br.readLine();
System.out.print(str);
}
}
Console output:
Exception in thread "main" java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at Classes.ClientSer.main(ClientSer.java:18)
In the server, do you know what interface it's listening on?
I would start the server and then use telnet to try to connect rather than your client. You might find the server is NOT listening on localhost. Or maybe it's listening on every interface (127.0.0.1 plus your local network). I just don't know if I trust SocketServer(portNumber).
I would consider creating an unbound SocketServer and then use socket.bind(), feeding it an InetSocketAddress object constructed with both host and port.
I built a client-server SSL app in which I want to make some tests but I have problem with the client. The server is running ok, but when I try to run the client I have this message:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source)
at sun.security.ssl.AppOutputStream.write(Unknown Source)
at java.io.OutputStream.write(Unknown Source)
at ssl.Client.main(Client.java:17)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 10 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.build(Unknown Source)
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 16 more
Server:
package ssl;
import java.io.PrintStream;
import java.math.BigInteger;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
public class Server {
private static final String HOST = "localhost";
private static final int PORT = 3443;
public static void main(String[] args) throws Exception {
System.setProperty("javax.net.ssl.keyStore", "DebKeyStore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "iliebc");
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
ServerSocket ss = ssf.createServerSocket(PORT, 0, InetAddress.getByName(HOST));
System.out.println("Server started on port " + PORT);
while (true) {
Socket s = ss.accept();
SSLSession session = ((SSLSocket) s).getSession();
//System.out.println(session.getLocalCertificates());
Certificate[] cchain2 = session.getLocalCertificates();
for (int i = 0; i < cchain2.length; i++) {
System.out.println(((X509Certificate) cchain2[i]).getSubjectDN());
}
System.out.println("Peer host is " + session.getPeerHost());
System.out.println("Cipher is " + session.getCipherSuite());
System.out.println("Protocol is " + session.getProtocol());
System.out.println("ID is " + new BigInteger(session.getId()));
System.out.println("Session created in " + session.getCreationTime());
System.out.println("Session accessed in " + session.getLastAccessedTime());
PrintStream out = new PrintStream(s.getOutputStream());
out.println("Hi");
out.close();
s.close();
}
}
}
Client:
package ssl;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import javax.net.ssl.SSLSocketFactory;
public class Client {
private static final String HOST = "localhost";
private static final int PORT = 3443;
public static void main(String[] args) throws Exception {
SSLSocketFactory sf = (SSLSocketFactory) SSLSocketFactory.getDefault();
Socket socket = sf.createSocket(InetAddress.getByName(HOST), PORT);
OutputStream out = socket.getOutputStream();
System.out.println(out);
out.write("\nConnection established.\n\n".getBytes());
out.flush();
int theCharacter = 0;
theCharacter = System.in.read();
while (theCharacter != '~') { // The '~' is an escape character to exit
out.write(theCharacter);
out.flush();
theCharacter = System.in.read();
}
out.close();
socket.close();
}
}
How may I solve this exception?
Solution:
System.setProperty("javax.net.ssl.keyStore", "DebKeyStore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "iliebc");
System.setProperty("javax.net.ssl.trustStore", "DebKeyStore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "iliebc");
the source code that I followed to create a keystore,
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.cert.Certificate;
public class MainClass {
public static void main(String args[]) throws Exception {
String pass = "wshr.ut";
String alias = "mytest";
String name = "mykeystore";
FileInputStream in = new FileInputStream(name);
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(in, pass.toCharArray());
Certificate c = ks.getCertificate(alias);
in.close();
System.out.println(c);
}
}
error when running:
Exception in thread "main" java.io.EOFException
at java.io.DataInputStream.readInt(Unknown Source)
at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source)
at java.security.KeyStore.load(Unknown Source)
at MainClass.main(MainClass.java:17)
can you plz give me any ideas or solutions to reslove this problem ?
I just want to post my answer for the future,
I faced the same issue and found the solution ,
that path you pass for the fileInputStream must be the path of keyStore inside java in my case I was on ubuntu 20.04 and java 11 the path was the following: "/usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts"
in case you are on windows the path will be: "C:/Program Files/Java/jre1.8.0_101/lib/security/cacerts"
make sure also that the password will usually be the default and it is like the following word: "changeit"
I have a cxf service running at
https://localhost:8443/services/MyService?wsdl
with client certificate required. The WSDL is not important here.
I am able to invoke the service when I remove the client certificate or https requirement.
The service and client classes were generated with cxf wsdl2java utility.
Here is MyService.class:
package com.mycompany;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceFeature;
/**
* This class was generated by Apache CXF 2.7.3 2013-03-29T13:59:37.423-03:00 Generated source version: 2.7.3
*/
#WebServiceClient(name = "MyService", wsdlLocation = "myservice.wsdl", targetNamespace = "http://server/schemas/services")
public class MyService extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://server/schemas/services", "MyService");
public final static QName MyServicePort = new QName("http://server/schemas/services", "MyServicePort");
static {
URL url = MyService.class.getResource("myservice.wsdl");
if (url == null) {
Logger.getLogger(MyService.class.getName()).log(Level.INFO, "Can not initialize the default wsdl from {0}", "myservice.wsdl");
}
WSDL_LOCATION = url;
}
public MyService(URL wsdlLocation) {
super(wsdlLocation, SERVICE);
}
public MyService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public MyService() {
super(WSDL_LOCATION, SERVICE);
}
/**
*
* #return returns EncaminharMensagemPortType
*/
#WebEndpoint(name = "MyServicePort")
public MyServicePortType getMyServicePort() {
return super.getPort(MyServicePort, MyServicePortType.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the
* <code>features</code> parameter will have their default values.
* #return returns EncaminharMensagemPortType
*/
#WebEndpoint(name = "MyServicePort")
public MyServicePortType getMyServicePort(WebServiceFeature... features) {
return super.getPort(MyServicePort, MyServicePortType.class, features);
}
}
Here is my client without client certificate requirement: (that work fine)
package com.mycompany;
import java.net.URL;
import javax.xml.namespace.QName;
import com.mycompany.IdHolder;
import com.mycompany.MyDataObject;
public class CxfClientSslTest {
public static void main(String[] args) {
try {
QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService");
URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl");
MyService ss = new MyService(wsdlURL, SERVICE_NAME);
MyServicePortType port = ss.getMyServicePort();
IdHolder mensagem = new IdHolder();
mensagem.setId(1L);
MyDataObject dataObject = port.getById(mensagem);
System.out.println("Id: " + dataObject.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
}
And here is my client send his certificate:
package com.mycompany;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.xml.namespace.QName;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
public class CxfClientSslTest {
public static void main(String[] args) {
try {
QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService");
URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl");
MyService ss = new MyService(wsdlURL, SERVICE_NAME);
MyServicePortType port = ss.getMyServicePort();
tslIt(port);
IdHolder mensagem = new IdHolder();
mensagem.setId(1L);
MyDataObject dataObject = port.getById(mensagem);
System.out.println("Id: " + dataObject.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void tslIt(MyServicePortType port) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
UnrecoverableKeyException {
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
TLSClientParameters tlsClientParameters = http.getTlsClientParameters();
KeyStore keyStore = getKeyStore();
KeyStore trustStore = getTrustStore();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "123456".toCharArray());
KeyManager[] keyMgrs = keyManagerFactory.getKeyManagers();
tlsClientParameters.setKeyManagers(keyMgrs);
trustManagerFactory.init(trustStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
tlsClientParameters.setTrustManagers(trustManagers);
tlsClientParameters.setDisableCNCheck(true);
}
public static KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
URL keyStoreUrl = CxfClientSslTest.class.getResource("/certs/client.jks");
File keystoreFile = new File(keyStoreUrl.getPath());
if (!keystoreFile.exists()) {
throw new RuntimeException("keystore doesn't exists: " + keystoreFile.getAbsolutePath());
}
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keystoreInput = new FileInputStream(keystoreFile.getAbsolutePath());
keystore.load(keystoreInput, "changeit".toCharArray());
keystoreInput.close();
return keystore;
}
public static KeyStore getTrustStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
URL trustStoreUrl = CxfClientSslTest.class.getResource("/certs/client-trust.jks");
File trustStoreFile = new File(trustStoreUrl.getPath());
if (!trustStoreFile.exists()) {
throw new RuntimeException("truststore doesn't exists: " + trustStoreFile.getAbsolutePath());
}
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream trustStoreInput = new FileInputStream(trustStoreFile.getAbsolutePath());
trustStore.load(trustStoreInput, "changeit".toCharArray());
trustStoreInput.close();
return trustStore;
}
}
The TLS configuration both from client and server were checked and are ok. But when I run the program I get this:
Information: Can not initialize the default wsdl from myservice.wsdl
javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:149)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:98)
at javax.xml.ws.Service.<init>(Service.java:77)
at com.mycompany.MyService.<init>(MyService.java:36)
at com.mycompany.CxfClientSslTest.main(CxfClientSslTest.java:32)
Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:100)
at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:199)
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:147)
... 4 more
Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: Problem parsing 'https://localhost:8443/services/MyService?wsdl'.: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:262)
at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:205)
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:98)
... 6 more
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1868)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:270)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1337)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:154)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:998)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1294)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1321)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1305)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:523)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1296)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:653)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:189)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:799)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:240)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:300)
... 12 more
Caused by: java.security.cert.CertificateException: No name matching localhost found
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:208)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:93)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:347)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:203)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:126)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1319)
... 30 more
I can see that the problem is happening before my https configuration get done, when cxf tries to download the wsdl.
I made a research on how to make cxf use that https configuration to download the wsdl. It take me a lot of time, but I can't find the answer out there.
So my question is: how to make cxf use the https configuration to download the wsdl?
Please, I have the answer already and I intend to put it here. So, if you don't have a good answer, or better the answer, please don't post one.
After a lot of research on the web without success, I decide it is time to debug the cxf API. That is one of the points of open source, right?
So I found out that cxf don't download directly the wsdl. It delegates that to wsdl4j through the call of
javax.wsdl.xml.WSDLReader.readWSDL(javax.wsdl.xml.WSDLLocator)
which calls
javax.wsdl.xml.WSDLLocator.getBaseInputSource()
which calls
org.apache.cxf.wsdl11.ResourceManagerWSDLLocator.getInputSource(String, String)
because ResourceManagerWSDLLocator were the WSDLLocator of the first method call.
ResourceManagerWSDLLocator.getInputSource first line is:
InputStream ins = bus.getExtension(ResourceManager.class).getResourceAsStream(importLocation);
Now as ResourceManager is a extension of xcf's Bus, and you can add more ResourceResolver to it and the DefaultResourceManager (implements ResourceManager) will loop through all registered resolvers and will use the first one resolving a non-null value, you just need add a ResourceResolver to the ResourceManager.
My final and working client application is:
package com.mycompany;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.xml.namespace.QName;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.resource.ResourceManager;
import org.apache.cxf.resource.ResourceResolver;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.BasicClientConnectionManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
public class CxfClientSslTest {
public static void main(String[] args) {
try {
Bus bus = BusFactory.getThreadDefaultBus();
ResourceManager extension = bus.getExtension(ResourceManager.class);
extension.addResourceResolver(new ResourceResolver() {
#Override
public <T> T resolve(String resourceName, Class<T> resourceType) {
System.out.println("resourceName: " + resourceName + " - resourceType: " + resourceType);
return null;
}
#Override
public InputStream getAsStream(String name) {
try {
if (!name.startsWith("https")) {
return null;
}
SSLSocketFactory sslSocketFactory = SslUtil.getSslSocketFactory();
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", 8443, sslSocketFactory));
final HttpParams httpParams = new BasicHttpParams();
DefaultHttpClient httpClient = new DefaultHttpClient(new BasicClientConnectionManager(schemeRegistry), httpParams);
HttpGet get = new HttpGet(name);
HttpResponse response = httpClient.execute(get);
return response.getEntity().getContent();
} catch (Exception e) {
return null;
}
}
});
QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService");
URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl");
MyService ss = new MyService(wsdlURL, SERVICE_NAME);
MyServicePortType port = ss.getMyServicePort();
tslIt(port);
IdHolder mensagem = new IdHolder();
mensagem.setId(1L);
MyDataObject dataObject = port.getById(mensagem);
System.out.println("Id: " + dataObject.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void tslIt(MyServicePortType port) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException,
UnrecoverableKeyException {
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
TLSClientParameters tlsClientParameters = http.getTlsClientParameters();
KeyStore keyStore = getKeyStore();
KeyStore trustStore = getTrustStore();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "123456".toCharArray());
KeyManager[] keyMgrs = keyManagerFactory.getKeyManagers();
tlsClientParameters.setKeyManagers(keyMgrs);
trustManagerFactory.init(trustStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
tlsClientParameters.setTrustManagers(trustManagers);
tlsClientParameters.setDisableCNCheck(true);
}
public static KeyStore getKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
URL keyStoreUrl = CxfClientSslTest.class.getResource("/certs/client.jks");
File keystoreFile = new File(keyStoreUrl.getPath());
if (!keystoreFile.exists()) {
throw new RuntimeException("keystore doesn't exists: " + keystoreFile.getAbsolutePath());
}
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream keystoreInput = new FileInputStream(keystoreFile.getAbsolutePath());
keystore.load(keystoreInput, "changeit".toCharArray());
keystoreInput.close();
return keystore;
}
public static KeyStore getTrustStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException {
URL trustStoreUrl = CxfClientSslTest.class.getResource("/certs/client-trust.jks");
File trustStoreFile = new File(trustStoreUrl.getPath());
if (!trustStoreFile.exists()) {
throw new RuntimeException("truststore doesn't exists: " + trustStoreFile.getAbsolutePath());
}
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream trustStoreInput = new FileInputStream(trustStoreFile.getAbsolutePath());
trustStore.load(trustStoreInput, "changeit".toCharArray());
trustStoreInput.close();
return trustStore;
}
}
I think the standard way in apache cxf is to set-up an http conduit in your cxf.xml refering to your jks keystore:
<http:conduit id="{Namespace}PortName.http-conduit">
<http:tlsClientParameters>
...
<sec:trustManagers>
<sec:keyStore type="JKS"
password="StorePass"
file="certs/truststore.jks"/>
</sec:trustManagers>
...
</http:tlsClientParameters>
</http:conduit>
More information here: Configuring SSL support
tlsClientParameters.setUseHttpsURLConnectionDefaultSslSocketFactory(false);
Above line is required to disable default SslSocketFactory (which will ignore the keyStore and trustStore configured in tlsClientParamters)
Adding to reply https://stackoverflow.com/a/15755512/19664676
by #DiogoSantana
One can simply add HTTPConduitConfigurer extension to bus like this.
package com.mycompany;
import com.mycompany.IdHolder;
import com.mycompany.MyDataObject;
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transport.http.HTTPConduitConfigurer;
import java.net.URL;
import java.security.SecureRandom;
import javax.net.ssl.SSLContext;
import javax.xml.namespace.QName;
public class CxfClientSslTest {
public static void main(String[] args) {
Bus bus = BusFactory.getThreadDefaultBus();
bus.setExtension(new HTTPConduitConfigurer() {
#Override
public void configure(String name, String address, HTTPConduit c) {
//crate and configure sslcontext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(getKeyManagers(), getTrustManagers(), new SecureRandom());
TLSClientParameters tls = new TLSClientParameters();
//configure tls client params here
tls.setSSLSocketFactory(sslContext.getSocketFactory());
//set tls client params
c.setTlsClientParameters(tls);
}
}, HTTPConduitConfigurer.class);
QName SERVICE_NAME = new QName("http://server/schemas/services", "MyService");
URL wsdlURL = new URL("https://localhost:8443/services/MyService?wsdl");
MyService ss = new MyService(wsdlURL, SERVICE_NAME);
MyServicePortType port = ss.getMyServicePort();
IdHolder mensagem = new IdHolder();
mensagem.setId(1L);
MyDataObject dataObject = port.getById(mensagem);
System.out.println("Id: " + dataObject.getId());
}
}
javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No name matching localhost found
Above exception happens When you create your self-signed certificate with your name,
To resolve this exception, you need to add "localhost" on the following step
What is your first and last name?
[Unknown]: localhost
I'm accessing an internal database using MATLAB's urlread command, everything was working fine until the service was moved to a secure server (i.e. with an HTTPS address rather than an HTTP address). Now urlread no longer successfully retrieves results. It gives an error:
Error downloading URL. Your network connection may be down or your proxy settings improperly configured.
I believe the problem is that the service is using an invalid digital certificate since if I try to access the resource directly in a web browser I get "untrusted connection" warning which I am able to pass through by adding the site to an Exception list. urlread doesn't have an obvious way of handling this problem.
Under the hood urlread is using Java to access web resources, and the error is thrown at this line:
inputStream = urlConnection.getInputStream;
where urlConnection is a Java object: sun.net.www.protocol.https.HttpsURLConnectionImpl.
Anyone suggest a workaround for this problem?
Consider the following Java class. Borrowing from this code: Disabling Certificate Validation in an HTTPS Connection
C:\MATLAB\MyJavaClasses\com\stackoverflow\Downloader.java
package com.stackoverflow;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.cert.X509Certificate;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.net.ssl.HostnameVerifier;
public class Downloader {
public static String getData(String address) throws Exception {
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) {
}
}
};
// Create a host name verifier that always passes
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
// Install the all-trusting trust manager
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
// Install the all-trusting host verifier
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
// open connection
URL page = new URL(address);
HttpURLConnection conn = (HttpURLConnection) page.openConnection();
BufferedReader buff = new BufferedReader(new InputStreamReader(conn.getInputStream()));
// read text
String line;
StringBuffer text = new StringBuffer();
while ( (line = buff.readLine()) != null ) {
//System.out.println(line);
text.append(line + "\n");
}
buff.close();
return text.toString();
}
public static void main(String[] argv) throws Exception {
String str = getData("https://expired.badssl.com/");
System.out.println(str);
}
}
MATLAB
First we compile the Java class (we must use a JDK version compatible with MATLAB):
>> version -java
>> system('javac C:\MATLAB\MyJavaClasses\com\stackoverflow\Downloader.java');
Next we instantiate and use it MATLAB as:
javaaddpath('C:\MATLAB\MyJavaClasses')
dl = com.stackoverflow.Downloader;
str = char(dl.getData('https://expired.badssl.com/'));
web(['text://' str], '-new')
Here are a few URLs with bad SSL certificates to test:
urls = {
'https://expired.badssl.com/' % expired
'https://wrong.host.badssl.com/' % wrong host
'https://self-signed.badssl.com/' % self-signed
'https://revoked.grc.com/' % revoked
};
UPDATE: I should mention that starting with R2014b, MATLAB has a new function webread that supersedes urlread.
thanks for the solution. It worked, however, sometimes, I had received the following exception "java.io.IOException: The issuer can not be found in the trusted CA list." and I was not able to get rid of this error.
Therefore, I tried an alternative solution that works well. You can use the following Java code in Matlab function:
function str = ReadUrl(url)
is = java.net.URL([], url, sun.net.www.protocol.https.Handler).openConnection().getInputStream();
br = java.io.BufferedReader(java.io.InputStreamReader(is));
str = char(br.readLine());
end
Best,
Jan
Note also that the "canonical" way to solve this issue is to import the certificate into MATLAB's keystore (i.e., not your JVM's keystore).
This is documented here: Mathworks on using untrusted SSL certificates.