1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package java.security.cert; 19 20import java.io.InputStream; 21import java.security.NoSuchAlgorithmException; 22import java.security.NoSuchProviderException; 23import java.security.Provider; 24import java.security.Security; 25import java.util.Collection; 26import java.util.Iterator; 27import java.util.List; 28import org.apache.harmony.security.fortress.Engine; 29 30 31/** 32 * This class implements the functionality of a certificate factory algorithm, 33 * relying on parsing a stream of bytes. 34 * <p> 35 * It defines methods for parsing certificate chains (certificate paths) and 36 * <i>Certificate Revocation Lists</i> (CRLs). 37 */ 38public class CertificateFactory { 39 40 // Store CertificateFactory service name 41 private static final String SERVICE = "CertificateFactory"; 42 43 // Used to access common engine functionality 44 private static final Engine ENGINE = new Engine(SERVICE); 45 46 // Store used provider 47 private final Provider provider; 48 49 // Store used CertificateFactorySpi implementation 50 private final CertificateFactorySpi spiImpl; 51 52 // Store used type 53 private final String type; 54 55 /** 56 * Creates a new {@code CertificateFactory} instance. 57 * 58 * @param certFacSpi 59 * the implementation delegate. 60 * @param provider 61 * the associated provider. 62 * @param type 63 * the certificate type. 64 */ 65 protected CertificateFactory(CertificateFactorySpi certFacSpi, 66 Provider provider, String type) { 67 this.provider = provider; 68 this.type = type; 69 this.spiImpl = certFacSpi; 70 } 71 72 /** 73 * Creates a new {@code CertificateFactory} instance that provides the 74 * requested certificate type. 75 * 76 * @param type 77 * the certificate type. 78 * @return the new {@code CertificateFactory} instance. 79 * @throws CertificateException 80 * if the specified certificate type is not available at any 81 * installed provider. 82 * @throws NullPointerException if {@code type == null} 83 */ 84 public static final CertificateFactory getInstance(String type) 85 throws CertificateException { 86 if (type == null) { 87 throw new NullPointerException("type == null"); 88 } 89 try { 90 Engine.SpiAndProvider sap = ENGINE.getInstance(type, null); 91 return new CertificateFactory((CertificateFactorySpi) sap.spi, sap.provider, type); 92 } catch (NoSuchAlgorithmException e) { 93 throw new CertificateException(e); 94 } 95 } 96 97 /** 98 * Creates a new {@code CertificateFactory} instance from the specified 99 * provider that provides the requested certificate type. 100 * 101 * @param type 102 * the certificate type. 103 * @param provider 104 * the name of the provider providing certificates of the 105 * specified type. 106 * @return the new {@code CertificateFactory} instance. 107 * @throws CertificateException 108 * if the specified certificate type is not available by the 109 * specified provider. 110 * @throws NoSuchProviderException 111 * if no provider with the specified name can be found. 112 * @throws IllegalArgumentException if {@code provider == null || provider.isEmpty()} 113 * @throws NullPointerException 114 * it {@code type} is {@code null}. 115 */ 116 public static final CertificateFactory getInstance(String type, 117 String provider) throws CertificateException, 118 NoSuchProviderException { 119 if (provider == null || provider.isEmpty()) { 120 throw new IllegalArgumentException("provider == null || provider.isEmpty()"); 121 } 122 Provider impProvider = Security.getProvider(provider); 123 if (impProvider == null) { 124 throw new NoSuchProviderException(provider); 125 } 126 return getInstance(type, impProvider); 127 } 128 129 /** 130 * Creates a new {@code CertificateFactory} instance from the specified 131 * provider that provides the requested certificate type. The 132 * {@code provider} supplied does not have to be registered. 133 * 134 * @param type 135 * the certificate type. 136 * @param provider 137 * the name of the provider providing certificates of the 138 * specified type. 139 * @return the new {@code CertificateFactory} instance. 140 * @throws CertificateException 141 * if the specified certificate type is not available at the 142 * specified provider. 143 * @throws IllegalArgumentException 144 * if the specified provider is {@code null}. 145 * @throws NullPointerException if {@code type == null} 146 * @throws IllegalArgumentException if {@code provider == null} 147 */ 148 public static final CertificateFactory getInstance(String type, 149 Provider provider) throws CertificateException { 150 if (provider == null) { 151 throw new IllegalArgumentException("provider == null"); 152 } 153 if (type == null) { 154 throw new NullPointerException("type == null"); 155 } 156 try { 157 Object spi = ENGINE.getInstance(type, provider, null); 158 return new CertificateFactory((CertificateFactorySpi) spi, provider, type); 159 } catch (NoSuchAlgorithmException e) { 160 throw new CertificateException(e); 161 } 162 } 163 164 /** 165 * Returns the {@code Provider} of the certificate factory represented by 166 * the certificate. 167 * 168 * @return the provider of this certificate factory. 169 */ 170 public final Provider getProvider() { 171 return provider; 172 } 173 174 /** 175 * Returns the Certificate type. 176 * 177 * @return type of certificate being used. 178 */ 179 public final String getType() { 180 return type; 181 } 182 183 /** 184 * Generates and initializes a {@code Certificate} from the provided input 185 * stream. 186 * 187 * @param inStream 188 * the stream from where data is read to create the {@code 189 * Certificate}. 190 * @return an initialized Certificate. 191 * @throws CertificateException 192 * if parsing problems are detected. 193 */ 194 public final Certificate generateCertificate(InputStream inStream) 195 throws CertificateException { 196 return spiImpl.engineGenerateCertificate(inStream); 197 } 198 199 /** 200 * Returns an {@code Iterator} over the supported {@code CertPath} encodings 201 * (as Strings). The first element is the default encoding scheme to apply. 202 * 203 * @return an iterator over supported {@link CertPath} encodings (as 204 * Strings). 205 */ 206 public final Iterator<String> getCertPathEncodings() { 207 return spiImpl.engineGetCertPathEncodings(); 208 } 209 210 /** 211 * Generates a {@code CertPath} (a certificate chain) from the provided 212 * {@code InputStream}. The default encoding scheme is applied. 213 * 214 * @param inStream 215 * {@code InputStream} with encoded data. 216 * @return a {@code CertPath} initialized from the provided data. 217 * @throws CertificateException 218 * if parsing problems are detected. 219 */ 220 public final CertPath generateCertPath(InputStream inStream) throws CertificateException { 221 Iterator<String> it = getCertPathEncodings(); 222 if (!it.hasNext()) { 223 throw new CertificateException("There are no CertPath encodings"); 224 } 225 return spiImpl.engineGenerateCertPath(inStream, it.next()); 226 } 227 228 /** 229 * Generates a {@code CertPath} (a certificate chain) from the given 230 * {@code inputStream}, assuming the given {@code encoding} from 231 * {@link #getCertPathEncodings()}. 232 * 233 * @throws CertificateException 234 * if parsing problems are detected. 235 * @throws UnsupportedOperationException 236 * if the provider does not implement this method. 237 */ 238 public final CertPath generateCertPath(InputStream inputStream, String encoding) 239 throws CertificateException { 240 return spiImpl.engineGenerateCertPath(inputStream, encoding); 241 } 242 243 /** 244 * Generates a {@code CertPath} from the provided list of certificates. The 245 * encoding is the default encoding. 246 * 247 * @param certificates 248 * the list containing certificates in a format supported by the 249 * {@code CertificateFactory}. 250 * @return a {@code CertPath} initialized from the provided data. 251 * @throws CertificateException 252 * if parsing problems are detected. 253 * @throws UnsupportedOperationException 254 * if the provider does not implement this method. 255 */ 256 public final CertPath generateCertPath(List<? extends Certificate> certificates) 257 throws CertificateException { 258 return spiImpl.engineGenerateCertPath(certificates); 259 } 260 261 /** 262 * Generates and initializes a collection of (unrelated) certificates from 263 * the provided input stream. 264 * 265 * @param inStream 266 * the stream from which the data is read to create the 267 * collection. 268 * @return an initialized collection of certificates. 269 * @throws CertificateException 270 * if parsing problems are detected. 271 */ 272 public final Collection<? extends Certificate> generateCertificates(InputStream inStream) 273 throws CertificateException { 274 return spiImpl.engineGenerateCertificates(inStream); 275 } 276 277 /** 278 * Generates and initializes a <i>Certificate Revocation List</i> (CRL) from 279 * the provided input stream. 280 * 281 * @param inStream 282 * the stream from where data is read to create the CRL. 283 * @return an initialized CRL. 284 * @throws CRLException 285 * if parsing problems are detected. 286 */ 287 public final CRL generateCRL(InputStream inStream) throws CRLException { 288 return spiImpl.engineGenerateCRL(inStream); 289 } 290 291 /** 292 * Generates and initializes a collection of <i>Certificate Revocation 293 * List</i> (CRL) from the provided input stream. 294 * 295 * @param inStream 296 * the stream from which the data is read to create the CRLs. 297 * @return an initialized collection of CRLs. 298 * @throws CRLException 299 * if parsing problems are detected. 300 */ 301 public final Collection<? extends CRL> generateCRLs(InputStream inStream) 302 throws CRLException { 303 return spiImpl.engineGenerateCRLs(inStream); 304 } 305} 306