package java.security.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 />
* Uses {@link CertUtil CertUtil} to actualiy load the SPI classes.
*
* @see CertUtil
**/
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;
}
}