//////////////////////////////////////////////////////////////////////////// 
// 
// Copyright (C) DSTC Pty Ltd (ACN 052 372 577) 1993, 1994, 1995.
// Unpublished work.  All Rights Reserved.
// 
// The software contained on this media is the property of the
// DSTC Pty Ltd.  Use of this software is strictly in accordance
// with the license agreement in the accompanying LICENSE.DOC 
// file. If your distribution of this software does not contain 
// a LICENSE.DOC file then you have no rights to use this 
// software in any manner and should contact DSTC at the address 
// below to determine an appropriate licensing arrangement.
// 
//      DSTC Pty Ltd
//      Level 7, GP South
//      University of Queensland
//      St Lucia, 4072
//      Australia
//      Tel: +61 7 3365 4310
//      Fax: +61 7 3365 4311
//      Email: jcsi@dstc.qut.edu.au
// 
// This software is being provided "AS IS" without warranty of
// any kind.  In no event shall DSTC Pty Ltd be liable for
// damage of any kind arising out of or in connection with
// the use or performance of this software.
// 
//////////////////////////////////////////////////////////////////////////// 

package javax.net.ssl;

import java.io.IOException;
import java.net.Socket;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * <p> SSLSocket is a class extended by sockets which support the "Secure
 *  Sockets Layer" (SSL) or IETF "Transport Layer Security" (TLS)
 *  protocols. Such sockets are normal stream sockets (java.net.Socket),
 *  but they add a layer of security protections over the underlying
 *  network transport protocol, such as TCP. Those protections include:
 *    * Integrity Protection. SSL protects against modification of
 *      messages by an active wiretapper.
 *    * Authentication. In most modes, SSL provides peer authentication.
 *      Servers are usually authenticated, and clients may be
 *      authenticated as requested by servers.
 *    * Confidentiality (Privacy Protection). In most modes, SSL encrypts
 *      data being sent between client and server. This protects the
 *      confidentiality of data, so that passive wiretappers won't see
 *      sensitive data such as financial information or personal
 *      information of many kinds.
 *
 *  <p> These kinds of protection are specified by a "cipher suite", which is
 *  a combination of cryptographic algorithms used by a given SSL
 *  connection. For example, how is integrity protection provided (what
 *  kind of message digest is used), how and whether the traffic is
 *  privacy-protected, and how authentication keys are exchanged.
 *
 *  <p> The cipher suite used is established by a negotiation process, between
 *  SSL clients and servers, which is called "handshaking". The goal of
 *  this process is to create or rejoin a "session", which may protect
 *  many connections over time. After handshaking has completed, you can
 *  get access to session attributes using the getSession method.
 *  Handshaking is fully transparent in most cases, but may be explicitly
 *  initiated.
 *
 *  <p> You may register to receive event notification of handshake
 *  completion, using the standard Java Beans event model. This involves
 *  the use of two additional classes. HandshakeCompletedEvent objects are
 *  passed to HandshakeCompletedListener instances, which are implemented
 *  by users of this API.
 *
 *  <p> When SSL connections are first set up, no security is provided.
 *  However, security is always provided by the time that application data
 *  is sent over the connection. Before sending such data, application
 *  programs may then express preferences for what cipher suites may be
 *  used in communication. SSL code performs a negotiation as part of
 *  preparing to send data. Some cipher suite that is supported by both
 *  sides of the SSL connection will be used. If there is no such suite,
 *  no SSL connection will be established, and no data can be exchanged.
 *
 *  <p> Implementation defaults are required to enable use only of cipher
 *  suites which authenticate servers, and which provide confidentiality.
 *  The client and server must both agree on a common cipher suite in
 *  order to communicate. Only if both explicitly agree to unauthenticated
 *  or nonprivate communications will those security protections not
 *  exist.
 *
 *  <p> There are two groups of cipher suites which you will need to know
 *  about when managing cipher suites, in addition to the default list and
 *  the active suite associated with the connection's session:
 *    * Supported cipher suites: all the suites which are supported by the
 *      SSL implementation. This list is reported using
 *      getSupportedCipherSuites.
 *    * Enabled cipher suites, which may be fewer than the full set of
 *      supported suites. This group is set using the
 *      setEnabledCipherSuites method, and queried using the
 *      getEnabledCipherSuites method. Initially, a default set of cipher
 *      suites will be enabled on a new socket that represents the minimum
 *      suggested configuration. This will normally ensure confidentiality
 *      and integrity of your data.
 *
 * @version 0.98, 98/09/10
 * @author Ming Yung
 */

public abstract class SSLSocket extends Socket
{
  /**
   * Constructor is used only by subclasses.
   * Constructs an uninitialized, unconnected TCP socket.  
   */
  protected SSLSocket()
  {
    super();
  }

  /**
   * Used only by subclasses. Constructs a TCP connection to a named host
   * at a specified port. This acts as the SSL client.
   *
   * @param host  name of the host with which to connect
   * @param port  number of the server's port
   */
  protected SSLSocket(String host, int port) 
    throws IOException, UnknownHostException
  {
    super(host, port);
  }


