// Path: mitm-common/src/main/java/uk/ac/cam/gpe21/droidssl/mitm/crypto/cert/CertificateUtils.java
// public final class CertificateUtils {
// 	private static final String[] EMPTY_STRING_ARRAY = new String[0];
// 
// 	public static X509Certificate readCertificate(Path path) throws IOException {
// 		try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
// 			return readCertificate(reader);
// 		}
// 	}
// 
// 	public static X509Certificate readCertificate(Reader reader) throws IOException {
// 		// TODO share with CertificateAuthority's own implementation
// 		try (PEMParser parser = new PEMParser(reader)) {
// 			Object object = parser.readObject();
// 			if (!(object instanceof X509CertificateHolder))
// 				throw new IOException("File does not contain a certificate");
// 
// 			X509CertificateHolder certificate = (X509CertificateHolder) object;
// 			return new JcaX509CertificateConverter().getCertificate(certificate);
// 		} catch (CertificateException ex) {
// 			throw new IOException(ex);
// 		}
// 	}
// 
// 	public static String extractCn(X509Certificate certificate) {
// 		X500Name dn = JcaX500NameUtil.getSubject(certificate);
// 		for (RDN rdn : dn.getRDNs()) {
// 			AttributeTypeAndValue first = rdn.getFirst();
// 			if (first.getType().equals(BCStyle.CN)) {
// 				return first.getValue().toString();
// 			}
// 		}
// 
// 		throw new IllegalArgumentException("certificate subject has no common name (CN)");
// 	}
// 
// 	public static String[] extractSans(X509Certificate certificate) {
// 		try {
// 			Collection<List<?>> pairs = certificate.getSubjectAlternativeNames();
// 			if (pairs == null)
// 				return EMPTY_STRING_ARRAY;
// 
// 			List<String> sans = new ArrayList<>();
// 			for (List<?> pair : pairs) {
// 				int type = (Integer) pair.get(0);
// 				if (type == 2) { // TODO fix magic number!
// 					String san = (String) pair.get(1);
// 					sans.add(san);
// 				}
// 			}
// 			return sans.toArray(EMPTY_STRING_ARRAY);
// 		} catch (CertificateParsingException ex) {
// 			throw new IllegalArgumentException(ex); // TODO ideal?
// 		}
// 	}
// 
// 	private CertificateUtils() {
// 		/* to prevent instantiation */
// 	}
// }
// 
// Path: mitm-common/src/main/java/uk/ac/cam/gpe21/droidssl/mitm/crypto/key/KeyUtils.java
// public final class KeyUtils {
// 	public static PrivateKey readPrivateKey(Path path) throws IOException {
// 		try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
// 			return readPrivateKey(reader);
// 		}
// 	}
// 
// 	public static PrivateKey readPrivateKey(Reader reader) throws IOException {
// 		try (PEMParser parser = new PEMParser(reader)) {
// 			Object object = parser.readObject();
// 			if (!(object instanceof PEMKeyPair))
// 				throw new IOException("File does not contain a key");
// 
// 			PEMKeyPair pair = (PEMKeyPair) object;
// 
// 			// TODO merge messy conversion logic with that below */
// 			AsymmetricKeyParameter privateKey = PrivateKeyFactory.createKey(pair.getPrivateKeyInfo());
// 			PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(privateKey);
// 			KeyFactory keyFactory = new DefaultJcaJceHelper().createKeyFactory("RSA"); // TODO should we really assume RSA?
// 			return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()));
// 		} catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
// 			throw new IOException(ex);
// 		}
// 	}
// 
// 	public static KeyPair convertToJca(AsymmetricCipherKeyPair keyPair) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
// 		SubjectPublicKeyInfo publicKey = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(keyPair.getPublic());
// 		PrivateKeyInfo privateKey = PrivateKeyInfoFactory.createPrivateKeyInfo(keyPair.getPrivate());
// 
// 		KeyFactory keyFactory = new DefaultJcaJceHelper().createKeyFactory("RSA"); // TODO should we really assume RSA?
// 		return new KeyPair(
// 			keyFactory.generatePublic(new X509EncodedKeySpec(publicKey.getEncoded())),
// 			keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey.getEncoded()))
// 		);
// 	}
// 
// 	private KeyUtils() {
// 		/* to prevent instantiation */
// 	}
// }


