Java security evolution and concepts, Part 5

J2SE 1.4 offers numerous improvements to Java security

1 2 3 4 Page 2
Page 2 of 4
    // Fetch or build a certificate chain
    Certificate[] certArray = pks.getCertificateChain("rags");
    // 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);
    // Create CertPathValidator that implements the "PKIX" algorithm
    CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
     // Set the Trust anchor
    TrustAnchor anchor = new TrustAnchor((X509Certificate)tks.getCertificate("ca"), null);
    // Set the PKIX parameters
    PKIXParameters params = new PKIXParameters(Collections.singleton(anchor));
    params.setRevocationEnabled(false);
    // Validate and obtain results
    try {
        PKIXCertPathValidatorResult result =
            (PKIXCertPathValidatorResult) cpv.validate(cp, params);
     } catch (CertPathValidatorException cpve) {
        System.out.println("Validation failure, cert[" 
            + cpve.getIndex() + "] :" + cpve.getMessage());
     }

The code snippet above illustrates the validation of a certificate chain from the keystore using a trust anchor obtained from a truststore.

Java Certification Path example programs

For the purposes of the examples, we have disabled revocation checking to make the sample code easier to execute. The PKIX validation algorithm requires us to check the revocation status of each certificate in a chain. The user should be aware of the security risks associated with explicitly disabling certificate revocation checking.

To illustrate the programming model highlighted above, we validate a self-certified certificate chain using the same key as trust anchor. The example is not a useful real-life example, but nevertheless illustrates the API's use:

Example 1, Step 1. Create a keystore with a key, which also self-certifies it.

C:\rags>keytool -genkey -alias rags -keystore certpath.keystore
Enter keystore password:  changeit
What is your first and last name?
  [Unknown]:  Rags Srinivas
What is the name of your organizational unit?
  [Unknown]:  SDN
What is the name of your organization?
  [Unknown]:  Sun
What is the name of your City or Locality?
  [Unknown]:  Burlington
What is the name of your State or Province?
  [Unknown]:  MA
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Rags Srinivas, OU=SDN, O=Sun, L=Burlington, ST=MA, C=US correct?
  [no]:  yes
Enter key password for <rags>
        (RETURN if same as keystore password):

Example 1, Step 2. Verify whether the certificate chain has been properly generated. The certificate chain length should be 1 and the owner and issuer must be identical.

C:\rags>keytool -list -v -alias rags -keystore certpath.keystore
Enter keystore password:  changeit
Alias name: rags
Creation date: Dec 10, 2001
Entry type: keyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Rags Srinivas, OU=SDN, O=Sun, L=Burlington, ST=MA, C=US
Issuer: CN=Rags Srinivas, OU=SDN, O=Sun, L=Burlington, ST=MA, C=US
Serial number: 3c148eca
Valid from: Mon Dec 10 05:30:34 EST 2001 until: Sun Mar 10 05:30:34 EST 2002
Certificate fingerprints:
         MD5:  97:40:C2:87:14:FD:54:1F:E3:EB:3E:27:C0:34:70:A8
         SHA1: B1:0E:0A:78:EA:10:D9:21:31:1F:DB:F2:2F:26:8B:97:77:5D:07:69

Example 1, Step 3. Compile and run the following program, which reads the self-certified chain from the keystore and validates it against the same certificate. The example program ignores some of the possible exceptions that could be generated.

/**
 * ValidateSelfCert : validates an X.509 certification path
 *      using a PKIX CertPathValidator
 *
 * Synopsis: java ValidateSelfCert keystore password alias
 *
 * The program validates the certificate chain in the keystore
 *  referred by the "alias".
 */
