package uk.ac.cam.gpe21.droidssl.mitm.testclient;

import uk.ac.cam.gpe21.droidssl.mitm.crypto.cert.CertificateUtils;

import javax.net.ssl.*;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;

public final class TestClient {
	public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException, IOException, KeyStoreException, CertificateException {
		TrustManager trustManager = new SecureTrustManager(CertificateUtils.readCertificate(Paths.get("ca.crt")));
		HostnameVerifier hostnameVerifier = new SecureHostnameVerifier();

		TestClient client = new TestClient(new InetSocketAddress("localhost", 12345), trustManager, hostnameVerifier);
		client.start();
	}

	private final InetSocketAddress address;
	private final HostnameVerifier hostnameVerifier;
	private final SSLSocketFactory factory;

	public TestClient(InetSocketAddress address, TrustManager trustManager, HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException {
		this.address = address;
		this.hostnameVerifier = hostnameVerifier;

		SSLContext context = SSLContext.getInstance("TLS");
		context.init(null, new TrustManager[] {
			trustManager
		}, null);
		this.factory = context.getSocketFactory();
	}

	public void start() throws IOException {
		SSLSocket socket = (SSLSocket) factory.createSocket(address.getAddress(), address.getPort());
		socket.startHandshake();
		if (!hostnameVerifier.verify(address.getHostName(), socket.getSession()))
			throw new IOException();
	}
}

@@ -156,32 +156,89 @@
 io.IOException;%0A
+import java.io.InputStream;%0Aimport java.io.OutputStream;%0A
 import java.net.
@@ -1550,16 +1550,21 @@
 ion %7B%0A%09%09
+try (
 SSLSocke
@@ -1647,18 +1647,21 @@
 tPort())
-;%0A
+) %7B%0A%09
 %09%09socket
@@ -1679,16 +1679,17 @@
 hake();%0A
+%09
 %09%09if (!h
@@ -1759,16 +1759,17 @@
 ()))%0A%09%09%09
+%09
 throw ne
@@ -1784,14 +1784,242 @@
 ption();
+%0A%0A%09%09%09try (InputStream is = socket.getInputStream();%0A%09%09%09     OutputStream os = socket.getOutputStream()) %7B%0A%09%09%09%09os.write(0xFF);%0A%0A%09%09%09%09if (is.read() != 0xFF)%0A%09%09%09%09%09throw new IOException(%22Server did not echo back 0xFF byte%22);%0A%09%09%09%7D%0A%09%09%7D
 %0A%09%7D%0A%7D%0A

Make TestClient send a byte back and forth.