import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;

/*
Generate self-signed ECDSA keypair with
keytool -genkeypair -alias ec -keyalg EC -keysize 256 -sigalg SHA256withECDSA -validity 365 -dname "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,S=Unknown,C=Unknown" -storetype JKS -keystore ectest.jks -storepass 123456 -ext KeyUsage:c=digitalSignature,keyCertSign
Generate self-signed ECDH keypair with
keytool -genkeypair -alias ec -keyalg EC -keysize 256 -sigalg SHA256withECDH -validity 365 -dname "CN=localhost,OU=Unknown,O=Unknown,L=Unknown,S=Unknown,C=Unknown" -storetype JKS -keystore ectest.jks -storepass 123456 -ext KeyUsage:c=keyAgreement,keyCertSign

Adjust cipher_suites as desired or comment them out entirely

Run with:
-Djavax.net.ssl.keyStore=/path/to/ectest.jks
-Djavax.net.ssl.keyStorePassword=123456
-Djavax.net.ssl.trustStore=/path/to/ectest.jks
-Djavax.net.ssl.trustStorePassword=123456
 */
public class ECCTest {

	private static final int delay = 1000; // in millis
	private static final String[] protocols = new String[] {"TLSv1.2"};
	public static final String[] cipher_suites = { "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256" };
	private static final String message =
			"Like most of life's problems, this one can be solved with bending!";

	public static void main(String[] args) throws Exception {
		try (EchoServer server = EchoServer.create()) {
			new Thread(server).start();
			Thread.sleep(delay);

			try (SSLSocket socket = createSocket("localhost", server.port())) {
				InputStream is = new BufferedInputStream(socket.getInputStream());
				OutputStream os = new BufferedOutputStream(socket.getOutputStream());
				os.write(message.getBytes());
				os.flush();
				byte[] data = new byte[2048];
				int len = is.read(data);
				if (len <= 0) {
					throw new IOException("no data received");
				}
				System.out.printf("client received %d bytes: %s%n",
						len, new String(data, 0, len));
			}
		}
	}

	public static SSLSocket createSocket(String host, int port) throws IOException {
		SSLSocket socket = (SSLSocket) SSLSocketFactory.getDefault()
				.createSocket(host, port);
		socket.setEnabledProtocols(protocols);
		return socket;
	}

	public static class EchoServer implements Runnable, AutoCloseable {

		private static final int FREE_PORT = 0;

		private final SSLServerSocket sslServerSocket;

		private EchoServer(SSLServerSocket sslServerSocket) {
			this.sslServerSocket = sslServerSocket;
		}

		public int port() {
			return sslServerSocket.getLocalPort();
		}

		@Override
		public void close() throws IOException {
			if (sslServerSocket != null && !sslServerSocket.isClosed()) {
				sslServerSocket.close();
			}
		}

		@Override
		public void run() {
			System.out.printf("server started on port %d%n", port());
			try (SSLSocket socket = (SSLSocket) sslServerSocket.accept()) {
				System.out.println("accepted");
				InputStream is = new BufferedInputStream(socket.getInputStream());
				OutputStream os = new BufferedOutputStream(socket.getOutputStream());
				byte[] data = new byte[2048];
				int len = is.read(data);
				if (len <= 0) {
					throw new IOException("no data received");
				}
				System.out.printf("server received %d bytes: %s%n",
						len, new String(data, 0, len));
				os.write(data, 0, len);
				os.flush();
			} catch (Exception e) {
				System.out.printf("exception: %s%n", e.getMessage());
			}
			System.out.println("server stopped");
		}

		public static EchoServer create() throws IOException {
			return create(FREE_PORT);
		}

		public static EchoServer create(int port) throws IOException {
			SSLServerSocket socket = (SSLServerSocket)
					SSLServerSocketFactory.getDefault().createServerSocket(port);
			socket.setEnabledCipherSuites(cipher_suites);
			socket.setEnabledProtocols(protocols);
			return new EchoServer(socket);
		}
	}
}
