/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package java.security.cert;

import java.io.IOException;
import java.math.BigInteger;
import java.util.*;

import javax.security.auth.x500.X500Principal;

import sun.security.util.Debug;
import sun.security.util.DerInputStream;
import sun.security.x509.CRLNumberExtension;
import sun.security.x509.X500Name;

/**
 * A <code>CRLSelector</code> that selects <code>X509CRLs</code> that
 * match all specified criteria. This class is particularly useful when
 * selecting CRLs from a <code>CertStore</code> to check revocation status
 * of a particular certificate.
 * <p>
 * When first constructed, an <code>X509CRLSelector</code> has no criteria
 * enabled and each of the <code>get</code> methods return a default
 * value (<code>null</code>). Therefore, the {@link #match match} method
 * would return <code>true</code> for any <code>X509CRL</code>. Typically,
 * several criteria are enabled (by calling {@link #setIssuers setIssuers}
 * or {@link #setDateAndTime setDateAndTime}, for instance) and then the
 * <code>X509CRLSelector</code> is passed to
 * {@link CertStore#getCRLs CertStore.getCRLs} or some similar
 * method.
 * <p>
 * Please refer to <a href="http://www.ietf.org/rfc/rfc3280.txt">RFC 3280:
 * Internet X.509 Public Key Infrastructure Certificate and CRL Profile</a>
 * for definitions of the X.509 CRL fields and extensions mentioned below.
 * <p>
 * <b>Concurrent Access</b>
 * <p>
 * Unless otherwise specified, the methods defined in this class are not
 * thread-safe. Multiple threads that need to access a single
 * object concurrently should synchronize amongst themselves and
 * provide the necessary locking. Multiple threads each manipulating
 * separate objects need not synchronize.
 *
 * @see CRLSelector
 * @see X509CRL
 *
 * @since       1.4
 * @author      Steve Hanna
 */
public class X509CRLSelector implements CRLSelector {

    private static final Debug debug = Debug.getInstance("certpath");
    private HashSet<Object> issuerNames;
    private HashSet<X500Principal> issuerX500Principals;
    private BigInteger minCRL;
    private BigInteger maxCRL;
    private Date dateAndTime;
    private X509Certificate certChecking;

    /**
     * Creates an <code>X509CRLSelector</code>. Initially, no criteria are set
     * so any <code>X509CRL</code> will match.
     */
    public X509CRLSelector() {}

    /**
     * Sets the issuerNames criterion. The issuer distinguished name in the
     * <code>X509CRL</code> must match at least one of the specified
     * distinguished names. If <code>null</code>, any issuer distinguished name
     * will do.
     * <p>
     * This method allows the caller to specify, with a single method call,
     * the complete set of issuer names which <code>X509CRLs</code> may contain.
     * The specified value replaces the previous value for the issuerNames
     * criterion.
     * <p>
     * The <code>names</code> parameter (if not <code>null</code>) is a
     * <code>Collection</code> of <code>X500Principal</code>s.
     * <p>
     * Note that the <code>names</code> parameter can contain duplicate
     * distinguished names, but they may be removed from the
     * <code>Collection</code> of names returned by the
     * {@link #getIssuers getIssuers} method.
     * <p>
     * Note that a copy is performed on the <code>Collection</code> to
     * protect against subsequent modifications.
     *
     * @param issuers a <code>Collection</code> of X500Principals
     *   (or <code>null</code>)
     * @see #getIssuers
     * @since 1.5
     */
    public void setIssuers(Collection<X500Principal> issuers) {
        if ((issuers == null) || issuers.isEmpty()) {
            issuerNames = null;
            issuerX500Principals = null;
        } else {
            // clone
            issuerX500Principals = new HashSet<X500Principal>(issuers);
            issuerNames = new HashSet<Object>();
            for (X500Principal p : issuerX500Principals) {
                issuerNames.add(p.getEncoded());
            }
        }
    }

