CertPathBuilder.java revision 12745:f068a4ffddd2
1/*
2 * Copyright (c) 2000, 2013, 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
26package java.security.cert;
27
28import java.security.AccessController;
29import java.security.InvalidAlgorithmParameterException;
30import java.security.NoSuchAlgorithmException;
31import java.security.NoSuchProviderException;
32import java.security.PrivilegedAction;
33import java.security.Provider;
34import java.security.Security;
35import sun.security.util.Debug;
36
37import sun.security.jca.*;
38import 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}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
76 * CertPathBuilder section</a> of the
77 * Java Cryptography Architecture Standard Algorithm Name Documentation.
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 */
101public 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     */
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     * @param algorithm the name of the requested {@code CertPathBuilder}
146     *  algorithm.  See the CertPathBuilder section in the <a href=
147     *  "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
148     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
149     * for information about standard algorithm names.
150     *
151     * @return a {@code CertPathBuilder} object that implements the
152     *          specified algorithm.
153     *
154     * @throws NoSuchAlgorithmException if no Provider supports a
155     *          CertPathBuilderSpi implementation for the
156     *          specified algorithm.
157     *
158     * @see java.security.Provider
159     */
160    public static CertPathBuilder getInstance(String algorithm)
161            throws NoSuchAlgorithmException {
162        Instance instance = GetInstance.getInstance("CertPathBuilder",
163            CertPathBuilderSpi.class, algorithm);
164        return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
165            instance.provider, algorithm);
166    }
167
168    /**
169     * Returns a {@code CertPathBuilder} object that implements the
170     * specified algorithm.
171     *
172     * <p> A new CertPathBuilder object encapsulating the
173     * CertPathBuilderSpi implementation from the specified provider
174     * is returned.  The specified provider must be registered
175     * in the security provider list.
176     *
177     * <p> Note that the list of registered providers may be retrieved via
178     * the {@link Security#getProviders() Security.getProviders()} method.
179     *
180     * @param algorithm the name of the requested {@code CertPathBuilder}
181     *  algorithm.  See the CertPathBuilder section in the <a href=
182     *  "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
183     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
184     * for information about standard algorithm names.
185     *
186     * @param provider the name of the provider.
187     *
188     * @return a {@code CertPathBuilder} object that implements the
189     *          specified algorithm.
190     *
191     * @throws NoSuchAlgorithmException if a CertPathBuilderSpi
192     *          implementation for the specified algorithm is not
193     *          available from the specified provider.
194     *
195     * @throws NoSuchProviderException if the specified provider is not
196     *          registered in the security provider list.
197     *
198     * @exception IllegalArgumentException if the {@code provider} is
199     *          null or empty.
200     *
201     * @see java.security.Provider
202     */
203    public static CertPathBuilder getInstance(String algorithm, String provider)
204           throws NoSuchAlgorithmException, NoSuchProviderException {
205        Instance instance = GetInstance.getInstance("CertPathBuilder",
206            CertPathBuilderSpi.class, algorithm, provider);
207        return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
208            instance.provider, algorithm);
209    }
210
211    /**
212     * Returns a {@code CertPathBuilder} object that implements the
213     * specified algorithm.
214     *
215     * <p> A new CertPathBuilder object encapsulating the
216     * CertPathBuilderSpi implementation from the specified Provider
217     * object is returned.  Note that the specified Provider object
218     * does not have to be registered in the provider list.
219     *
220     * @param algorithm the name of the requested {@code CertPathBuilder}
221     *  algorithm.  See the CertPathBuilder section in the <a href=
222     *  "{@docRoot}/../technotes/guides/security/StandardNames.html#CertPathBuilder">
223     * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
224     * for information about standard algorithm names.
225     *
226     * @param provider the provider.
227     *
228     * @return a {@code CertPathBuilder} object that implements the
229     *          specified algorithm.
230     *
231     * @exception NoSuchAlgorithmException if a CertPathBuilderSpi
232     *          implementation for the specified algorithm is not available
233     *          from the specified Provider object.
234     *
235     * @exception IllegalArgumentException if the {@code provider} is
236     *          null.
237     *
238     * @see java.security.Provider
239     */
240    public static CertPathBuilder getInstance(String algorithm,
241            Provider provider) throws NoSuchAlgorithmException {
242        Instance instance = GetInstance.getInstance("CertPathBuilder",
243            CertPathBuilderSpi.class, algorithm, provider);
244        return new CertPathBuilder((CertPathBuilderSpi)instance.impl,
245            instance.provider, algorithm);
246    }
247
248    /**
249     * Returns the provider of this {@code CertPathBuilder}.
250     *
251     * @return the provider of this {@code CertPathBuilder}
252     */
253    public final Provider getProvider() {
254        return this.provider;
255    }
256
257    /**
258     * Returns the name of the algorithm of this {@code CertPathBuilder}.
259     *
260     * @return the name of the algorithm of this {@code CertPathBuilder}
261     */
262    public final String getAlgorithm() {
263        return this.algorithm;
264    }
265
266    /**
267     * Attempts to build a certification path using the specified algorithm
268     * parameter set.
269     *
270     * @param params the algorithm parameters
271     * @return the result of the build algorithm
272     * @throws CertPathBuilderException if the builder is unable to construct
273     *  a certification path that satisfies the specified parameters
274     * @throws InvalidAlgorithmParameterException if the specified parameters
275     * are inappropriate for this {@code CertPathBuilder}
276     */
277    public final CertPathBuilderResult build(CertPathParameters params)
278        throws CertPathBuilderException, InvalidAlgorithmParameterException
279    {
280        return builderSpi.engineBuild(params);
281    }
282
283    /**
284     * Returns the default {@code CertPathBuilder} type as specified by
285     * the {@code certpathbuilder.type} security property, or the string
286     * {@literal "PKIX"} if no such property exists.
287     *
288     * <p>The default {@code CertPathBuilder} type can be used by
289     * applications that do not want to use a hard-coded type when calling one
290     * of the {@code getInstance} methods, and want to provide a default
291     * type in case a user does not specify its own.
292     *
293     * <p>The default {@code CertPathBuilder} type can be changed by
294     * setting the value of the {@code certpathbuilder.type} security property
295     * to the desired type.
296     *
297     * @see java.security.Security security properties
298     * @return the default {@code CertPathBuilder} type as specified
299     * by the {@code certpathbuilder.type} security property, or the string
300     * {@literal "PKIX"} if no such property exists.
301     */
302    public static final String getDefaultType() {
303        String cpbtype =
304            AccessController.doPrivileged(new PrivilegedAction<>() {
305                public String run() {
306                    return Security.getProperty(CPB_TYPE);
307                }
308            });
309        return (cpbtype == null) ? "PKIX" : cpbtype;
310    }
311
312    /**
313     * Returns a {@code CertPathChecker} that the encapsulated
314     * {@code CertPathBuilderSpi} implementation uses to check the revocation
315     * status of certificates. A PKIX implementation returns objects of
316     * type {@code PKIXRevocationChecker}. Each invocation of this method
317     * returns a new instance of {@code CertPathChecker}.
318     *
319     * <p>The primary purpose of this method is to allow callers to specify
320     * additional input parameters and options specific to revocation checking.
321     * See the class description for an example.
322     *
323     * @return a {@code CertPathChecker}
324     * @throws UnsupportedOperationException if the service provider does not
325     *         support this method
326     * @since 1.8
327     */
328    public final CertPathChecker getRevocationChecker() {
329        return builderSpi.engineGetRevocationChecker();
330    }
331}
332