1 /*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package java.security.cert;
27
28 import java.security.AccessController;
29 import java.security.InvalidAlgorithmParameterException;
30 import java.security.NoSuchAlgorithmException;
31 import java.security.NoSuchProviderException;
32 import java.security.PrivilegedAction;
33 import java.security.Provider;
34 import java.security.Security;
35 import sun.security.util.Debug;
36
37 import sun.security.jca;
38 import sun.security.jca.GetInstance.Instance;
39
40 /**
41 * A class for building certification paths (also known as certificate chains).
42 * <p>
43 * This class uses a provider-based architecture.
44 * To create a <code>CertPathBuilder</code>, call
45 * one of the static <code>getInstance</code> methods, passing in the
46 * algorithm name of the <code>CertPathBuilder</code> desired and optionally
47 * the name of the provider desired.
48 * <p>
49 * Once a <code>CertPathBuilder</code> object has been created, certification
50 * paths can be constructed by calling the {@link #build build} method and
51 * passing it an algorithm-specific set of parameters. If successful, the
52 * result (including the <code>CertPath</code> that was built) is returned
53 * in an object that implements the <code>CertPathBuilderResult</code>
54 * interface.
55 * <p>
56 * <b>Concurrent Access</b>
57 * <p>
58 * The static methods of this class are guaranteed to be thread-safe.
59 * Multiple threads may concurrently invoke the static methods defined in
60 * this class with no ill effects.
61 * <p>
62 * However, this is not true for the non-static methods defined by this class.
63 * Unless otherwise documented by a specific provider, threads that need to
64 * access a single <code>CertPathBuilder</code> instance concurrently should
65 * synchronize amongst themselves and provide the necessary locking. Multiple
66 * threads each manipulating a different <code>CertPathBuilder</code> instance
67 * need not synchronize.
68 *
69 * @see CertPath
70 *
71 * @since 1.4
72 * @author Sean Mullan
73 * @author Yassir Elley
74 */
75 public class CertPathBuilder {
76
77 /*
78 * Constant to lookup in the Security properties file to determine
79 * the default certpathbuilder type. In the Security properties file,
80 * the default certpathbuilder type is given as:
81 * <pre>
82 * certpathbuilder.type=PKIX
83 * </pre>
84 */
85 private static final String CPB_TYPE = "certpathbuilder.type";
86 private static final Debug debug = Debug.getInstance("certpath");
87 private CertPathBuilderSpi builderSpi;
88 private Provider provider;
89 private String algorithm;
90
91 /**
92 * Creates a <code>CertPathBuilder</code> object of the given algorithm,
93 * and encapsulates the given provider implementation (SPI object) in it.
94 *
95 * @param builderSpi the provider implementation
96 * @param provider the provider
97 * @param algorithm the algorithm name
98 */
99 protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider,
100 String algorithm)
101 {
102 this.builderSpi = builderSpi;
103 this.provider = provider;
104 this.algorithm = algorithm;
105 }
106
107 /**
108 * Returns a <code>CertPathBuilder</code> object that implements the
109 * specified algorithm.
110 *
111 * <p> This method traverses the list of registered security Providers,
112 * starting with the most preferred Provider.
113 * A new CertPathBuilder object encapsulating the
114 * CertPathBuilderSpi implementation from the first
115 * Provider that supports the specified algorithm is returned.
116 *
117 * <p> Note that the list of registered providers may be retrieved via
118 * the {@link Security#getProviders() Security.getProviders()} method.
119 *
120 * @param algorithm the name of the requested <code>CertPathBuilder</code>
121 * algorithm. See Appendix A in the <a href=
122 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
123 * Java Certification Path API Programmer's Guide </a>
124 * for information about standard algorithm names.
125 *
126 * @return a <code>CertPathBuilder</code> object that implements the
127 * specified algorithm.
128 *
129 * @throws NoSuchAlgorithmException if no Provider supports a
130 * CertPathBuilderSpi implementation for the
131 * specified algorithm.
132 *
133 * @see java.security.Provider
134 */
135 public static CertPathBuilder getInstance(String algorithm)
136 throws NoSuchAlgorithmException {
137 Instance instance = GetInstance.getInstance("CertPathBuilder",
138 CertPathBuilderSpi.class, algorithm);
139 return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
140 instance.provider, algorithm);
141 }
142
143 /**
144 * Returns a <code>CertPathBuilder</code> object that implements the
145 * specified algorithm.
146 *
147 * <p> A new CertPathBuilder object encapsulating the
148 * CertPathBuilderSpi implementation from the specified provider
149 * is returned. The specified provider must be registered
150 * in the security provider list.
151 *
152 * <p> Note that the list of registered providers may be retrieved via
153 * the {@link Security#getProviders() Security.getProviders()} method.
154 *
155 * @param algorithm the name of the requested <code>CertPathBuilder</code>
156 * algorithm. See Appendix A in the <a href=
157 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
158 * Java Certification Path API Programmer's Guide </a>
159 * for information about standard algorithm names.
160 *
161 * @param provider the name of the provider.
162 *
163 * @return a <code>CertPathBuilder</code> object that implements the
164 * specified algorithm.
165 *
166 * @throws NoSuchAlgorithmException if a CertPathBuilderSpi
167 * implementation for the specified algorithm is not
168 * available from the specified provider.
169 *
170 * @throws NoSuchProviderException if the specified provider is not
171 * registered in the security provider list.
172 *
173 * @exception IllegalArgumentException if the <code>provider</code> is
174 * null or empty.
175 *
176 * @see java.security.Provider
177 */
178 public static CertPathBuilder getInstance(String algorithm, String provider)
179 throws NoSuchAlgorithmException, NoSuchProviderException {
180 Instance instance = GetInstance.getInstance("CertPathBuilder",
181 CertPathBuilderSpi.class, algorithm, provider);
182 return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
183 instance.provider, algorithm);
184 }
185
186 /**
187 * Returns a <code>CertPathBuilder</code> object that implements the
188 * specified algorithm.
189 *
190 * <p> A new CertPathBuilder object encapsulating the
191 * CertPathBuilderSpi implementation from the specified Provider
192 * object is returned. Note that the specified Provider object
193 * does not have to be registered in the provider list.
194 *
195 * @param algorithm the name of the requested <code>CertPathBuilder</code>
196 * algorithm. See Appendix A in the <a href=
197 * "../../../../technotes/guides/security/certpath/CertPathProgGuide.html#AppA">
198 * Java Certification Path API Programmer's Guide </a>
199 * for information about standard algorithm names.
200 *
201 * @param provider the provider.
202 *
203 * @return a <code>CertPathBuilder</code> object that implements the
204 * specified algorithm.
205 *
206 * @exception NoSuchAlgorithmException if a CertPathBuilderSpi
207 * implementation for the specified algorithm is not available
208 * from the specified Provider object.
209 *
210 * @exception IllegalArgumentException if the <code>provider</code> is
211 * null.
212 *
213 * @see java.security.Provider
214 */
215 public static CertPathBuilder getInstance(String algorithm,
216 Provider provider) throws NoSuchAlgorithmException {
217 Instance instance = GetInstance.getInstance("CertPathBuilder",
218 CertPathBuilderSpi.class, algorithm, provider);
219 return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
220 instance.provider, algorithm);
221 }
222
223 /**
224 * Returns the provider of this <code>CertPathBuilder</code>.
225 *
226 * @return the provider of this <code>CertPathBuilder</code>
227 */
228 public final Provider getProvider() {
229 return this.provider;
230 }
231
232 /**
233 * Returns the name of the algorithm of this <code>CertPathBuilder</code>.
234 *
235 * @return the name of the algorithm of this <code>CertPathBuilder</code>
236 */
237 public final String getAlgorithm() {
238 return this.algorithm;
239 }
240
241 /**
242 * Attempts to build a certification path using the specified algorithm
243 * parameter set.
244 *
245 * @param params the algorithm parameters
246 * @return the result of the build algorithm
247 * @throws CertPathBuilderException if the builder is unable to construct
248 * a certification path that satisfies the specified parameters
249 * @throws InvalidAlgorithmParameterException if the specified parameters
250 * are inappropriate for this <code>CertPathBuilder</code>
251 */
252 public final CertPathBuilderResult build(CertPathParameters params)
253 throws CertPathBuilderException, InvalidAlgorithmParameterException
254 {
255 return builderSpi.engineBuild(params);
256 }
257
258 /**
259 * Returns the default <code>CertPathBuilder</code> type as specified in
260 * the Java security properties file, or the string "PKIX"
261 * if no such property exists. The Java security properties file is
262 * located in the file named <JAVA_HOME>/lib/security/java.security.
263 * <JAVA_HOME> refers to the value of the java.home system property,
264 * and specifies the directory where the JRE is installed.
265 *
266 * <p>The default <code>CertPathBuilder</code> type can be used by
267 * applications that do not want to use a hard-coded type when calling one
268 * of the <code>getInstance</code> methods, and want to provide a default
269 * type in case a user does not specify its own.
270 *
271 * <p>The default <code>CertPathBuilder</code> type can be changed by
272 * setting the value of the "certpathbuilder.type" security property
273 * (in the Java security properties file) to the desired type.
274 *
275 * @return the default <code>CertPathBuilder</code> type as specified
276 * in the Java security properties file, or the string "PKIX"
277 * if no such property exists.
278 */
279 public final static String getDefaultType() {
280 String cpbtype;
281 cpbtype = AccessController.doPrivileged(new PrivilegedAction<String>() {
282 public String run() {
283 return Security.getProperty(CPB_TYPE);
284 }
285 });
286 if (cpbtype == null) {
287 cpbtype = "PKIX";
288 }
289 return cpbtype;
290 }
291 }