    /**
     * <strong>Note:</strong> use {@linkplain #setIssuers(Collection)} instead
     * or only specify the byte array form of distinguished names when using
     * this method. See {@link #addIssuerName(String)} for more information.
     * <p>
     * Sets the issuerNames criterion. The issuer distinguished name in the
     * <code>X509CRL</code> must match at least one of the specified
     * distinguished names. If <code>null</code>, any issuer distinguished name
     * will do.
     * <p>
     * This method allows the caller to specify, with a single method call,
     * the complete set of issuer names which <code>X509CRLs</code> may contain.
     * The specified value replaces the previous value for the issuerNames
     * criterion.
     * <p>
     * The <code>names</code> parameter (if not <code>null</code>) is a
     * <code>Collection</code> of names. Each name is a <code>String</code>
     * or a byte array representing a distinguished name (in
     * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a> or
     * ASN.1 DER encoded form, respectively). If <code>null</code> is supplied
     * as the value for this argument, no issuerNames check will be performed.
     * <p>
     * Note that the <code>names</code> parameter can contain duplicate
     * distinguished names, but they may be removed from the
     * <code>Collection</code> of names returned by the
     * {@link #getIssuerNames getIssuerNames} method.
     * <p>
     * If a name is specified as a byte array, it should contain a single DER
     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
     * this structure is as follows.
     * <pre><code>
     * Name ::= CHOICE {
     *   RDNSequence }
     *
     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
     *
     * RelativeDistinguishedName ::=
     *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
     *
     * AttributeTypeAndValue ::= SEQUENCE {
     *   type     AttributeType,
     *   value    AttributeValue }
     *
     * AttributeType ::= OBJECT IDENTIFIER
     *
     * AttributeValue ::= ANY DEFINED BY AttributeType
     * ....
     * DirectoryString ::= CHOICE {
     *       teletexString           TeletexString (SIZE (1..MAX)),
     *       printableString         PrintableString (SIZE (1..MAX)),
     *       universalString         UniversalString (SIZE (1..MAX)),
     *       utf8String              UTF8String (SIZE (1.. MAX)),
     *       bmpString               BMPString (SIZE (1..MAX)) }
     * </code></pre>
     * <p>
     * Note that a deep copy is performed on the <code>Collection</code> to
     * protect against subsequent modifications.
     *
     * @param names a <code>Collection</code> of names (or <code>null</code>)
     * @throws IOException if a parsing error occurs
     * @see #getIssuerNames
     */
    public void setIssuerNames(Collection<?> names) throws IOException {
        if (names == null || names.size() == 0) {
            issuerNames = null;
            issuerX500Principals = null;
        } else {
            HashSet<Object> tempNames = cloneAndCheckIssuerNames(names);
            // Ensure that we either set both of these or neither
            issuerX500Principals = parseIssuerNames(tempNames);
            issuerNames = tempNames;
        }
    }

    /**
     * Adds a name to the issuerNames criterion. The issuer distinguished
     * name in the <code>X509CRL</code> must match at least one of the specified
     * distinguished names.
     * <p>
     * This method allows the caller to add a name to the set of issuer names
     * which <code>X509CRLs</code> may contain. The specified name is added to
     * any previous value for the issuerNames criterion.
     * If the specified name is a duplicate, it may be ignored.
     *
     * @param issuer the issuer as X500Principal
     * @since 1.5
     */
    public void addIssuer(X500Principal issuer) {
        addIssuerNameInternal(issuer.getEncoded(), issuer);
    }

    /**
     * <strong>Denigrated</strong>, use
     * {@linkplain #addIssuer(X500Principal)} or
     * {@linkplain #addIssuerName(byte[])} instead. This method should not be
     * relied on as it can fail to match some CRLs because of a loss of
     * encoding information in the RFC 2253 String form of some distinguished
     * names.
     * <p>
     * Adds a name to the issuerNames criterion. The issuer distinguished
     * name in the <code>X509CRL</code> must match at least one of the specified
     * distinguished names.
     * <p>
     * This method allows the caller to add a name to the set of issuer names
     * which <code>X509CRLs</code> may contain. The specified name is added to
     * any previous value for the issuerNames criterion.
     * If the specified name is a duplicate, it may be ignored.
     *
     * @param name the name in RFC 2253 form
     * @throws IOException if a parsing error occurs
     */
    public void addIssuerName(String name) throws IOException {
        addIssuerNameInternal(name, new X500Name(name).asX500Principal());
    }

