/* PKIXParameters.java -- parameters for the PKIX cert path algorithm
   Copyright (C) 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.cert;

import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.KeyStoreException;

import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

/**
 * Parameters for verifying certificate paths using the PKIX
 * (Public-Key Infrastructure (X.509)) algorithm.
 *
 * @see CertPathBuilder
 * @since 1.4
 */
public class PKIXParameters implements CertPathParameters
{

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

  /** The trusted certificates. */
  private final Set trustAnchors;

  /** The set of initial policy identifiers. */
  private final Set initPolicies;

  /** The list of certificate stores. */
  private final List certStores;

  /** The list of path checkers. */
  private final List pathCheckers;

  /** The revocation enabled flag. */
  private boolean revocationEnabled;

  /** The explicit policy required flag. */
  private boolean exPolicyRequired;

  /** The policy mapping inhibited flag. */
  private boolean policyMappingInhibited;

  /** The any policy inhibited flag. */
  private boolean anyPolicyInhibited;

  /** The policy qualifiers rejected flag. */
  private boolean policyQualRejected;

  /** The target validation date. */
  private Date date;

  /** The signature algorithm provider. */
  private String sigProvider;

  /** The target constraints. */
  private CertSelector targetConstraints;

  // Constructors.
  // ------------------------------------------------------------------------

  /**
   * Create a new PKIXParameters object, populating the trusted
   * certificates set with all certificates found in the given key
   * store. All certificates found in the key store are assumed to be
   * trusted by this constructor.
   *
   * @param keystore The key store.
   * @throws KeyStoreException If the certificates cannot be retrieved
   *         from the key store.
   * @throws InvalidAlgorithmParameterException If there are no
   *         certificates in the key store.
   * @throws NullPointerException If <i>keystore</i> is null.
   */
  public PKIXParameters(KeyStore keystore)
    throws KeyStoreException, InvalidAlgorithmParameterException
  {
    this();
    for (Enumeration e = keystore.aliases(); e.hasMoreElements(); )
      {
        String alias = (String) e.nextElement();
        if (!keystore.isCertificateEntry(alias))
          continue;
        Certificate cert = keystore.getCertificate(alias);
        if (cert instanceof X509Certificate)
          trustAnchors.add(new TrustAnchor((X509Certificate) cert, null));
      }
    if (trustAnchors.isEmpty())
      throw new InvalidAlgorithmParameterException("no certs in the key store");
  }

  /**
   * Create a new PKIXParameters object, populating the trusted
   * certificates set with the elements of the given set, each of which
   * must be a {@link TrustAnchor}.
   *
   * @param trustAnchors The set of trust anchors.
   * @throws InvalidAlgorithmParameterException If there are no
   *         certificates in the set.
   * @throws NullPointerException If <i>trustAnchors</i> is null.
   * @throws ClassCastException If every element in <i>trustAnchors</i>
   *         is not a {@link TrustAnchor}.
   */
  public PKIXParameters(Set<TrustAnchor> trustAnchors)
    throws InvalidAlgorithmParameterException
  {
    this();
    setTrustAnchors(trustAnchors);
  }

  /**
   * Default constructor.
   */
  private PKIXParameters()
  {
    trustAnchors = new HashSet();
    initPolicies = new HashSet();
    certStores = new LinkedList();
    pathCheckers = new LinkedList();
    revocationEnabled = true;
    exPolicyRequired = false;
    policyMappingInhibited = false;
    anyPolicyInhibited = false;
    policyQualRejected = true;
  }

  /**
   * Copying constructor for cloning.
   *
   * @param that The instance being cloned.
   */
  private PKIXParameters(PKIXParameters that)
  {
    this();
    this.trustAnchors.addAll(that.trustAnchors);
    this.initPolicies.addAll(that.initPolicies);
    this.certStores.addAll(that.certStores);
    this.pathCheckers.addAll(that.pathCheckers);
    this.revocationEnabled = that.revocationEnabled;
    this.exPolicyRequired = that.exPolicyRequired;
    this.policyMappingInhibited = that.policyMappingInhibited;
    this.anyPolicyInhibited = that.anyPolicyInhibited;
    this.policyQualRejected = that.policyQualRejected;
    this.date = that.date;
    this.sigProvider = that.sigProvider;
    this.targetConstraints = that.targetConstraints != null
      ? (CertSelector) that.targetConstraints.clone() : null;
  }

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

  /**
   * Returns an immutable set of trust anchors. The set returned will
   * never be null and will never be empty.
   *
   * @return A (never null, never empty) immutable set of trust anchors.
   */
  public Set<TrustAnchor> getTrustAnchors()
  {
    return Collections.unmodifiableSet(trustAnchors);
  }

