package primer_harold;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;

public class SecureOrderTaker {

	public static final int DEFAULT_PORT = 443;
	public static final String algorithm = "SSL";

	public static void main(String[] args) {

		int port = DEFAULT_PORT;
		if (args.length > 0) {
			try {
				port = Integer.parseInt(args[0]);
				if (port < 0 || port >= 65536) {
					System.out.println("Port must be between 0 and 65535");
					return;
				}
			} catch (NumberFormatException e) {
			}
		}

		try {
			SSLContext context = SSLContext.getInstance(algorithm);

			// The reference implementation only supports X.509 keys
			KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");

			// Sun's default kind of key store
			KeyStore ks = KeyStore.getInstance("JKS");

			char[] password = "2andnotafnord".toCharArray();
			ks.load(new FileInputStream("jnp3e.keys"), password);
			kmf.init(ks, password);

			context.init(kmf.getKeyManagers(), null, null);

			SSLServerSocketFactory factory = context.getServerSocketFactory();
			SSLServerSocket server = (SSLServerSocket) factory.createServerSocket(port);

			String[] supported = server.getSupportedCipherSuites();
			String[] anonCipherSuitesSupported = new String[supported.length];
			int numAnonCipherSuitesSupported = 0;
			for (int i = 0; i < supported.length; i++) {
				if (supported[i].indexOf("_anon_") > 0) {
					anonCipherSuitesSupported[numAnonCipherSuitesSupported++] = supported[i];
				}
			}

			String[] oldEnabled = server.getEnabledCipherSuites();
			String[] newEnabled = new String[oldEnabled.length + numAnonCipherSuitesSupported];
			System.arraycopy(oldEnabled, 0, newEnabled, 0, oldEnabled.length);
			System.arraycopy(anonCipherSuitesSupported, 0, newEnabled, oldEnabled.length, numAnonCipherSuitesSupported);

			server.setEnabledCipherSuites(newEnabled);

			try {
				while (true) {
					// This socket will be secure,
					Socket theConnection = server.accept();
					InputStream in = theConnection.getInputStream();
					int c;
					while ((c = in.read()) != -1) {
						System.out.write(c);
					}
					theConnection.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (KeyStoreException e) {
			e.printStackTrace();
		} catch (CertificateException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
		} catch (KeyManagementException e) {
			e.printStackTrace();
		}

	}

}
