CertificateFactory.java revision f33eae7e84eb6d3b0f4e86b59605bb3de73009f3
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; 28 29import org.apache.harmony.security.fortress.Engine; 30import org.apache.harmony.security.internal.nls.Messages; 31 32 33/** 34 * This class implements the functionality of a certificate factory algorithm, 35 * relying on parsing a stream of bytes. 36 * <p> 37 * It defines methods for parsing certificate chains (certificate paths) and 38 * <i>Certificate Revocation Lists</i> (CRLs). 39 */ 40public class CertificateFactory { 41 42 // Store CertificateFactory service name 43 private static final String SERVICE = "CertificateFactory"; 44 45 // Used to access common engine functionality 46 private static Engine engine = new Engine(SERVICE); 47 48 // Store used provider 49 private final Provider provider; 50 51 // Store used CertificateFactorySpi implementation 52 private final CertificateFactorySpi spiImpl; 53 54 // Store used type 55 private final String type; 56 57 /** 58 * Creates a new {@code CertificateFactory} instance. 59 * 60 * @param certFacSpi 61 * the implementation delegate. 62 * @param provider 63 * the associated provider. 64 * @param type 65 * the certificate type. 66 */ 67 protected CertificateFactory(CertificateFactorySpi certFacSpi, 68 Provider provider, String type) { 69 this.provider = provider; 70 this.type = type; 71 this.spiImpl = certFacSpi; 72 } 73 74 /** 75 * Creates a new {@code CertificateFactory} instance that provides the 76 * requested certificate type. 77 * 78 * @param type 79 * the certificate type. 80 * @return the new {@code CertificateFactory} instance. 81 * @throws CertificateException 82 * if the specified certificate type is not available at any 83 * installed provider. 84 * @throws NullPointerException 85 * if {@code type} is {@code null}. 86 */ 87 public static final CertificateFactory getInstance(String type) 88 throws CertificateException { 89 if (type == null) { 90 throw new NullPointerException(Messages.getString("security.07")); 91 } 92 try { 93 synchronized (engine) { 94 engine.getInstance(type, null); 95 return new CertificateFactory((CertificateFactorySpi) engine.spi, 96 engine.provider, type); 97 } 98 } catch (NoSuchAlgorithmException e) { 99 throw new CertificateException(e); 100 } 101 } 102 103 /** 104 * Creates a new {@code CertificateFactory} instance from the specified 105 * provider that provides the requested certificate type. 106 * 107 * @param type 108 * the certificate type. 109 * @param provider 110 * the name of the provider providing certificates of the 111 * specified type. 112 * @return the new {@code CertificateFactory} instance. 113 * @throws CertificateException 114 * if the specified certificate type is not available by the 115 * specified provider. 116 * @throws NoSuchProviderException 117 * if no provider with the specified name can be found. 118 * @throws IllegalArgumentException 119 * if the specified provider name is {@code null} or empty. 120 * @throws NullPointerException 121 * it {@code type} is {@code null}. 122 */ 123 public static final CertificateFactory getInstance(String type, 124 String provider) throws CertificateException, 125 NoSuchProviderException { 126 if ((provider == null) || (provider.length() == 0)) { 127 throw new IllegalArgumentException(Messages.getString("security.02")); 128 } 129 Provider impProvider = Security.getProvider(provider); 130 if (impProvider == null) { 131 throw new NoSuchProviderException(provider); 132 } 133 return getInstance(type, impProvider); 134 } 135 136 /** 137 * Creates a new {@code CertificateFactory} instance from the specified 138 * provider that provides the requested certificate type. 139 * 140 * @param type 141 * the certificate type. 142 * @param provider 143 * the name of the provider providing certificates of the 144 * specified type. 145 * @return the new {@code CertificateFactory} instance. 146 * @throws CertificateException 147 * if the specified certificate type is not available at the 148 * specified provider. 149 * @throws IllegalArgumentException 150 * if the specified provider is {@code null}. 151 * @throws NullPointerException 152 * is {@code type} is {@code null}. 153 */ 154 public static final CertificateFactory getInstance(String type, 155 Provider provider) throws CertificateException { 156 if (provider == null) { 157 throw new IllegalArgumentException(Messages.getString("security.04")); 158 } 159 if (type == null) { 160 throw new NullPointerException(Messages.getString("security.07")); 161 } 162 try { 163 synchronized (engine) { 164 engine.getInstance(type, provider, null); 165 return new CertificateFactory((CertificateFactorySpi) engine.spi, 166 provider, type); 167 } 168 } catch (NoSuchAlgorithmException e) { 169 throw new CertificateException(e.getMessage()); 170 } 171 } 172 173 /** 174 * Returns the {@code Provider} of the certificate factory represented by 175 * the certificate. 176 * 177 * @return the provider of this certificate factory. 178 */ 179 public final Provider getProvider() { 180 return provider; 181 } 182 183 /** 184 * Returns the Certificate type. 185 * 186 * @return type of certificate being used. 187 */ 188 public final String getType() { 189 return type; 190 } 191 192 /** 193 * Generates and initializes a {@code Certificate} from the provided input 194 * stream. 195 * 196 * @param inStream 197 * the stream from where data is read to create the {@code 198 * Certificate}. 199 * @return an initialized Certificate. 200 * @throws CertificateException 201 * if parsing problems are detected. 202 */ 203 public final Certificate generateCertificate(InputStream inStream) 204 throws CertificateException { 205 return spiImpl.engineGenerateCertificate(inStream); 206 } 207 208 /** 209 * Returns an {@code Iterator} over the supported {@code CertPath} encodings 210 * (as Strings). The first element is the default encoding scheme to apply. 211 * 212 * @return an iterator over supported {@link CertPath} encodings (as 213 * Strings). 214 */ 215 public final Iterator<String> getCertPathEncodings() { 216 return spiImpl.engineGetCertPathEncodings(); 217 } 218 219 /** 220 * Generates a {@code CertPath} (a certificate chain) from the provided 221 * {@code InputStream}. The default encoding scheme is applied. 222 * 223 * @param inStream 224 * {@code InputStream} with encoded data. 225 * @return a {@code CertPath} initialized from the provided data. 226 * @throws CertificateException 227 * if parsing problems are detected. 228 */ 229 public final CertPath generateCertPath(InputStream inStream) 230 throws CertificateException { 231 Iterator<String> it = getCertPathEncodings(); 232 if (!it.hasNext()) { 233 throw new CertificateException(Messages.getString("security.74")); 234 } 235 return spiImpl.engineGenerateCertPath(inStream, it.next()); 236 } 237 238 /** 239 * Generates a {@code CertPath} (a certificate chain) from the provided 240 * {@code InputStream} and the specified encoding scheme. 241 * 242 * @param inStream 243 * {@code InputStream} containing certificate path data in 244 * specified encoding. 245 * @param encoding 246 * encoding of the data in the input stream. 247 * @return a {@code CertPath} initialized from the provided data. 248 * @throws CertificateException 249 * if parsing problems are detected. 250 * @throws UnsupportedOperationException 251 * if the provider does not implement this method. 252 */ 253 public final CertPath generateCertPath(InputStream inStream, String encoding) 254 throws CertificateException { 255 return spiImpl.engineGenerateCertPath(inStream, encoding); 256 } 257 258 /** 259 * Generates a {@code CertPath} from the provided list of certificates. The 260 * encoding is the default encoding. 261 * 262 * @param certificates 263 * the list containing certificates in a format supported by the 264 * {@code CertificateFactory}. 265 * @return a {@code CertPath} initialized from the provided data. 266 * @throws CertificateException 267 * if parsing problems are detected. 268 * @throws UnsupportedOperationException 269 * if the provider does not implement this method. 270 */ 271 public final CertPath generateCertPath(List<? extends Certificate> certificates) 272 throws CertificateException { 273 return spiImpl.engineGenerateCertPath(certificates); 274 } 275 276 /** 277 * Generates and initializes a collection of (unrelated) certificates from 278 * the provided input stream. 279 * 280 * @param inStream 281 * the stream from which the data is read to create the 282 * collection. 283 * @return an initialized collection of certificates. 284 * @throws CertificateException 285 * if parsing problems are detected. 286 */ 287 public final Collection<? extends Certificate> generateCertificates(InputStream inStream) 288 throws CertificateException { 289 return spiImpl.engineGenerateCertificates(inStream); 290 } 291 292 /** 293 * Generates and initializes a <i>Certificate Revocation List</i> (CRL) from 294 * the provided input stream. 295 * 296 * @param inStream 297 * the stream from where data is read to create the CRL. 298 * @return an initialized CRL. 299 * @exception CRLException 300 * if parsing problems are detected. 301 */ 302 public final CRL generateCRL(InputStream inStream) throws CRLException { 303 return spiImpl.engineGenerateCRL(inStream); 304 } 305 306 /** 307 * Generates and initializes a collection of <i>Certificate Revocation 308 * List</i> (CRL) from the provided input stream. 309 * 310 * @param inStream 311 * the stream from which the data is read to create the CRLs. 312 * @return an initialized collection of CRLs. 313 * @exception CRLException 314 * if parsing problems are detected. 315 */ 316 public final Collection<? extends CRL> generateCRLs(InputStream inStream) 317 throws CRLException { 318 return spiImpl.engineGenerateCRLs(inStream); 319 } 320} 321