001    /* CertStore -- stores and retrieves certificates.
002       Copyright (C) 2003, 2004  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package java.security.cert;
040    
041    import gnu.java.lang.CPStringBuilder;
042    
043    import gnu.java.security.Engine;
044    
045    import java.lang.reflect.InvocationTargetException;
046    import java.security.InvalidAlgorithmParameterException;
047    import java.security.NoSuchAlgorithmException;
048    import java.security.NoSuchProviderException;
049    import java.security.PrivilegedAction;
050    import java.security.Provider;
051    import java.security.Security;
052    import java.util.Collection;
053    
054    /**
055     * A CertStore is a read-only repository for certificates and
056     * certificate revocation lists.
057     *
058     * @since 1.4
059     */
060    public class CertStore
061    {
062    
063      // Constants and fields.
064      // ------------------------------------------------------------------------
065    
066      /** Service name for CertStore. */
067      private static final String CERT_STORE = "CertStore";
068    
069      /** The underlying implementation. */
070      private CertStoreSpi storeSpi;
071    
072      /** This implementation's provider. */
073      private Provider provider;
074    
075      /** The name of this key store type. */
076      private String type;
077    
078      /** The parameters used to initialize this instance, if any. */
079      private CertStoreParameters params;
080    
081      // Constructor.
082      // ------------------------------------------------------------------------
083    
084      /**
085       * Create a new CertStore.
086       *
087       * @param storeSpi The underlying implementation.
088       * @param provider The provider of this implementation.
089       * @param type     The type of CertStore this class represents.
090       * @param params   The parameters used to initialize this instance, if any.
091       */
092      protected CertStore(CertStoreSpi storeSpi, Provider provider, String type,
093                          CertStoreParameters params)
094      {
095        this.storeSpi = storeSpi;
096        this.provider = provider;
097        this.type = type;
098        this.params = params;
099      }
100    
101    // Class methods.
102      // ------------------------------------------------------------------------
103    
104      /**
105       * Returns the default certificate store type.
106       *
107       * <p>This value can be set at run-time via the security property
108       * "certstore.type"; if not specified than the default type will be
109       * "LDAP".
110       *
111       * @return The default CertStore type.
112       */
113      public static final synchronized String getDefaultType()
114      {
115        String type = null;
116        type = (String) java.security.AccessController.doPrivileged(
117          new PrivilegedAction() {
118            public Object run() {
119              return Security.getProperty("certstore.type");
120            }
121          }
122        );
123        if (type == null)
124          type = "LDAP";
125        return type;
126      }
127    
128      /**
129       * Returns an instance of the given certificate store type from the first
130       * installed provider.
131       *
132       * @param type The type of <code>CertStore</code> to create.
133       * @param params The parameters to initialize this cert store with.
134       * @return The new instance.
135       * @throws InvalidAlgorithmParameterException If the instance rejects the
136       *           specified parameters.
137       * @throws NoSuchAlgorithmException If no installed provider implements the
138       *           specified CertStore.
139       * @throws IllegalArgumentException if <code>type</code> is
140       *           <code>null</code> or is an empty string.
141       */
142      public static CertStore getInstance(String type, CertStoreParameters params)
143        throws InvalidAlgorithmParameterException, NoSuchAlgorithmException
144      {
145        Provider[] p = Security.getProviders();
146        NoSuchAlgorithmException lastException = null;
147        for (int i = 0; i < p.length; i++)
148          try
149            {
150              return getInstance(type, params, p[i]);
151            }
152          catch (NoSuchAlgorithmException x)
153            {
154              lastException = x;
155            }
156        if (lastException != null)
157          throw lastException;
158        throw new NoSuchAlgorithmException(type);
159      }
160    
161      /**
162       * Returns an instance of the given certificate store type from a named
163       * provider.
164       *
165       * @param type The type of <code>CertStore</code> to create.
166       * @param params The parameters to initialize this cert store with.
167       * @param provider The name of the provider to use.
168       * @return The new instance.
169       * @throws InvalidAlgorithmParameterException If the instance rejects the
170       *           specified parameters.
171       * @throws NoSuchAlgorithmException If the specified provider does not
172       *           implement the specified CertStore.
173       * @throws NoSuchProviderException If no provider named <i>provider</i> is
174       *           installed.
175       * @throws IllegalArgumentException if either <code>type</code> or
176       *           <code>provider</code> is <code>null</code>, or if
177       *           <code>type</code> is an empty string.
178       */
179      public static CertStore getInstance(String type, CertStoreParameters params,
180                                          String provider)
181        throws InvalidAlgorithmParameterException, NoSuchAlgorithmException,
182               NoSuchProviderException
183      {
184        if (provider == null)
185          throw new IllegalArgumentException("provider MUST NOT be null");
186        Provider p = Security.getProvider(provider);
187        if (p == null)
188          throw new NoSuchProviderException(provider);
189        return getInstance(type, params, p);
190      }
191    
192      /**
193       * Returns an instance of the given certificate store type from a given
194       * provider.
195       *
196       * @param type The type of <code>CertStore</code> to create.
197       * @param params   The parameters to initialize this cert store with.
198       * @param provider The provider to use.
199       * @return The new instance.
200       * @throws InvalidAlgorithmParameterException If the instance rejects
201       *         the specified parameters.
202       * @throws NoSuchAlgorithmException If the specified provider does not
203       *         implement the specified CertStore.
204       * @throws IllegalArgumentException if either <code>type</code> or
205       *           <code>provider</code> is <code>null</code>, or if
206       *           <code>type</code> is an empty string.
207       */
208      public static CertStore getInstance(String type, CertStoreParameters params,
209                                          Provider provider)
210          throws InvalidAlgorithmParameterException, NoSuchAlgorithmException
211      {
212        CPStringBuilder sb = new CPStringBuilder("CertStore of type [")
213            .append(type).append("] from provider[")
214            .append(provider).append("] could not be created");
215        Throwable cause;
216        try
217          {
218            Object[] args = new Object[] { params };
219            Object spi = Engine.getInstance(CERT_STORE, type, provider, args);
220            return new CertStore((CertStoreSpi) spi, provider, type, params);
221          }
222        catch (InvocationTargetException x)
223          {
224            cause = x.getCause();
225            if (cause instanceof NoSuchAlgorithmException)
226              throw (NoSuchAlgorithmException) cause;
227            if (cause == null)
228              cause = x;
229          }
230        catch (ClassCastException x)
231          {
232            cause = x;
233          }
234        NoSuchAlgorithmException x = new NoSuchAlgorithmException(sb.toString());
235        x.initCause(cause);
236        throw x;
237      }
238    
239      /**
240       * Return the type of certificate store this instance represents.
241       *
242       * @return The CertStore type.
243       */
244      public final String getType()
245      {
246        return type;
247      }
248    
249      /**
250       * Return the provider of this implementation.
251       *
252       * @return The provider.
253       */
254      public final Provider getProvider()
255      {
256        return provider;
257      }
258    
259      /**
260       * Get the parameters this instance was created with, if any. The
261       * parameters will be cloned before they are returned.
262       *
263       * @return The parameters, or null.
264       */
265      public final CertStoreParameters getCertStoreParameters()
266      {
267        return params != null ? (CertStoreParameters) params.clone() : null;
268      }
269    
270      /**
271       * Get a collection of certificates from this CertStore, optionally
272       * filtered by the specified CertSelector. The Collection returned may
273       * be empty, but will never be null.
274       *
275       * <p>Implementations may not allow a null argument, even if no
276       * filtering is desired.
277       *
278       * @param selector The certificate selector.
279       * @return The collection of certificates.
280       * @throws CertStoreException If the certificates cannot be retrieved.
281       */
282      public final Collection<? extends Certificate> getCertificates(CertSelector selector)
283        throws CertStoreException
284      {
285        return storeSpi.engineGetCertificates(selector);
286      }
287    
288      /**
289       * Get a collection of certificate revocation lists from this CertStore,
290       * optionally filtered by the specified CRLSelector. The Collection
291       * returned may be empty, but will never be null.
292       *
293       * <p>Implementations may not allow a null argument, even if no
294       * filtering is desired.
295       *
296       * @param selector The certificate selector.
297       * @return The collection of certificate revocation lists.
298       * @throws CertStoreException If the CRLs cannot be retrieved.
299       */
300      public final Collection<? extends CRL> getCRLs(CRLSelector selector)
301        throws CertStoreException
302      {
303        return storeSpi.engineGetCRLs(selector);
304      }
305    }