Posts Tagged ‘ssl’

Testing SSL (HTTPS) clients with Junit and Jetty

Posted in: , , , J2EE, java, maven 2, open source.

I recently ran into a situation where a web service client had issues when invoking a webservice via HTTPS. To reproduce, I needed a lightweight, JUnit-based test to reproduce the problem and write a regression test. Here is how I got it to work:

First, I used the basic HTTP test setup. Now however, I needed Jetty to provide a HTTPS connector. For this to work, Jetty – just like any other webserver, such as apache – needs a server certificate and a private key in a keystore. To create the keystore, I simply followed the excellent Jetty SSL guide. Namingly, I did this (using Ubuntu, see the above link for alternatives):

openssl genrsa -des3 -out jetty.key
openssl req -new -x509 -key jetty.key -out jetty.crt
openssl pkcs12 -inkey jetty.key -in jetty.crt -export -out jetty.pkcs12
$JAVA_HOME/bin/keytool -importkeystore -srckeystore jetty.pkcs12 -srcstoretype PKCS12 -destkeystore keystore

Once I had the keystore set up, I placed it in the src/main/resources folder (the root of the classpath, in case you’re not a maven user) and extended the HttpTestServer like so:

import java.net.URL;

import org.junit.Ignore;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.security.SslSocketConnector;

/**
 * A test server for testing SSL requests.
 *
 * @author Olaf Otto
 */
@Ignore
public class SslTestServer extends HttpTestServer {
	private static final int HTTPS_PORT = 50443;

	public SslTestServer() {
	}

	public SslTestServer(String mockData) {
		super(mockData);
	}

	@Override
	protected void configureServer() {
		super.configureServer();
		Connector secureConnector = createSecureConnector();
		getServer().addConnector(secureConnector);
	}

	private Connector createSecureConnector() {
		SslSocketConnector connector = new SslSocketConnector();
		connector.setPort(HTTPS_PORT);
		URL keystoreUrl = getClass().getClassLoader().getResource("keystore");
		connector.setKeystore(keystoreUrl.getFile());
		connector.setKeyPassword("test");
		return connector;
	}

	public static void main(String[] args) {
		SslTestServer server = new SslTestServer();
		try {
			server.start();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

(I added the @Ignore annotation as I placed the class in the test sources folder, though it’s not a test…)
You might use it in your JUnit-based test like so:

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * @author Olaf Otto
 */
public class MySslTest {
	private SslTestServer _server;

	@Before
	public void startServer() throws Exception {
		_server = new SslTestServer();
		_server.start();
	}

	@After
	public void stopServer() throws Exception {
		_server.stop();
	}

	@Test
	public void mySsltest() {
		_server.setMockResponseData("<xml>My client expects this response</xml>");
		// Perform tests on port 50443...
	}
}

Here is the whole package as a maven 2 project (including the keystore with a self-signed certificate). Download, unzip, and give it a try (mvn test).

No Comments