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. 132 * 133 * @param type 134 * the certificate type. 135 * @param provider 136 * the name of the provider providing certificates of the 137 * specified type. 138 * @return the new {@code CertificateFactory} instance. 139 * @throws CertificateException 140 * if the specified certificate type is not available at the 141 * specified provider. 142 * @throws IllegalArgumentException 143 * if the specified provider is {@code null}. 144 * @throws NullPointerException if {@code type == null} 145 * @throws IllegalArgumentException if {@code provider == null} 146 */ 147 public static final CertificateFactory getInstance(String type, 148 Provider provider) throws CertificateException { 149 if (provider == null) { 150 throw new IllegalArgumentException("provider == null"); 151 } 152 if (type == null) { 153 throw new NullPointerException("type == null"); 154 } 155 try { 156 Object spi = ENGINE.getInstance(type, provider, null); 157 return new CertificateFactory((CertificateFactorySpi) spi, provider, type); 158 } catch (NoSuchAlgorithmException e) { 159 throw new CertificateException(e); 160 } 161 } 162 163 /** 164 * Returns the {@code Provider} of the certificate factory represented by 165 * the certificate. 166 * 167 * @return the provider of this certificate factory. 168 */ 169 public final Provider getProvider() { 170 return provider; 171 } 172 173 /** 174 * Returns the Certificate type. 175 * 176 * @return type of certificate being used. 177 */ 178 public final String getType() { 179 return type; 180 } 181 182 /** 183 * Generates and initializes a {@code Certificate} from the provided input 184 * stream. 185 * 186 * @param inStream 187 * the stream from where data is read to create the {@code 188 * Certificate}. 189 * @return an initialized Certificate. 190 * @throws CertificateException 191 * if parsing problems are detected. 192 */ 193 public final Certificate generateCertificate(InputStream inStream) 194 throws CertificateException { 195 return spiImpl.engineGenerateCertificate(inStream); 196 } 197 198 /** 199 * Returns an {@code Iterator} over the supported {@code CertPath} encodings 200 * (as Strings). The first element is the default encoding scheme to apply. 201 * 202 * @return an iterator over supported {@link CertPath} encodings (as 203 * Strings). 204 */ 205 public final Iterator<String> getCertPathEncodings() { 206 return spiImpl.engineGetCertPathEncodings(); 207 } 208 209 /** 210 * Generates a {@code CertPath} (a certificate chain) from the provided 211 * {@code InputStream}. The default encoding scheme is applied. 212 * 213 * @param inStream 214 * {@code InputStream} with encoded data. 215 * @return a {@code CertPath} initialized from the provided data. 216 * @throws CertificateException 217 * if parsing problems are detected. 218 */ 219 public final CertPath generateCertPath(InputStream inStream) throws CertificateException { 220 Iterator<String> it = getCertPathEncodings(); 221 if (!it.hasNext()) { 222 throw new CertificateException("There are no CertPath encodings"); 223 } 224 return spiImpl.engineGenerateCertPath(inStream, it.next()); 225 } 226 227 /** 228 * Generates a {@code CertPath} (a certificate chain) from the provided 229 * {@code InputStream} and the specified encoding scheme. 230 * 231 * @param inStream 232 * {@code InputStream} containing certificate path data in 233 * specified encoding. 234 * @param encoding 235 * encoding of the data in the input stream. 236 * @return a {@code CertPath} initialized from the provided data. 237 * @throws CertificateException 238 * if parsing problems are detected. 239 * @throws UnsupportedOperationException 240 * if the provider does not implement this method. 241 */ 242 public final CertPath generateCertPath(InputStream inStream, String encoding) 243 throws CertificateException { 244 return spiImpl.engineGenerateCertPath(inStream, encoding); 245 } 246 247 /** 248 * Generates a {@code CertPath} from the provided list of certificates. The 249 * encoding is the default encoding. 250 * 251 * @param certificates 252 * the list containing certificates in a format supported by the 253 * {@code CertificateFactory}. 254 * @return a {@code CertPath} initialized from the provided data. 255 * @throws CertificateException 256 * if parsing problems are detected. 257 * @throws UnsupportedOperationException 258 * if the provider does not implement this method. 259 */ 260 public final CertPath generateCertPath(List<? extends Certificate> certificates) 261 throws CertificateException { 262 return spiImpl.engineGenerateCertPath(certificates); 263 } 264 265 /** 266 * Generates and initializes a collection of (unrelated) certificates from 267 * the provided input stream. 268 * 269 * @param inStream 270 * the stream from which the data is read to create the 271 * collection. 272 * @return an initialized collection of certificates. 273 * @throws CertificateException 274 * if parsing problems are detected. 275 */ 276 public final Collection<? extends Certificate> generateCertificates(InputStream inStream) 277 throws CertificateException { 278 return spiImpl.engineGenerateCertificates(inStream); 279 } 280 281 /** 282 * Generates and initializes a <i>Certificate Revocation List</i> (CRL) from 283 * the provided input stream. 284 * 285 * @param inStream 286 * the stream from where data is read to create the CRL. 287 * @return an initialized CRL. 288 * @exception CRLException 289 * if parsing problems are detected. 290 */ 291 public final CRL generateCRL(InputStream inStream) throws CRLException { 292 return spiImpl.engineGenerateCRL(inStream); 293 } 294 295 /** 296 * Generates and initializes a collection of <i>Certificate Revocation 297 * List</i> (CRL) from the provided input stream. 298 * 299 * @param inStream 300 * the stream from which the data is read to create the CRLs. 301 * @return an initialized collection of CRLs. 302 * @exception CRLException 303 * if parsing problems are detected. 304 */ 305 public final Collection<? extends CRL> generateCRLs(InputStream inStream) 306 throws CRLException { 307 return spiImpl.engineGenerateCRLs(inStream); 308 } 309} 310