  /**
   * Sets the trust anchors of this class, replacing the current trust
   * anchors with those in the given set. The supplied set is copied to
   * prevent modification.
   *
   * @param trustAnchors The new set of trust anchors.
   * @throws InvalidAlgorithmParameterException If there are no
   *         certificates in the set.
   * @throws NullPointerException If <i>trustAnchors</i> is null.
   * @throws ClassCastException If every element in <i>trustAnchors</i>
   *         is not a {@link TrustAnchor}.
   */
  public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
    throws InvalidAlgorithmParameterException
  {
    if (trustAnchors.isEmpty())
      throw new InvalidAlgorithmParameterException("no trust anchors");
    this.trustAnchors.clear();
    for (Iterator i = trustAnchors.iterator(); i.hasNext(); )
      {
        this.trustAnchors.add((TrustAnchor) i.next());
      }
  }

  /**
   * Returns the set of initial policy identifiers (as OID strings). If
   * any policy is accepted, this method returns the empty set.
   *
   * @return An immutable set of initial policy OID strings, or the
   *         empty set if any policy is acceptable.
   */
  public Set<String> getInitialPolicies()
  {
    return Collections.unmodifiableSet(initPolicies);
  }

  /**
   * Sets the initial policy identifiers (as OID strings). If the
   * argument is null or the empty set, then any policy identifier will
   * be accepted.
   *
   * @param initPolicies The new set of policy strings, or null.
   * @throws ClassCastException If any element in <i>initPolicies</i> is
   *         not a string.
   */
  public void setInitialPolicies(Set<String> initPolicies)
  {
    this.initPolicies.clear();
    if (initPolicies == null)
      return;
    for (Iterator i = initPolicies.iterator(); i.hasNext(); )
      {
        this.initPolicies.add((String) i.next());
      }
  }

  /**
   * Add a {@link CertStore} to the list of cert stores.
   *
   * @param store The CertStore to add.
   */
  public void addCertStore(CertStore store)
  {
    if (store != null)
      certStores.add(store);
  }

  /**
   * Returns an immutable list of cert stores. This method never returns
   * null.
   *
   * @return The list of cert stores.
   */
  public List<CertStore> getCertStores()
  {
    return Collections.unmodifiableList(certStores);
  }

  /**
   * Set the cert stores. If the argument is null the list of cert
   * stores will be empty.
   *
   * @param certStores The cert stores.
   */
  public void setCertStores(List<CertStore> certStores)
  {
    this.certStores.clear();
    if (certStores == null)
      return;
    for (Iterator i = certStores.iterator(); i.hasNext(); )
      {
        this.certStores.add((CertStore) i.next());
      }
  }

  /**
   * Returns the value of the <i>revocation enabled</i> flag. The default
   * value for this flag is <code>true</code>.
   *
   * @return The <i>revocation enabled</i> flag.
   */
  public boolean isRevocationEnabled()
  {
    return revocationEnabled;
  }

  /**
   * Sets the value of the <i>revocation enabled</i> flag.
   *
   * @param value The new value.
   */
  public void setRevocationEnabled(boolean value)
  {
    revocationEnabled = value;
  }

  /**
   * Returns the value of the <i>explicit policy required</i> flag. The
   * default value of this flag is <code>false</code>.
   *
   * @return The <i>explicit policy required</i> flag.
   */
  public boolean isExplicitPolicyRequired()
  {
    return exPolicyRequired;
  }

  /**
   * Sets the value of the <i>explicit policy required</i> flag.
   *
   * @param value The new value.
   */
  public void setExplicitPolicyRequired(boolean value)
  {
    exPolicyRequired = value;
  }

  /**
   * Returns the value of the <i>policy mapping inhibited</i> flag. The
   * default value of this flag is <code>false</code>.
   *
   * @return The <i>policy mapping inhibited</i> flag.
   */
  public boolean isPolicyMappingInhibited()
  {
    return policyMappingInhibited;
  }

  /**
   * Sets the value of the <i>policy mapping inhibited</i> flag.
   *
   * @param value The new value.
   */
  public void setPolicyMappingInhibited(boolean value)
  {
    policyMappingInhibited = value;
  }

  /**
   * Returns the value of the <i>any policy inhibited</i> flag. The
   * default value of this flag is <code>false</code>.
   *
   * @return The <i>any policy inhibited</i> flag.
   */
  public boolean isAnyPolicyInhibited()
  {
    return anyPolicyInhibited;
  }