  /**
   * Used only by subclasses. Constructs a TCP connection to a server at a
   * specified address and port. This acts as the SSL client.
   *
   * @param address  the server's host
   * @param port  its port
   */
  protected SSLSocket(InetAddress address, int port) 
    throws IOException, UnknownHostException
  {
    super(address, port);
  }

  /**
   * Used only by subclasses. Constructs an SSL connection to a named host
   * at a specified port, binding the client side of the connection
   * a given address and port. This acts as the SSL client.
   *
   * @param host  name of the host with which to connect
   * @param port  number of the server's port
   */
  protected SSLSocket(String host, int port, InetAddress clientAddress,
                     int clientPort) 
    throws IOException, UnknownHostException
  {
    super(host, port, clientAddress, clientPort);
  }


  /**
   * Used only by subclasses. Constructs an SSL connection to a server at a
   * specified address and TCP port, binding the client side of the
   * connection a given address and port. This acts as the SSL
   * client.
   *
   * @param address  the server's host
   * @param port  its port
   */
  protected SSLSocket(InetAddress address, int port,
                     InetAddress clientAddress, int clientPort) 
    throws IOException, UnknownHostException
  {
    super(address, port, clientAddress, clientPort);
  }

  /**
   * Returns the names of the cipher suites which could be enabled for use
   * on an SSL connection. Normally, only a subset of these will
   * actually be enabled by default, since this list may include
   * cipher suites which do not meet quality of service requirements
   * for those defaults. Such cipher suites are useful in
   * specialized applications.
   *
   * @return an array of cipher suite names
   */
  public abstract String[] getSupportedCipherSuites();

  /**
   * Returns the names of the SSL cipher suites which are currently enabled
   * for use on this connection. When an SSL socket is first
   * created, all enabled cipher suites support a minium quality of
   * service. Thus, in some environments this value might be empty.
   *
   * @return an array of cipher suite names
   */
  public abstract String[] getEnabledCipherSuites();

  /**
   * Controls which particular cipher suites are enabled for use on this
   * connection. The cipher suites must have been listed by
   * getSupportedCipherSuites() as being supported. Even if a suite
   * has been enabled, it might never be used if no peer supports
   * it, or the requisite certificates (and private keys) are not
   * available.
   *
   * @param suites  Names of all the cipher suites to enable.
   *
   * @throw IllegalArgumentException when one of the ciphers 
   * named by the parameter is not supported.
   */
  public abstract void setEnabledCipherSuites(String suites[]);

  /**
   * Returns the the SSL Session in use by this connection. These can be
   * long lived, and frequently correspond to an entire login
   * session for some user. The session specifies a particular
   * cipher suite which is being actively used by all connections in
   * that session, as well as the identities of the session's client
   * and server.
   */
  public abstract SSLSession getSession();

  /**
   * Registers an event listener to receive notifications that an SSL
   * handshake has completed on this connection.
   */
  public abstract void 
    addHandshakeCompletedListener(HandshakeCompletedListener listener);

  /**
   * Removes a previously registered handshake completion listener.
   */
  public abstract void 
    removeHandshakeCompletedListener(HandshakeCompletedListener listener);

  /**
   * Starts an SSL handshake on this connection. Common reasons include a
   * need to use new encryption keys, to change cipher suites, or to
   * initiate a new session. To force complete reauthentication, the
   * current session could be invalidated before starting this
   * handshake.
   *
   * <p> If data has already been sent on the connection, it continues
   * to flow during this handshake. When the handshake completes,
   * this will be signaled with an event.
   */
  public abstract void startHandshake() throws IOException;

  /**
   * Configures the socket to use client (or server) mode in its first
   * handshake. Servers normally authenticate themselves, and
   * clients are not required to do so.
   *
   * @param mode  true iff the socket should start its first
   * handshake in "client" mode
   */
  public abstract void setUseClientMode(boolean mode);

  /**
   * Returns true if the socket is set to use client mode in its first
   * handshake.
   *
   * @return true iff the socket should start its first handshake in
   * "client" mode
   */
  public abstract boolean getUseClientMode();

  /**
   * Configures the socket to require client authentication. The socket
   * must be a server mode socket.
   *
   * @param need  true iff the server mode socket should request
   * that the client authenticate itself.
   */
  public abstract void setNeedClientAuth(boolean need);

  /**
   * Returns true if the socket will require client authentication. The
   * socket must be a server mode socket.
   *
   * @return true iff the server mode socket should request that the
   * client authenticate itself.
   */
  public abstract boolean getNeedClientAuth();

  /**
   * Controls whether new SSL sessions may be established by this socket.
   *
   * @param flag  true indicates that sessions may be created; this
   * is the default. false indicates that an existing session
   * must be resumed.
   */
  public abstract void setEnableSessionCreation(boolean flag);

  /**
   * Returns true if new SSL sessions may be established by this socket.
   *
   * @return true indicates that sessions may be created; this is the
   * default. false indicates that an existing session must be
   * resumed.
   */
  public abstract boolean getEnableSessionCreation();
}
