Thursday Jul 02, 2009

Enable OCSP checking

If a certificate is issued with a authority information access extension which indicates the OCSP access method and location, one can enable the default implementation of OCSP checker during building or validating a certification path.

Maybe you need to check your certificate firstly, in the purpose of making sure it includes a OCSP authority information access extension:

#${JAVA_HOME}/bin/keytool -printcert -v -file target.cert

You are expected to see similar lines in the output:

#3: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
[accessMethod: 1.3.6.1.5.5.7.48.1
accessLocation: URIName: http://onsite-ocsp.verisign.com]
]

In the above output, "http://onsite-ocsp.verisign.com" indicates the location of the OCSP service.

If you find one of similar authority information access extension in your certificate path, you need to enable OCSP checker.

For Sun PKIX implementation, OCSP checking is not enabled by default for compatibility, note that enabling OCSP checking only has an effect if revocation checking has also been enabled. So, in order to enable OCSP checker, first of all, you need to active certificate revocation checking; then active OCSP checking. It is simple and straightforward, only needs a few lines.

PKIXParameters params = new PKIXParameters(anchors);

// Activate certificate revocation checking
params.setRevocationEnabled(true);

// Activate OCSP
Security.setProperty("ocsp.enable", "true");

After that above two configurations, the default Sun PKIX implementation will try to get certificate status from the OCSP service indicated in the authority information access extension. For the above example, "http://onsite-ocsp.verisign.com" is the OCSP service. The enabled Sun OCSP checker will send certificate status request to the service, get response, and analysis the status from the response, if the status is revoked or unknown, the target certificate would be rejected.

Here is a sample code I wrote help you test your certificates and OCSP service, hope it helps.

/\*\*
 \* @author Xuelei Fan
 \*/
import java.io.\*;
import java.net.SocketException;
import java.util.\*;
import java.security.Security;
import java.security.cert.\*;

public class AuthorizedResponderNoCheck {

    static String selfSignedCertStr =
        "-----BEGIN CERTIFICATE-----\\n" +
        // copy your trust anchor certificate here, in PEM format.
        "-----END CERTIFICATE-----";

    static String trusedCertStr =
        "-----BEGIN CERTIFICATE-----\\n" +
        // copy your trusted enterprise certificate here, in PEM format.
        "-----END CERTIFICATE-----";

    static String issuerCertStr =
        "-----BEGIN CERTIFICATE-----\\n" +
        // copy the intermediate CA certificate here, in PEM format.
        "-----END CERTIFICATE-----";

    static String targetCertStr =
        "-----BEGIN CERTIFICATE-----\\n" +
        // copy the target certificate here, in PEM format.
        "-----END CERTIFICATE-----";


    private static CertPath generateCertificatePath()
            throws CertificateException {
        // generate certificate from cert strings
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        ByteArrayInputStream is =
            new ByteArrayInputStream(issuerCertStr.getBytes());
        Certificate issuerCert = cf.generateCertificate(is);

        is = new ByteArrayInputStream(targetCertStr.getBytes());
        Certificate targetCert = cf.generateCertificate(is);

        is = new ByteArrayInputStream(trusedCertStr.getBytes());
        Certificate trusedCert = cf.generateCertificate(is);

        is.close();

        // generate certification path
        List list = Arrays.asList(new Certificate[] {
                        targetCert, issuerCert, trusedCert});

        return cf.generateCertPath(list);
    }

    private static Set generateTrustAnchors()
            throws CertificateException {
        // generate certificate from cert string
        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        ByteArrayInputStream is =
                    new ByteArrayInputStream(selfSignedCertStr.getBytes());
        Certificate selfSignedCert = cf.generateCertificate(is);

        is.close();

        // generate a trust anchor
        TrustAnchor anchor =
            new TrustAnchor((X509Certificate)selfSignedCert, null);

        return Collections.singleton(anchor);
    }

    public static void main(String args[]) throws Exception {

        // if you work behind proxy, configure the proxy.
        System.setProperty("http.proxyHost", "proxyhost");
        System.setProperty("http.proxyPort", "proxyport");

        CertPath path = generateCertificatePath();
        Set anchors = generateTrustAnchors();

        PKIXParameters params = new PKIXParameters(anchors);

        // Activate certificate revocation checking
        params.setRevocationEnabled(true);

        // Activate OCSP
        Security.setProperty("ocsp.enable", "true");

        // Activate CRLDP
        System.setProperty("com.sun.security.enableCRLDP", "true");

        // Ensure that the ocsp.responderURL property is not set.
        if (Security.getProperty("ocsp.responderURL") != null) {
            throw new
                Exception("The ocsp.responderURL property must not be set");
        }

        CertPathValidator validator = CertPathValidator.getInstance("PKIX");

        validator.validate(path, params);
    }
}
About

A blog on security and networking

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today