org.bouncycastle.jsse.provider.ProvSSLSession Maven / Gradle / Ivy
package org.bouncycastle.jsse.provider;
import java.security.Principal;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLPeerUnverifiedException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionBindingEvent;
import javax.net.ssl.SSLSessionBindingListener;
import javax.net.ssl.SSLSessionContext;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.tls.SessionParameters;
import org.bouncycastle.tls.TlsSession;
import org.bouncycastle.util.Arrays;
// TODO[jsse] Serializable ?
class ProvSSLSession
implements SSLSession
{
// TODO[jsse] Ensure this behaves according to the javadoc for SSLSocket.getSession and SSLEngine.getSession
protected final static ProvSSLSession NULL_SESSION = new ProvSSLSession(null, null);
protected final Map valueMap = Collections.synchronizedMap(new HashMap());
protected final ProvSSLSessionContext sslSessionContext;
protected final TlsSession tlsSession;
protected final SessionParameters sessionParameters;
ProvSSLSession(ProvSSLSessionContext sslSessionContext, TlsSession tlsSession)
{
this.sslSessionContext = sslSessionContext;
this.tlsSession = tlsSession;
this.sessionParameters = tlsSession == null ? null : tlsSession.exportSessionParameters();
}
public int getApplicationBufferSize()
{
// TODO[jsse] See comments for getPacketBufferSize
return 1 << 14;
}
public String getCipherSuite()
{
return sessionParameters == null
? null
: sslSessionContext.getSSLContext().getCipherSuiteString(sessionParameters.getCipherSuite());
}
public long getCreationTime()
{
throw new UnsupportedOperationException();
}
public byte[] getId()
{
return tlsSession == null
? null
: Arrays.clone(tlsSession.getSessionID());
}
public long getLastAccessedTime()
{
throw new UnsupportedOperationException();
}
public Certificate[] getLocalCertificates()
{
if (sessionParameters != null)
{
X509Certificate[] chain = JsseUtils.getX509CertificateChain(sessionParameters.getLocalCertificate());
if (chain != null && chain.length > 0)
{
return chain;
}
}
return null;
}
public Principal getLocalPrincipal()
{
return sessionParameters == null
? null
: JsseUtils.getSubject(sessionParameters.getLocalCertificate());
}
public int getPacketBufferSize()
{
/*
* TODO[jsse] This is the maximum possible per RFC (but see jsse.SSLEngine.acceptLargeFragments System property).
* It would be nice to dynamically check with the underlying RecordStream, which might know a tighter limit, e.g.
* when the max_fragment_length extension has been negotiated, or when no compression was negotiated).
*/
// Header size + Fragment length limit + Compression expansion + Cipher expansion
return 5 + (1 << 14) + 1024 + 1024;
}
public javax.security.cert.X509Certificate[] getPeerCertificateChain() throws SSLPeerUnverifiedException
{
/*
* TODO[jsse] "Note: this method exists for compatibility with previous releases. New
* applications should use getPeerCertificates() instead."
*/
throw new UnsupportedOperationException();
}
public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException
{
if (sessionParameters != null)
{
X509Certificate[] chain = JsseUtils.getX509CertificateChain(sessionParameters.getPeerCertificate());
if (chain != null && chain.length > 0)
{
return chain;
}
}
throw new SSLPeerUnverifiedException("No peer identity established");
}
public String getPeerHost()
{
// TODO[jsse] "It is mainly used as a hint for SSLSession caching strategies."
return null;
}
public int getPeerPort()
{
// TODO[jsse] "It is mainly used as a hint for SSLSession caching strategies."
return -1;
}
public Principal getPeerPrincipal() throws SSLPeerUnverifiedException
{
if (sessionParameters != null)
{
X500Principal principal = JsseUtils.getSubject(sessionParameters.getPeerCertificate());
if (principal != null)
{
return principal;
}
}
throw new SSLPeerUnverifiedException("No peer identity established");
}
public String getProtocol()
{
return sessionParameters == null
? null
: sslSessionContext.getSSLContext().getProtocolString(sessionParameters.getNegotiatedVersion());
}
public SSLSessionContext getSessionContext()
{
return sslSessionContext;
}
public Object getValue(String name)
{
return valueMap.get(name);
}
public String[] getValueNames()
{
synchronized (valueMap)
{
return valueMap.keySet().toArray(new String[valueMap.size()]);
}
}
public void invalidate()
{
if (tlsSession != null)
{
tlsSession.invalidate();
}
}
public boolean isValid()
{
return tlsSession != null && tlsSession.isResumable();
}
public void putValue(String name, Object value)
{
notifyUnbound(name, valueMap.put(name, value));
notifyBound(name, value);
}
public void removeValue(String name)
{
notifyUnbound(name, valueMap.remove(name));
}
protected void notifyBound(String name, Object value)
{
if (value instanceof SSLSessionBindingListener)
{
new SessionBindingListenerAdapter((SSLSessionBindingListener)value)
.valueBound(new SSLSessionBindingEvent(this, name));
}
}
protected void notifyUnbound(String name, Object value)
{
if (value instanceof SSLSessionBindingListener)
{
new SessionBindingListenerAdapter((SSLSessionBindingListener)value)
.valueUnbound(new SSLSessionBindingEvent(this, name));
}
}
}