/* X509CRLSelector.java -- selects X.509 CRLs by criteria.
   Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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 gnu.java.security.action.GetPropertyAction;
import gnu.java.security.der.DERReader;
import gnu.java.security.der.DERValue;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.AccessController;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.security.auth.x500.X500Principal;

/**
 * A class for matching X.509 certificate revocation lists by criteria.
 *
 * <p>Use of this class requires extensive knowledge of the Internet
 * Engineering Task Force's Public Key Infrastructure (X.509). The primary
 * document describing this standard is <a
 * href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280: Internet X.509
 * Public Key Infrastructure Certificate and Certificate Revocation List
 * (CRL) Profile</a>.
 *
 * <p>Note that this class is not thread-safe. If multiple threads will
 * use or modify this class then they need to synchronize on the object.
 *
 * @author Casey Marshall (csm@gnu.org)
 */
public class X509CRLSelector implements CRLSelector, Cloneable
{

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

  private static final String CRL_NUMBER_ID = "2.5.29.20";

  private List issuerNames;
  private BigInteger maxCrlNumber;
  private BigInteger minCrlNumber;
  private Date date;
  private X509Certificate cert;

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

  /**
   * Creates a new CRL selector with no criteria enabled; i.e., every CRL
   * will be matched.
   */
  public X509CRLSelector()
  {
  }

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

  /**
   * Add an issuer name to the set of issuer names criteria, as the DER
   * encoded form.
   *
   * @param name The name to add, as DER bytes.
   * @throws IOException If the argument is not a valid DER-encoding.
   */
  public void addIssuerName(byte[] name) throws IOException
  {
    X500Principal p = null;
    try
      {
        p = new X500Principal(name);
      }
    catch (IllegalArgumentException iae)
      {
        IOException ioe = new IOException("malformed name");
        ioe.initCause(iae);
        throw ioe;
      }
    if (issuerNames == null)
      issuerNames = new LinkedList();
    issuerNames.add(p);
  }

  /**
   * Add an issuer name to the set of issuer names criteria, as a
   * String representation.
   *
   * @param name The name to add.
   * @throws IOException If the argument is not a valid name.
   */
  public void addIssuerName(String name) throws IOException
  {
    X500Principal p = null;
    try
      {
        p = new X500Principal(name);
      }
    catch (IllegalArgumentException iae)
      {
        IOException ioe = new IOException("malformed name: " + name);
        ioe.initCause(iae);
        throw ioe;
      }
    if (issuerNames == null)
      issuerNames = new LinkedList();
    issuerNames.add(p);
  }

  /**
   * Sets the issuer names criterion. Pass <code>null</code> to clear this
   * value. CRLs matched by this selector must have an issuer name in this
   * set.
   *
   * @param names The issuer names.
   * @throws IOException If any of the elements in the collection is not
   *         a valid name.
   */
  public void setIssuerNames(Collection names) throws IOException
  {
    if (names == null)
      {
        issuerNames = null;
        return;
      }
    List l = new ArrayList(names.size());
    for (Iterator it = names.iterator(); it.hasNext(); )
      {
        Object o = it.next();
        if (o instanceof X500Principal)
          l.add(o);
        else if (o instanceof String)
          {
            try
              {
                l.add(new X500Principal((String) o));
              }
            catch (IllegalArgumentException iae)
              {
                IOException ioe = new IOException("malformed name: " + o);
                ioe.initCause(iae);
                throw ioe;
              }
          }
        else if (o instanceof byte[])
          {
            try
              {
                l.add(new X500Principal((byte[]) o));
              }
            catch (IllegalArgumentException iae)
              {
                IOException ioe = new IOException("malformed name");
                ioe.initCause(iae);
                throw ioe;
              }
          }
        else if (o instanceof InputStream)
          {
            try
              {
                l.add(new X500Principal((InputStream) o));
              }
            catch (IllegalArgumentException iae)
              {
                IOException ioe = new IOException("malformed name");
                ioe.initCause(iae);
                throw ioe;
              }
          }
        else
          throw new IOException("not a valid name: " +
                                (o != null ? o.getClass().getName() : "null"));

      }
    issuerNames = l;
  }

  /**
   * Returns the set of issuer names that are matched by this selector,
   * or <code>null</code> if this criteria is not set. The returned
   * collection is not modifiable.
   *
   * @return The set of issuer names.
   */
  public Collection getIssuerNames()
  {
    if (issuerNames != null)
      return Collections.unmodifiableList(issuerNames);
    else
      return null;
  }

  /**
   * Returns the maximum value of the CRLNumber extension present in
   * CRLs matched by this selector, or <code>null</code> if this
   * criteria is not set.
   *
   * @return The maximum CRL number.
   */
  public BigInteger getMaxCRL()
  {
    return maxCrlNumber;
  }

  /**
   * Returns the minimum value of the CRLNumber extension present in
   * CRLs matched by this selector, or <code>null</code> if this
   * criteria is not set.
   *
   * @return The minimum CRL number.
   */
  public BigInteger getMinCRL()
  {
    return minCrlNumber;
  }

