package org.bouncycastle.jce.cert; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; import java.security.Security; /** * A class for building certification paths (also known as certificate chains).<br /> * <br /> * This class uses a provider-based architecture, as described in the Java * Cryptography Architecture. To create a <code>CertPathBuilder</code>, call * one of the static <code>getInstance</code> methods, passing in the * algorithm name of the CertPathBuilder desired and optionally the name of the * provider desired.<br /> * <br /> * Once a <code>CertPathBuilder</code> object has been created, certification * paths can be constructed by calling the {@link #build build} method and * passing it an algorithm-specific set of parameters. If successful, the result * (including the CertPath that was built) is returned in an object that * implements the <code>CertPathBuilderResult</code> interface.<br /> * <br /> * <strong>Concurrent Access</strong><br /> * <br /> * The static methods of this class are guaranteed to be thread-safe. Multiple * threads may concurrently invoke the static methods defined in this class with * no ill effects.<br /> * <br /> * However, this is not true for the non-static methods defined by this class. * Unless otherwise documented by a specific provider, threads that need to * access a single <code>CertPathBuilder</code> instance concurrently should * synchronize amongst themselves and provide the necessary locking. Multiple * threads each manipulating a different <code>CertPathBuilder</code> instance * need not synchronize.<br /> * <br /> */ public class CertPathBuilder extends Object { private CertPathBuilderSpi builderSpi; private Provider provider; private String algorithm; /** * Creates a CertPathBuilder object of the given algorithm, and encapsulates * the given provider implementation (SPI object) in it. * * @param builderSpi * the provider implementation * @param provider * the provider * @param algorithm * the algorithm name */ protected CertPathBuilder( CertPathBuilderSpi builderSpi, Provider provider, String algorithm) { this.builderSpi = builderSpi; this.provider = provider; this.algorithm = algorithm; } /** * Returns a CertPathBuilder object that implements the specified algorithm.<br /> * <br /> * If the default provider package provides an implementation of the * specified CertPathBuilder algorithm, an instance of CertPathBuilder * containing that implementation is returned. If the requested algorithm is * not available in the default package, other packages are searched.<br /> * <br /> * * @param algorithm * the name of the requested CertPathBuilder algorithm * * @return a CertPathBuilder object that implements the specified algorithm * * @exception NoSuchAlgorithmException * if the requested algorithm is not available in the default * provider package or any of the other provider packages * that were searched */ public static CertPathBuilder getInstance(String algorithm) throws NoSuchAlgorithmException { try { CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathBuilder", algorithm, (String)null); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), imp.getProvider(), algorithm); } } catch (NoSuchProviderException ex) { } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider. * * @param algorithm * the name of the requested CertPathBuilder algorithm * @param provider * the name of the provider * * @return a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested algorithm is not available from the * specified provider * @exception NoSuchProviderException * if the provider has not been configured * @exception IllegalArgumentException * if the provider is null */ public static CertPathBuilder getInstance(String algorithm, String provider) throws NoSuchAlgorithmException, NoSuchProviderException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathBuilder", algorithm, provider); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), imp .getProvider(), algorithm); } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider. Note: the provider doesn't have to * be registered. * * @param algorithm * the name of the requested CertPathBuilder algorithm * @param provider * the provider * @return a CertPathBuilder object that implements the specified algorithm, * as supplied by the specified provider * * @exception NoSuchAlgorithmException * if the requested algorithm is not available from the * specified provider * @exception IllegalArgumentException * if the provider is null. */ public static CertPathBuilder getInstance(String algorithm, Provider provider) throws NoSuchAlgorithmException { if (provider == null) { throw new IllegalArgumentException("provider must be non-null"); } CertUtil.Implementation imp = CertUtil.getImplementation( "CertPathBuilder", algorithm, provider); if (imp != null) { return new CertPathBuilder((CertPathBuilderSpi)imp.getEngine(), provider, algorithm); } throw new NoSuchAlgorithmException("can't find type " + algorithm); } /** * Returns the provider of this <code>CertPathBuilder</code>. * * @return the provider of this <code>CertPathBuilder</code> */ public final Provider getProvider() { return provider; } /** * Returns the name of the algorithm of this <code>CertPathBuilder</code>. * * @return the name of the algorithm of this <code>CertPathBuilder</code> */ public final String getAlgorithm() { return algorithm; } /** * Attempts to build a certification path using the specified algorithm * parameter set. * * @param params * the algorithm parameters * * @return the result of the build algorithm * * @exception CertPathBuilderException * if the builder is unable to construct a certification path * that satisfies the specified parameters * @exception InvalidAlgorithmParameterException * if the specified parameters * are inappropriate for this * <code>CertPathBuilder</code> */ public final CertPathBuilderResult build(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParameterException { return builderSpi.engineBuild(params); } /** * Returns the default <code>CertPathBuilder</code> type as specified in * the Java security properties file, or the string "PKIX" if no * such property exists. The Java security properties file is located in the * file named <JAVA_HOME>/lib/security/java.security, where * <JAVA_HOME> refers to the directory where the SDK was installed.<br /> * <br /> * The default <code>CertPathBuilder</code> type can be used by * applications that do not want to use a hard-coded type when calling one * of the <code>getInstance</code> methods, and want to provide a default * type in case a user does not specify its own.<br /> * <br /> * The default <code>CertPathBuilder</code> type can be changed by setting * the value of the "certpathbuilder.type" security property (in the Java * security properties file) to the desired type. * * @return the default <code>CertPathBuilder</code> type as specified in * the Java security properties file, or the string "PKIX" * if no such property exists. */ public static final String getDefaultType() { String defaulttype = null; defaulttype = Security.getProperty("certpathbuilder.type"); if (defaulttype == null || defaulttype.length() <= 0) { return "PKIX"; } else { return defaulttype; } } }