CertPath provides a full-fledged API framework for application developers who wish to integrate the functionality of checking, verifying, and validating digital certificates into their applications. Digital certificates play the role of establishing trust and credentials when conducting business or other transactions. Issued by a Certification Authority (CA), a digital certificate defines a binding data structure containing the holder name, a serial number, expiration dates, a public key, and the digital signature of the CA so that a recipient can verify the authenticity of the certificate. CAs usually obtain their certificates from their own higher-level authority. Typically in a certificate binding, a chain of certificates (referred to as a certification chain) starts from the certificate holder, is followed by zero or more certificates of intermediate CAs, and ends with a root-certificate of some top-level CA. So the process of reading, verifying, and validating certificate chains becomes important in PKI certificate-enabled applications and systems. In J2SE, Java CertPath APIs provides API-based mechanisms for parsing and managing certificates, certificate revocation lists (CRLs), and certification paths (also referred to as certificate chains). The API implementations can be plugged into any J2SE environment, because the same JCA provider interfaces are used. The API includes algorithm-specific classes for building and validating X.509 certification paths according to IETF-defined PKIX standards. With the release of J2SE 5.0, CertPath provides client-side support for the Online Certificate Status Protocol (OCSP) as per RFC2560 that allows determining the current status of a certificate without requiring CRLs. The J2SE 5.0 CertPath implementation has also passed the compliance tests of the Public Key Interoperability Test Suite (PKITS) defined by NIST in conjunction with Digital-Net and NSA. Let's take a closer look at the Java CertPath API and its core classes, interfaces, and programming model. Java CertPathClasses and InterfacesIn J2SE, the Java CertPath API is an extension of the JCA, and it exists as part of the java.security.cert.* package. The core classes fit into four basic categories: Basic Certification path classes, Certification path Validation classes, Certification path Building classes, and Certificate/CRL Storage classes. Let's take a look at some of the most important classes from the Java CertPath API.
Java CertPath API Programming ModelLet's explore the CertPath API programming model and the steps involved in using those important classes and mechanisms. Although the details of using specific algorithms and operations vary, the common steps are discussed in the code fragments shown in the following sections. Create a Certificate Chain Using CertPathThe following is an example code fragment (see Example 4-17) that demonstrates the steps involved in creating a CertPath object for a specified list of certificates: Example 4-17. Creating a certificate chain for a list of certificatesCertPath createCertPath(java.security.cert.Certificate[] certs) { try { //1. Instantiate CertificateFactory for X.509 CertificateFactory certFact = CertificateFactory.getInstance("X.509"); // 2. Generate a Certificate chain // for the specified list of certificates CertPath path = certFact.generateCertPath(Arrays.asList(certs)); return path; } catch(java.security.cert.CertificateEncodingException e) { } catch (CertificateException e) { } return null; } Validate a Certificate Chain Using CertPathExample 4-18 is an example code fragment that demonstrates the steps involved in validating a CertPath object using a trusted CA in the trusted certificate keystore (cacerts). Before using this code snippet, make sure a CertPath object is created and available for validation. Example 4-18. Validating a certificate chaintry { // 1. Load the J2SE cacerts truststore file String filename = System.getProperty("java.home") + "/lib/security/cacerts".replace('/', File.separatorChar); FileInputStream is = new FileInputStream(filename); // 2. Load the default keystore KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); String password = "changeit"; keystore.load(is, password.toCharArray()); // 3. Create the parameters for the validator PKIXParameters params = new PKIXParameters(keystore); // 4. Disable CRL checking // as we are not supplying any CRLs params.setRevocationEnabled(false); // 5. Create the validator and validate // the specified certpath CertPathValidator certPathValidator = CertPathValidator.getInstance (CertPathValidator.getDefaultType()); CertPathValidatorResult result = certPathValidator.validate(certPath, params); // 6. Get the CA used to validate this path PKIXCertPathValidatorResult pkixResult = (PKIXCertPathValidatorResult)result; TrustAnchor ta = pkixResult.getTrustAnchor(); X509Certificate cert = ta.getTrustedCert(); } catch (CertificateException ce) { } catch (KeyStoreException ke) { } catch (NoSuchAlgorithmException ne) { } catch (InvalidAlgorithmParameterException ie) { } catch (CertPathValidatorException cpe) { // Validation failed } In the next section, we will explore Java Secure Socket Extensions (JSSE), which defines an API framework to secure communications over the network using standardized protocols. |