  /**
   * Sets the maximum value of the CRLNumber extension present in CRLs
   * matched by this selector. Specify <code>null</code> to clear this
   * criterion.
   *
   * @param maxCrlNumber The maximum CRL number.
   */
  public void setMaxCRLNumber(BigInteger maxCrlNumber)
  {
    this.maxCrlNumber = maxCrlNumber;
  }

  /**
   * Sets the minimum value of the CRLNumber extension present in CRLs
   * matched by this selector. Specify <code>null</code> to clear this
   * criterion.
   *
   * @param minCrlNumber The minimum CRL number.
   */
  public void setMinCRLNumber(BigInteger minCrlNumber)
  {
    this.minCrlNumber = minCrlNumber;
  }

  /**
   * Returns the date when this CRL must be valid; that is, the date
   * must be after the thisUpdate date, but before the nextUpdate date.
   * Returns <code>null</code> if this criterion is not set.
   *
   * @return The date.
   */
  public Date getDateAndTime()
  {
    return date != null ? (Date) date.clone() : null;
  }

  /**
   * Sets the date at which this CRL must be valid. Specify
   * <code>null</code> to clear this criterion.
   *
   * @param date The date.
   */
  public void setDateAndTime(Date date)
  {
    this.date = date != null ? (Date) date.clone() : null;
  }

  /**
   * Returns the certificate being checked, or <code>null</code> if this
   * value is not set.
   *
   * @return The certificate.
   */
  public X509Certificate getCertificateChecking()
  {
    return cert;
  }

  /**
   * Sets the certificate being checked. This is not a criterion, but
   * info used by certificate store implementations to aid in searching.
   *
   * @param cert The certificate.
   */
  public void setCertificateChecking(X509Certificate cert)
  {
    this.cert = cert;
  }

  /**
   * Returns a string representation of this selector. The string will
   * only describe the enabled criteria, so if none are enabled this will
   * return a string that contains little else besides the class name.
   *
   * @return The string.
   */
  public String toString()
  {
    StringBuffer str = new StringBuffer(X509CRLSelector.class.getName());
    GetPropertyAction getProp = new GetPropertyAction("line.separator");
    String nl = (String) AccessController.doPrivileged(getProp);
    String eol = ";" + nl;

    str.append(" {").append(nl);
    if (issuerNames != null)
      str.append("  issuer names = ").append(issuerNames).append(eol);
    if (maxCrlNumber != null)
      str.append("  max CRL = ").append(maxCrlNumber).append(eol);
    if (minCrlNumber != null)
      str.append("  min CRL = ").append(minCrlNumber).append(eol);
    if (date != null)
      str.append("  date = ").append(date).append(eol);
    if (cert != null)
      str.append("  certificate = ").append(cert).append(eol);
    str.append("}").append(nl);
    return str.toString();
  }

  /**
   * Checks a CRL against the criteria of this selector, returning
   * <code>true</code> if the given CRL matches all the criteria.
   *
   * @param _crl The CRL being checked.
   * @return True if the CRL matches, false otherwise.
   */
  public boolean match(CRL _crl)
  {
    if (!(_crl instanceof X509CRL))
      return false;
    X509CRL crl = (X509CRL) _crl;
    if (issuerNames != null)
      {
        if (!issuerNames.contains(crl.getIssuerX500Principal()))
          return false;
      }
    BigInteger crlNumber = null;
    if (maxCrlNumber != null)
      {
        byte[] b = crl.getExtensionValue(CRL_NUMBER_ID);
        if (b == null)
          return false;
        try
          {
            DERValue val = DERReader.read(b);
            if (!(val.getValue() instanceof BigInteger))
              return false;
            crlNumber = (BigInteger) val.getValue();
          }
        catch (IOException ioe)
          {
            return false;
          }
        if (maxCrlNumber.compareTo(crlNumber) < 0)
          return false;
      }
    if (minCrlNumber != null)
      {
        if (crlNumber == null)
          {
            byte[] b = crl.getExtensionValue(CRL_NUMBER_ID);
            if (b == null)
              return false;
            try
              {
                DERValue val = DERReader.read(b);
                if (!(val.getValue() instanceof BigInteger))
                  return false;
                crlNumber = (BigInteger) val.getValue();
              }
            catch (IOException ioe)
              {
                return false;
              }
          }
        if (minCrlNumber.compareTo(crlNumber) > 0)
          return false;
      }
    if (date != null)
      {
        if (date.compareTo(crl.getThisUpdate()) < 0 ||
            date.compareTo(crl.getNextUpdate()) > 0)
          return false;
      }
    return true;
  }

  /**
   * Returns a copy of this object.
   *
   * @return The copy.
   */
  public Object clone()
  {
    try
      {
        return super.clone();
      }
    catch (CloneNotSupportedException shouldNotHappen)
      {
        throw new Error(shouldNotHappen);
      }
  }
}
