/* Signer.java --- Signer Class
   Copyright (C) 1999, 2003, Free Software Foundation, Inc.

This file is 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, 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; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, 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 java.security;

/**
 * <p>This class is used to represent an {@link Identity} that can also
 * digitally sign data.</p>
 *
 * <p>The management of a signer's private keys is an important and sensitive
 * issue that should be handled by subclasses as appropriate to their intended
 * use.</p>
 *
 * @author Mark Benvenuto (ivymccough@worldnet.att.net)
 * @deprecated This class is no longer used. Its functionality has been replaced
 * by <code>java.security.KeyStore</code>, the <code>java.security.cert</code>
 * package, and <code>java.security.Principal</code>.
 */
public abstract class Signer extends Identity
{
  private static final long serialVersionUID = -1763464102261361480L;
  private PrivateKey privateKey = null;

  /**
   * Creates a <code>Signer</code>. This constructor should only be used for
   * serialization.
   */
  protected Signer()
  {
  }

  /**
   * Creates a <code>Signer</code> with the specified identity name.
   *
   * @param name the identity name.
   */
  public Signer(String name)
  {
    super(name);
  }

  /**
   * Creates a <code>Signer</code> with the specified identity name and scope.
   *
   * @param name the identity name.
   * @param scope the scope of the identity.
   * @throws KeyManagementException if there is already an identity with the
   * same name in the scope.
   */
  public Signer(String name, IdentityScope scope) throws KeyManagementException
  {
    super(name, scope);
  }

  /**
   * <p>Returns this signer's private key.</p>
   *
   * <p>First, if there is a security manager, its <code>checkSecurityAccess()
   * </code> method is called with <code>"getSignerPrivateKey"</code> as its
   * argument to see if it's ok to return the private key.</p>
   *
   * @return this signer's private key, or <code>null</code> if the private key
   * has not yet been set.
   * @throws SecurityException if a security manager exists and its
   * <code>checkSecurityAccess()</code> method doesn't allow returning the
   * private key.
   * @see SecurityManager#checkSecurityAccess(String)
   */
  public PrivateKey getPrivateKey()
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkSecurityAccess("getSignerPrivateKey");

    return privateKey;
  }

  /**
   * <p>Sets the key pair (public key and private key) for this signer.</p>
   *
   * <p>First, if there is a security manager, its <code>checkSecurityAccess()
   * </code> method is called with <code>"setSignerKeyPair"</code> as its
   * argument to see if it's ok to set the key pair.</p>
   *
   * @param pair an initialized key pair.
   * @throws InvalidParameterException if the key pair is not properly
   * initialized.
   * @throws KeyException if the key pair cannot be set for any other reason.
   * @throws SecurityException if a security manager exists and its
   * <code>checkSecurityAccess()</code> method doesn't allow setting the key
   * pair.
   * @see SecurityManager#checkSecurityAccess(String)
   */
  public final void setKeyPair(KeyPair pair)
    throws InvalidParameterException, KeyException
  {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null)
      sm.checkSecurityAccess("setSignerKeyPair");

    try
      {
        if (pair.getPublic() != null)
          setPublicKey(pair.getPublic());
        else
          throw new InvalidParameterException();

      }
    catch (KeyManagementException kme)
      {
        throw new KeyException();
      }

    if (pair.getPrivate() != null)
        privateKey = pair.getPrivate();
    else
      throw new InvalidParameterException();
  }

  /**
   * Returns a string of information about the signer.
   *
   * @return a string of information about the signer.
   * @see SecurityManager#checkSecurityAccess(String)
   */
  public String toString()
  {
    return (getName() + ": " + privateKey);
  }
}