    /**
     * Adds a name to the issuerNames criterion. The issuer distinguished
     * name in the <code>X509CRL</code> must match at least one of the specified
     * distinguished names.
     * <p>
     * This method allows the caller to add a name to the set of issuer names
     * which <code>X509CRLs</code> may contain. The specified name is added to
     * any previous value for the issuerNames criterion. If the specified name
     * is a duplicate, it may be ignored.
     * If a name is specified as a byte array, it should contain a single DER
     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
     * this structure is as follows.
     * <p>
     * The name is provided as a byte array. This byte array should contain
     * a single DER encoded distinguished name, as defined in X.501. The ASN.1
     * notation for this structure appears in the documentation for
     * {@link #setIssuerNames setIssuerNames(Collection names)}.
     * <p>
     * Note that the byte array supplied here is cloned to protect against
     * subsequent modifications.
     *
     * @param name a byte array containing the name in ASN.1 DER encoded form
     * @throws IOException if a parsing error occurs
     */
    public void addIssuerName(byte[] name) throws IOException {
        // clone because byte arrays are modifiable
        addIssuerNameInternal(name.clone(), new X500Name(name).asX500Principal());
    }

    /**
     * A private method that adds a name (String or byte array) to the
     * issuerNames criterion. The issuer distinguished
     * name in the <code>X509CRL</code> must match at least one of the specified
     * distinguished names.
     *
     * @param name the name in string or byte array form
     * @param principal the name in X500Principal form
     * @throws IOException if a parsing error occurs
     */
    private void addIssuerNameInternal(Object name, X500Principal principal) {
        if (issuerNames == null) {
            issuerNames = new HashSet<Object>();
        }
        if (issuerX500Principals == null) {
            issuerX500Principals = new HashSet<X500Principal>();
        }
        issuerNames.add(name);
        issuerX500Principals.add(principal);
    }

    /**
     * Clone and check an argument of the form passed to
     * setIssuerNames. Throw an IOException if the argument is malformed.
     *
     * @param names a <code>Collection</code> of names. Each entry is a
     *              String or a byte array (the name, in string or ASN.1
     *              DER encoded form, respectively). <code>null</code> is
     *              not an acceptable value.
     * @return a deep copy of the specified <code>Collection</code>
     * @throws IOException if a parsing error occurs
     */
    private static HashSet<Object> cloneAndCheckIssuerNames(Collection<?> names)
        throws IOException
    {
        HashSet<Object> namesCopy = new HashSet<Object>();
        Iterator<?> i = names.iterator();
        while (i.hasNext()) {
            Object nameObject = i.next();
            if (!(nameObject instanceof byte []) &&
                !(nameObject instanceof String))
                throw new IOException("name not byte array or String");
            if (nameObject instanceof byte [])
                namesCopy.add(((byte []) nameObject).clone());
            else
                namesCopy.add(nameObject);
        }
        return(namesCopy);
    }

    /**
     * Clone an argument of the form passed to setIssuerNames.
     * Throw a RuntimeException if the argument is malformed.
     * <p>
     * This method wraps cloneAndCheckIssuerNames, changing any IOException
     * into a RuntimeException. This method should be used when the object being
     * cloned has already been checked, so there should never be any exceptions.
     *
     * @param names a <code>Collection</code> of names. Each entry is a
     *              String or a byte array (the name, in string or ASN.1
     *              DER encoded form, respectively). <code>null</code> is
     *              not an acceptable value.
     * @return a deep copy of the specified <code>Collection</code>
     * @throws RuntimeException if a parsing error occurs
     */
    private static HashSet<Object> cloneIssuerNames(Collection<Object> names) {
        try {
            return cloneAndCheckIssuerNames(names);
        } catch (IOException ioe) {
            throw new RuntimeException(ioe);
        }
    }

