Connecting a client to a Java-based server using OpenSSL socket, second part

By | January 15, 2011

In this part of the tutorial, the source code for creating a Java server socket is given. The server code is deployed as a .jar file. The JAR file also contains the public and private key pair (keystore server.private) and the public key of the client (client.public). The example contains a hard-coded password for the keystore, which makes it a bad example.. Please let me know what the best approach is.

public class ServerMain implements org.apache.commons.daemon.Daemon {
	static Logger logger = Logger.getLogger(ServerMain.class);
	public static final int SERVER_PORT = 33333;
	private SSLServerSocket serverSocket;
	
	// Client keystore contains only the public key for SSL client, no password is set.
        // Paths are relative to the JAR file 
	private final String clientKeyFile = "/client.public";
	private final String serverKeyFile = "/server.private";
	
	private String passphrase = "password for server.private";

	public void createSocket(int port) throws Exception {
		// find files packed in a JAR
		URL resource = getClass().getResource(clientKeyFile);
		File certFile = new File(resource.toURI());
		
		resource = getClass().getResource(serverKeyFile);
		File serverFile = new File(resource.toURI());
		
		System.setProperty("javax.net.ssl.keyStore", serverFile.getAbsolutePath());
		System.setProperty("javax.net.ssl.keyStorePassword", passphrase);
		System.setProperty("javax.net.ssl.trustStore", certFile.getAbsolutePath());

		ServerSocketFactory ssf = SSLServerSocketFactory. getDefault();

		serverSocket = (SSLServerSocket) ssf.createServerSocket(SERVER_PORT);
		serverSocket.setNeedClientAuth(true);

		// Socket is opened, listen for connections
		logger.debug("Listening for client connections");
	}

	public void acceptConnection() throws IOException {
		Socket socket = serverSocket.accept();
		socket.setKeepAlive(true);

		logger.debug("Client connected: " + socket.getRemoteSocketAddress().toString());

		InputStream in = socket.getInputStream();
		OutputStream out = socket.getOutputStream();

		// Can read and write now using the streams. 
		
		// Or create a dedicated thread for the client:
		ClientThread clientThread = new ClientThread(socket);
		Thread thread = new Thread(clientThread);
		thread.start();
	}

	public static void main(String[] args) {
		new ServerMain().startServer();
	}

	private void startServer() {
		try {
			createSocket(SERVER_PORT);
			do {
				acceptConnection();
			} while (true);
		} catch (Exception e) {
			logger.fatal(e.getMessage(), e);
		}
	}

	// Daemon stuff

	public void destroy() {
	}

	public void init(DaemonContext arg0) throws Exception {

	}

	public void init(String arg0) throws Exception {

	}

	public void start() throws Exception {
		main(null);
	}

	public void stop() throws Exception {
		closeSocket();
	}

	private void closeSocket() {
		try {
			serverSocket.close();
		} catch (IOException e) {
			logger.debug("Exception", e);
		}
	}
}

Leave a Reply

Your email address will not be published.