import uk.ac.cam.gpe21.droidssl.mitm.crypto.cert.CertificateUtils;
import uk.ac.cam.gpe21.droidssl.mitm.crypto.key.KeyUtils;
import javax.net.ssl.*;
import java.io.IOException;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
/*
 * Copyright 2013-2014 Graham Edgecombe
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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



public final class SniServer {
	public static void main(String[] args) throws IOException, NoSuchAlgorithmException, KeyManagementException {
		System.setProperty("java.net.preferIPv4Stack", "true");

// Path: mitm-common/src/main/java/uk/ac/cam/gpe21/droidssl/mitm/crypto/cert/CertificateUtils.java
// public final class CertificateUtils {
// 	private static final String[] EMPTY_STRING_ARRAY = new String[0];
// 
// 	public static X509Certificate readCertificate(Path path) throws IOException {
// 		try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
// 			return readCertificate(reader);
// 		}
// 	}
// 
// 	public static X509Certificate readCertificate(Reader reader) throws IOException {
// 		// TODO share with CertificateAuthority's own implementation
// 		try (PEMParser parser = new PEMParser(reader)) {
// 			Object object = parser.readObject();
// 			if (!(object instanceof X509CertificateHolder))
// 				throw new IOException("File does not contain a certificate");
// 
// 			X509CertificateHolder certificate = (X509CertificateHolder) object;
// 			return new JcaX509CertificateConverter().getCertificate(certificate);
// 		} catch (CertificateException ex) {
// 			throw new IOException(ex);
// 		}
// 	}
// 
// 	public static String extractCn(X509Certificate certificate) {
// 		X500Name dn = JcaX500NameUtil.getSubject(certificate);
// 		for (RDN rdn : dn.getRDNs()) {
// 			AttributeTypeAndValue first = rdn.getFirst();
// 			if (first.getType().equals(BCStyle.CN)) {
// 				return first.getValue().toString();
// 			}
// 		}
// 
// 		throw new IllegalArgumentException("certificate subject has no common name (CN)");
// 	}
// 
// 	public static String[] extractSans(X509Certificate certificate) {
// 		try {
// 			Collection<List<?>> pairs = certificate.getSubjectAlternativeNames();
// 			if (pairs == null)
// 				return EMPTY_STRING_ARRAY;
// 
// 			List<String> sans = new ArrayList<>();
// 			for (List<?> pair : pairs) {
// 				int type = (Integer) pair.get(0);
// 				if (type == 2) { // TODO fix magic number!
// 					String san = (String) pair.get(1);
// 					sans.add(san);
// 				}
// 			}
// 			return sans.toArray(EMPTY_STRING_ARRAY);
// 		} catch (CertificateParsingException ex) {
// 			throw new IllegalArgumentException(ex); // TODO ideal?
// 		}
// 	}
// 
// 	private CertificateUtils() {
// 		/* to prevent instantiation */
// 	}
// }
// 
// Path: mitm-common/src/main/java/uk/ac/cam/gpe21/droidssl/mitm/crypto/key/KeyUtils.java
// public final class KeyUtils {
// 	public static PrivateKey readPrivateKey(Path path) throws IOException {
// 		try (Reader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
// 			return readPrivateKey(reader);
// 		}
// 	}
// 
// 	public static PrivateKey readPrivateKey(Reader reader) throws IOException {
// 		try (PEMParser parser = new PEMParser(reader)) {
// 			Object object = parser.readObject();
// 			if (!(object instanceof PEMKeyPair))
// 				throw new IOException("File does not contain a key");
// 
// 			PEMKeyPair pair = (PEMKeyPair) object;
// 
// 			// TODO merge messy conversion logic with that below */
// 			AsymmetricKeyParameter privateKey = PrivateKeyFactory.createKey(pair.getPrivateKeyInfo());
// 			PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.createPrivateKeyInfo(privateKey);
// 			KeyFactory keyFactory = new DefaultJcaJceHelper().createKeyFactory("RSA"); // TODO should we really assume RSA?
// 			return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyInfo.getEncoded()));
// 		} catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
// 			throw new IOException(ex);
// 		}
// 	}
// 
// 	public static KeyPair convertToJca(AsymmetricCipherKeyPair keyPair) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
// 		SubjectPublicKeyInfo publicKey = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(keyPair.getPublic());
// 		PrivateKeyInfo privateKey = PrivateKeyInfoFactory.createPrivateKeyInfo(keyPair.getPrivate());
// 
// 		KeyFactory keyFactory = new DefaultJcaJceHelper().createKeyFactory("RSA"); // TODO should we really assume RSA?
// 		return new KeyPair(
// 			keyFactory.generatePublic(new X509EncodedKeySpec(publicKey.getEncoded())),
// 			keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKey.getEncoded()))
// 		);
// 	}
// 
// 	private KeyUtils() {
// 		/* to prevent instantiation */
// 	}
// }


// Path: mitm-test-sni-server/src/main/java/uk/ac/cam/gpe21/droidssl/mitm/testserver/SniServer.java
import uk.ac.cam.gpe21.droidssl.mitm.crypto.cert.CertificateUtils;
import uk.ac.cam.gpe21.droidssl.mitm.crypto.key.KeyUtils;
import javax.net.ssl.*;
import java.io.IOException;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

/*
 * Copyright 2013-2014 Graham Edgecombe
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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



public final class SniServer {
	public static void main(String[] args) throws IOException, NoSuchAlgorithmException, KeyManagementException {
		System.setProperty("java.net.preferIPv4Stack", "true");

		PrivateKey key = KeyUtils.readPrivateKey(Paths.get("cert.key"));