    /**
     * Parse an argument of the form passed to setIssuerNames,
     * returning a Collection of issuerX500Principals.
     * Throw an IOException if the argument is malformed.
     *
     * @param names a <code>Collection</code> of names. Each entry is a
     *              String or a byte array (the name, in string or ASN.1
     *              DER encoded form, respectively). <Code>Null</Code> is
     *              not an acceptable value.
     * @return a HashSet of issuerX500Principals
     * @throws IOException if a parsing error occurs
     */
    private static HashSet<X500Principal> parseIssuerNames(Collection<Object> names)
    throws IOException {
        HashSet<X500Principal> x500Principals = new HashSet<X500Principal>();
        for (Iterator<Object> t = names.iterator(); t.hasNext(); ) {
            Object nameObject = t.next();
            if (nameObject instanceof String) {
                x500Principals.add(new X500Name((String)nameObject).asX500Principal());
            } else {
                try {
                    x500Principals.add(new X500Principal((byte[])nameObject));
                } catch (IllegalArgumentException e) {
                    throw (IOException)new IOException("Invalid name").initCause(e);
                }
            }
        }
        return x500Principals;
    }

    /**
     * Sets the minCRLNumber criterion. The <code>X509CRL</code> must have a
     * CRL number extension whose value is greater than or equal to the
     * specified value. If <code>null</code>, no minCRLNumber check will be
     * done.
     *
     * @param minCRL the minimum CRL number accepted (or <code>null</code>)
     */
    public void setMinCRLNumber(BigInteger minCRL) {
        this.minCRL = minCRL;
    }

    /**
     * Sets the maxCRLNumber criterion. The <code>X509CRL</code> must have a
     * CRL number extension whose value is less than or equal to the
     * specified value. If <code>null</code>, no maxCRLNumber check will be
     * done.
     *
     * @param maxCRL the maximum CRL number accepted (or <code>null</code>)
     */
    public void setMaxCRLNumber(BigInteger maxCRL) {
        this.maxCRL = maxCRL;
    }

    /**
     * Sets the dateAndTime criterion. The specified date must be
     * equal to or later than the value of the thisUpdate component
     * of the <code>X509CRL</code> and earlier than the value of the
     * nextUpdate component. There is no match if the <code>X509CRL</code>
     * does not contain a nextUpdate component.
     * If <code>null</code>, no dateAndTime check will be done.
     * <p>
     * Note that the <code>Date</code> supplied here is cloned to protect
     * against subsequent modifications.
     *
     * @param dateAndTime the <code>Date</code> to match against
     *                    (or <code>null</code>)
     * @see #getDateAndTime
     */
    public void setDateAndTime(Date dateAndTime) {
        if (dateAndTime == null)
            this.dateAndTime = null;
        else
            this.dateAndTime = (Date) dateAndTime.clone();
    }

    /**
     * Sets the certificate being checked. This is not a criterion. Rather,
     * it is optional information that may help a <code>CertStore</code>
     * find CRLs that would be relevant when checking revocation for the
     * specified certificate. If <code>null</code> is specified, then no
     * such optional information is provided.
     *
     * @param cert the <code>X509Certificate</code> being checked
     *             (or <code>null</code>)
     * @see #getCertificateChecking
     */
    public void setCertificateChecking(X509Certificate cert) {
        certChecking = cert;
    }

    /**
     * Returns the issuerNames criterion. The issuer distinguished
     * name in the <code>X509CRL</code> must match at least one of the specified
     * distinguished names. If the value returned is <code>null</code>, any
     * issuer distinguished name will do.
     * <p>
     * If the value returned is not <code>null</code>, it is a
     * unmodifiable <code>Collection</code> of <code>X500Principal</code>s.
     *
     * @return an unmodifiable <code>Collection</code> of names
     *   (or <code>null</code>)
     * @see #setIssuers
     * @since 1.5
     */
    public Collection<X500Principal> getIssuers() {
        if (issuerX500Principals == null) {
            return null;
        }
        return Collections.unmodifiableCollection(issuerX500Principals);
    }

