Certificate Path Validation

  

Certificate Path Validation

One of the purposes of the JSR-055 ( http://jcp.org/jsr/detail/055.jsp ) that is distributed with the JDK 1.4 is to provide basic path validation. Basic path validation is necessary for many algorithms, such as SSL/TLS and IPSEC. Checking the basic path validation is also important to an organization if it wants to check internally whether the organization's certificate set is valid. The JDK 1.4 distribution provides an API for path validation of certificates.

The PKI documentation ( http://www.ietf.org/internet-drafts/draft-ietf-pkix-new-part1-11.txt ) defines an algorithm that should be used for basic path validation of certificates. The algorithm defines the inputs to be a Trust Anchor, the current date/time, and a certificate to be checked. It also defines indicators for the policy mapping being allowed, the path validation being allowed for at least one of the certificate policies, and an indicator if the anyPolicy OID should be used in the validation.

Figure 25-8 demonstrates the basic path validation algorithm where the certificate and values (like the policies) are used to process or validate the certificate, and the algorithm continues till the last certificate in the path.


Figure 25-8: Basic path validation algorithm

The initialization begins with, but doesn't end with the creation from the java.security.cert.CertPath class. The CertPath is an engine class that is generated by the CertificateFactory class. Listing 25-1 shows the CertPath initialization example.

Listing 25-1: The RichPath : A CertPath initialization example
start example
 package com.richware.chap25;     import java.security.cert.CertPath; import java.security.cert.CertificateFactory; import java.security.cert.CertPathParameters; import java.security.cert.CertPathValidatorResult; import java.security.cert.CertPathValidator; import java.security.KeyStore; import java.security.PublicKey; import java.security.cert.Certificate; import java.util.Date; import java.security.cert.X509CRLSelector; import java.security.cert.PKIXParameters; import java.security.cert.PKIXCertPathValidatorResult; import java.security.cert.PolicyNode; import java.security.cert.TrustAnchor; import java.util.Collection; import java.util.Collections; import java.security.cert.LDAPCertStoreParameters; import java.security.cert.CertStore; import java.security.cert.X509CertSelector; import java.math.BigInteger; import java.util.List; import java.io.FileInputStream; import java.util.Arrays;  /**  * Class RichPath  * Description: A custom demonstration of the path verification  * for a certificate.  *  * Copyright:    Copyright (c) 2002 Wiley Publishing, Inc.  * @author Rich Helton <rhelton@richware.com>  * @version 1.0    * DISCLAIMER: Please refer to the disclaimer at the beginning of this book.   */ public class RichPath {   private static final boolean _DEBUG = true;       /**    * Method main    * Description: The main driver to run the methods.    *    *    * @param args (no arguments presently).    *    */   public static void main(String args[]) {     try {       System.out.println("Starting RichPath....");       /*        * Pass in the argument of the keystore file        * It will be opened in the same directory as the application        */       if (args[0] == null)        {         System.out.println(           "This application requires an input file for the location of  the keystore");       }           String localDirectory = System.getProperty("user.dir");       System.out.println("Changing directory to Chapter 25");       System.setProperty("user.dir",                          localDirectory                          + "\com\richware\chap25\");       localDirectory = System.getProperty("user.dir");           /*        * Get the local keystore that contains a trusted certificate        */       String localInputFile = localDirectory + args[0];       System.out.println(         "Openining Chapter 25 plus the input file as an argument: "         + localInputFile);           /*        * Import the certificate path keystore        */       RichPath myPath  = new RichPath();       CertPath newpath =         myPath.importCertPath(localInputFile,"password", "rich2");       /*        *   catches.        */     } catch (Exception e) {       e.printStackTrace();     }   }       /**    * Method importCertPath    * Description: Import the certificate path from the     * keystore.    *    * @param filename of the keystore to import.    * @param password    * @param chain    *    * @return the certification path.    *    */   public CertPath importCertPath(String filename,                                  String password,                                  String chain) {     CertPath certPath = null;     try {       /*        * instantiate a CertificateFactory for X.509        */       CertificateFactory cf =         CertificateFactory.getInstance("X.509");           /*        * instantiate a KeyStore with type JKS        */       KeyStore ks = KeyStore.getInstance("JKS");           /*        * load the contents of the KeyStore        */       ks.load(new FileInputStream(filename),               password.toCharArray());           /*        * fetch certificate chain stored         */       Certificate[] certArray = ks.getCertificateChain(chain);           /*        * convert chain to a List        */       List certList = Arrays.asList(certArray);           /*        * extract the certification path from the List of         * Certificates        */       certPath = cf.generateCertPath(certList);       System.out.println(" CertPath :" + certPath);           /*        *   catches.        */     } catch (java.security.cert.CertificateException e) {       e.printStackTrace();     } catch (java.security.KeyStoreException e) {       e.printStackTrace();     } catch (java.security.NoSuchAlgorithmException e) {       e.printStackTrace();     } catch (java.io.IOException e) {       e.printStackTrace();     }         return certPath;   } } 
end example
 

Listing 25-1 demonstrates the initialization of the CertPath class. This CertPath object gets the certificate path from the keystore passed in that is called ./keystore . The certificate chain that will be validated is for the rich certificate in the keystore. The password for the certificate in the keystore must be used to retrieve the certificate.

The output of RichPath is as follows :

 >java com.richware.chap25.RichPath .keystore Starting RichPath.... Changing directory to Chapter 25 Opening Chapter 25 plus the input file as an argument:  C:\com\richware\chap25\.keystore  CertPath : X.509 Cert Path: length = 1. [ =========================================================Certificate 1  start. [ [   Version: V1   Subject: CN=rich helton, OU=development, O=richware, L=denver, ST=co,  C=us   Signature Algorithm: SHA1withDSA, OID = 1.2.840.10040.4.3       Key:  Sun DSA Public Key     Parameters:DSA         p:     fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400  c31e3f80 b6 512669     455d4022 51fb593d 8d58fabf c5f5ba30 f6cb9b55 6cd7813b 801d346f  f26660b7     6b9950a5 a49f9fe8 047b1022 c24fbba9 d7feb7c6 1bf83b57 e7c6a8a6  150f04fb     83f6d3c5 1ec30235 54135a16 9132f675 f3ae2b61 d72aeff2 2203199d  d14801c7         q:     9760508f 15230bcc b292b982 a2eb840b f0581cf5         g:     f7e1a085 d69b3dde cbbcab5c 36b857b9 7994afbb fa3aea82  f9574c0b 3d 078267     5159578e bad4594f e6710710 8180b449 167123e8 4c281613 b7cf0932  8cc8a6e1     3c167a8b 547c8d28 e0a3ae1e 2bb3a675 916ea37f 0bfa2135 62f1fb62  7a01243b     cca4f1be a8519089 a883dfe1 5ae59f06 928b665e 807b5525 64014c3b  fecf492a       y:     9b256cb3 09f61b20 2835df0a 0db97f65 786448dd 2599b6f9 148d1040  79b02014     df239539 954c69a4 a45d4cb0 7b98ad33 f881e2c4 4481c122 ebf98941  134be3cb     5077e54a 03774c6d 513f647c 79532772 09c50fea c2f1b5d2 f0d2016c  be4118ce     f76f757e cfb587c8 376efd44 d961af85 747f4c77 3b03883f 9a5ffb67  6b74ac71       Validity: [From: Fri Nov 23 22:53:46 MST 2001,                To: Thu Feb 21 22:53:46 MST 2002]   Issuer: CN=rich helton, OU=development, O=richware, L=denver, ST=co,  C=us   SerialNumber: [    3bff35ea ]     ]   Algorithm: [SHA1withDSA]   Signature: 0000: 30 2C 02 14 7E 8C 41 2A   2A 3F 9D A8 6C C0 40 58   0,....A**?..l.@X 0010: C8 36 BA 1D EA CC 2B D3   02 14 24 DE E1 54 9E 47   .6....+...$..T.G 0020: AE 33 BF 3D 28 94 9E B6   86 FF 7D 0D E2 DA        .3.=(.........     ]  =========================================================Certificate 1  end. ] 

This example does not end the initialization phase of the algorithm. Other values must be initialized such as the current date to ensure that the certificate falls within the current date. A Trust Anchor must also be initialized that will tell the algorithm which path to validate. The certificate path must always go through the Trust Anchor of the end-entity certificate. Any policies that it will be validated against must also be initialized . The class for initializing these parameters to be validated against is the java.security.cert.PKIXParameters class. The PKIXParameters must be initialized with a Trust Anchor. The Trust Anchor could either be the trusted certificates in the KeyStore or a Trusted Anchor created with the java.security.cert.TrustAnchor class. Listing 25-2 shows an example of how to build parameters using PKIXParameters class.

Listing 25-2: Building parameters with the PKIXParameters class
start example
 /**    * Method buildParams    * Purpose: Build the initialization parameters for the     * certificate validation.    *    * @param filename of the KeyStore    * @param password of the KeyStore    *    * @return the parameters built to validate.    *    */   public PKIXParameters buildParams(String filename,                                     String password) {         /*      * create CertPathValidator that implements the "PKIX"       * algorithm      */     try {           /* Pass in a TrustAnchor as a         * (Collections.singleton(anchor)) or        * retrieve all trusted certificates         * from KeyStore as anchor        * If a TrustAnchor was set here,         * the caName and publicKey of        * the CA would have to know         * or the X509Certificate which is        * the certificate of the TrustAnchor.        * Also any nameConstraints.        */       if ((filename == null)  (filename.length() < 1)) {         return null;       }           if ((password == null)  (password.length() < 1)) {         return null;       }           /*        * instantiate a KeyStore with type JKS        */       KeyStore ks = KeyStore.getInstance(_keystoreType);           /*        * load the contents of the KeyStore        */       ks.load(new FileInputStream(filename),               password.toCharArray());           PKIXParameters params = new PKIXParameters(ks);           /*        * Parameters used as input for the PKIX         * CertPathValidator algorithm.        */       /*        *  An example of setting policies would be:        *  params.setExplicitPolicyRequired(true);        *  params.setInitialPolicies(policyIds);        */       Date currentDate = new Date();       /*        * Set the current Date        */       params.setDate(currentDate);       return params;     } catch (Exception e) {       e.printStackTrace();     }     return null;   } 
end example
 

Part of the validation includes checking to see if the digital certificate is revoked. If the digital certificate is not revoked , the certificate is valid to proceed with the certificate path and validation against the parameters. The CRL is returned from a Certificate Store. The Certificate Store is initialized from the java.security.cert.CertStore class. A CertStore provides access to a collection of untrusted certificates and CRLs that can be used for purposes other than a trusted store. It is different than the KeyStore implementation that provides access to a collection of private keys and trusted certificates for an organization. The CertStore has two implementations : LDAP and Collection schemas. See Listing 25-3.

Listing 25-3: Retrieving CRLs from the LDAP server
start example
 /**    * Method buildLDAPCRLS    * Purpose: Build a CRL from the LDAP     * Server satisfying the conditions.    *    * @return the Collection of CRL certificates.    *    */   public Collection buildLDAPCRLS() {         try {     /*      * Access the LDAP Server      */       LDAPCertStoreParameters lcsp  =         new LDAPCertStoreParameters("ldap.sun.com", 389);       CertStore               cs    =         CertStore.getInstance("LDAP", lcsp);       X509CRLSelector         xcrls = new X509CRLSelector();           /*        * select CRLs satisfying current date and time        */       xcrls.setDateAndTime(new Date());           /*        * select CRLs issued by 'O=richwareLLC, C=us'        */       xcrls.addIssuerName("O=richwareLLC, C=us");           /*        * select only CRLs with a CRL number at least '2'        */       xcrls.setMinCRLNumber(new BigInteger("2"));           Collection crls = cs.getCRLs(xcrls);           return crls;      } catch (java.io.IOException e) {       e.printStackTrace();     } catch (java.security             .InvalidAlgorithmParameterException e) {       e.printStackTrace();     } catch (java.security.cert.CertStoreException e) {       e.printStackTrace();     } catch (java.security.NoSuchAlgorithmException e) {       e.printStackTrace();     }         return null;   } 
end example
 

After the certificate is ensured not to belong to the revoked certificate class, the parameters must be validated against the certification path. If the basic path validation is successful, the subject's public key can be returned with other items such as the certificate policy tree. The class that returns the results is the java.security.cert.PKIXCertPathValidatorResult class. Listing 25-4 shows the final validation code.

Listing 25-4: Final validation
start example
 /**    * Method certPathValidator    * Purpose: To validate the basic certificate path.    *    * @param certPath the certification path.    * @param params the certificate parameters.    *    * @return the results of the validation.    *    */   public PKIXCertPathValidatorResult certPathValidator(           CertPath certPath, PKIXParameters params) {         /*      * create CertPathValidator that implements the "PKIX" algorithm      */     try {       CertPathValidator cpv =         CertPathValidator.getInstance("PKIX");           /*        * validate the path and parameters        */       PKIXCertPathValidatorResult result           =         (PKIXCertPathValidatorResult) cpv.validate(certPath,           params);       /*        * retruns the root node of the policy tree        */       PolicyNode                  policyTree       =         result.getPolicyTree();       /*        * Get the Subject's Public Key        */       PublicKey                   subjectPublicKey =         result.getPublicKey();           return result;     } catch (java.security.NoSuchAlgorithmException e) {       e.printStackTrace();     } catch (java.security             .InvalidAlgorithmParameterException e) {       e.printStackTrace();     } catch (java.security.cert.CertPathValidatorException e) {       e.printStackTrace();     }         return null;   } 
end example
 
  


Java Security Solutions
Java Security Solutions
ISBN: 0764549286
EAN: 2147483647
Year: 2001
Pages: 222

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net