• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000, 2017, Oracle and/or its affiliates. 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * 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 java.util.Objects;
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}, call
45  * one of the static {@code getInstance} methods, passing in the
46  * algorithm name of the {@code CertPathBuilder} desired and optionally
47  * the name of the provider desired.
48  *
49  * <p>Once a {@code CertPathBuilder} 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} that was built) is returned
53  * in an object that implements the {@code CertPathBuilderResult}
54  * interface.
55  *
56  * <p>The {@link #getRevocationChecker} method allows an application to specify
57  * additional algorithm-specific parameters and options used by the
58  * {@code CertPathBuilder} when checking the revocation status of certificates.
59  * Here is an example demonstrating how it is used with the PKIX algorithm:
60  *
61  * <pre>
62  * CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
63  * PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker();
64  * rc.setOptions(EnumSet.of(Option.PREFER_CRLS));
65  * params.addCertPathChecker(rc);
66  * CertPathBuilderResult cpbr = cpb.build(params);
67  * </pre>
68  *
69  * <p>Every implementation of the Java platform is required to support the
70  * following standard {@code CertPathBuilder} algorithm:
71  * <ul>
72  * <li>{@code PKIX}</li>
73  * </ul>
74  * This algorithm is described in the <a href=
75  * "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
76  * CertPathBuilder section</a> of the
77  * Java Security Standard Algorithm Names Specification.
78  * Consult the release documentation for your implementation to see if any
79  * other algorithms are supported.
80  *
81  * <p>
82  * <b>Concurrent Access</b>
83  * <p>
84  * The static methods of this class are guaranteed to be thread-safe.
85  * Multiple threads may concurrently invoke the static methods defined in
86  * this class with no ill effects.
87  * <p>
88  * However, this is not true for the non-static methods defined by this class.
89  * Unless otherwise documented by a specific provider, threads that need to
90  * access a single {@code CertPathBuilder} instance concurrently should
91  * synchronize amongst themselves and provide the necessary locking. Multiple
92  * threads each manipulating a different {@code CertPathBuilder} instance
93  * need not synchronize.
94  *
95  * @see CertPath
96  *
97  * @since       1.4
98  * @author      Sean Mullan
99  * @author      Yassir Elley
100  */
101 public class CertPathBuilder {
102 
103     /*
104      * Constant to lookup in the Security properties file to determine
105      * the default certpathbuilder type. In the Security properties file,
106      * the default certpathbuilder type is given as:
107      * <pre>
108      * certpathbuilder.type=PKIX
109      * </pre>
110      */
111     private static final String CPB_TYPE = "certpathbuilder.type";
112     private final CertPathBuilderSpi builderSpi;
113     private final Provider provider;
114     private final String algorithm;
115 
116     /**
117      * Creates a {@code CertPathBuilder} object of the given algorithm,
118      * and encapsulates the given provider implementation (SPI object) in it.
119      *
120      * @param builderSpi the provider implementation
121      * @param provider the provider
122      * @param algorithm the algorithm name
123      */
CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider, String algorithm)124     protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider,
125         String algorithm)
126     {
127         this.builderSpi = builderSpi;
128         this.provider = provider;
129         this.algorithm = algorithm;
130     }
131 
132     /**
133      * Returns a {@code CertPathBuilder} object that implements the
134      * specified algorithm.
135      *
136      * <p> This method traverses the list of registered security Providers,
137      * starting with the most preferred Provider.
138      * A new CertPathBuilder object encapsulating the
139      * CertPathBuilderSpi implementation from the first
140      * Provider that supports the specified algorithm is returned.
141      *
142      * <p> Note that the list of registered providers may be retrieved via
143      * the {@link Security#getProviders() Security.getProviders()} method.
144      *
145      * @implNote
146      * The JDK Reference Implementation additionally uses the
147      * {@code jdk.security.provider.preferred}
148      * {@link Security#getProperty(String) Security} property to determine
149      * the preferred provider order for the specified algorithm. This
150      * may be different than the order of providers returned by
151      * {@link Security#getProviders() Security.getProviders()}.
152      *
153      * @param algorithm the name of the requested {@code CertPathBuilder}
154      *  algorithm.  See the CertPathBuilder section in the <a href=
155      *  "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
156      * Java Security Standard Algorithm Names Specification</a>
157      * for information about standard algorithm names.
158      *
159      * @return a {@code CertPathBuilder} object that implements the
160      *         specified algorithm
161      *
162      * @throws NoSuchAlgorithmException if no {@code Provider} supports a
163      *         {@code CertPathBuilderSpi} implementation for the
164      *         specified algorithm
165      *
166      * @throws NullPointerException if {@code algorithm} is {@code null}
167      *
168      * @see java.security.Provider
169      */
getInstance(String algorithm)170     public static CertPathBuilder getInstance(String algorithm)
171             throws NoSuchAlgorithmException {
172         Objects.requireNonNull(algorithm, "null algorithm name");
173         Instance instance = GetInstance.getInstance("CertPathBuilder",
174             CertPathBuilderSpi.class, algorithm);
175         return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
176             instance.provider, algorithm);
177     }
178 
179     /**
180      * Returns a {@code CertPathBuilder} object that implements the
181      * specified algorithm.
182      *
183      * <p> A new CertPathBuilder object encapsulating the
184      * CertPathBuilderSpi implementation from the specified provider
185      * is returned.  The specified provider must be registered
186      * in the security provider list.
187      *
188      * <p> Note that the list of registered providers may be retrieved via
189      * the {@link Security#getProviders() Security.getProviders()} method.
190      *
191      * @param algorithm the name of the requested {@code CertPathBuilder}
192      *  algorithm.  See the CertPathBuilder section in the <a href=
193      *  "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
194      * Java Security Standard Algorithm Names Specification</a>
195      * for information about standard algorithm names.
196      *
197      * @param provider the name of the provider.
198      *
199      * @return a {@code CertPathBuilder} object that implements the
200      *         specified algorithm
201      *
202      * @throws IllegalArgumentException if the {@code provider} is
203      *         {@code null} or empty
204      *
205      * @throws NoSuchAlgorithmException if a {@code CertPathBuilderSpi}
206      *         implementation for the specified algorithm is not
207      *         available from the specified provider
208      *
209      * @throws NoSuchProviderException if the specified provider is not
210      *         registered in the security provider list
211      *
212      * @throws NullPointerException if {@code algorithm} is {@code null}
213      *
214      * @see java.security.Provider
215      */
getInstance(String algorithm, String provider)216     public static CertPathBuilder getInstance(String algorithm, String provider)
217            throws NoSuchAlgorithmException, NoSuchProviderException {
218         Objects.requireNonNull(algorithm, "null algorithm name");
219         Instance instance = GetInstance.getInstance("CertPathBuilder",
220             CertPathBuilderSpi.class, algorithm, provider);
221         return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
222             instance.provider, algorithm);
223     }
224 
225     /**
226      * Returns a {@code CertPathBuilder} object that implements the
227      * specified algorithm.
228      *
229      * <p> A new CertPathBuilder object encapsulating the
230      * CertPathBuilderSpi implementation from the specified Provider
231      * object is returned.  Note that the specified Provider object
232      * does not have to be registered in the provider list.
233      *
234      * @param algorithm the name of the requested {@code CertPathBuilder}
235      *  algorithm.  See the CertPathBuilder section in the <a href=
236      *  "{@docRoot}/../specs/security/standard-names.html#certpathbuilder-algorithms">
237      * Java Security Standard Algorithm Names Specification</a>
238      * for information about standard algorithm names.
239      *
240      * @param provider the provider.
241      *
242      * @return a {@code CertPathBuilder} object that implements the
243      *         specified algorithm
244      *
245      * @throws IllegalArgumentException if the {@code provider} is
246      *         {@code null}
247      *
248      * @throws NoSuchAlgorithmException if a {@code CertPathBuilderSpi}
249      *         implementation for the specified algorithm is not available
250      *         from the specified {@code Provider} object
251      *
252      * @throws NullPointerException if {@code algorithm} is {@code null}
253      *
254      * @see java.security.Provider
255      */
getInstance(String algorithm, Provider provider)256     public static CertPathBuilder getInstance(String algorithm,
257             Provider provider) throws NoSuchAlgorithmException {
258         Objects.requireNonNull(algorithm, "null algorithm name");
259         Instance instance = GetInstance.getInstance("CertPathBuilder",
260             CertPathBuilderSpi.class, algorithm, provider);
261         return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
262             instance.provider, algorithm);
263     }
264 
265     /**
266      * Returns the provider of this {@code CertPathBuilder}.
267      *
268      * @return the provider of this {@code CertPathBuilder}
269      */
getProvider()270     public final Provider getProvider() {
271         return this.provider;
272     }
273 
274     /**
275      * Returns the name of the algorithm of this {@code CertPathBuilder}.
276      *
277      * @return the name of the algorithm of this {@code CertPathBuilder}
278      */
getAlgorithm()279     public final String getAlgorithm() {
280         return this.algorithm;
281     }
282 
283     /**
284      * Attempts to build a certification path using the specified algorithm
285      * parameter set.
286      *
287      * @param params the algorithm parameters
288      * @return the result of the build algorithm
289      * @throws CertPathBuilderException if the builder is unable to construct
290      *  a certification path that satisfies the specified parameters
291      * @throws InvalidAlgorithmParameterException if the specified parameters
292      * are inappropriate for this {@code CertPathBuilder}
293      */
build(CertPathParameters params)294     public final CertPathBuilderResult build(CertPathParameters params)
295         throws CertPathBuilderException, InvalidAlgorithmParameterException
296     {
297         return builderSpi.engineBuild(params);
298     }
299 
300     /**
301      * Returns the default {@code CertPathBuilder} type as specified by
302      * the {@code certpathbuilder.type} security property, or the string
303      * {@literal "PKIX"} if no such property exists.
304      *
305      * <p>The default {@code CertPathBuilder} type can be used by
306      * applications that do not want to use a hard-coded type when calling one
307      * of the {@code getInstance} methods, and want to provide a default
308      * type in case a user does not specify its own.
309      *
310      * <p>The default {@code CertPathBuilder} type can be changed by
311      * setting the value of the {@code certpathbuilder.type} security property
312      * to the desired type.
313      *
314      * @see java.security.Security security properties
315      * @return the default {@code CertPathBuilder} type as specified
316      * by the {@code certpathbuilder.type} security property, or the string
317      * {@literal "PKIX"} if no such property exists.
318      */
getDefaultType()319     public static final String getDefaultType() {
320         String cpbtype =
321             AccessController.doPrivileged(new PrivilegedAction<>() {
322                 public String run() {
323                     return Security.getProperty(CPB_TYPE);
324                 }
325             });
326         return (cpbtype == null) ? "PKIX" : cpbtype;
327     }
328 
329     /**
330      * Returns a {@code CertPathChecker} that the encapsulated
331      * {@code CertPathBuilderSpi} implementation uses to check the revocation
332      * status of certificates. A PKIX implementation returns objects of
333      * type {@code PKIXRevocationChecker}. Each invocation of this method
334      * returns a new instance of {@code CertPathChecker}.
335      *
336      * <p>The primary purpose of this method is to allow callers to specify
337      * additional input parameters and options specific to revocation checking.
338      * See the class description for an example.
339      *
340      * @return a {@code CertPathChecker}
341      * @throws UnsupportedOperationException if the service provider does not
342      *         support this method
343      * @since 1.8
344      */
getRevocationChecker()345     public final CertPathChecker getRevocationChecker() {
346         return builderSpi.engineGetRevocationChecker();
347     }
348 }
349