  /**
   * Sets the value of the <i>any policy inhibited</i> flag.
   *
   * @param value The new value.
   */
  public void setAnyPolicyInhibited(boolean value)
  {
    anyPolicyInhibited = value;
  }

  /**
   * Returns the value of the <i>policy qualifiers enabled</i> flag. The
   * default value of this flag is <code>true</code>.
   *
   * @return The <i>policy qualifiers enabled</i> flag.
   */
  public boolean getPolicyQualifiersRejected()
  {
    return policyQualRejected;
  }

  /**
   * Sets the value of the <i>policy qualifiers enabled</i> flag.
   *
   * @param value The new value.
   */
  public void setPolicyQualifiersRejected(boolean value)
  {
    policyQualRejected = value;
  }

  /**
   * Returns the date for which the certificate path should be
   * validated, or null if the current time should be used. The date
   * object is copied to prevent subsequent modification.
   *
   * @return The date, or null if not set.
   */
  public Date getDate()
  {
    return date != null ? (Date) date.clone() : null;
  }

  /**
   * Sets the date for which the certificate path should be validated,
   * or null if the current time should be used.
   *
   * @param date The new date, or null.
   */
  public void setDate(Date date)
  {
    if (date != null)
      this.date = (Date) date.clone();
    else
      this.date = null;
  }

  /**
   * Add a certificate path checker.
   *
   * @param checker The certificate path checker to add.
   */
  public void addCertPathChecker(PKIXCertPathChecker checker)
  {
    if (checker != null)
      pathCheckers.add(checker);
  }

  /**
   * Returns an immutable list of all certificate path checkers.
   *
   * @return An immutable list of all certificate path checkers.
   */
  public List<PKIXCertPathChecker> getCertPathCheckers()
  {
    return Collections.unmodifiableList(pathCheckers);
  }

  /**
   * Sets the certificate path checkers. If the argument is null, the
   * list of checkers will merely be cleared.
   *
   * @param pathCheckers The new list of certificate path checkers.
   * @throws ClassCastException If any element of <i>pathCheckers</i> is
   *         not a {@link PKIXCertPathChecker}.
   */
  public void setCertPathCheckers(List<PKIXCertPathChecker> pathCheckers)
  {
    this.pathCheckers.clear();
    if (pathCheckers == null)
      return;
    for (Iterator i = pathCheckers.iterator(); i.hasNext(); )
      {
        this.pathCheckers.add((PKIXCertPathChecker) i.next());
      }
  }

  /**
   * Returns the signature algorithm provider, or null if not set.
   *
   * @return The signature algorithm provider, or null if not set.
   */
  public String getSigProvider()
  {
    return sigProvider;
  }

  /**
   * Sets the signature algorithm provider, or null if there is no
   * preferred provider.
   *
   * @param sigProvider The signature provider name.
   */
  public void setSigProvider(String sigProvider)
  {
    this.sigProvider = sigProvider;
  }

  /**
   * Returns the constraints placed on the target certificate, or null
   * if there are none. The target constraints are copied to prevent
   * subsequent modification.
   *
   * @return The target constraints, or null.
   */
  public CertSelector getTargetCertConstraints()
  {
    return targetConstraints != null
      ? (CertSelector) targetConstraints.clone() : null;
  }

  /**
   * Sets the constraints placed on the target certificate.
   *
   * @param targetConstraints The target constraints.
   */
  public void setTargetCertConstraints(CertSelector targetConstraints)
  {
    this.targetConstraints = targetConstraints != null
      ? (CertSelector) targetConstraints.clone() : null;
  }

  /**
   * Returns a copy of these parameters.
   *
   * @return The copy.
   */
  public Object clone()
  {
    return new PKIXParameters(this);
  }

  /**
   * Returns a printable representation of these parameters.
   *
   * @return A printable representation of these parameters.
   */
  public String toString() {
    return "[ Trust Anchors: " + trustAnchors + "; Initial Policy OIDs="
      + (initPolicies != null ? initPolicies.toString() : "any")
      + "; Validity Date=" + date + "; Signature Provider="
      + sigProvider + "; Default Revocation Enabled=" + revocationEnabled
      + "; Explicit Policy Required=" + exPolicyRequired
      + "; Policy Mapping Inhibited=" + policyMappingInhibited
      + "; Any Policy Inhibited=" + anyPolicyInhibited
      + "; Policy Qualifiers Rejected=" + policyQualRejected
      + "; Target Cert Contstraints=" + targetConstraints
      + "; Certification Path Checkers=" + pathCheckers
      + "; CertStores=" + certStores + " ]";
  }
}