    /**
     * Returns a copy of the issuerNames criterion. The issuer distinguished
     * name in the <code>X509CRL</code> must match at least one of the specified
     * distinguished names. If the value returned is <code>null</code>, any
     * issuer distinguished name will do.
     * <p>
     * If the value returned is not <code>null</code>, it is a
     * <code>Collection</code> of names. Each name is a <code>String</code>
     * or a byte array representing a distinguished name (in RFC 2253 or
     * ASN.1 DER encoded form, respectively).  Note that the
     * <code>Collection</code> returned may contain duplicate names.
     * <p>
     * If a name is specified as a byte array, it should contain a single DER
     * encoded distinguished name, as defined in X.501. The ASN.1 notation for
     * this structure is given in the documentation for
     * {@link #setIssuerNames setIssuerNames(Collection names)}.
     * <p>
     * Note that a deep copy is performed on the <code>Collection</code> to
     * protect against subsequent modifications.
     *
     * @return a <code>Collection</code> of names (or <code>null</code>)
     * @see #setIssuerNames
     */
    public Collection<Object> getIssuerNames() {
        if (issuerNames == null) {
            return null;
        }
        return cloneIssuerNames(issuerNames);
    }

    /**
     * Returns the minCRLNumber criterion. The <code>X509CRL</code> must have a
     * CRL number extension whose value is greater than or equal to the
     * specified value. If <code>null</code>, no minCRLNumber check will be done.
     *
     * @return the minimum CRL number accepted (or <code>null</code>)
     */
    public BigInteger getMinCRL() {
        return minCRL;
    }

    /**
     * Returns the maxCRLNumber criterion. The <code>X509CRL</code> must have a
     * CRL number extension whose value is less than or equal to the
     * specified value. If <code>null</code>, no maxCRLNumber check will be
     * done.
     *
     * @return the maximum CRL number accepted (or <code>null</code>)
     */
    public BigInteger getMaxCRL() {
        return maxCRL;
    }

    /**
     * Returns the dateAndTime criterion. The specified date must be
     * equal to or later than the value of the thisUpdate component
     * of the <code>X509CRL</code> and earlier than the value of the
     * nextUpdate component. There is no match if the
     * <code>X509CRL</code> does not contain a nextUpdate component.
     * If <code>null</code>, no dateAndTime check will be done.
     * <p>
     * Note that the <code>Date</code> returned is cloned to protect against
     * subsequent modifications.
     *
     * @return the <code>Date</code> to match against (or <code>null</code>)
     * @see #setDateAndTime
     */
    public Date getDateAndTime() {
        if (dateAndTime == null)
            return null;
        return (Date) dateAndTime.clone();
    }

    /**
     * Returns the certificate being checked. This is not a criterion. Rather,
     * it is optional information that may help a <code>CertStore</code>
     * find CRLs that would be relevant when checking revocation for the
     * specified certificate. If the value returned is <code>null</code>, then
     * no such optional information is provided.
     *
     * @return the certificate being checked (or <code>null</code>)
     * @see #setCertificateChecking
     */
    public X509Certificate getCertificateChecking() {
        return certChecking;
    }

    /**
     * Returns a printable representation of the <code>X509CRLSelector</code>.
     *
     * @return a <code>String</code> describing the contents of the
     *         <code>X509CRLSelector</code>.
     */
    public String toString() {
        StringBuffer sb = new StringBuffer();
        sb.append("X509CRLSelector: [\n");
        if (issuerNames != null) {
            sb.append("  IssuerNames:\n");
            Iterator<Object> i = issuerNames.iterator();
            while (i.hasNext())
                sb.append("    " + i.next() + "\n");
        }
        if (minCRL != null)
            sb.append("  minCRLNumber: " + minCRL + "\n");
        if (maxCRL != null)
            sb.append("  maxCRLNumber: " + maxCRL + "\n");
        if (dateAndTime != null)
            sb.append("  dateAndTime: " + dateAndTime + "\n");
        if (certChecking != null)
            sb.append("  Certificate being checked: " + certChecking + "\n");
        sb.append("]");
        return sb.toString();
    }

