/* 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 + " ]";
  }
}
