/* SessionImpl.java -- concrete definition of SSLSession.
   Copyright (C) 2006  Free Software Foundation, Inc.

This file is a part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
USA

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version.  */


package gnu.javax.net.ssl;

import gnu.java.lang.CPStringBuilder;

import java.io.Serializable;

import java.security.Principal;
import java.security.SecureRandom;
import java.security.cert.Certificate;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;

import javax.crypto.SealedObject;
import javax.net.ssl.SSLException;
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.cert.X509Certificate;

/**
 * A concrete implementation of the {@link SSLSession} interface. This
 * class is provided to allow pluggable {@link AbstractSessionContext}
 * implementations.
 */
public abstract class Session implements SSLSession, Serializable
{
  protected final long creationTime;
  protected long lastAccessedTime;
  protected int applicationBufferSize;
  
  protected ID sessionId;
  protected Certificate[] localCerts;
  protected Certificate[] peerCerts;
  protected X509Certificate[] peerCertChain;
  protected String peerHost;
  protected int peerPort;
  protected boolean peerVerified;
  protected HashMap<String,Object> values;
  protected boolean valid;
  protected boolean truncatedMac = false;
  transient protected SecureRandom random;
  transient protected SSLSessionContext context;

  protected Session()
  {
    creationTime = System.currentTimeMillis();
    values = new HashMap<String, Object>();
    applicationBufferSize = (1 << 14);
  }

  public void access()
  {
    lastAccessedTime = System.currentTimeMillis ();
  }

  public int getApplicationBufferSize()
  {
    return applicationBufferSize;
  }

  public String getCipherSuite()
  {
    return null;
  }

  public long getCreationTime()
  {
    return creationTime;
  }

  public byte[] getId()
  {
    return sessionId.id();
  }

  public ID id()
  {
    return sessionId;
  }

  public long getLastAccessedTime()
  {
    return lastAccessedTime;
  }

  public Certificate[] getLocalCertificates()
  {
    if (localCerts == null)
      return null;
    return (Certificate[]) localCerts.clone();
  }

  public Principal getLocalPrincipal()
  {
    if (localCerts != null)
      {
        if (localCerts[0] instanceof java.security.cert.X509Certificate)
          return ((java.security.cert.X509Certificate) localCerts[0]).getSubjectDN();
      }
    return null;
  }
  
  public int getPacketBufferSize()
  {
    return applicationBufferSize + 2048;
  }
  
  public Certificate[] getPeerCertificates() throws SSLPeerUnverifiedException
  {
    if (!peerVerified)
      throw new SSLPeerUnverifiedException("peer not verified");
    if (peerCerts == null)
      return null;
    return (Certificate[]) peerCerts.clone();
  }

  public X509Certificate[] getPeerCertificateChain()
    throws SSLPeerUnverifiedException
  {
    if (!peerVerified)
      throw new SSLPeerUnverifiedException("peer not verified");
    if (peerCertChain == null)
      return null;
    return (X509Certificate[]) peerCertChain.clone();
  }
  
  public String getPeerHost()
  {
    return peerHost;
  }
  
  public int getPeerPort()
  {
    return peerPort;
  }
  
  public Principal getPeerPrincipal() throws SSLPeerUnverifiedException
  {
    if (!peerVerified)
      throw new SSLPeerUnverifiedException("peer not verified");
    if (peerCertChain == null)
      return null;
    return peerCertChain[0].getSubjectDN();
  }
  
  public SSLSessionContext getSessionContext()
  {
    return context;
  }
  
  public String[] getValueNames()
  {
    Set<String> keys = this.values.keySet();
    return keys.toArray(new String[keys.size()]);
  }
  
  public Object getValue(String name)
  {
    return values.get(name);
  }
  
  public void invalidate()
  {
    valid = false;
  }
  
  public boolean isValid()
  {
    return valid;
  }
  
  public void putValue(String name, Object value)
  {
    values.put(name, value);
    try
      {
        if (value instanceof SSLSessionBindingListener)
          ((SSLSessionBindingListener) value).valueBound
            (new SSLSessionBindingEvent(this, name));
      }
    catch (Exception x)
      {
      }
  }
  
  public void removeValue(String name)
  {
    Object value = values.remove(name);
    try
      {
        if (value instanceof SSLSessionBindingListener)
          ((SSLSessionBindingListener) value).valueUnbound
            (new SSLSessionBindingEvent(this, name));
      }
    catch (Exception x)
      {
      }   
  }
  
  public final boolean isTruncatedMac()
  {
    return truncatedMac;
  }

  /**
   * Prepare this session for serialization. Private data will be encrypted
   * with the given password, and this object will then be ready to be
   * serialized.
   * 
   * @param password The password to protect this session with.
   * @throws SSLException If encrypting this session's private data fails.
   */
  public abstract void prepare (char[] password) throws SSLException;
  
  /**
   * Repair this session's private data after deserialization. This method
   * will decrypt this session's private data, and prepare the session for
   * use in new SSL connections.
   * 
   * @param password The password to decrypt the private data with.
   * @throws SSLException
   */
  public abstract void repair(char[] password) throws SSLException;
  
  /**
   * Get the private data of this session. This method may only be called
   * after first calling {@link #prepare(char[])}.
   * 
   * @return The sealed private data.
   * @throws SSLException If the private data have not been sealed.
   */
  public abstract SealedObject privateData() throws SSLException;
  
  /**
   * Set the private data of this session.
   * @param data
   * @throws SSLException
   */
  public abstract void setPrivateData(SealedObject data) throws SSLException;

  // Inner classes.
  // -------------------------------------------------------------------------

  /**
   * An SSL or TLS session ID.
   */
  public static final class ID implements Comparable, Serializable
  {

    // Fields.
    // -----------------------------------------------------------------------

    static final long serialVersionUID = 7887036954666565936L;
    /** The ID itself. */
    private final byte[] id;

    // Constructor.
    // -----------------------------------------------------------------------

    /**
     * Creates a new ID.
     *
     * @param id The ID. The array is cloned.
     */
    public ID (final byte[] id)
    {
      if (id.length > 32)
        throw new IllegalArgumentException ("session ID's are limited to 32 bytes");
      this.id = (byte[]) id.clone();
    }

    // Instance methods.
    // -----------------------------------------------------------------------

    public byte[] id()
    {
      return (byte[]) id.clone();
    }

    public boolean equals(Object other)
    {
      if (!(other instanceof ID))
        return false;
      return Arrays.equals(id, ((ID) other).id);
    }

    public int hashCode()
    {
      int code = 0;
      for (int i = 0; i < id.length; i++)
        code |= (id[i] & 0xFF) << ((i & 3) << 3);
      return code;
    }

    public int compareTo(Object other)
    {
      byte[] id2 = ((ID) other).id;
      if (id.length != id2.length)
        return (id.length < id2.length) ? -1 : 1;
      for (int i = 0; i < id.length; i++)
        {
          if ((id[i] & 0xFF) < (id2[i] & 0xFF))
            return -1;
          if ((id[i] & 0xFF) > (id2[i] & 0xFF))
            return 1;
        }
      return 0;
    }

    public String toString()
    {
      CPStringBuilder str = new CPStringBuilder (3 * id.length + 1);
      for (int i = 0; i < id.length; i++)
        {
          int x = id[i] & 0xFF;
          str.append (Character.forDigit ((x >>> 4) & 0xF, 16));
          str.append (Character.forDigit (x & 0xF, 16));
          if (i != id.length - 1)
            str.append (':');
        }
      return str.toString ();
    }
  }
}
