package org.globus.gsi.jsse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.ByteArrayInputStream;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.security.auth.Subject;
import org.apache.commons.codec.binary.Hex;

public class GlobusTLSContext {
	private static ThreadLocal<Subject> containerSubjectHolder = new ThreadLocal<Subject>();
	private Subject containerSubject;
	private Subject peerSubject;
	private X509Certificate[] localCertChain;
	private X509Certificate[] peerCertChain;
	private Principal localPrincipal;
	private Principal peerPrincipal;
	private Date creationTime;
	private String sessionId;
	private String cipherSuite;
	private String protocol;
	private String peerHost;
	private int peerPort;
	private Log logger = LogFactory.getLog(getClass().getCanonicalName());

	public GlobusTLSContext(SSLSession sslSession) {
		containerSubject = new Subject();
		containerSubject.getPrincipals().add(sslSession.getLocalPrincipal());
		containerSubject.getPublicCredentials().add(
				getLocalCertChain(sslSession));
		GlobusTLSContext.containerSubjectHolder.set(containerSubject);
		peerSubject = new Subject();
		try {
			peerSubject.getPrincipals().add(sslSession.getPeerPrincipal());
		} catch (SSLPeerUnverifiedException e) {
			// We should already be verified, but if by some crazy chance we
			// aren't
			logger.warn(e.getLocalizedMessage(), e);
		}
		peerSubject.getPublicCredentials().add(getPeerCertChain(sslSession));

		creationTime = new Date(sslSession.getCreationTime());
		try {
			sessionId = Hex.encodeHexString(sslSession.getId());
		} catch (Exception e) {
			logger.warn(e.getLocalizedMessage(), e);
		}
		cipherSuite = sslSession.getCipherSuite();
		protocol = sslSession.getProtocol();
		peerHost = sslSession.getPeerHost();
		peerPort = sslSession.getPeerPort();
	}

	public static Subject getCurrentContainerSubject() {
		return GlobusTLSContext.containerSubjectHolder.get();
	}

	public X509Certificate[] getLocalCertChain() {
		return localCertChain;
	}

	public X509Certificate[] getPeerCertChain() {
		return peerCertChain;
	}

	public Principal getLocalPrincipal() {
		return localPrincipal;
	}

	public Principal getPeerPrincipal() {
		return peerPrincipal;
	}

	public Date getCreationTime() {
		return creationTime;
	}

	public String getSessionId() {
		return sessionId;
	}

	public String getCipherSuite() {
		return cipherSuite;
	}

	public String getProtocol() {
		return protocol;
	}

	public String getPeerHost() {
		return peerHost;
	}

	public int getPeerPort() {
		return peerPort;
	}

	private X509Certificate[] getLocalCertChain(SSLSession sslSession) {
		try {
			Certificate[] javaxCerts = sslSession.getLocalCertificates();
			return processCerts(javaxCerts);
		} catch (Exception e) {
			logger.warn(e.getLocalizedMessage(), e);
			return null;
		}
	}

	private X509Certificate[] getPeerCertChain(SSLSession sslSession) {
		Certificate[] javaxCerts;
		try {
			javaxCerts = sslSession.getPeerCertificates();
			return processCerts(javaxCerts);
		} catch (SSLPeerUnverifiedException e) {
			logger.warn(e.getLocalizedMessage(), e);
			return null;
		} catch (CertificateEncodingException e) {
			logger.warn(e.getLocalizedMessage(), e);
			return null;
		} catch (CertificateException e) {
			logger.warn(e.getLocalizedMessage(), e);
			return null;
		}
	}

	private X509Certificate[] processCerts(
			java.security.cert.Certificate[] javaxCerts)
			throws CertificateException, CertificateEncodingException {
		if (javaxCerts == null || javaxCerts.length == 0)
			return null;
		int length = javaxCerts.length;
		X509Certificate[] javaCerts = new X509Certificate[length];
		java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory
				.getInstance("X.509");
		for (int i = 0; i < length; i++) {
			byte bytes[] = javaxCerts[i].getEncoded();
			ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
			javaCerts[i] = (X509Certificate) cf.generateCertificate(stream);
		}
		return javaCerts;
	}

}

@@ -1214,75 +1214,160 @@
 ;%0A%09%09
-containerSubject.getPrincipals().add(sslSession.getLocalPrincipal()
+localPrincipal = sslSession.getLocalPrincipal();%0A%09%09containerSubject.getPrincipals().add(localPrincipal);%0A%09%09localCertChain = getLocalCertChain(sslSession
 );%0A%09
@@ -1415,17 +1415,9 @@
 add(
-%0A%09%09%09%09getL
+l
 ocal
@@ -1425,28 +1425,16 @@
 ertChain
-(sslSession)
 );%0A%09%09Glo
@@ -1532,16 +1532,66 @@
 %09%09try %7B%0A
+%09%09%09peerPrincipal = sslSession.getPeerPrincipal();%0A
 %09%09%09peerS
@@ -1617,31 +1617,17 @@
 s().add(
-sslSession.getP
+p
 eerPrinc
@@ -1630,18 +1630,16 @@
 rincipal
-()
 );%0A%09%09%7D c
@@ -1805,16 +1805,64 @@
 e);%0A%09%09%7D%0A
+%09%09peerCertChain = getPeerCertChain(sslSession);%0A
 %09%09peerSu
@@ -1894,20 +1894,17 @@
 s().add(
-getP
+p
 eerCertC
@@ -1907,28 +1907,16 @@
 ertChain
-(sslSession)
 );%0A%0A%09%09cr

Properly set all the variables