setAnyPolicyInhibited
and
isAnyPolicyInhibited
methods to the PKIXParameters
class to support the initial-any-policy-inhibit input flag.
PolicyNode
interface, representing a node
of the policy tree as defined in the PKIX draft.
getQualifiers
and getPolicies
methods from the PKIXCertPathValidatorResult
class, and
replaced them with the getPolicyTree
method which returns
a PolicyNode
object representing the root of the policy tree
as returned by the PKIX validation algorithm. Also added the
getPublicKey
method which returns the subject public key
(including any inherited parameters if applicable) resulting from the
validation algorithm.
getCertificateIndex
method and the index
constructor parameter from the PolicyQualifierInfo
class. This
functionality is replaced by the getDepth
method of the
PolicyNode
interface.
X509CertSelector
, X509CRLSelector
,
PKIXParameters
and PKIXBuilderParameters
classes)
from RFC 1779 to RFC 2253 (2253 obsoletes 1779).
PolicyQualifierInfo
class.
setCertPath
and setIndex
methods of
CertPathValidatorException
and added equivalent parameters to the
constructors.
getEncodings
method of the CertPath
class
to return an Iterator
instead of an Enumeration
. Also
applies to the getCertPathEncodings
method of CertificateFactory
and the engineGetCertPathEncodings
method of CertificateFactorySpi
.
LDAPCertStoreParameters
class to not implement
Serializable
.
setTrustedCerts
method of the
PKIXParameters
and PKIXBuilderParameters
classes
to throw ClassCastException
when the
elements of the Set are not of type X509Certificate
. Also changed
the setCertPathCheckers
method to throw ClassCastException
when the elements of the List are not of type PKIXCertPathChecker
.
CertStoreParameters
interface to extend
Cloneable
and defined a clone
method that
throws no exceptions. This allows all CertStoreParameter
s to be
cloned.
setCertificate
and
getCertificate
methods to the X509CertSelector
class.
This is useful for specifying target certificate constraints with a
PKIXBuilderParameters
object when a relying party possesses the
target certificate.
X509CertSelector
class description, described which
criteria combinations would likely select a unique certificate.
setMatchAllSubjectAltNames
and
getMatchAllSubjectAltNames
methods to the X509CertSelector
class. These methods allow a caller to choose to match on at least one or all subject
alternative names in an X509Certificate
.
getCertificates
and
getCRLs
methods of CertStore
may throw a
CertStoreException
because the caller has supplied insufficient
information for the CertStore
to find the requested certificates or CRLs.
The Java Certification Path API consists of classes and interfaces for handling certification paths (also known as "certificate chains"). A certification path is an ordered list of certificates. If a certification path meets certain validation rules, it may be used to securely establish the mapping of a public key to a subject.
This API defines interfaces and abstract classes for creating, building, and validating certification paths. Implementations may be plugged in using a provider-based interface. The API is based on the Cryptographic Service Provider architecture, described in the Java Cryptography Architecture Document.
The API also includes algorithm specific classes for building and validating X.509 certification paths according to the PKIX standards. The PKIX standards are developed by the IETF PKIX working group. Section 6 of http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-02.txt defines an algorithm for validating chains of X.509 certificates.
This API is being reviewed using the Java Community Process program. This is the Public Review Draft version of the CertPath API. Comments from experts and members of the Java Community should be sent to the email address noted at the end of this specification.
The author would like to thank the individuals who contributed to the Certification Path API and provided useful comments and technical advice. Special thanks to the members of the Sun Microsystems Laboratories team who designed and developed the Certification Path API which provided the basis of the work for the Java Community Process. This team includes Anne Anderson, Yassir Elley, Geoff Goodell, Steve Hanna, Sean Mullan, Radia Perlman, and Seth Proctor.The expert group helped improve and refine the API using the Java Community Process and includes the following members:
Maxine Erlund, Steve Hanna, Phil Rosenzweig and Bob Sproull of Sun Microsystems provided leadership and vision. The members of the Java Security and Networking Group of Sun Microsystems contributed invaluable comments and support, especially Sharon Liu, Jeff Nisewanger, and Gary Ellison. Helpful comments and advice were received from many in the technical community, especially Edward Dobner, Tom Gindin, Jan Luehe, David Kuehr-McLaren, and Alexei Semidetnov.
- Peter Hesse, CygnaCom Solutions, An Entrust Technologies Company
- Sean Mullan, Sun Microsystems (Specification Lead)
- Anthony Nadalin, IBM
- Bob Naugle, Bluestone Software
- Hemma Prafullchandra, Critical Path
- Ming Yung, DSTC
This document is intended for two classes of experienced developers:
those who want to design secure applications that create, build, or validate certification paths.
those who want to write a service provider implementation for a particular certification path algorithm, type, or storage repository.
This document assumes you have already read the following documents (available online at http://java.sun.com/j2se/1.3/docs/guide/security/index.html):
Users of public key applications and systems must be confident that a subject's public key is genuine, i.e. that the associated private key is owned by the subject. Public key certificates are used to establish this trust. A public key (or identity) certificate is a binding of a public key to an identity, which is digitally signed by the private key of another entity, often called a Certification Authority (CA). We shall use the term CA to refer to an entity that signs a certificate for the remainder of this section.
If the user does not have a trusted copy of the public key of the CA that signed the subject's public key certificate, then another public key certificate vouching for the signing CA is required. This logic can be applied recursively, until a chain of certificates (or a certification path) is discovered from a trust anchor or a most-trusted CA to the subject. The most-trusted CA is usually specified by a certificate issued to a CA that the user directly trusts. In general, a certification path is an ordered list of certificates, usually comprised of the subject's public key certificate and zero or more additional certificates. A certification path typically has one or more encodings, allowing it to be safely transmitted across networks and to different operating system architectures.
Figure 1 illustrates a certification path from a most-trusted CA's public key (CA 1) to the subject (Alice). The certification path establishes trust in Alice's public key through an intermediate CA named CA2.
Figure 1: Certification Path
A certification path must be validated before it can be relied on to establish trust in a subject's public key. Validation can consist of various checks on the certificates contained in the certification path, such as verifying the signatures and checking that each certificate has not been revoked. The PKIX standards define an algorithm for validating certification paths consisting of X.509 certificates.
Often a user may not have a certification path from a most-trusted CA to the subject. Providing services to build or discover certification paths is an important feature of public key enabled systems. RFC 2587 defines an LDAP schema definition which facilitates the discovery of X.509 certification paths using the LDAP directory service protocol.
Building and validating certification paths is an important part of many standard security protocols such as SSL/TLS, S/MIME, and IPSEC. The Java Certification Path API provides a set of classes and interfaces to Java developers who need to integrate this functionality into their applications. This API benefits two types of developers: those who need to write service provider implementations for a specific certification path algorithm; and those who need to access standard algorithms for creating, building, and validating certification paths in an implementation independent manner.
The core classes of the Java
Certification Path API consist of interfaces and classes that support
certification path functionality in an algorithm and implementation
independent manner. The API also includes a set of algorithm-specific
classes for the PKIX standards and these are discussed in the section
titled PKIX Classes. The API builds on and
extends the existing J2SE (Java 2 Standard Edition) java.security.cert
package for handling certificates. The core classes can be broken up
into 4 class categories: Basic, Validation, Building, and Storage:
Basic Certification Path Classes
CertPath
,
CertificateFactory
,
CertPathParameters
Certification Path Validation Classes
CertPathValidator
,
CertPathValidatorResult
Certification Path Building Classes
CertPathBuilder
,
CertPathBuilderResult
Certificate/CRL Storage Classes
CertStore
,
CertStoreParameters
,
CertSelector
, CRLSelector
The following sections describe the most commonly used methods of each class and interface. Usage examples for some of the classes are interspersed throughout the guide. The complete reference documentation for the relevant Certification Path API classes can be found in:
Unless otherwise specified, the classes and interfaces in the CertPath API are not thread-safe. Multiple threads that need to access a single object concurrently should synchronize amongst themselves and provide the necessary locking. Multiple threads each manipulating separate objects need not synchronize.
The basic certification path classes are those that provide fundamental functionality for creating certification paths. The key basic class in the Java Certification Path API is CertPath, which encapsulates the universal aspects shared by all types of certification paths. An application uses an instance of the CertificateFactory class to create a CertPath object.
The CertPath class is an abstract class for certification paths. It defines the functionality shared by all certification path objects. Various certification path types can be implemented by subclassing the CertPath class, even though they may have different contents and ordering schemes. All CertPath objects are immutable and thread-safe and share the following characteristics:
A type
This corresponds
to the type of the certificates in the certification path, for
example: X.509. The type of a CertPath is obtained using
the method:
public String getType()
A list of certificates
The
getCertificates method returns the list of certificates in
the certification path:
public abstract List getCertificates()This method returns a List of zero or more Certificate objects. The returned
List
and the Certificates
contained within it are immutable, in order to protect the contents
of the CertPath object.
The ordering of the certificates
returned depends on the type. By convention, the certificates in a
CertPath object of type X.509 are ordered from target
subject to trust anchor. That is, the issuer of one certificate is
the subject of the following one. However, unvalidated X.509
CertPaths may not follow this convention. PKIX
CertPathValidators will
detect any departure from this convention and throw a
CertPathValidatorException.
In addition, an X.509
CertPath
may not contain the most-trusted CA certificate
used to anchor the path. However, the getTrustedCert
method of
a PKIXCertPathValidatorResult
returns the most-trusted CA certificate (or null
if not applicable)
used by a PKIX CertPathValidator
to anchor the path. The PKIX
classes are discussed more in the PKIX Classes
section.
One or more encodings
Each
CertPath
object supports one
or more encodings. These are external encoded forms for the
certification path, used when a standard representation of the path
is needed outside the Java Virtual Machine (as when transmitting the
path over a network to some other party). Each path can be encoded
in a default format, the bytes of which are returned using the
method:
public abstract byte[] getEncoded()The getEncoded(String) method returns a supported encoding by specifying the encoding format as a String (ex: "PKCS7"). A list of standard encoding formats are defined in Appendix A.
public abstract byte[] getEncoded(String encoding)The getEncodings method returns an iterator over the supported encoding format Strings (the default encoding format is returned first):
public abstract Iterator getEncodings()
CertPath objects are
generated from an encoded byte array or list of Certificate
s
using a CertificateFactory.
Alternatively a CertPathBuilder
may be used to try to find a CertPath
from a most-trusted CA to a particular subject. Once a CertPath
object has been created, it may be validated by passing it to the
validate
method of
CertPathValidator
. Each of
these concepts are explained in more detail in subsequent sections.
The CertificateFactory
class is an existing engine
class that defines the functionality of a certificate factory.
This class has been enhanced to generate certification path
(CertPath) objects as well as
Certificate
and CRL
objects. A CertificateFactory should not be confused with a
CertPathBuilder. A CertPathBuilder
(discussed later) is used to discover or find a certification path
when one does not exist. In contrast, a CertificateFactory
is used when a certification path has already been discovered and the
caller needs to instantiate a CertPath object from its
contents which exist in a different form such as an encoded PKCS#7
byte array.
Creating a CertificateFactory Object
See the
CertificateFactory
section in the Java Cryptography Architecture for details on creating aCertificateFactory
object.Generating CertPath Objects
A CertificateFactory instance generates CertPath objects from a
List
of Certificate objects or from anInputStream
that contains the encoded form of aCertPath
. Just like aCertPath
, each CertificateFactory supports a default encoding format for certification paths (ex: PKCS#7). To generate aCertPath
object and initialize it with the data read from an input stream (in the default encoding format), use the generateCertPath method:public final CertPath generateCertPath(InputStream inStream)or from a particular encoding format:
public final CertPath generateCertPath(InputStream inStream, String encoding)To find out what encoding formats are supported, use the getCertPathEncodings method (the default encoding is returned first):
public final Iterator getCertPathEncodings()To generate a certification path object from a List of Certificate objects, use the following method:
public final CertPath generateCertPath(List certificates)A
CertificateFactory
always returns CertPath objects that consist ofCertificate
s that are of the same type as the factory. For example, a CertificateFactory of type X.509 returns CertPath objects consisting of certificates that are an instance of java.security.cert.X509Certificate.The following code sample illustrates generating a certification path from a PKCS#7 encoded certificate reply stored in a file:
// open an input stream to the file
FileInputStream fis = new FileInputStream(filename);
// instantiate a CertificateFactory for X.509
CertificateFactory cf = CertificateFactory.getInstance("X.509");
// extract the certification path from
// the PKCS7 SignedData structure
CertPath cp = cf.generateCertPath(fis, "PKCS7");
// print each certificate in the path
List certs = cp.getCertificates();
Iterator i = certs.iterator();
while (i.hasNext()) {
X509Certificate cert = (X509Certificate) i.next();
System.out.println(cert);
}
Note
that there is an existing method in CertificateFactory
named generateCertificates
that parses a sequence of Certificate
s.
For encodings consisting of multiple certificates, use
generateCertificates
when you
want to parse a collection of possibly unrelated certificates.
Otherwise, use generateCertPath
when you want to generate a CertPath
and subsequently validate it with a CertPathValidator
(discussed later).
The CertPathParameters
interface is a transparent representation of the set of parameters
used with a particular certification path builder or validation
algorithm. Its main purpose is to group (and provide type safety
for) all certification path parameter specifications. The
CertPathParameters
interface extends the Cloneable
interface and defines a clone()
method that does not throw an exception. All concrete
implementations of this interface should implement and override the
Object.clone()
method, if
necessary. This allows applications to clone any CertPathParameters
object.
Objects implementing the CertPathParameters interface are passed as arguments to methods of the CertPathValidator and CertPathBuilder classes.
The Java Certification Path API includes classes and interfaces for validating certification paths. An application uses an instance of the CertPathValidator class to validate a CertPath object. If successful, the result of the validation algorithm is returned in an object implementing the CertPathValidatorResult interface.
The CertPathValidator class is an engine class used to validate a certification path.
Creating a CertPathValidator Object
As with all engine classes, the way to get a CertPathValidator object for a particular validation algorithm is to call the getInstance static factory method on the CertPathValidator class:
public static CertPathValidator getInstance(String algorithm) public static CertPathValidator getInstance(String algorithm, String provider)Validating a Certification Path
Once a CertPathValidator object is created, paths can be validated by calling the validate method, passing it the certification path to be validated and a set of algorithm-specific parameters (see PKIXParameters for an example):
public final CertPathValidatorResult validate(CertPath certPath, CertPathParameters params) throws CertPathValidatorException, InvalidAlgorithmParametersExceptionIf the validation algorithm is successful, the result is returned in an object implementing the CertPathValidatorResult interface. Otherwise, a CertPathValidatorException is thrown. The CertPathValidatorException contains methods that return the CertPath, and if relevant, the index of the certificate that caused the algorithm to fail and the root exception or cause of the failure.
The CertPath object passed to the validate method must be of a type that is supported by the validation algorithm. For example, a CertPathValidator instance that implements the PKIX algorithm validates CertPath objects of type X.509.
The
CertPathValidatorResult interface is a transparent
representation of the result or output of a certification path
validation algorithm. Its main purpose is to group (and provide type
safety for) all validation results. Like the CertPathParameters
interface, CertPathValidatorResult
extends Cloneable
and defines
a clone()
method that does not
throw an exception. This allows applications to clone any
CertPathValidatorResult
object.
Objects implementing the CertPathValidatorResult interface are returned by the validate method of CertPathValidator.
The Java Certification Path API includes classes for building (or discovering) certification paths. An application uses an instance of the CertPathBuilder class to build a CertPath object. If successful, the result of the build is returned in an object implementing the CertPathBuilderResult interface.
The CertPathBuilder class is an engine class used to build a certification path.
Creating a CertPathBuilder Object
As with all engine classes, the way to get a CertPathBuilder object for a particular build algorithm is to call the getInstance static factory method on the CertPathBuilder class:
public static CertPathBuilder getInstance(String algorithm) public static CertPathBuilder getInstance(String algorithm, String provider)Building a Certification Path
Once a CertPathBuilder object is created, paths can be constructed by calling the build method, passing it an algorithm-specific parameter specification (see PKIXBuilderParameters for an example):
public final CertPathBuilderResult build(CertPathParameters params) throws CertPathBuilderException, InvalidAlgorithmParametersExceptionIf the build algorithm is successful, the result is returned in an object implementing the CertPathBuilderResult interface. Otherwise, a CertPathBuilderException is thrown containing information about the failure; for example, the underlying exception (if any) and an error message.
The CertPathBuilderResult interface is a transparent representation of the result or output of a certification path builder algorithm. This interface contains a method to return the certification path that has been successfully built:
public CertPath getCertPath()
The purpose of
the CertPathBuilderResult interface is to group (and provide
type safety for) all build results. Like the
CertPathValidatorResult
interface, CertPathBuilderResult
extends Cloneable
and defines
a clone()
method that does not
throw an exception. This allows applications to clone any
CertPathBuilderResult
object.
Objects implementing the CertPathBuilderResult interface are returned by the build method of CertPathBuilder.
The Java Certification Path API also
includes the CertStore
class
for retrieving certificates and CRLs from a repository. This is
useful because it allows a caller to specify the repository a
CertPathValidator or CertPathBuilder implementation
should use to find certificates and CRLs (see the addCertStores
method of PKIXParameters for
an example).
A CertPathValidator or CertPathBuilder implementation may use the methods of the CertStore class as a callback mechanism to select certificates and CRLs from a repository. Selection criteria for choosing specific certificates and CRLs are specified in objects implementing the CertSelector and CRLSelector interfaces. CertStore instances may need to be initialized with repository specific input parameters before usage.
The CertStore class is an engine class used to provide the functionality of a certificate and certificate revocation list (CRL) repository. It can be used by CertPathBuilder and CertPathValidator implementations to find certificates and CRLs or as a general purpose certificate and CRL retrieval mechanism.
Unlike the
java.security.KeyStore
class,
which provides access to a cache of private keys and trusted
certificates, a CertStore
is
designed to provide access to a potentially vast repository of
untrusted certificates and CRLs. For example, an LDAP implementation
of CertStore
provides access
to certificates and CRLs stored in one or more directories using the
LDAP protocol.
Creating a CertStore Object
As with all engine classes, the way to get a CertStore object for a particular repository type is to call the getInstance static factory method on the CertStore class:
public static CertStore getInstance(String type) public static CertStore getInstance(String type, String provider)Initializing a CertStore Object
A CertStore object may need to be initialized before it can be used. The initialization is done by calling the init method and passing it a repository specific set of parameters:
public final void init(CertStoreParameters params) throws InvalidAlgorithmParametersExceptionThe initialization parameters are specific to the repository type. For example, the initialization parameters for a server based repository may include the hostname and the port of the server. An
InvalidAlgorithmParametersException
is thrown if the parameters are invalid for thisCertStore
type.Retrieving Certificates
Once you have created and initialized a CertStore object, you can retrieve certificates from the repository using the getCertificates method. This method takes a CertSelector object as an argument, which specifies a set of selection criteria for determining which certificates should be returned:
public final Collection getCertificates(CertSelector selector) throws CertStoreExceptionThis method returns a Collection of java.security.cert.Certificate objects that satisfy the selection criteria. An empty Collection is returned if there are no matches. A
CertStoreException
is usually thrown if an unexpected error condition is encountered, such as a communications failure with a remote repository.For some CertStore implementations, it may not be feasible to search the entire repository for certificates or CRLs that match the specified selection criteria. In these instances, the CertStore implementation may use information that is specified in the selectors to locate certificates and CRLs. For instance, an LDAP CertStore may not search all entries in the directory. Instead, it may just search entries that are likely to contain the certificates it is looking for. If the CertSelector provided does not provide enough information for the LDAP CertStore to determine which entries it should look in, the LDAP CertStore may throw a CertStoreException.
Retrieving CRLs
You can also retrieve CRLs from the repository using the getCRLs method. This method takes a CRLSelector object as an argument, which specifies a set of selection criteria for determining which CRLs should be returned:
public final Collection getCRLs(CRLSelector selector) throws CertStoreExceptionThis method returns a Collection of java.security.cert.CRL objects that satisfy the selection criteria. An empty Collection is returned if there are no matches.
The
getCertificates
andgetCRLs
methods of allCertStore
objects must be thread-safe. That is, multiple threads may concurrently invoke these methods on a singleCertStore
object (or more than one) with no ill effects. This allows aCertPathBuilder
to search for a CRL while simultaneously searching for further certificates, for instance. The static methods of this class are also guaranteed to be thread-safe. Multiple threads may concurrently invoke the static methods defined in this class with no ill effects. Theinit
method should not be called concurrently with any other method nor should multiple threads invoke theinit
method concurrently on a singleCertStore
object. Otherwise, the results are undefined.
The
CertStoreParameters interface is a transparent
representation of the set of parameters used with a particular
certificate and CRL repository (CertStore).
Its main purpose is to
group (and provide type safety for) all certificate storage parameter
specifications. The CertStoreParameters
interface extends the
Cloneable
interface and defines a clone
method that
does not throw an exception. Implementations of this interface should implement
and override the Object.clone()
method, if necessary. This allows
applications to clone any CertStoreParameters
object.
Objects implementing the CertStoreParameters interface are passed as arguments to the init method of the CertStore class. Two classes implementing the CertStoreParameters interface are defined in this API: the LDAPCertStoreParameters and the CollectionCertStoreParameters classes.
The LDAPCertStoreParameters Class
The LDAPCertStoreParameters class is an implementation of the CertStoreParameters interface and holds a set of minimal initialization parameters (host and port number of the directory server) for retrieving certificates and CRLs from an LDAP directory. It is passed to the init method of CertStore instances of type LDAP.
Please refer to the LDAPCertStoreParameters API documentation for more detailed information on this class.
The CollectionCertStoreParameters Class
The CollectionCertStoreParameters class is an implementation of the CertStoreParameters interface and holds a set of initialization parameters for retrieving certificates and CRLs from a Collection. It is passed to the init method of CertStore instances of type Collection.
Please refer to the CollectionCertStoreParameters API documentation for more detailed information on this class.
The CertSelector
and CRLSelector interfaces are a specification of the set of
criteria for selecting certificates and CRLs from a collection or
large group of certificates and CRLs. The interfaces group and
provide type safety for all selector specifications. Each selector interface
extends Cloneable
and defines
a clone()
method that does not
throw an exception. This allows applications to clone any
CertSelector
or CRLSelector
object.
The CertSelector and CRLSelector interfaces each define a method named match. The match method takes a Certificate or CRL object as an argument and returns true if the object satisfies the selection criteria. Otherwise, it returns false. The match method for the CertSelector interface is defined as follows:
public boolean match(Certificate cert)
and for the CRLSelector interface:
public boolean match(CRL crl)
Objects
implementing these interfaces are passed as parameters to the
getCertificates
and getCRLs
methods of the CertStore
class. These methods return a Collection
of Certificate
s or CRL
s
from the CertStore
repository
that match the specified selection criteria.
The X509CertSelector class is an implementation of the CertSelector interface that defines a set of criteria for selecting X.509 certificates. An X509Certificate object must match all of the specified criteria to be selected by the match method. The selection criteria are designed to be used by a CertPathBuilder implementation to discover potential certificates as it builds an X.509 certification path.
For example, the
setPathToName
method of
X509CertSelector
allows a PKIX
CertPathBuilder
to filter out
X509Certificate
s that contain
a name constraints extension that would prohibit building a path to the
requested subject name(s). By setting this and other criteria in an
X509CertSelector
object, it
allows the CertPathBuilder
to
discard non-relevant certificates and more easily find an X.509
certification path that meets the requirements specified in the
CertPathParameters
object.
Please refer to http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-02.txt for definitions of the X.509 certificate extensions mentioned in this section.
Creating an X509CertSelector Object
An X509CertSelector object is created by calling the default constructor:
public X509CertSelector()No criteria are initially set (any
X509Certificate
will match).Setting Selection Criteria
The selection criteria allow a caller to match on different components of an X.509 certificate. A few of the methods for setting selection criteria are described here, please refer to the X509CertSelector API documentation for details on the other methods.
The setIssuer methods set the issuer criterion:
public void setIssuer(String issuerDN) public void setIssuer(byte[] issuerDN)The specified distinguished name (in RFC 2253 String or ASN.1 DER encoded form) must match the issuer distinguished name in the certificate. If null, any issuer distinguished name will do.
Similarly, the setSubject methods set the subject criterion:
public void setSubject(String subjectDN) public void setSubject(byte[] subjectDN)The setSerialNumber method sets the serialNumber criterion:
public void setSerialNumber(BigInteger serial)The specified serial number must match the certificate serial number in the certificate. If null, any certificate serial number will do.
The setAuthorityKeyIdentifier method sets the authorityKeyIdentifier criterion:
public void setAuthorityKeyIdentifier(byte[] authorityKeyID)The certificate must contain an Authority Key Identifier extension matching the specified value. If null, no check will be done on the authorityKeyIdentifier criterion.
The setCertificateValid method sets the certificateValid criterion:
public void setCertificateValid(Date certValid)The specified date must fall within the certificate validity period for the certificate. If null, any date is valid.
The setKeyUsage method sets the keyUsage criterion:
public void setKeyUsage(boolean[] keyUsage)The certificate's Key Usage Extension must allow the specified key usage values (those which are set to true). If null, no keyUsage check will be done.
Getting Selection Criteria
The current values for each of the selection criteria can be retrieved using an appropriate get method. Please refer to the X509CertSelector API documentation for further details on these methods.
Example
This is an example of retrieving X.509 certificates from an LDAP CertStore with the X509CertSelector class.
First, create the CertStore object, as in the following statement:
CertStore cs = CertStore.getInstance("LDAP");This call creates a CertStore object that retrieves certificates and CRLs from an LDAP repository using the schema defined in RFC 2587. See Appendix A for a complete discussion of standard names and algorithms.
The next step is to initialize the certificate storage object with the hostname and port of the LDAP server. To do that, we create an LDAPCertStoreParameters object and pass it to the init method:
LDAPCertStoreParameters csp = new LDAPCertStoreParameters("ldap.sun.com", 389); cs.init(csp);The following block of code establishes an
X509CertSelector
to retrieve all unexpired (as of the current date and time) end-entity certificates issued to a particular subject with 1) a key usage that allows digital signatures, and 2) a subject alternative name with a specific email address:X509CertSelector xcs = new X509CertSelector(); // select only unexpired certificates xcs.setCertificateValid(new Date()); // select only certificates issued to // 'CN=mullan, O=sun, C=us' xcs.setSubject("CN=mullan, O=sun, C=us"); // select only end-entity certificates xcs.setBasicConstraints(-2); // select only certificates with a digitalSignature // keyUsage bit set (set the first entry in the // boolean array to true) boolean[] keyUsage = {true}; xcs.setKeyUsage(keyUsage); // select only certificates with a subjectAltName of // 'sean.mullan@sun.com' (1 is the integer value of // an RFC822Name) xcs.addSubjectAlternativeName(1, "sean.mullan@sun.com");Then we pass the selector to the getCertificates method of our CertStore object that we previously created:
Collection certs = cs.getCertificates(xcs);
The X509CRLSelector class is an implementation of the CRLSelector interface that defines a set of criteria for selecting X.509 CRLs. An X509CRL object must match all of the specified criteria to be selected by the match method. The selection criteria are designed to be useful to a CertPathValidator or CertPathBuilder implementation that must retrieve CRLs from a repository to check the revocation status of certificates in an X.509 certification path.
For example, the
setDateAndTime
method of
X509CRLSelector
allows a PKIX
CertPathValidator
to filter
out X509CRL
s that have been
issued after or expire before the time indicated. By setting this and
other criteria in an X509CRLSelector
object, it allows the CertPathValidator
to discard non-relevant CRLs and more easily check if a certificate
has been revoked.
Please refer to http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-02.txt for definitions of the X.509 CRL fields and extensions mentioned in this section.
Creating an X509CRLSelector Object
An X509CRLSelector object is created by calling the default constructor:
public X509CRLSelector()No criteria are initially set (any
X509CRL
will match).Setting Selection Criteria
The selection criteria allow a caller to match on different components of an X.509 CRL. A few of the methods for setting selection criteria are described here, please refer to the X509CRLSelector API documentation for details on the other methods.
The setIssuerNames method sets the issuerNames criterion:
public void setIssuerNames(Collection names)The issuer distinguished name in the CRL must match at least one of the specified distinguished names. Each entry of the names argument is either a String or a byte array (representing the name, in RFC 2253 or ASN.1 DER encoded form, respectively). If null, any issuer distinguished name will do.
The setMinCRLNumber and setMaxCRLNumber methods set the minCRLNumber and maxCRLNumber criterion:
public void setMinCRLNumber(BigInteger minCRL) public void setMaxCRLNumber(BigInteger maxCRL)The CRL must have a CRL Number extension whose value is greater than or equal to the specified value if the setMinCRLNumber method is called, and less than or equal to the specified value if the setMaxCRLNumber method is called. If the value passed to one of these methods is null, the corresponding check is not done.
The setDateAndTime method sets the dateAndTime criterion:
public void setDateAndTime(Date dateAndTime)The specified date must be equal to or later than the value of the thisUpdate component of the CRL and earlier than the value of the nextUpdate component. If null, no dateAndTime check will be done.
The setCertificateChecking method sets the certificate whose revocation status is being checked:
public void setCertificateChecking(X509Certificate cert)This is not a criterion. Rather, it is optional information that may help a
CertStore
find CRLs that would be relevant when checking revocation for the specified certificate. If null is specified, then no such optional information is provided. An application should always call this method when checking revocation for a particular certificate, as it may provide theCertStore
with more information for finding the correct CRLs and filtering out non-relevant ones.Getting Selection Criteria
The current values for each of the selection criteria can be retrieved using an appropriate get method. Please refer to the X509CRLSelector API documentation for further details on these methods.
Example
Creating an X509CRLSelector to retrieve CRLs from an LDAP repository is similar to the X509CertSelector example. Suppose we want to retrieve all current (as of the current date and time) CRLs issued by a specific CA and with a minimum CRL number. First, we create an X509CRLSelector object and call the appropriate methods to set the selection criteria:
X509CRLSelector xcrls = new X509CRLSelector(); // select CRLs satisfying current date and time xcrls.setDateAndTime(new Date()); // select CRLs issued by 'O=sun, C=us' xcrls.addIssuerName("O=sun, C=us"); // select only CRLs with a CRL number at least '2' xcrls.setMinCRLNumber(new BigInteger("2"));Then we pass the selector to the getCRLs method of our CertStore object (created in the X509CertSelector example):
Collection crls = cs.getCRLs(xcrls);
The Java Certification Path API also includes a set of algorithm specific classes for use with the PKIX certification path validation algorithm defined in http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-02.txt. This is the third draft of a specification based upon RFC 2459. When complete, this specification will obsolete RFC 2459.
This class (which implements the CertPathParameters interface) specifies the set of input parameters defined by the PKIX certification path validation algorithm. It also includes a few additional useful parameters.
An X.509
CertPath
object and a
PKIXParameters object are passed as arguments to the
validate method of a CertPathValidator
instance implementing the PKIX algorithm. The CertPathValidator
uses the parameters to initialize the PKIX certification path
validation algorithm.
Creating a PKIXParameters Object
To instantiate a
PKIXParameters
object, a caller must specify "the most-trusted CA(s)" as defined by the PKIX validation algorithm. The most-trusted CA can be specified in one of several ways. First, the caller can specify the public key, name, and optionally the unique identifier of the most-trusted CA. Alternatively, if more than one CA is trusted, a caller can specify a Set of trusted X509Certificates. Finally, a caller can specify a KeyStore instance containing trusted certificate entries, each of which will be considered as a most-trusted CA. Use one of the following constructors to create a PKIXParameters object:public PKIXParameters(PublicKey pubKey, String caName) public PKIXParameters(PublicKey pubKey, String caName, boolean[] uniqueID) public PKIXParameters(Set trustedCerts) public PKIXParameters(KeyStore keystore)Setting Parameter Values
Once a PKIXParameters object has been created, a caller can set (or replace the current value of) various parameters. A few of the methods for setting parameters are described here, please refer to the PKIXParameters API documentation for details on the other methods.
The setInitialPolicies method sets the initial policy identifiers, as specified by the PKIX validation algorithm. The elements of the Set are object identifiers (OIDs) represented as a String. If the
initialPolicies
parameter is null or not set, any policy is acceptable:public void setInitialPolicies(Set initialPolicies)The setDate method sets the time for which the validity of the path should be determined. If the date parameter is not set or is null, the current date is used:
public void setDate(Date date)The setPolicyMappingInhibited method sets the value of the policy mapping inhibited flag. The default value for the flag, if not specified, is false:
public void setPolicyMappingInhibited(boolean val)The setExplicitPolicyRequired method sets the value of the explicit policy required flag. The default value for the flag, if not specified, is false:
public void setExplicitPolicyRequired(boolean val)The setAnyPolicyInhibited method sets the value of the any policy inhibited flag. The default value for the flag, if not specified, is false:
public void setAnyPolicyInhibited(boolean val)The setTargetCertConstraints method allows the caller to set constraints on the target certificate. For example, the caller can specify that the target certificate must contain a specific subject name. The constraints are specified as a
CertSelector
object. If theselector
parameter is null or not set, no constraints are defined on the target certificate:public void setTargetCertConstraints(CertSelector selector)The setCertStores method allows a caller to specify a
List
of CertStore objects that will be used by a PKIX implementation of CertPathBuilder or CertPathValidator to find certificates and CRLs for path construction and validation. This provides an extensible mechanism for specifying where to locate certificates and CRLs. The setCertStores method takes aList
of CertStore objects as a parameter. The first CertStores in the list may be preferred to those that appear later.public void setCertStores(List stores)The setCertPathCheckers method allows a caller to extend the PKIX validation algorithm by creating implementation-specific certification path checkers. For example, this mechanism can be used to process private certificate extensions. The setCertPathCheckers method takes a list of PKIXCertPathChecker (discussed later) objects as a parameter:
public void setCertPathCheckers(List checkers)The setRevocationEnabled method allows a caller to disable revocation checking. Revocation checking is enabled by default, since it is a required check of the PKIX validation algorithm. However, PKIX does not define how revocation should be checked. An implementation may use CRLs or OCSP, for example. This method allows the caller to disable the implementation's default revocation checking mechanism if it is not appropriate. A different revocation checking mechanism can then be specified by calling the setCertPathCheckers method, and passing it a
PKIXCertPathChecker
that implements the alternate mechanism.public void setRevocationEnabled(boolean val)The setPolicyQualifiersRejected method allows a caller to enable or disable policy qualifier processing. When a PKIXParameters object is created, this flag is set to true. This setting reflects the most common (and simplest) strategy for processing policy qualifiers. Applications that want to use a more sophisticated policy must set this flag to false.
public void setPolicyQualifiersRejected(boolean qualifiersRejected)Getting Parameter Values
The current values for each of the parameters can be retrieved using an appropriate get method. Please refer to the PKIXParameters API documentation for further details on these methods.
This class
(which implements the CertPathValidatorResult
interface) represents the result of the PKIX certification path
validation algorithm. It holds the valid policy tree
and subject public key resulting from the validation algorithm, and
includes methods (getPolicyTree()
and getPublicKey()
)
for returning them. Instances of PKIXCertPathValidatorResult are
returned by the validate method of
CertPathValidator
objects implementing the PKIX algorithm. The getTrustedCert
method returns the Certificate
of the most-trusted CA (if applicable) that was selected to anchor the path.
Please refer to the PKIXCertPathValidatorResult API documentation for more detailed information on this class.
The PolicyNode
interface represents a node of a valid policy tree
resulting from a successful execution of the PKIX certification path validation. An
application can obtain the root of a valid policy tree using the getPolicyTree
method of PKIXCertPathValidatorResult
. Policy Trees are discussed in
more detail in the PKIX Certificate and CRL profile
(http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-02.txt).
The getPolicyQualifiers
method of PolicyNode
returns
a Set
of PolicyQualifierInfo
objects, each of which
represents a policy qualifier contained in the Certificate Policies extension of
the relevant certificate that this policy applies to.
Please refer to the
PolicyNode
and
PolicyQualifierInfo
API documentation for more detailed information on
these classes.
This is an example of validating a certification path with the PKIX validation algorithm. First, create the CertPathValidator, as in the following line:
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
This call creates a CertPathValidator object that implements the PKIX algorithm defined in http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-02.txt. See Appendix A for a complete discussion of standard names and algorithms.
The next step is to create a PKIXParameters object. This will be used to populate the parameters used by the PKIX algorithm. In this example, the most-trusted CA is specified as a public key and name:
PKIXParameters params = new PKIXParameters(pubKey, "O=sun, C=us");
Next, we populate the parameters object with constraints or other parameters used by the validation algorithm. In this example, we enable the explicitPolicyRequired flag and specify a set of initial policy OIDs:
// set other PKIX parameters here params.setExplicitPolicyRequired(true); params.setInitialPolicies(policyIds);
The final step is to validate the certification path using the input parameter set we have created:
PKIXCertPathValidatorResult result = (PKIXCertPathValidatorResult) cpv.validate(certPath, params);
If the validation algorithm is successful, the policy tree and subject public key resulting from the validation algorithm can be obtained from the result using these methods:
PolicyNode policyTree = result.getPolicyTree(); PublicKey subjectPublicKey = result.getPublicKey();
Otherwise, a CertPathValidatorException is thrown and the caller can catch the exception (not shown) and print the error message and which certificate caused the failure as follows:
System.out.println("Validation failure, cert[" + e.getIndex() + "] " + e.getMessage());
This class (which extends the PKIXParameters class) specifies the set of parameters to be used with CertPathBuilders that build certification paths validated against the PKIX certification path validation algorithm.
A PKIXBuilderParameters object is passed as an argument to the build method of a CertPathBuilder instance implementing the PKIX algorithm. All PKIX CertPathBuilders must return certification paths which have been validated according to the PKIX certification path validation algorithm.
Creating a PKIXBuilderParameters Object
Creating a PKIXBuilderParameters object is similar to creating a PKIXParameters object. However, a caller must specify constraints on the target certificate when creating a PKIXBuilderParameters object. These constraints should provide the
CertPathBuilder
with enough information to find the target certificate. The constraints are specified as aCertSelector
object. Use one of the following constructors to create a PKIXBuilderParameters object:public PKIXBuilderParameters(PublicKey pubKey, String caName, CertSelector targetConstraints) public PKIXBuilderParameters(PublicKey pubKey, String caName, boolean[] uniqueID, CertSelector targetConstraints) public PKIXBuilderParameters(Set trustedCerts, CertSelector targetConstraints) public PKIXBuilderParameters(KeyStore keystore, CertSelector targetConstraints)Getting/Setting Parameter Values
The PKIXBuilderParameters class inherits all of the parameters that can be set in the PKIXParameters class. In addition, the setMaxPathLength method can be called to place a limit on the maximum number of certificates in a certification path:
public void setMaxPathLength(int maxPathLength)The maxPathLength parameter specifies the maximum number of CA certificates that can exist in a certification path. A CertPathBuilder instance implementing the PKIX algorithm must not build paths longer than the length specified. If the value is 0, the path can only contain a single end-entity certificate. If the value is -1, the path length is unconstrained (i.e. there is no maximum). The default maximum path length, if not specified, is 5. This method is useful to prevent the builder from spending resources and time constructing long paths that may or may not meet the caller's requirements.
If any of the CA certificates in the path contain a Basic Constraints extension, the value of the pathLenConstraint component of the extension overrides the value of the maxPathLength parameter whenever the result is a certification path of smaller length.
This class (which extends the PKIXCertPathValidatorResult class and implements the CertPathBuilderResult interface) represents the result of the PKIX certification path construction algorithm. Instances of PKIXCertPathBuilderResult are returned by the build method of CertPathBuilder objects implementing the PKIX algorithm.
The getCertPath
method of a PKIXCertPathBuilderResult instance always
returns a CertPath object validated using the PKIX
certification path validation algorithm. The returned CertPath
object does not include the most-trusted CA certificate that may have
been used to anchor the path. Instead, use the getTrustedCert
method to get the Certificate
of the most-trusted CA.
Please refer to the PKIXCertPathBuilderResult API documentation for more detailed information on this class.
This is an example of of building a certification path validated against the PKIX algorithm. First, create the CertPathBuilder, as in the following example:
CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
This call creates a CertPathBuilder object that returns paths validated against the PKIX algorithm. See Appendix A for a complete discussion of standard names and algorithms.
The next step is to create a PKIXBuilderParameters object. This will be used to populate the PKIX parameters used by the CertPathBuilder:
// Create parameters object, passing it a Set of // trusted certs for anchoring the path // and a target subject DN. X509CertSelector targetConstraints = new X509CertSelector(); targetConstraints.setSubject("CN=mullan, O=sun, C=us"); PKIXBuilderParameters params = new PKIXBuilderParameters(trustedCerts, targetConstraints);
The next step is to specify the CertStore that the CertPathBuilder will use to look for certificates and CRLs. For this example, we will populate a Collection CertStore with the certificates and CRLs:
CertStore store = CertStore.getInstance("Collection"); CollectionCertStoreParameters p = new CollectionCertStoreParameters(certs); store.init(p); params.addCertStore(store);
The next step is to build the certification path using the input parameter set we have created:
PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) cpb.build(params);
If the builder cannot build a path that meets the supplied parameters it will throw a CertPathBuilderException. Otherwise, the validated certification path can be obtained from the PKIXCertPathBuilderResult as follows:
CertPath cp = result.getCertPath();
This section describes a powerful class that allows a user to extend a PKIX CertPathValidator or CertPathBuilder implementation. This is an advanced feature that most users will not need to understand. However, anyone implementing a PKIX service provider should read this section.
The PKIXCertPathChecker class is an abstract class that executes one or more checks on an X.509 certificate. Developers should create concrete implementations of the PKIXCertPathChecker class when it is necessary to dynamically extend a PKIX CertPathValidator or CertPathBuilder implementation at runtime. The following are a few examples of when a PKIXCertPathChecker implementation is useful:
If the revocation mechanism supplied by a PKIX CertPathValidator or CertPathBuilder implementation is not adequate. For example, a developer might implement a PKIXCertPathChecker that uses OCSP (RFC 2560) to check that certificates have not been revoked.
If the user wants to recognize certificates containing a critical private extension. Since the extension is private, it will not be recognized by the PKIX CertPathValidator or CertPathBuilder implementation and a CertPathValidatorException will be thrown. In this case, a developer can implement a PKIXCertPathChecker that recognizes and processes the critical private extension.
If the developer wants to record information about each certificate processed for debugging or display purposes.
If the user wants to reject certificates with certain policy qualifiers.
The
setCertPathCheckers method of the PKIXParameters
class allows a user to pass a List
of PKIXCertPathChecker objects to a PKIX CertPathValidator
or CertPathBuilder implementation. Each of the
PKIXCertPathChecker objects will be called in turn, for each
certificate processed by the PKIX CertPathValidator or
CertPathBuilder implementation.
Creating and using a PKIXCertPathChecker Object
The PKIXCertPathChecker class does not have a public constructor. This is intentional, since creating an instance of PKIXCertPathChecker is an implementation specific issue. For example, the constructor for a PKIXCertPathChecker implementation that uses OCSP to check a certificate's revocation status may require the hostname and port of the OCSP server:
PKIXCertPathChecker checker = new OCSPChecker("ocsp.sun.com", 1321);Once the checker has been instantiated, it can be added as a parameter using the addCertPathChecker method of the PKIXParameters class:
params.addCertPathChecker(checker);Alternatively, a List of checkers can be added using the setCertPathCheckers method of the PKIXParameters class.
Implementing a PKIXCertPathChecker Object
The PKIXCertPathChecker class is abstract. It has four methods (check, getSupportedExtensions, init, and isForwardCheckingSupported) that all concrete subclasses must implement.
Implementing a PKIXCertPathChecker may be trivial or complex. A PKIXCertPathChecker implementation can be stateless or stateful. A stateless implementation does not maintain state between successive calls of the check method. For example, a PKIXCertPathChecker that checks that each certificate contains a particular policy qualifier is stateless. In contrast, a stateful implementation does maintain state between successive calls of the check method. The check method of a stateful implementation usually depends on the contents of prior certificates in the certification path. For example, a PKIXCertPathChecker that processes the NameConstraints extension is stateful.
Also, the order in which the certificates processed by a service provider implementation are presented (passed) to a PKIXCertPathChecker is very important, especially if the implementation is stateful. Depending on the algorithm used by the service provider, the certificates may be presented in reverse or forward order. A reverse ordering means that the certificates are ordered from the most trusted CA (if present) to the target subject, whereas a forward ordering means that the certificates are ordered from the target subject to the most trusted CA. The order must be made known to the PKIXCertPathChecker implementation, so that it knows how to process consecutive certificates.
Initializing a PKIXCertPathChecker Object
The init method initializes the internal state of the checker:
public abstract void init(boolean forward)All stateful implementations should clear or initialize any internal state in the checker. This prevents a service provider implementation from calling a checker that is in an uninitialized state. It also allows stateful checkers to be reused in subsequent operations without reinstantiating them. The forward parameter indicates the order of the certificates presented to the PKIXCertPathChecker. If forward is true, the certificates are presented from target to trust anchor; if false, from trust anchor to target.
Supported Extensions
The getSupportedExtensions method returns an immutable Set of OID Strings for the X.509 extensions that the PKIXCertPathChecker implementation supports (i.e. recognizes, is able to process):
public abstract Set getSupportedExtensions()The method should return null if no extensions are processed. All implementations should return the Set of OID Strings that the check method may process.
Forward Checking
The isForwardCheckingSupported method returns a boolean that indicates if the PKIXCertPathChecker supports forward checking:
public abstract boolean isForwardCheckingSupported()All PKIXCertPathChecker implementations must support reverse checking. A PKIXCertPathChecker implementation may support forward checking.
Executing the Check
The following method executes a check on the certificate:
public abstract void check(Certificate cert, Collection unresolvedCritExts) throws CertPathValidatorExceptionThe unresolvedCritExts parameter contains a collection of OIDs as Strings. These OIDs represent the set of critical extensions in the certificate that have not yet been resolved by the certification path validation algorithm. Concrete implementations of the check method should remove any critical extensions that it processes from the unresolvedCritExts parameter.
If the certificate does not pass the check(s), a CertPathValidatorException should be thrown.
Cloning a PKIXCertPathChecker
The PKIXCertPathChecker class implements the Cloneable interface. All stateful PKIXCertPathChecker implementations must override the clone method if necessary. The default implementation of the clone method calls the Object.clone method, which performs a simple clone by copying all fields of the original object to the new object. A stateless implementation should not override the clone method. However, all stateful implementations must ensure that the default clone method is correct, and override it if necessary. For example, a PKIXCertPathChecker that stores state in an array must override the clone method to make a copy of the array, rather than just a reference to the array.
The reason that PKIXCertPathChecker objects are Cloneable is to allow a PKIX CertPathBuilder implementation to efficiently backtrack and try another path when a potential certification path reaches a dead end or point of failure. In this case, the implementation is able to restore prior path validation states by restoring the cloned objects.
Example
This is an example of a stateless PKIXCertPathChecker implementation. It checks if a private extension exists in a certificate and processes it according to some rules.
import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Collections; import java.util.Set; import java.security.cert.PKIXCertPathChecker; import java.security.cert.CertPathValidatorException; public class MyChecker extends PKIXCertPathChecker { private static Set supportedExtensions = Collections.singleton("2.16.840.1.113730.1.1"); /* * Initialize checker */ public void init(boolean forward) throws CertPathValidatorException { // nothing to initialize } public Set getSupportedExtensions() { return supportedExtensions; } public boolean isForwardCheckingSupported() { return true; } /* * Check certificate for presence of Netscape's * private extension * with OID "2.16.840.1.113730.1.1" */ public void check(Certificate cert, Collection unresolvedCritExts) throws CertPathValidatorException { X509Certificate xcert = (X509Certificate) cert; byte[] ext = xcert.getExtensionValue("2.16.840.1.113730.1.1"); if (ext == null) return; // // process private extension according to some // rules - if check fails, throw a // CertPathValidatorException ... // {insert code here} // remove extension from collection of unresolved // extensions (if it exists) if (unresolvedCritExts != null) unresolvedCritExts.remove("2.16.840.1.113730.1.1"); } }How a PKIX Service Provider implementation should use a PKIXCertPathChecker
Each PKIXCertPathChecker object must be initialized by a service provider implementation before commencing the build or validation algorithm, for example:
List checkers = params.getCertPathCheckers(); ListIterator li = checkers.listIterator(); while (li.hasNext()) { PKIXCertPathChecker checker = (PKIXCertPathChecker) li.next(); checker.init(false); }For each certificate that it validates, the service provider implementation must call the check method of each PKIXCertPathChecker object in turn, passing it the certificate and any remaining unresolved critical extensions:
ListIterator li = checkers.listIterator(); while (li.hasNext()) { PKIXCertPathChecker checker = (PKIXCertPathChecker) li.next(); checker.check(cert, unresolvedCritExts); }If any of the checks throw a CertPathValidatorException, the service provider implementation should terminate the validation procedure. However, a CertPathBuilder implementation may simply log the failure and continue to search for other potential paths. If all of the checks are successful, the service provider implementation should check that all critical extensions have been resolved and if not, throw an exception. For example:
if (unresolvedCritExts != null && !unresolvedCritExts.isEmpty()) { throw new CertPathValidatorException("Unrecognized Critical Extension"); }As discussed in the previous section, a CertPathBuilder implementation may need to backtrack when a potential certification path reaches a dead end or point of failure. Backtracking in this context implies returning to the previous certificate in the path and checking for other potential paths. If the CertPathBuilder implementation is validating the path as it is building it, it will need to restore the previous state of each PKIXCertPathChecker. It can do this by making clones of the PKIXCertPathChecker objects before each certificate is processed, for example:
/* clone checkers */ List newList = new ArrayList(checkers); ListIterator li = newList.listIterator(); while (li.hasNext()) { PKIXCertPathChecker checker = (PKIXCertPathChecker) li.next(); li.set(checker.clone()); }
This section is intended for experienced programmers wishing to create their own provider packages supplying certification path service implementations. This section assumes you have read the document: How to Implement a Provider for the Java Cryptography Architecture.
The following engine classes are defined in the Java Certification Path API:
CertPathValidator
- used to validate certification paths
CertPathBuilder
- used to build certification paths
CertStore
- used to retrieve certificates and CRLs from a repository
In addition, the existing
CertificateFactory
engine
class has been enhanced to support generation of certification
paths.
The application interfaces supplied by an engine class are implemented in terms of a "Service Provider Interface" (SPI). The name of each SPI class is the same as that of the corresponding engine class, followed by "Spi". For example, the SPI class corresponding to the CertPathValidator engine class is the CertPathValidatorSpi class. Each SPI class is abstract. To supply the implementation of a particular type of service, for a specific algorithm, a provider must subclass the corresponding SPI class and provide implementations for all the abstract methods. For example, the CertStore class provides access to the functionality of retrieving certificates and CRLs from a repository. The actual implementation supplied in a CertStoreSpi subclass would be that for a specific type of certificate repository, such as LDAP.
Developers should follow the required steps listed in the How To Implement A Provider for the Java Cryptography Architecture document. Here are some additional rules to follow for certain steps:
Step 3: Write your "Master Class", a subclass of Provider
These are the properties that must
be defined for the certification path services, where the
algorithm name is substituted
for algName, and certstore type for storeType:
CertPathValidator.algName
CertPathBuilder.algName
CertStore.storeType
See Appendix A
for the standard names that should be used above. The value of
each property must be the fully qualified name of the class implementing
the specified algorithm, or certstore type. That is, it must be the
package name followed by the class name, where the two are separated by
a period. For example, a provider sets the CertPathValidator.PKIX
property to have the value "sun.security.provider.certpath.PKIXCertPathValidator"
as follows:
put("CertPathValidator.PKIX", "sun.security.provider.certpath.PKIXCertPathValidator")
In addition,
service attributes can be defined for the certification path
services. These attributes can be used as filters for selecting
service providers. See Appendix A for the definition of some
standard service attributes. For example, a provider may set the
RFC
service attribute to have the value "2459"
for the CertPathValidator.PKIX
algorithm as follows:
put("CertPathValidator.PKIX RFC", "2459");
Step 8: Document your Provider and its Supported Services
Certification path service providers should document the following information for each SPI:
Certificate Factories
A provider should document what types of certification paths (and the version numbers of the certificates in the path, if relevant) can be created by the factory. A provider should describe the ordering of the certificates in the certification path, as well as the contents.
A provider should document the list of encoding formats supported. This is not technically necessary, since the client can request them by calling the getCertPathEncodings method. However, the documentation should describe each encoding format in more detail and reference any standards when applicable.
Certification Path Validators
A provider should document any relevant information regarding the CertPathValidator implementation, including the types of certification paths that it validates. In particular, a PKIX CertPathValidator implementation should document the following information:
Certification Path Builders
A provider should document any relevant information regarding the CertPathBuilder implementation, including the types of certification paths that it creates and whether or not they are validated. In particular a PKIX CertPathBuilder implementation should document the following information:
All CertPathBuilder implementations should provide additional debugging support, in order to analyze and correct potential path building problems. Details on how to access this debugging information should be documented.
Certificate/CRL Stores
A provider should document what types of certificates and CRLs (and the version numbers, if relevant) are retrieved by the CertStore.
A provider should also document any relevant information regarding the CertStore implementation (such as protocols used or formats supported). For example, an LDAP CertStore implementation should describe which versions of LDAP are supported and which standard attributes are used for finding certificates and CRLs. It should also document if the implementation caches results, and for how long (i.e. under what conditions are they refreshed).
If the implementation returns the
certificates and CRLs in a particular order, it should describe
the sorting algorithm. An implementation should also document any
additional or default initialization parameters.
Finally,
an implementation should document if and how it uses information
in the CertSelector or CRLSelector objects to
find certificates and CRLs.
Here are some common types of algorithm interdependencies in certification path service implementations:
Certification Path Validation and Signature Algorithms
A CertPathValidator implementation often requires use of a signature algorithm to verify each certificate's digital signature. The setSigProvider method of the PKIXParameters class allows a user to specify a specific Signature provider.
Certification Path Builders and Certificate Factories
A CertPathBuilder implementation will often utilize a CertificateFactory to generate a certification path from a list of certificates.
CertStores and Certificate Factories
A CertStore implementation will often utilize a CertificateFactory to generate certificates and CRLs from their encodings. For example, an LDAP CertStore implementation may use an X.509 CertificateFactory to generate X.509 certificates and CRLs from their ASN.1 encoded form.
The Certification Path API contains two interfaces representing transparent specifications of parameters, the CertPathParameters and CertStoreParameters interfaces.
Two implementations of the CertPathParameters interface are included, the PKIXParameters and PKIXBuilderParameters classes. If you are working with PKIX certification path validation and algorithm parameters, you can utilize these classes. If you need parameters for a different algorithm, you will need to supply your own CertPathParameters implementation for that algorithm.
Two implementations of the CertStoreParameters interface are included, the LDAPCertStoreParameters and the CollectionCertStoreParameters classes. These classes are to be used with LDAP and Collection CertStore implementations, respectively. If you need parameters for a different repository type, you will need to supply your own CertStoreParameters implementation for that type.
The Certification Path API contains two interfaces representing transparent specifications of results, the CertPathValidatorResult and CertPathBuilderResult interfaces.
One implementation for each of the interfaces is included: the PKIXCertPathValidatorResult and PKIXCertPathBuilderResult classes. If you are implementing PKIX certification path service providers, you can utilize these classes. If you need certification path results for a different algorithm, you will need to supply your own CertPathValidatorResult or CertPathBuilderResult implementation for that algorithm.
A PKIX implementation of a CertPathValidator or a CertPathBuilder may find it useful to store additional information in the PKIXCertPathValidatorResult or PKIXCertPathBuilderResult, such as debugging traces. In these cases, the implementation should implement a subclass of the appropriate result class with methods to retrieve the relevant information. These classes must be shipped with the provider classes, for example, as part of the provider JAR file.
The
Certification Path API contains a set of exception classes for
handling errors. CertPathValidatorException,
CertPathBuilderException, and CertStoreException
are subclasses of GeneralSecurityException.
You may
need to extend these classes in your service provider
implementation. For example, a CertPathBuilder
implementation may provide additional information such as debugging
traces when a CertPathBuilderException is thrown. The
implementation may throw a subclass of CertPathBuilderException
that holds this information. Likewise, a CertStore
implementation can provide additional information when a failure
occurs by throwing a subclass of CertStoreException. Also,
you may want to implement a subclass of CertPathValidatorException
to describe a particular failure mode of your CertPathValidator
implementation.
In each case, the new exception classes must
be shipped with the provider classes, for example, as part of the
provider JAR file. Each provider should document the exception
subclasses.
The Java Certification Path API requires and utilizes a set of standard names for certification path validation algorithms, encodings and certificate storage types. It supplements the list of standard names defined in Appendix A in the Java Cryptography Architecture API Specification and Reference. Note that algorithm names are treated as case-insensitive (for comparison).
Please note that a service provider may choose to define a new name for
a proprietary or non-standard algorithm not mentioned below. However, to
prevent name collisions, it is recommended that the name be prefixed with
the reverse Internet domain name of the provider's organization (for example: com.sun.MyCertPathValidator
).
The algorithm names in this section can be specified when generating an instance of CertPathValidator.
PKIX: The PKIX certification path validation algorithm as defined in the RFC service attribute. If the attribute is not defined, RFC 2459 is assumed.
The algorithm names in this section can be specified when generating an instance of CertPathBuilder.
PKIX: The PKIX certification path validation algorithm as defined in the RFC service attribute. If the attribute is not defined, RFC 2459 is assumed. The output of CertPathBuilder instances implementing this algorithm is a certification path validated against the PKIX validation algorithm.
The following types can be specified when generating an instance of CertStore:
LDAP: A CertStore implementation that fetches certificates and CRLs from an LDAP directory using the schema defined in the RFC service attribute. If the attribute is not defined, RFC 2587 is assumed.
Collection: A CertStore implementation that retrieves certificates and CRLs from a Collection.
The following encodings may be passed to the getEncoded method of CertPath or the generateCertPath(InputStream inStream, String encoding) method of CertificateFactory.
PKCS7: A PKCS#7 SignedData object, with the only significant field being certificates. In particular, the signature and the contents are ignored. If no certificates are present, a zero-length CertPath is assumed.
RFC: The number of the RFC (Request For Comments) that this implementation complies with. All CertPathBuilder and CertPathValidator implementations of the PKIX algorithm should provide a value for this attribute (for example, 2459). Also, all CertStore implementations of the LDAP type should provide a value for this attribute (for example, 2587).
Copyright © 1998-2000, Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California, 94303, U.S.A. All Rights Reserved. Please send comments to: certpath-experts-lead@ireland.sun.com. This is not a subscription list. |