Source for java.security.cert.CertificateFactory

   1: /* CertificateFactory.java -- Certificate Factory Class
   2:    Copyright (C) 1999, 2002, 2003, 2004  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package java.security.cert;
  40: 
  41: import gnu.java.security.Engine;
  42: 
  43: import java.io.InputStream;
  44: import java.lang.reflect.InvocationTargetException;
  45: import java.security.NoSuchAlgorithmException;
  46: import java.security.NoSuchProviderException;
  47: import java.security.Provider;
  48: import java.security.Security;
  49: import java.util.Collection;
  50: import java.util.Iterator;
  51: import java.util.List;
  52: 
  53: /**
  54:  * This class implements the CertificateFactory class interface used to
  55:  * generate certificates, certificate revocation lists (CRLs), and certificate
  56:  * paths objects from their encoded forms.
  57:  *
  58:  * @author Mark Benvenuto
  59:  * @author Casey Marshall
  60:  * @since 1.2
  61:  * @status Fully compatible with JDK 1.4.
  62:  */
  63: public class CertificateFactory
  64: {
  65: 
  66:   /** The service name for certificate factories. */
  67:   private static final String CERTIFICATE_FACTORY = "CertificateFactory";
  68: 
  69:   private CertificateFactorySpi certFacSpi;
  70:   private Provider provider;
  71:   private String type;
  72: 
  73:   /**
  74:    * Creates an instance of CertificateFactory.
  75:    *
  76:    * @param certFacSpi The underlying CertificateFactory engine.
  77:    * @param provider   The provider of this implementation.
  78:    * @param type       The type of Certificate this factory creates.
  79:    */
  80:   protected CertificateFactory(CertificateFactorySpi certFacSpi,
  81:                                Provider provider, String type)
  82:   {
  83:     this.certFacSpi = certFacSpi;
  84:     this.provider = provider;
  85:     this.type = type;
  86:   }
  87: 
  88:   /**
  89:    * Returns an instance of a <code>CertificateFactory</code> representing the
  90:    * specified certificate factory type.
  91:    *
  92:    * @param type The type of certificate factory to create.
  93:    * @return A <code>CertificateFactory</code> of the desired type.
  94:    * @throws CertificateException If the type of certificate factory is not
  95:    *           implemented by any installed provider.
  96:    * @throws IllegalArgumentException if <code>type</code> is
  97:    *           <code>null</code> or is an empty string.
  98:    */
  99:   public static final CertificateFactory getInstance(String type)
 100:       throws CertificateException
 101:   {
 102:     Provider[] p = Security.getProviders();
 103:     CertificateException lastException = null;
 104:     for (int i = 0; i < p.length; i++)
 105:       try
 106:         {
 107:           return getInstance(type, p[i]);
 108:         }
 109:       catch (CertificateException x)
 110:         {
 111:           lastException = x;
 112:         }
 113:     if (lastException != null)
 114:       throw lastException;
 115:     throw new CertificateException(type);
 116:   }
 117: 
 118:   /**
 119:    * Returns an instance of a <code>CertificateFactory</code> representing the
 120:    * specified certificate factory type from the named provider.
 121:    *
 122:    * @param type The type of certificate factory to create.
 123:    * @param provider The name of the provider to use.
 124:    * @return A <code>CertificateFactory</code> for the desired type.
 125:    * @throws CertificateException If the type of certificate is not implemented
 126:    *           by the named provider.
 127:    * @throws NoSuchProviderException If the named provider is not installed.
 128:    * @throws IllegalArgumentException if either <code>type</code> or
 129:    *           <code>provider</code> is <code>null</code>, or if
 130:    *           <code>type</code> is an empty string.
 131:    */
 132:   public static final CertificateFactory getInstance(String type,
 133:                                                      String provider)
 134:     throws CertificateException, NoSuchProviderException
 135:   {
 136:     if (provider == null)
 137:       throw new IllegalArgumentException("provider MUST NOT be null");
 138:     Provider p = Security.getProvider(provider);
 139:     if (p == null)
 140:       throw new NoSuchProviderException(provider);
 141:     return getInstance(type, p);
 142:   }
 143: 
 144:   /**
 145:    * Returns an instance of a <code>CertificateFactory</code> representing the
 146:    * specified certificate factory type from the designated provider.
 147:    *
 148:    * @param type The type of certificate factory to create.
 149:    * @param provider The provider from which to get the implementation.
 150:    * @return A <code>CertificateFactory</code> for the desired type.
 151:    * @throws CertificateException If the type of certificate is not implemented
 152:    *           by the provider.
 153:    * @throws IllegalArgumentException if either <code>type</code> or
 154:    *           <code>provider</code> is <code>null</code>, or if
 155:    *           <code>type</code> is an empty string.
 156:    */
 157:   public static final CertificateFactory getInstance(String type,
 158:                                                      Provider provider)
 159:       throws CertificateException
 160:   {
 161:     Throwable cause;
 162:     try
 163:       {
 164:         Object spi = Engine.getInstance(CERTIFICATE_FACTORY, type, provider);
 165:         return new CertificateFactory((CertificateFactorySpi) spi, provider, type);
 166:       }
 167:     catch (ClassCastException x)
 168:       {
 169:         cause = x;
 170:       }
 171:     catch (InvocationTargetException x)
 172:       {
 173:         cause = x.getCause() != null ? x.getCause() : x;
 174:       }
 175:     catch (NoSuchAlgorithmException x)
 176:       {
 177:         cause = x;
 178:       }
 179:     CertificateException x = new CertificateException(type);
 180:     x.initCause(cause);
 181:     throw x;
 182:   }
 183: 
 184:   /**
 185:    * Gets the provider of this implementation.
 186:    *
 187:    * @return The provider of this implementation.
 188:    */
 189:   public final Provider getProvider()
 190:   {
 191:     return provider;
 192:   }
 193: 
 194:   /**
 195:    * Returns the type of the certificate this factory creates.
 196:    *
 197:    * @return A string with the type of certificate
 198:    */
 199:   public final String getType()
 200:   {
 201:     return type;
 202:   }
 203: 
 204:   /**
 205:    * Generates a Certificate from the encoded data read
 206:    * from an InputStream.
 207:    *
 208:    * <p>The input stream must contain only one certificate.
 209:    *
 210:    * <p>If there exists a specialized certificate class for the
 211:    * certificate format handled by the certificate factory
 212:    * then the return Ceritificate should be a typecast of it.
 213:    * Ex: A X.509 CertificateFactory should return X509Certificate.
 214:    *
 215:    * <p>For X.509 certificates, the certificate in inStream must be
 216:    * DER encoded and supplied in binary or printable (Base64)
 217:    * encoding. If the certificate is in Base64 encoding, it must be
 218:    * bounded by -----BEGINCERTIFICATE-----, and
 219:    * -----END CERTIFICATE-----.
 220:    *
 221:    * @param inStream An input stream containing the certificate data.
 222:    * @return A certificate initialized from the decoded InputStream data.
 223:    * @throws CertificateException If an error occurs decoding the
 224:    *   certificate.
 225:    */
 226:   public final Certificate generateCertificate(InputStream inStream)
 227:     throws CertificateException
 228:   {
 229:     return certFacSpi.engineGenerateCertificate(inStream);
 230:   }
 231: 
 232:   /**
 233:    * Returns a collection of certificates that were read from the
 234:    * input stream. It may be empty, have only one, or have
 235:    * multiple certificates.
 236:    *
 237:    * For a X.509 certificate factory, the stream may contain a
 238:    * single DER encoded certificate or a PKCS#7 certificate
 239:    * chain. This is a PKCS#7 <I>SignedData</I> object with the
 240:    * most significant field being <I>certificates</I>. If no
 241:    * CRLs are present, then an empty collection is returned.
 242:          *
 243:    * @param inStream An input stream containing the certificate data.
 244:    * @return A collection of certificates initialized from the decoded
 245:    *   InputStream data.
 246:    * @throws CertificateException If an error occurs decoding the
 247:    *   certificates.
 248:    */
 249:   public final Collection<? extends Certificate> generateCertificates(InputStream inStream)
 250:     throws CertificateException
 251:   {
 252:     return certFacSpi.engineGenerateCertificates(inStream);
 253:   }
 254: 
 255:   /**
 256:    * Generates a CRL based on the encoded data read
 257:    * from the InputStream.
 258:    *
 259:    * <p>The input stream must contain only one CRL.
 260:    *
 261:    * <p>If there exists a specialized CRL class for the
 262:    * CRL format handled by the certificate factory
 263:    * then the return CRL should be a typecast of it.
 264:    * Ex: A X.509 CertificateFactory should return X509CRL.
 265:    *
 266:    * @param inStream An input stream containing the CRL data.
 267:    * @return A CRL initialized from the decoded InputStream data.
 268:    * @throws CRLException If an error occurs decoding the CRL.
 269:    */
 270:   public final CRL generateCRL(InputStream inStream)
 271:     throws CRLException
 272:   {
 273:     return certFacSpi.engineGenerateCRL(inStream);
 274:   }
 275: 
 276:   /**
 277:    * <p>Generates CRLs based on the encoded data read
 278:    * from the InputStream.
 279:    *
 280:    * <p>For a X.509 certificate factory, the stream may contain a
 281:    * single DER encoded CRL or a PKCS#7 CRL set. This is a
 282:    * PKCS#7 <I>SignedData</I> object with the most significant
 283:    * field being <I>crls</I>. If no CRLs are present, then an
 284:    * empty collection is returned.
 285:    *
 286:    * @param inStream an input stream containing the CRLs.
 287:    * @return a collection of CRLs initialized from the decoded
 288:    *    InputStream data.
 289:    * @throws CRLException If an error occurs decoding the CRLs.
 290:    */
 291:   public final Collection<? extends CRL> generateCRLs(InputStream inStream)
 292:     throws CRLException
 293:   {
 294:     return certFacSpi.engineGenerateCRLs( inStream );
 295:   }
 296: 
 297:   /**
 298:    * Generate a {@link CertPath} and initialize it with data parsed from
 299:    * the input stream. The default encoding of this factory is used.
 300:    *
 301:    * @param inStream The InputStream containing the CertPath data.
 302:    * @return A CertPath initialized from the input stream data.
 303:    * @throws CertificateException If an error occurs decoding the
 304:    * CertPath.
 305:    */
 306:   public final CertPath generateCertPath(InputStream inStream)
 307:     throws CertificateException
 308:   {
 309:     return certFacSpi.engineGenerateCertPath(inStream);
 310:   }
 311: 
 312:   /**
 313:    * Generate a {@link CertPath} and initialize it with data parsed from
 314:    * the input stream, using the specified encoding.
 315:    *
 316:    * @param inStream The InputStream containing the CertPath data.
 317:    * @param encoding The encoding of the InputStream data.
 318:    * @return A CertPath initialized from the input stream data.
 319:    * @throws CertificateException If an error occurs decoding the
 320:    *   CertPath.
 321:    */
 322:   public final CertPath generateCertPath(InputStream inStream, String encoding)
 323:     throws CertificateException
 324:   {
 325:     return certFacSpi.engineGenerateCertPath(inStream, encoding);
 326:   }
 327: 
 328:   /**
 329:    * Generate a {@link CertPath} and initialize it with the certificates
 330:    * in the {@link java.util.List} argument.
 331:    *
 332:    * @param certificates The list of certificates with which to create
 333:    *   the CertPath.
 334:    * @return A CertPath initialized from the certificates.
 335:    * @throws CertificateException If an error occurs generating the
 336:    *   CertPath.
 337:    */
 338:   public final CertPath generateCertPath(List<? extends Certificate> certificates)
 339:     throws CertificateException
 340:   {
 341:     return certFacSpi.engineGenerateCertPath(certificates);
 342:   }
 343: 
 344:   /**
 345:    * Returns an Iterator of CertPath encodings supported by this
 346:    * factory, with the default encoding first. The returned Iterator
 347:    * cannot be modified.
 348:    *
 349:    * @return The Iterator of supported encodings.
 350:    */
 351:   public final Iterator<String> getCertPathEncodings()
 352:   {
 353:     return certFacSpi.engineGetCertPathEncodings();
 354:   }
 355: } // class CertificateFactory