/*
 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.provider.certpath.ldap;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URI;
import java.util.*;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NameNotFoundException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.*;
import javax.security.auth.x500.X500Principal;

import sun.misc.HexDumpEncoder;
import sun.security.provider.certpath.X509CertificatePair;
import sun.security.util.Cache;
import sun.security.util.Debug;
import sun.security.x509.X500Name;
import sun.security.action.GetPropertyAction;

/**
 * A <code>CertStore</code> that retrieves <code>Certificates</code> and
 * <code>CRL</code>s from an LDAP directory, using the PKIX LDAP V2 Schema
 * (RFC 2587):
 * <a href="http://www.ietf.org/rfc/rfc2587.txt">
 * http://www.ietf.org/rfc/rfc2587.txt</a>.
 * <p>
 * Before calling the {@link #engineGetCertificates engineGetCertificates} or
 * {@link #engineGetCRLs engineGetCRLs} methods, the
 * {@link #LDAPCertStore(CertStoreParameters)
 * LDAPCertStore(CertStoreParameters)} constructor is called to create the
 * <code>CertStore</code> and establish the DNS name and port of the LDAP
 * server from which <code>Certificate</code>s and <code>CRL</code>s will be
 * retrieved.
 * <p>
 * <b>Concurrent Access</b>
 * <p>
 * As described in the javadoc for <code>CertStoreSpi</code>, the
 * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods
 * must be thread-safe. That is, multiple threads may concurrently
 * invoke these methods on a single <code>LDAPCertStore</code> object
 * (or more than one) with no ill effects. This allows a
 * <code>CertPathBuilder</code> to search for a CRL while simultaneously
 * searching for further certificates, for instance.
 * <p>
 * This is achieved by adding the <code>synchronized</code> keyword to the
 * <code>engineGetCertificates</code> and <code>engineGetCRLs</code> methods.
 * <p>
 * This classes uses caching and requests multiple attributes at once to
 * minimize LDAP round trips. The cache is associated with the CertStore
 * instance. It uses soft references to hold the values to minimize impact
 * on footprint and currently has a maximum size of 750 attributes and a
 * 30 second default lifetime.
 * <p>
 * We always request CA certificates, cross certificate pairs, and ARLs in
 * a single LDAP request when any one of them is needed. The reason is that
 * we typically need all of them anyway and requesting them in one go can
 * reduce the number of requests to a third. Even if we don't need them,
 * these attributes are typically small enough not to cause a noticeable
 * overhead. In addition, when the prefetchCRLs flag is true, we also request
 * the full CRLs. It is currently false initially but set to true once any
 * request for an ARL to the server returns an null value. The reason is
 * that CRLs could be rather large but are rarely used. This implementation
 * should improve performance in most cases.
 *
 * @see java.security.cert.CertStore
 *
 * @since       1.4
 * @author      Steve Hanna
 * @author      Andreas Sterbenz
 */
public class LDAPCertStore extends CertStoreSpi {

    private static final Debug debug = Debug.getInstance("certpath");

    private final static boolean DEBUG = false;

    /**
     * LDAP attribute identifiers.
     */
    private static final String USER_CERT = "userCertificate;binary";
    private static final String CA_CERT = "cACertificate;binary";
    private static final String CROSS_CERT = "crossCertificatePair;binary";
    private static final String CRL = "certificateRevocationList;binary";
    private static final String ARL = "authorityRevocationList;binary";
    private static final String DELTA_CRL = "deltaRevocationList;binary";

    // Constants for various empty values
    private final static String[] STRING0 = new String[0];

    private final static byte[][] BB0 = new byte[0][];

    private final static Attributes EMPTY_ATTRIBUTES = new BasicAttributes();

    // cache related constants
    private final static int DEFAULT_CACHE_SIZE = 750;
    private final static int DEFAULT_CACHE_LIFETIME = 30;

    private final static int LIFETIME;

    private final static String PROP_LIFETIME =
                            "sun.security.certpath.ldap.cache.lifetime";

    static {
        String s = AccessController.doPrivileged(
                                new GetPropertyAction(PROP_LIFETIME));
        if (s != null) {
            LIFETIME = Integer.parseInt(s); // throws NumberFormatException
        } else {
            LIFETIME = DEFAULT_CACHE_LIFETIME;
        }
    }

    /**
     * The CertificateFactory used to decode certificates from
     * their binary stored form.
     */
    private CertificateFactory cf;
    /**
     * The JNDI directory context.
     */
    private DirContext ctx;

