The CertificateFactory Class

The CertificateFactory class is an engine class that defines the functionality of a certificate factory. It was used to generate Certificate and CRL objects. It has been enhanced in Java™ Certification Path to also be used to generate certification path (CertPath) 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 byte array or an array of Certificate objects.

Creating a CertificateFactory Object

As with all engine classes, the way to get a CertificateFactory object for a particular certificate or CRL type is to call the getInstance static factory method on the CertificateFactory class:

    public static CertificateFactory getInstance(String type)

Note: The type name is case-insensitive.

A caller may optionally specify the name of a provider, which will guarantee that the implementation of the certificate factory requested is from the named provider.

    public static CertificateFactory getInstance(String type, String provider)

Generating CertPath Objects

A CertificateFactory instance generates CertPath objects from a List of Certificate objects or from an InputStream that contains the encoded form of a CertPath. Just like a CertPath, each CertificateFactory supports a default encoding format for certification paths (for example: PKCS#7). To generate a CertPath 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 of Certificates 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);
    }

Here's another code sample that fetches a certificate chain from a KeyStore and converts it to a CertPath using a CertificateFactory:

    // instantiate a KeyStore with type JKS
    KeyStore ks = KeyStore.getInstance("JKS");
    // load the contents of the KeyStore
    ks.load(new FileInputStream("./keystore"),
         "password".toCharArray());
    // fetch certificate chain stored with alias "sean"
    Certificate[] certArray = ks.getCertificateChain("sean");
    // convert chain to a List
    List certList = Arrays.asList(certArray);
    // instantiate a CertificateFactory for X.509
    CertificateFactory cf = CertificateFactory.getInstance("X.509");
    // extract the certification path from
    // the List of Certificates
    CertPath cp = cf.generateCertPath(certList);

Note that there is an existing method in CertificateFactory named generateCertificates that parses a sequence of Certificate objects. 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).