This section provides a tutorial example on how to write a sample program to create a SSL client socket to connect to a SSL server socket. The connection will fail if the server's certificate is self-signed.
Since my SSL socket server does not require client authentication,
we can create a SSL socket client with the default SSL socket factory.
Here is my sample program, SslSocketClient.java, which can be used
to communicate with SslReverseEchoer.java:
/**
* SslSocketClient.java
* Copyright (c) 2005 by Dr. Herong Yang
*/
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
public class SslSocketClient {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
PrintStream out = System.out;
SSLSocketFactory f =
(SSLSocketFactory) SSLSocketFactory.getDefault();
try {
SSLSocket c =
(SSLSocket) f.createSocket("localhost", 8888);
printSocketInfo(c);
c.startHandshake();
BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(c.getOutputStream()));
BufferedReader r = new BufferedReader(
new InputStreamReader(c.getInputStream()));
String m = null;
while ((m=r.readLine())!= null) {
out.println(m);
m = in.readLine();
w.write(m,0,m.length());
w.newLine();
w.flush();
}
w.close();
r.close();
c.close();
} catch (IOException e) {
System.err.println(e.toString());
}
}
private static void printSocketInfo(SSLSocket s) {
System.out.println("Socket class: "+s.getClass());
System.out.println(" Remote address = "
+s.getInetAddress().toString());
System.out.println(" Remote port = "+s.getPort());
System.out.println(" Local socket address = "
+s.getLocalSocketAddress().toString());
System.out.println(" Local address = "
+s.getLocalAddress().toString());
System.out.println(" Local port = "+s.getLocalPort());
System.out.println(" Need client authentication = "
+s.getNeedClientAuth());
SSLSession ss = s.getSession();
System.out.println(" Cipher suite = "+ss.getCipherSuite());
System.out.println(" Protocol = "+ss.getProtocol());
}
}
Now run this program in a separate window, you will get:
Socket class: class com.sun.net.ssl.internal.ssl.SSLSocketImpl
Remote address = localhost/127.0.0.1
Remote port = 8888
Local socket address = /127.0.0.1:2183
Local address = /127.0.0.1
Local port = 2183
Need client authentication = false
Cipher suite = SSL_NULL_WITH_NULL_NULL
Protocol = NONE
javax.net.ssl.SSLException: Connection has been shutdown:
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
Obviously, there is a problem. The TCP/IP layer connection was ok, but
the SSL handshake process failed. The error message says that server certificate
received has no valid path from any existing certificate authority.
This is an expected error, because the server certificate is a self-signed certificate,
not signed by any trusted certificate authorities directly or indirectly.
See the next section on how to resolve this problem.