/**
 * An experiment to measure the speeds of SSL requests.
 */

package timingexp;

import java.io.*;
import java.net.*;
import java.util.*;
import COM.claymoresystems.cert.*;
import COM.claymoresystems.ptls.*;
import COM.claymoresystems.sslg.*;
import jp.*;
import Tools.*;
import com.mortbay.HTTP.*;
import com.mortbay.Util.*;

// based on COM.claymoresystems.ptls.demo.SSLClient

public class SSLExp
	extends HttpExp {
	void testSSL() {
		try {
			Timer t = new Timer();

			String host = "shovel.cs.dartmouth.edu";
			int port = 443;

			SSLContext ctx = new SSLContext();
			SSLPolicyInt policy = new SSLPolicyInt();

			// TODO: will this eliminate some pk verifies that it shouldn't?
			policy.acceptUnverifiableCertificates(false);

			ctx.setPolicy(policy);

			// ctx.loadRootCertificates("/u/jonh/puretls-0.9b1/root.pem");
			ctx.loadRootCertificates("/usr/local/apache/conf/ssl.crt/snakeoil-ca-rsa.crt");
			ctx.loadEAYKeyFile("/u/jonh/puretls-0.9b1/client.pem",
				"password");
			ctx.seedRNG(null);	// "fakeseed"

			for (int j=0; j<10; j++) {
				Timer t2 = new Timer();
				int loops;
				for (loops=0; loops<10; loops++) {
					testConn11(ctx,host,port);
				}
				System.err.println("loops: "+loops+" * testConn: "+t2);
			}

			System.err.println("one testSSL: "+t);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	void testConn10(SSLContext c, String host, int port)
		throws IOException, java.net.UnknownHostException {
		try {
			SSLSocket s;
			s=new SSLSocket(c,host,port);

//			int cs=s.getCipherSuite();
//			System.out.println("Cipher suite: "+SSLPolicyInt.getCipherSuiteName
//				(cs));
//			dumpCertChain(s.getCertificateChain());

			OutputStream os = s.getOutputStream();
			os.write(rawrequest);
			os.flush();

			InputStream is = s.getInputStream();
			while (true) {
				try {
					suckSocketDry(is, Integer.MAX_VALUE);
					break;
				} catch (SSLReHandshakeException e){
					System.out.println("Renegotiate requested. Renegotiating");
					s.renegotiate();
				}
			}
			s.close();
		} catch (SSLAlertException e) {
			e.printStackTrace();
			throw new Error(e.toString());
		}
	}

	void testConn11(SSLContext c, String host, int port)
		throws IOException, java.net.UnknownHostException {
		try {
			SSLSocket s;
			s=new SSLSocket(c,host,port);

			testConn11(s);
		} catch (SSLAlertException e) {
			e.printStackTrace();
			throw new Error(e.toString());
		}
	}

	void dumpCertChain(Vector cc) {
		if (cc!=null) {
			System.out.println("Cert chain");

			for(int i=0;i<cc.size();i++) {
				X509Cert cert=(X509Cert)cc.elementAt(i);
				System.out.println("Issuer "	
					+cert.getIssuerName().getNameString());
				System.out.println("Subject "
					+cert.getSubjectName().getNameString());
				System.out.println("Serial "
					+cert.getSerial());
				System.out.println("Validity "
					+cert.getValidityNotBefore() +"-"+
					cert.getValidityNotAfter());
			}
		} else {
			System.out.println("Cert chain is empty!");
		}
	}

	public static void main(String[] args) {
		SSLDebug.setDebug(
			// SSLDebug.DEBUG_INIT
			// | SSLDebug.DEBUG_CERT
			// |
			SSLDebug.DEBUG_HANDSHAKE);	// TODO turn off
		SSLExp exp = new SSLExp();
		exp.testSSL();
		exp.testSSL();
		exp.testSSL();
	}
}