    /**
     * Flag indicating whether we should prefetch CRLs.
     */
    private boolean prefetchCRLs = false;

    private final Cache valueCache;

    private int cacheHits = 0;
    private int cacheMisses = 0;
    private int requests = 0;

    /**
     * Creates a <code>CertStore</code> with the specified parameters.
     * For this class, the parameters object must be an instance of
     * <code>LDAPCertStoreParameters</code>.
     *
     * @param params the algorithm parameters
     * @exception InvalidAlgorithmParameterException if params is not an
     *   instance of <code>LDAPCertStoreParameters</code>
     */
    public LDAPCertStore(CertStoreParameters params)
            throws InvalidAlgorithmParameterException {
        super(params);
        if (!(params instanceof LDAPCertStoreParameters))
          throw new InvalidAlgorithmParameterException(
            "parameters must be LDAPCertStoreParameters");

        LDAPCertStoreParameters lparams = (LDAPCertStoreParameters) params;

        // Create InitialDirContext needed to communicate with the server
        createInitialDirContext(lparams.getServerName(), lparams.getPort());

        // Create CertificateFactory for use later on
        try {
            cf = CertificateFactory.getInstance("X.509");
        } catch (CertificateException e) {
            throw new InvalidAlgorithmParameterException(
                "unable to create CertificateFactory for X.509");
        }
        if (LIFETIME == 0) {
            valueCache = Cache.newNullCache();
        } else if (LIFETIME < 0) {
            valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE);
        } else {
            valueCache = Cache.newSoftMemoryCache(DEFAULT_CACHE_SIZE, LIFETIME);
        }
    }

    /**
     * Returns an LDAP CertStore. This method consults a cache of
     * CertStores (shared per JVM) using the LDAP server/port as a key.
     */
    private static final Cache certStoreCache = Cache.newSoftMemoryCache(185);
    static synchronized CertStore getInstance(LDAPCertStoreParameters params)
        throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        CertStore lcs = (CertStore) certStoreCache.get(params);
        if (lcs == null) {
            lcs = CertStore.getInstance("LDAP", params);
            certStoreCache.put(params, lcs);
        } else {
            if (debug != null) {
                debug.println("LDAPCertStore.getInstance: cache hit");
            }
        }
        return lcs;
    }

    /**
     * Create InitialDirContext.
     *
     * @param server Server DNS name hosting LDAP service
     * @param port   Port at which server listens for requests
     * @throws InvalidAlgorithmParameterException if creation fails
     */
    private void createInitialDirContext(String server, int port)
            throws InvalidAlgorithmParameterException {
        String url = "ldap://" + server + ":" + port;
        Hashtable<String,Object> env = new Hashtable<String,Object>();
        env.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, url);
        try {
            ctx = new InitialDirContext(env);
            /*
             * By default, follow referrals unless application has
             * overridden property in an application resource file.
             */
            Hashtable<?,?> currentEnv = ctx.getEnvironment();
            if (currentEnv.get(Context.REFERRAL) == null) {
                ctx.addToEnvironment(Context.REFERRAL, "follow");
            }
        } catch (NamingException e) {
            if (debug != null) {
                debug.println("LDAPCertStore.engineInit about to throw "
                    + "InvalidAlgorithmParameterException");
                e.printStackTrace();
            }
            Exception ee = new InvalidAlgorithmParameterException
                ("unable to create InitialDirContext using supplied parameters");
            ee.initCause(e);
            throw (InvalidAlgorithmParameterException)ee;
        }
    }

    /**
     * Private class encapsulating the actual LDAP operations and cache
     * handling. Use:
     *
     *   LDAPRequest request = new LDAPRequest(dn);
     *   request.addRequestedAttribute(CROSS_CERT);
     *   request.addRequestedAttribute(CA_CERT);
     *   byte[][] crossValues = request.getValues(CROSS_CERT);
     *   byte[][] caValues = request.getValues(CA_CERT);
     *
     * At most one LDAP request is sent for each instance created. If all
     * getValues() calls can be satisfied from the cache, no request
     * is sent at all. If a request is sent, all requested attributes
     * are always added to the cache irrespective of whether the getValues()
     * method is called.
     */
    private class LDAPRequest {

        private final String name;
        private Map<String, byte[][]> valueMap;
        private final List<String> requestedAttributes;

        LDAPRequest(String name) {
            this.name = name;
            requestedAttributes = new ArrayList<String>(5);
        }

        String getName() {
            return name;
        }

        void addRequestedAttribute(String attrId) {
            if (valueMap != null) {
                throw new IllegalStateException("Request already sent");
            }
            requestedAttributes.add(attrId);
        }

        /**
         * Gets one or more binary values from an attribute.
         *
         * @param name          the location holding the attribute
         * @param attrId                the attribute identifier
         * @return                      an array of binary values (byte arrays)
         * @throws NamingException      if a naming exception occurs
         */
        byte[][] getValues(String attrId) throws NamingException {
            if (DEBUG && ((cacheHits + cacheMisses) % 50 == 0)) {
                System.out.println("Cache hits: " + cacheHits + "; misses: "
                        + cacheMisses);
            }
            String cacheKey = name + "|" + attrId;
            byte[][] values = (byte[][])valueCache.get(cacheKey);
            if (values != null) {
                cacheHits++;
                return values;
            }
            cacheMisses++;
            Map<String, byte[][]> attrs = getValueMap();
            values = attrs.get(attrId);
            return values;
        }

        /**
         * Get a map containing the values for this request. The first time
         * this method is called on an object, the LDAP request is sent,
         * the results parsed and added to a private map and also to the
         * cache of this LDAPCertStore. Subsequent calls return the private
         * map immediately.
         *
         * The map contains an entry for each requested attribute. The
         * attribute name is the key, values are byte[][]. If there are no
         * values for that attribute, values are byte[0][].
         *
         * @return                      the value Map
         * @throws NamingException      if a naming exception occurs
         */
        private Map<String, byte[][]> getValueMap() throws NamingException {
            if (valueMap != null) {
                return valueMap;
            }
            if (DEBUG) {
                System.out.println("Request: " + name + ":" + requestedAttributes);
                requests++;
                if (requests % 5 == 0) {
                    System.out.println("LDAP requests: " + requests);
                }
            }
            valueMap = new HashMap<String, byte[][]>(8);
            String[] attrIds = requestedAttributes.toArray(STRING0);
            Attributes attrs;
            try {
                attrs = ctx.getAttributes(name, attrIds);
            } catch (NameNotFoundException e) {
                // name does not exist on this LDAP server
                // treat same as not attributes found
                attrs = EMPTY_ATTRIBUTES;
            }
            for (String attrId : requestedAttributes) {
                Attribute attr = attrs.get(attrId);
                byte[][] values = getAttributeValues(attr);
                cacheAttribute(attrId, values);
                valueMap.put(attrId, values);
            }
            return valueMap;
        }

        /**
         * Add the values to the cache.
         */
        private void cacheAttribute(String attrId, byte[][] values) {
            String cacheKey = name + "|" + attrId;
            valueCache.put(cacheKey, values);
        }

        /**
         * Get the values for the given attribute. If the attribute is null
         * or does not contain any values, a zero length byte array is
         * returned. NOTE that it is assumed that all values are byte arrays.
         */
        private byte[][] getAttributeValues(Attribute attr)
                throws NamingException {
            byte[][] values;
            if (attr == null) {
                values = BB0;
            } else {
                values = new byte[attr.size()][];
                int i = 0;
                NamingEnumeration<?> enum_ = attr.getAll();
                while (enum_.hasMore()) {
                    Object obj = enum_.next();
                    if (debug != null) {
                        if (obj instanceof String) {
                            debug.println("LDAPCertStore.getAttrValues() "
                                + "enum.next is a string!: " + obj);
                        }
                    }
                    byte[] value = (byte[])obj;
                    values[i++] = value;
                }
            }
            return values;
        }

    }

    /*
     * Gets certificates from an attribute id and location in the LDAP
     * directory. Returns a Collection containing only the Certificates that
     * match the specified CertSelector.
     *
     * @param name the location holding the attribute
     * @param id the attribute identifier
     * @param sel a CertSelector that the Certificates must match
     * @return a Collection of Certificates found
     * @throws CertStoreException       if an exception occurs
     */
    private Collection<X509Certificate> getCertificates(LDAPRequest request,
        String id, X509CertSelector sel) throws CertStoreException {

        /* fetch encoded certs from storage */
        byte[][] encodedCert;
        try {
            encodedCert = request.getValues(id);
        } catch (NamingException namingEx) {
            throw new CertStoreException(namingEx);
        }

        int n = encodedCert.length;
        if (n == 0) {
            return Collections.<X509Certificate>emptySet();
        }

        List<X509Certificate> certs = new ArrayList<X509Certificate>(n);
        /* decode certs and check if they satisfy selector */
        for (int i = 0; i < n; i++) {
            ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert[i]);
            try {
                Certificate cert = cf.generateCertificate(bais);
                if (sel.match(cert)) {
                  certs.add((X509Certificate)cert);
                }
            } catch (CertificateException e) {
                if (debug != null) {
                    debug.println("LDAPCertStore.getCertificates() encountered "
                        + "exception while parsing cert, skipping the bad data: ");
                    HexDumpEncoder encoder = new HexDumpEncoder();
                    debug.println(
                        "[ " + encoder.encodeBuffer(encodedCert[i]) + " ]");
                }
            }
        }

        return certs;
    }

    /*
     * Gets certificate pairs from an attribute id and location in the LDAP
     * directory.
     *
     * @param name the location holding the attribute
     * @param id the attribute identifier
     * @return a Collection of X509CertificatePairs found
     * @throws CertStoreException       if an exception occurs
     */
    private Collection<X509CertificatePair> getCertPairs(
        LDAPRequest request, String id) throws CertStoreException {

        /* fetch the encoded cert pairs from storage */
        byte[][] encodedCertPair;
        try {
            encodedCertPair = request.getValues(id);
        } catch (NamingException namingEx) {
            throw new CertStoreException(namingEx);
        }

        int n = encodedCertPair.length;
        if (n == 0) {
            return Collections.<X509CertificatePair>emptySet();
        }

        List<X509CertificatePair> certPairs =
                                new ArrayList<X509CertificatePair>(n);
        /* decode each cert pair and add it to the Collection */
        for (int i = 0; i < n; i++) {
            try {
                X509CertificatePair certPair =
                    X509CertificatePair.generateCertificatePair(encodedCertPair[i]);
                certPairs.add(certPair);
            } catch (CertificateException e) {
                if (debug != null) {
                    debug.println(
                        "LDAPCertStore.getCertPairs() encountered exception "
                        + "while parsing cert, skipping the bad data: ");
                    HexDumpEncoder encoder = new HexDumpEncoder();
                    debug.println(
                        "[ " + encoder.encodeBuffer(encodedCertPair[i]) + " ]");
                }
            }
        }

        return certPairs;
    }

    /*
     * Looks at certificate pairs stored in the crossCertificatePair attribute
     * at the specified location in the LDAP directory. Returns a Collection
     * containing all Certificates stored in the forward component that match
     * the forward CertSelector and all Certificates stored in the reverse
     * component that match the reverse CertSelector.
     * <p>
     * If either forward or reverse is null, all certificates from the
     * corresponding component will be rejected.
     *
     * @param name the location to look in
     * @param forward the forward CertSelector (or null)
     * @param reverse the reverse CertSelector (or null)
     * @return a Collection of Certificates found
     * @throws CertStoreException       if an exception occurs
     */
    private Collection<X509Certificate> getMatchingCrossCerts(
            LDAPRequest request, X509CertSelector forward,
            X509CertSelector reverse)
            throws CertStoreException {
        // Get the cert pairs
        Collection<X509CertificatePair> certPairs =
                                getCertPairs(request, CROSS_CERT);

        // Find Certificates that match and put them in a list
        ArrayList<X509Certificate> matchingCerts =
                                        new ArrayList<X509Certificate>();
        for (X509CertificatePair certPair : certPairs) {
            X509Certificate cert;
            if (forward != null) {
                cert = certPair.getForward();
                if ((cert != null) && forward.match(cert)) {
                    matchingCerts.add(cert);
                }
            }
            if (reverse != null) {
                cert = certPair.getReverse();
                if ((cert != null) && reverse.match(cert)) {
                    matchingCerts.add(cert);
                }
            }
        }
        return matchingCerts;
    }

    /**
     * Returns a <code>Collection</code> of <code>Certificate</code>s that
     * match the specified selector. If no <code>Certificate</code>s
     * match the selector, an empty <code>Collection</code> will be returned.
     * <p>
     * It is not practical to search every entry in the LDAP database for
     * matching <code>Certificate</code>s. Instead, the <code>CertSelector</code>
     * is examined in order to determine where matching <code>Certificate</code>s
     * are likely to be found (according to the PKIX LDAPv2 schema, RFC 2587).
     * If the subject is specified, its directory entry is searched. If the
     * issuer is specified, its directory entry is searched. If neither the
     * subject nor the issuer are specified (or the selector is not an
     * <code>X509CertSelector</code>), a <code>CertStoreException</code> is
     * thrown.
     *
     * @param selector a <code>CertSelector</code> used to select which
     *  <code>Certificate</code>s should be returned.
     * @return a <code>Collection</code> of <code>Certificate</code>s that
     *         match the specified selector
     * @throws CertStoreException if an exception occurs
     */
    public synchronized Collection<X509Certificate> engineGetCertificates
            (CertSelector selector) throws CertStoreException {
        if (debug != null) {
            debug.println("LDAPCertStore.engineGetCertificates() selector: "
                + String.valueOf(selector));
        }

        if (selector == null) {
            selector = new X509CertSelector();
        }
        if (!(selector instanceof X509CertSelector)) {
            throw new CertStoreException("LDAPCertStore needs an X509CertSelector " +
                                         "to find certs");
        }
        X509CertSelector xsel = (X509CertSelector) selector;
        int basicConstraints = xsel.getBasicConstraints();
        String subject = xsel.getSubjectAsString();
        String issuer = xsel.getIssuerAsString();
        HashSet<X509Certificate> certs = new HashSet<X509Certificate>();
        if (debug != null) {
            debug.println("LDAPCertStore.engineGetCertificates() basicConstraints: "
                + basicConstraints);
        }

        // basicConstraints:
        // -2: only EE certs accepted
        // -1: no check is done
        //  0: any CA certificate accepted
        // >1: certificate's basicConstraints extension pathlen must match
        if (subject != null) {
            if (debug != null) {
                debug.println("LDAPCertStore.engineGetCertificates() "
                    + "subject is not null");
            }
            LDAPRequest request = new LDAPRequest(subject);
            if (basicConstraints > -2) {
                request.addRequestedAttribute(CROSS_CERT);
                request.addRequestedAttribute(CA_CERT);
                request.addRequestedAttribute(ARL);
                if (prefetchCRLs) {
                    request.addRequestedAttribute(CRL);
                }
            }
            if (basicConstraints < 0) {
                request.addRequestedAttribute(USER_CERT);
            }

            if (basicConstraints > -2) {
                certs.addAll(getMatchingCrossCerts(request, xsel, null));
                if (debug != null) {
                    debug.println("LDAPCertStore.engineGetCertificates() after "
                        + "getMatchingCrossCerts(subject,xsel,null),certs.size(): "
                        + certs.size());
                }
                certs.addAll(getCertificates(request, CA_CERT, xsel));
                if (debug != null) {
                    debug.println("LDAPCertStore.engineGetCertificates() after "
                        + "getCertificates(subject,CA_CERT,xsel),certs.size(): "
                        + certs.size());
                }
            }
            if (basicConstraints < 0) {
                certs.addAll(getCertificates(request, USER_CERT, xsel));
                if (debug != null) {
                    debug.println("LDAPCertStore.engineGetCertificates() after "
                        + "getCertificates(subject,USER_CERT, xsel),certs.size(): "
                        + certs.size());
                }
            }
        } else {
            if (debug != null) {
                debug.println
                    ("LDAPCertStore.engineGetCertificates() subject is null");
            }
            if (basicConstraints == -2) {
                throw new CertStoreException("need subject to find EE certs");
            }
            if (issuer == null) {
                throw new CertStoreException("need subject or issuer to find certs");
            }
        }
        if (debug != null) {
            debug.println("LDAPCertStore.engineGetCertificates() about to "
                + "getMatchingCrossCerts...");
        }
        if ((issuer != null) && (basicConstraints > -2)) {
            LDAPRequest request = new LDAPRequest(issuer);
            request.addRequestedAttribute(CROSS_CERT);
            request.addRequestedAttribute(CA_CERT);
            request.addRequestedAttribute(ARL);
            if (prefetchCRLs) {
                request.addRequestedAttribute(CRL);
            }

            certs.addAll(getMatchingCrossCerts(request, null, xsel));
            if (debug != null) {
                debug.println("LDAPCertStore.engineGetCertificates() after "
                    + "getMatchingCrossCerts(issuer,null,xsel),certs.size(): "
                    + certs.size());
            }
            certs.addAll(getCertificates(request, CA_CERT, xsel));
            if (debug != null) {
                debug.println("LDAPCertStore.engineGetCertificates() after "
                    + "getCertificates(issuer,CA_CERT,xsel),certs.size(): "
                    + certs.size());
            }
        }
        if (debug != null) {
            debug.println("LDAPCertStore.engineGetCertificates() returning certs");
        }
        return certs;
    }

    /*
     * Gets CRLs from an attribute id and location in the LDAP directory.
     * Returns a Collection containing only the CRLs that match the
     * specified CRLSelector.
     *
     * @param name the location holding the attribute
     * @param id the attribute identifier
     * @param sel a CRLSelector that the CRLs must match
     * @return a Collection of CRLs found
     * @throws CertStoreException       if an exception occurs
     */
    private Collection<X509CRL> getCRLs(LDAPRequest request, String id,
            X509CRLSelector sel) throws CertStoreException {

        /* fetch the encoded crls from storage */
        byte[][] encodedCRL;
        try {
            encodedCRL = request.getValues(id);
        } catch (NamingException namingEx) {
            throw new CertStoreException(namingEx);
        }

        int n = encodedCRL.length;
        if (n == 0) {
            return Collections.<X509CRL>emptySet();
        }

        List<X509CRL> crls = new ArrayList<X509CRL>(n);
        /* decode each crl and check if it matches selector */
        for (int i = 0; i < n; i++) {
            try {
                CRL crl = cf.generateCRL(new ByteArrayInputStream(encodedCRL[i]));
                if (sel.match(crl)) {
                    crls.add((X509CRL)crl);
                }
            } catch (CRLException e) {
                if (debug != null) {
                    debug.println("LDAPCertStore.getCRLs() encountered exception"
                        + " while parsing CRL, skipping the bad data: ");
                    HexDumpEncoder encoder = new HexDumpEncoder();
                    debug.println("[ " + encoder.encodeBuffer(encodedCRL[i]) + " ]");
                }
            }
        }

        return crls;
    }

    /**
     * Returns a <code>Collection</code> of <code>CRL</code>s that
     * match the specified selector. If no <code>CRL</code>s
     * match the selector, an empty <code>Collection</code> will be returned.
     * <p>
     * It is not practical to search every entry in the LDAP database for
     * matching <code>CRL</code>s. Instead, the <code>CRLSelector</code>
     * is examined in order to determine where matching <code>CRL</code>s
     * are likely to be found (according to the PKIX LDAPv2 schema, RFC 2587).
     * If issuerNames or certChecking are specified, the issuer's directory
     * entry is searched. If neither issuerNames or certChecking are specified
     * (or the selector is not an <code>X509CRLSelector</code>), a
     * <code>CertStoreException</code> is thrown.
     *
     * @param selector A <code>CRLSelector</code> used to select which
     *  <code>CRL</code>s should be returned. Specify <code>null</code>
     *  to return all <code>CRL</code>s.
     * @return A <code>Collection</code> of <code>CRL</code>s that
     *         match the specified selector
     * @throws CertStoreException if an exception occurs
     */
    public synchronized Collection<X509CRL> engineGetCRLs(CRLSelector selector)
            throws CertStoreException {
        if (debug != null) {
            debug.println("LDAPCertStore.engineGetCRLs() selector: "
                + selector);
        }
        // Set up selector and collection to hold CRLs
        if (selector == null) {
            selector = new X509CRLSelector();
        }
        if (!(selector instanceof X509CRLSelector)) {
            throw new CertStoreException("need X509CRLSelector to find CRLs");
        }
        X509CRLSelector xsel = (X509CRLSelector) selector;
        HashSet<X509CRL> crls = new HashSet<X509CRL>();

        // Look in directory entry for issuer of cert we're checking.
        Collection<Object> issuerNames;
        X509Certificate certChecking = xsel.getCertificateChecking();
        if (certChecking != null) {
            issuerNames = new HashSet<Object>();
            X500Principal issuer = certChecking.getIssuerX500Principal();
            issuerNames.add(issuer.getName(X500Principal.RFC2253));
        } else {
            // But if we don't know which cert we're checking, try the directory
            // entries of all acceptable CRL issuers
            issuerNames = xsel.getIssuerNames();
            if (issuerNames == null) {
                throw new CertStoreException("need issuerNames or certChecking to "
                    + "find CRLs");
            }
        }
        for (Object nameObject : issuerNames) {
            String issuerName;
            if (nameObject instanceof byte[]) {
                try {
                    X500Principal issuer = new X500Principal((byte[])nameObject);
                    issuerName = issuer.getName(X500Principal.RFC2253);
                } catch (IllegalArgumentException e) {
                    continue;
                }
            } else {
                issuerName = (String)nameObject;
            }
            // If all we want is CA certs, try to get the (probably shorter) ARL
            Collection<X509CRL> entryCRLs = Collections.<X509CRL>emptySet();
            if (certChecking == null || certChecking.getBasicConstraints() != -1) {
                LDAPRequest request = new LDAPRequest(issuerName);
                request.addRequestedAttribute(CROSS_CERT);
                request.addRequestedAttribute(CA_CERT);
                request.addRequestedAttribute(ARL);
                if (prefetchCRLs) {
                    request.addRequestedAttribute(CRL);
                }
                try {
                    entryCRLs = getCRLs(request, ARL, xsel);
                    if (entryCRLs.isEmpty()) {
                        // no ARLs found. We assume that means that there are
                        // no ARLs on this server at all and prefetch the CRLs.
                        prefetchCRLs = true;
                    } else {
                        crls.addAll(entryCRLs);
                    }
                } catch (CertStoreException e) {
                    if (debug != null) {
                        debug.println("LDAPCertStore.engineGetCRLs non-fatal error "
                            + "retrieving ARLs:" + e);
                        e.printStackTrace();
                    }
                }
            }
            // Otherwise, get the CRL
            // if certChecking is null, we don't know if we should look in ARL or CRL
            // attribute, so check both for matching CRLs.
            if (entryCRLs.isEmpty() || certChecking == null) {
                LDAPRequest request = new LDAPRequest(issuerName);
                request.addRequestedAttribute(CRL);
                entryCRLs = getCRLs(request, CRL, xsel);
                crls.addAll(entryCRLs);
            }
        }
        return crls;
    }

    // converts an LDAP URI into LDAPCertStoreParameters
    static LDAPCertStoreParameters getParameters(URI uri) {
        String host = uri.getHost();
        if (host == null) {
            return new SunLDAPCertStoreParameters();
        } else {
            int port = uri.getPort();
            return (port == -1
                    ? new SunLDAPCertStoreParameters(host)
                    : new SunLDAPCertStoreParameters(host, port));
        }
    }

    /*
     * Subclass of LDAPCertStoreParameters with overridden equals/hashCode
     * methods. This is necessary because the parameters are used as
     * keys in the LDAPCertStore cache.
     */
    private static class SunLDAPCertStoreParameters
        extends LDAPCertStoreParameters {

        private volatile int hashCode = 0;

        SunLDAPCertStoreParameters(String serverName, int port) {
            super(serverName, port);
        }
        SunLDAPCertStoreParameters(String serverName) {
            super(serverName);
        }
        SunLDAPCertStoreParameters() {
            super();
        }
        public boolean equals(Object obj) {
            if (!(obj instanceof LDAPCertStoreParameters)) {
                return false;
            }
            LDAPCertStoreParameters params = (LDAPCertStoreParameters) obj;
            return (getPort() == params.getPort() &&
                    getServerName().equalsIgnoreCase(params.getServerName()));
        }
        public int hashCode() {
            if (hashCode == 0) {
                int result = 17;
                result = 37*result + getPort();
                result = 37*result + getServerName().toLowerCase().hashCode();
                hashCode = result;
            }
            return hashCode;
        }
    }

    /*
     * This inner class wraps an existing X509CertSelector and adds
     * additional criteria to match on when the certificate's subject is
     * different than the LDAP Distinguished Name entry. The LDAPCertStore
     * implementation uses the subject DN as the directory entry for
     * looking up certificates. This can be problematic if the certificates
     * that you want to fetch have a different subject DN than the entry
     * where they are stored. You could set the selector's subject to the
     * LDAP DN entry, but then the resulting match would fail to find the
     * desired certificates because the subject DNs would not match. This
     * class avoids that problem by introducing a certSubject which should
     * be set to the certificate's subject DN when it is different than
     * the LDAP DN.
     */
    static class LDAPCertSelector extends X509CertSelector {

        private X500Principal certSubject;
        private X509CertSelector selector;
        private X500Principal subject;

        /**
         * Creates an LDAPCertSelector.
         *
         * @param selector the X509CertSelector to wrap
         * @param certSubject the subject DN of the certificate that you want
         *      to retrieve via LDAP
         * @param ldapDN the LDAP DN where the certificate is stored
         */
        LDAPCertSelector(X509CertSelector selector, X500Principal certSubject,
            String ldapDN) throws IOException {
            this.selector = selector == null ? new X509CertSelector() : selector;
            this.certSubject = certSubject;
            this.subject = new X500Name(ldapDN).asX500Principal();
        }

        // we only override the get (accessor methods) since the set methods
        // will not be invoked by the code that uses this LDAPCertSelector.
        public X509Certificate getCertificate() {
            return selector.getCertificate();
        }
        public BigInteger getSerialNumber() {
            return selector.getSerialNumber();
        }
        public X500Principal getIssuer() {
            return selector.getIssuer();
        }
        public String getIssuerAsString() {
            return selector.getIssuerAsString();
        }
        public byte[] getIssuerAsBytes() throws IOException {
            return selector.getIssuerAsBytes();
        }
        public X500Principal getSubject() {
            // return the ldap DN
            return subject;
        }
        public String getSubjectAsString() {
            // return the ldap DN
            return subject.getName();
        }
        public byte[] getSubjectAsBytes() throws IOException {
            // return the encoded ldap DN
            return subject.getEncoded();
        }
        public byte[] getSubjectKeyIdentifier() {
            return selector.getSubjectKeyIdentifier();
        }
        public byte[] getAuthorityKeyIdentifier() {
            return selector.getAuthorityKeyIdentifier();
        }
        public Date getCertificateValid() {
            return selector.getCertificateValid();
        }
        public Date getPrivateKeyValid() {
            return selector.getPrivateKeyValid();
        }
        public String getSubjectPublicKeyAlgID() {
            return selector.getSubjectPublicKeyAlgID();
        }
        public PublicKey getSubjectPublicKey() {
            return selector.getSubjectPublicKey();
        }
        public boolean[] getKeyUsage() {
            return selector.getKeyUsage();
        }
        public Set<String> getExtendedKeyUsage() {
            return selector.getExtendedKeyUsage();
        }
        public boolean getMatchAllSubjectAltNames() {
            return selector.getMatchAllSubjectAltNames();
        }
        public Collection<List<?>> getSubjectAlternativeNames() {
            return selector.getSubjectAlternativeNames();
        }
        public byte[] getNameConstraints() {
            return selector.getNameConstraints();
        }
        public int getBasicConstraints() {
            return selector.getBasicConstraints();
        }
        public Set<String> getPolicy() {
            return selector.getPolicy();
        }
        public Collection<List<?>> getPathToNames() {
            return selector.getPathToNames();
        }

        public boolean match(Certificate cert) {
            // temporarily set the subject criterion to the certSubject
            // so that match will not reject the desired certificates
            selector.setSubject(certSubject);
            boolean match = selector.match(cert);
            selector.setSubject(subject);
            return match;
        }
    }

    /**
     * This class has the same purpose as LDAPCertSelector except it is for
     * X.509 CRLs.
     */
    static class LDAPCRLSelector extends X509CRLSelector {

        private X509CRLSelector selector;
        private Collection<X500Principal> certIssuers;
        private Collection<X500Principal> issuers;
        private HashSet<Object> issuerNames;

        /**
         * Creates an LDAPCRLSelector.
         *
         * @param selector the X509CRLSelector to wrap
         * @param certIssuers the issuer DNs of the CRLs that you want
         *      to retrieve via LDAP
         * @param ldapDN the LDAP DN where the CRL is stored
         */
        LDAPCRLSelector(X509CRLSelector selector,
            Collection<X500Principal> certIssuers, String ldapDN)
            throws IOException {
            this.selector = selector == null ? new X509CRLSelector() : selector;
            this.certIssuers = certIssuers;
            issuerNames = new HashSet<Object>();
            issuerNames.add(ldapDN);
            issuers = new HashSet<X500Principal>();
            issuers.add(new X500Name(ldapDN).asX500Principal());
        }
        // we only override the get (accessor methods) since the set methods
        // will not be invoked by the code that uses this LDAPCRLSelector.
        public Collection<X500Principal> getIssuers() {
            // return the ldap DN
            return Collections.unmodifiableCollection(issuers);
        }
        public Collection<Object> getIssuerNames() {
            // return the ldap DN
            return Collections.unmodifiableCollection(issuerNames);
        }
        public BigInteger getMinCRL() {
            return selector.getMinCRL();
        }
        public BigInteger getMaxCRL() {
            return selector.getMaxCRL();
        }
        public Date getDateAndTime() {
            return selector.getDateAndTime();
        }
        public X509Certificate getCertificateChecking() {
            return selector.getCertificateChecking();
        }
        public boolean match(CRL crl) {
            // temporarily set the issuer criterion to the certIssuers
            // so that match will not reject the desired CRL
            selector.setIssuers(certIssuers);
            boolean match = selector.match(crl);
            selector.setIssuers(issuers);
            return match;
        }
    }
}