import java.security.*;
import java.security.cert.*;
import java.util.*;
import java.io.*;
class ValidateSelfCert
{
    public static void main(String args[])
    {
        // Instantiate a KeyStore with type JKS
        try {
            if (args.length != 3)
                throw new Exception("ValidateCert " + "keystore " + "password " + "alias");
           KeyStore ks = KeyStore.getInstance("JKS");
            // Load the contents of the KeyStore
            ks.load(new FileInputStream(args[0]),
                args[1].toCharArray());
             // Fetch certificate chain stored with alias "rags"
             java.security.cert.Certificate[] certArray = ks.getCertificateChain(args[2]);
             if (certArray == null)
                throw new Exception("Alias " + args[2] + " is not a certificate chain");
             // 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);
             // Create CertPathValidator that implements the "PKIX" algorithm
             CertPathValidator cpv = null;
             cpv = CertPathValidator.getInstance("PKIX");
             // Set the Trust anchor
             TrustAnchor anchor = new TrustAnchor((X509Certificate)ks.getCertificate(args[2]), null);
             // Set the PKIX parameters
             PKIXParameters params = new PKIXParameters(Collections.singleton(anchor));
             params.setRevocationEnabled(false);
             // Validate and obtain results
             try {
                 PKIXCertPathValidatorResult result =
                     (PKIXCertPathValidatorResult) cpv.validate(cp, params);
                 PolicyNode policyTree = result.getPolicyTree();
                 PublicKey subjectPublicKey = result.getPublicKey();
                 System.out.println("Certificate validated");
                 System.out.println("Policy Tree:\n" + policyTree);
                 System.out.println("Subject Public key:\n" +subjectPublicKey);
             } catch (CertPathValidatorException cpve) {
                 System.out.println("Validation failure, cert[" 
                     + cpve.getIndex() + "] :" + cpve.getMessage());
             }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

You should see output resembling:

C:\rags>java ValidateSelfCert certpath.keystore changeit rags
Certificate validated
Policy Tree:
null
Subject Public key:
Sun DSA Public Key
    Parameters:DSA
        p:     fd7f5381 1d751229 52df4a9c 2eece4e7 f611b752 3cef4400 c31e3f80 b6512669
    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 3d078267
    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:
    5834e353 dbc0be85 fce9c28d 1679066c b2a93d23 651f731b 40c96e2f 445db11b
    82209777 2cce98a8 65aa5545 5a0d4e3a 45b52fe3 24276c7b 7f8f5189 162626cc
    bf98703f 9350b49f 7ae22330 dfe11f89 928f3acc 69e69419 d73ca568 a0f459c1
    743028b3 b59977a3 66b0383c aaf01645 efa7091d 493e6b8c 15f06391 c780f6e2

The example above illustrates a certification path validation. However, the example seems unrealistic since the validation concerns a self-certified certificate.

In a real-life scenario, certification paths will validate against standard CAs, using CRLs. You'll find a more realistic scenario in Example 2.

Example 2, Step 1. Obtain a certificate chain beginning or ending with a standard CA. The following certificate serves as an example. You may want to obtain your own certificate chain by validating your certificate request from a CA.

C:\rags>type verisign.cer
-----BEGIN CERTIFICATE-----
MIAGCSqGSIb3DQEHAqCAMIACAQExADALBgkqhkiG9w0BBwGggDCCB3AwggbZoAMC
AQICEHFplLgCsdyOEiRuw5RKX1wwDQYJKoZIhvcNAQEEBQAwgcgxFzAVBgNVBAoT
DlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3Jr
MUYwRAYDVQQLEz13d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvUlBBIEluY29y
cC4gYnkgUmVmLixMSUFCLkxURChjKTk4MUQwQgYDVQQDEztWZXJpU2lnbiBDbGFz
cyAzIENBIC0gQ29tbWVyY2lhbCBDb250ZW50L1NvZnR3YXJlIFB1Ymxpc2hlcjAe
Fw0wMTAzMjkwMDAwMDBaFw0wMjAzMjkyMzU5NTlaMIIBDjEXMBUGA1UEChMOVmVy
aVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxRjBE
BgNVBAsTPXd3dy52ZXJpc2lnbi5jb20vcmVwb3NpdG9yeS9SUEEgSW5jb3JwLiBi
eSBSZWYuLExJQUIuTFREKGMpOTkxMTAvBgNVBAsTKERpZ2l0YWwgSUQgQ2xhc3Mg
MyAtIEphdmEgT2JqZWN0IFNpZ25pbmcxGTAXBgNVBAMUEFN1biBNaWNyb3N5c3Rl
bXMxDTALBgNVBAsUBE1ERFIxEzARBgNVBAcTCkJ1cmxpbmd0b24xCzAJBgNVBAgT
Ak1BMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAz4XG
ut3Y9h5ihAwYvp2BklMbUFml/mSjoOA328yuc+UoJ9McsRcEMmx1nTWtIzL2Q/bU
RKH8OnGx845vwVnbxy3HgG+9hC+BT8jtcJeriFYS+j7LQ+jJkYJa1++WXxTQyMNu
yxzcOrxpRaxQvr49Nn+uYn0gkCswjM1JY04I24MCAwEAAaOCBBAwggQMMAkGA1Ud
EwQCMAAwCwYDVR0PBAQDAgWgMBEGCWCGSAGG+EIBAQQEAwIEEDA2BglghkgBhvhC
AQgEKRYnaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JlcG9zaXRvcnkvQ1BTMIID
jQYJYIZIAYb4QgENBIIDfhaCA3pUaGlzIGNlcnRpZmljYXRlIGluY29ycG9yYXRl
cyBieSByZWZlcmVuY2UsIGFuZCAKaXRzIHVzZSBpcyBzdHJpY3RseSBzdWJqZWN0
IHRvLCB0aGUgVmVyaVNpZ24gCkNlcnRpZmljYXRpb24gUHJhY3RpY2UgU3RhdGVt
ZW50IChDUFMpLCBhdmFpbGFibGUKaW4gdGhlIFZlcmlTaWduIHJlcG9zaXRvcnkg
YXQ6IApodHRwczovL3d3dy52ZXJpc2lnbi5jb207IGJ5IEUtbWFpbCBhdApDUFMt
cmVxdWVzdHNAdmVyaXNpZ24uY29tOyBvciBieSBtYWlsIGF0IFZlcmlTaWduLApJ
bmMuLCAyNTkzIENvYXN0IEF2ZS4sIE1vdW50YWluIFZpZXcsIENBIDk0MDQzIFVT
QQoKQ29weXJpZ2h0IChjKTE5OTYgVmVyaVNpZ24sIEluYy4gIEFsbCBSaWdodHMg
ClJlc2VydmVkLiAKCldBUk5JTkc6IFRIRSBVU0UgT0YgVEhJUyBDRVJUSUZJQ0FU
RSBJUyBTVFJJQ1RMWQpTVUJKRUNUIFRPIFRIRSBWRVJJU0lHTiBDRVJUSUZJQ0FU
SU9OIFBSQUNUSUNFClNUQVRFTUVOVC4gIFRIRSBJU1NVSU5HIEFVVEhPUklUWSBE
SVNDTEFJTVMgQ0VSVEFJTgpJTVBMSUVEIEFORCBFWFBSRVNTIFdBUlJBTlRJRVMs
IElOQ0xVRElORyBXQVJSQU5USUVTCk9GIE1FUkNIQU5UQUJJTElUWSBPUiBGSVRO
RVNTIEZPUiBBIFBBUlRJQ1VMQVIKUFVSUE9TRSwgQU5EIFdJTEwgTk9UIEJFIExJ
QUJMRSBGT1IgQ09OU0VRVUVOVElBTCwKUFVOSVRJVkUsIEFORCBDRVJUQUlOIE9U
SEVSIERBTUFHRVMuIFNFRSBUSEUgQ1BTCkZPUiBERVRBSUxTLgoKQ29udGVudHMg
b2YgdGhlIFZlcmlTaWduIHJlZ2lzdGVyZWQKbm9udmVyaWZpZWRTdWJqZWN0QXR0
cmlidXRlcyBleHRlbnNpb24gdmFsdWUgc2hhbGwgCm5vdCBiZSBjb25zaWRlcmVk
IGFzIGFjY3VyYXRlIGluZm9ybWF0aW9uIHZhbGlkYXRlZCAKYnkgdGhlIElBLjAW
BgorBgEEAYI3AgEbBAgwBgEBAAEB/zANBgkqhkiG9w0BAQQFAAOBgQDJn6qbpwJs
o5Tysnbj8tIaX4i5P3kY65Coofi5JHFF2qG7wIH4LLvNBkUr+mEbPRD+jpUdaCM4
nf2gHyhB1uTcFrQtV8Zqx7gUjC0Ndqs8jpmPneJo8jGQ8U5eCgKHGgxVjP1QViaB
8m/NMZP2v1EL5n3+zsKF4xqyVkuMmtURkDCCA4gwggLxoAMCAQICEQDL4hP+j/J6
JPdDkHw35sUaMA0GCSqGSIb3DQEBAgUAMF8xCzAJBgNVBAYTAlVTMRcwFQYDVQQK
Ew5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMyBQdWJsaWMgUHJpbWFy
eSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05ODEyMzEwMDAwMDBaFw0wNDAx
MDYyMzU5NTlaMIHIMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMW
VmVyaVNpZ24gVHJ1c3QgTmV0d29yazFGMEQGA1UECxM9d3d3LnZlcmlzaWduLmNv
bS9yZXBvc2l0b3J5L1JQQSBJbmNvcnAuIGJ5IFJlZi4sTElBQi5MVEQoYyk5ODFE
MEIGA1UEAxM7VmVyaVNpZ24gQ2xhc3MgMyBDQSAtIENvbW1lcmNpYWwgQ29udGVu
dC9Tb2Z0d2FyZSBQdWJsaXNoZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB
AMwDv0OpVc4RkrY16GDdlPVCVnDUNt1kF4iXjE36csP4vR1frVAxyOPRWkLO2YmX
tjWkmM8aKrNS8YoxrIynXjcGeANLqu0Sfmr64jbRx/VHL1VNftzN4ECyIFxSOpHW
WtzWlTZto4XA/ybUItwv+ReVQlhRjRLELziznveIqoJ1AgMBAAGjgdkwgdYwIwYD
VR0RBBwwGqQYMBYxFDASBgNVBAMTC0NsYXNzM0NBMS0zMEcGA1UdIARAMD4wPAYL
YIZIAYb4RQEHAQEwLTArBggrBgEFBQcCARYfd3d3LnZlcmlzaWduLmNvbS9yZXBv
c2l0b3J5L1JQQTAPBgNVHRMECDAGAQH/AgEAMAsGA1UdDwQEAwIBBjA1BgNVHR8E
LjAsMCqgKKAmhiRodHRwOi8vY3JsLnZlcmlzaWduLmNvbS9wY2EzLjEuMS5jcmww
EQYJYIZIAYb4QgEBBAQDAgABMA0GCSqGSIb3DQEBAgUAA4GBAEX3+xIpzyHQlCu1
ulIBa1kfTTCMQAdHRdE+ZSZjy6jLZsI6YJOt3HaC3D6/+IOQ4fVOBrWmy4yfr7yA
4n+qqqNc4gt1RUKgXVDHmZKJ9nandj27TshjUmtBrmUn/FGP3W12t3cAJoW9SRIu
EBH+Lx97yU48SQNlOoMnc7kxeJ+4AAAxAAAAAAAAAA==
-----END CERTIFICATE-----

Example 2, Step 2. Verify whether the certificate chain has been properly generated. The certificate chain length should be greater than 1 and signed by a standard CA.

C:\rags>keytool -printcert -file verisign.cer
Certificate[1]:
Owner: C=US, ST=MA, L=Burlington, OU=MDDR, CN=Sun Microsystems, OU=Digital ID Class 3 - Java Object Signing, OU="www.verisign.com/repository/RPA Incorp. by Ref.,LIAB.LTD(c)99", OU=VeriSign Trust Network, O="VeriSign, Inc."
Issuer: CN=VeriSign Class 3 CA - Commercial Content/Software Publisher, OU="www.verisign.com/repository/RPA Incorp. by Ref.,LIAB.LTD(c)98", OU=VeriSign Trust Network, O="VeriSign, Inc."
Serial number: 716994b802b1dc8e12246ec3944a5f5c
Valid from: Wed Mar 28 19:00:00 EST 2001 until: Fri Mar 29 18:59:59 EST 2002
Certificate fingerprints:
         MD5:  8C:DA:A6:0B:38:7C:09:B2:2E:51:94:02:FA:18:EC:76
         SHA1: 68:49:64:A3:15:0C:C7:68:82:69:05:85:AE:05:0E:41:1E:C2:D9:F3
Certificate[2]:
Owner: CN=VeriSign Class 3 CA - Commercial Content/Software Publisher, OU="www.verisign.com/repository/RPA Incorp. by Re
f.,LIAB.LTD(c)98", OU=VeriSign Trust Network, O="VeriSign, Inc."
Issuer: OU=Class 3 Public Primary Certification Authority, O="VeriSign, Inc.", C=US
Serial number: cbe213fe8ff27a24f743907c37e6c51a
Valid from: Wed Dec 30 19:00:00 EST 1998 until: Tue Jan 06 18:59:59 EST 2004
Certificate fingerprints:
         MD5:  3D:65:D5:67:C2:75:90:3D:3A:9E:20:82:FE:A0:C5:9C
         SHA1: 48:8D:67:77:D8:6F:E4:BA:FF:E8:A2:BC:A3:E6:29:95:81:D5:2E:04

Example 2, Step 3. Obtain the certificate corresponding to the trusted anchor (Verisign Class 3 CA, in this example). In this case, we obtain the trusted anchor's certificate from the cacerts file, which contains some standard CAs' certificates.

C:\rags>keytool -export -alias verisignclass3ca -keystore c:\jdk1.4\jre\lib\security\cacerts -file verisignclass3ca.cer
Enter keystore password:  changeit
Certificate stored in file <verisignclass3ca.cer>

Example 2, Step 4. Now run the following program, which validates the certificate chain shown in Step 2, with the standard CA used in Step 3.

1 2 3 4 Page 2
Page 2 of 4