    /**
     * Decides whether a <code>CRL</code> should be selected.
     *
     * @param crl the <code>CRL</code> to be checked
     * @return <code>true</code> if the <code>CRL</code> should be selected,
     *         <code>false</code> otherwise
     */
    public boolean match(CRL crl) {
        if (!(crl instanceof X509CRL)) {
            return false;
        }
        X509CRL xcrl = (X509CRL)crl;

        /* match on issuer name */
        if (issuerNames != null) {
            X500Principal issuer = xcrl.getIssuerX500Principal();
            Iterator<X500Principal> i = issuerX500Principals.iterator();
            boolean found = false;
            while (!found && i.hasNext()) {
                if (i.next().equals(issuer)) {
                    found = true;
                }
            }
            if (!found) {
                if (debug != null) {
                    debug.println("X509CRLSelector.match: issuer DNs "
                        + "don't match");
                }
                return false;
            }
        }

        if ((minCRL != null) || (maxCRL != null)) {
            /* Get CRL number extension from CRL */
            byte[] crlNumExtVal = xcrl.getExtensionValue("2.5.29.20");
            if (crlNumExtVal == null) {
                if (debug != null) {
                    debug.println("X509CRLSelector.match: no CRLNumber");
                }
            }
            BigInteger crlNum;
            try {
                DerInputStream in = new DerInputStream(crlNumExtVal);
                byte[] encoded = in.getOctetString();
                CRLNumberExtension crlNumExt =
                    new CRLNumberExtension(Boolean.FALSE, encoded);
                crlNum = (BigInteger)crlNumExt.get(CRLNumberExtension.NUMBER);
            } catch (IOException ex) {
                if (debug != null) {
                    debug.println("X509CRLSelector.match: exception in "
                        + "decoding CRL number");
                }
                return false;
            }

            /* match on minCRLNumber */
            if (minCRL != null) {
                if (crlNum.compareTo(minCRL) < 0) {
                    if (debug != null) {
                        debug.println("X509CRLSelector.match: CRLNumber too small");
                    }
                    return false;
                }
            }

            /* match on maxCRLNumber */
            if (maxCRL != null) {
                if (crlNum.compareTo(maxCRL) > 0) {
                    if (debug != null) {
                        debug.println("X509CRLSelector.match: CRLNumber too large");
                    }
                    return false;
                }
            }
        }


        /* match on dateAndTime */
        if (dateAndTime != null) {
            Date crlThisUpdate = xcrl.getThisUpdate();
            Date nextUpdate = xcrl.getNextUpdate();
            if (nextUpdate == null) {
                if (debug != null) {
                    debug.println("X509CRLSelector.match: nextUpdate null");
                }
                return false;
            }
            if (crlThisUpdate.after(dateAndTime)
                  || nextUpdate.before(dateAndTime)) {
                if (debug != null) {
                    debug.println("X509CRLSelector.match: update out of range");
                }
                return false;
            }
        }

        return true;
    }

    /**
     * Returns a copy of this object.
     *
     * @return the copy
     */
    public Object clone() {
        try {
            X509CRLSelector copy = (X509CRLSelector)super.clone();
            if (issuerNames != null) {
                copy.issuerNames =
                        new HashSet<Object>(issuerNames);
                copy.issuerX500Principals =
                        new HashSet<X500Principal>(issuerX500Principals);
            }
            return copy;
        } catch (CloneNotSupportedException e) {
            /* Cannot happen */
            throw new InternalError(e.toString());
        }
    }
}
