[Pki-devel] [PATCH] 550 Refactored OCSPClient.

Endi Sukma Dewata edewata at redhat.com
Wed Feb 4 18:04:00 UTC 2015


The OCSPClient CLI has been refactored into an OCSP utility class
such that the functionality can be reused.

https://fedorahosted.org/pki/ticket/1250

-- 
Endi S. Dewata
-------------- next part --------------
From 5b05f3a976900b8ac542b3b325f99394c91d1c6f Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata at redhat.com>
Date: Thu, 29 Jan 2015 21:50:46 -0500
Subject: [PATCH] Refactored OCSPClient.

The OCSPClient CLI has been refactored into an OCSP utility class
such that the functionality can be reused.

https://fedorahosted.org/pki/ticket/1250
---
 .../src/com/netscape/cmstools/OCSPClient.java      | 412 +++++++++------------
 .../templates/pki_java_command_wrapper.in          |   3 +
 base/util/src/CMakeLists.txt                       |  17 +-
 base/util/src/com/netscape/cmsutil/ocsp/OCSP.java  | 170 +++++++++
 4 files changed, 364 insertions(+), 238 deletions(-)
 create mode 100644 base/util/src/com/netscape/cmsutil/ocsp/OCSP.java

diff --git a/base/java-tools/src/com/netscape/cmstools/OCSPClient.java b/base/java-tools/src/com/netscape/cmstools/OCSPClient.java
index ce0e853cdfeb98c4521d743e3f092205f342a2ca..f03b89a32508ce68dab47c99a96ee0506b21389b 100644
--- a/base/java-tools/src/com/netscape/cmstools/OCSPClient.java
+++ b/base/java-tools/src/com/netscape/cmstools/OCSPClient.java
@@ -17,288 +17,226 @@
 // --- END COPYRIGHT BLOCK ---
 package com.netscape.cmstools;
 
-import java.io.BufferedInputStream;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.Socket;
-import java.security.MessageDigest;
-
-import netscape.security.x509.X500Name;
-import netscape.security.x509.X509CertImpl;
-import netscape.security.x509.X509Key;
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.CommandLineParser;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.PosixParser;
 import org.mozilla.jss.CryptoManager;
-import org.mozilla.jss.asn1.INTEGER;
-import org.mozilla.jss.asn1.NULL;
-import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
-import org.mozilla.jss.asn1.OCTET_STRING;
-import org.mozilla.jss.asn1.SEQUENCE;
-import org.mozilla.jss.crypto.X509Certificate;
-import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
 
 import com.netscape.cmsutil.ocsp.BasicOCSPResponse;
-import com.netscape.cmsutil.ocsp.CertID;
 import com.netscape.cmsutil.ocsp.CertStatus;
 import com.netscape.cmsutil.ocsp.GoodInfo;
+import com.netscape.cmsutil.ocsp.OCSP;
 import com.netscape.cmsutil.ocsp.OCSPRequest;
 import com.netscape.cmsutil.ocsp.OCSPResponse;
-import com.netscape.cmsutil.ocsp.Request;
 import com.netscape.cmsutil.ocsp.ResponseBytes;
 import com.netscape.cmsutil.ocsp.ResponseData;
 import com.netscape.cmsutil.ocsp.RevokedInfo;
 import com.netscape.cmsutil.ocsp.SingleResponse;
-import com.netscape.cmsutil.ocsp.TBSRequest;
 import com.netscape.cmsutil.ocsp.UnknownInfo;
-import com.netscape.cmsutil.util.Utils;
 
 /**
- * This class implements a OCSP client for testing.
+ * This class implements an OCSP command line interface.
  *
  * @version $Revision$, $Date$
  */
 public class OCSPClient {
-    private String _host = null;
-    private int _port = 0;
-
-    public OCSPClient(String host, int port, String dbdir)
-            throws Exception {
-        _host = host;
-        _port = port;
-        CryptoManager.initialize(dbdir);
-    }
 
-    public void send(String uri, String nickname, int serialno, String output)
-            throws Exception {
-        CryptoManager manager = CryptoManager.getInstance();
-        X509Certificate caCert = manager.findCertByNickname(nickname);
-        OCSPRequest request = getOCSPRequest(caCert, serialno);
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        request.encode(os);
-        byte request_data[] = os.toByteArray();
-        sendOCSPRequest(uri, _host, _port, request_data, output);
+    public static Options createOptions() throws UnknownHostException {
+
+        Options options = new Options();
+
+        Option option = new Option("d", true, "Security database location (default: current directory)");
+        option.setArgName("database");
+        options.addOption(option);
+
+        option = new Option("h", true, "OCSP server hostname (default: "+ InetAddress.getLocalHost().getCanonicalHostName() + ")");
+        option.setArgName("hostname");
+        options.addOption(option);
+
+        option = new Option("p", true, "OCSP server port number (default: 8080)");
+        option.setArgName("port");
+        options.addOption(option);
+
+        option = new Option("t", true, "OCSP service path (default: /ocsp/ee/ocsp)");
+        option.setArgName("path");
+        options.addOption(option);
+
+        option = new Option("c", true, "CA certificate nickname (default: CA Signing Certificate)");
+        option.setArgName("nickname");
+        options.addOption(option);
+
+        option = new Option("n", true, "Number of submission times (default: 1)");
+        option.setArgName("times");
+        options.addOption(option);
+
+        option = new Option(null, "serial", true, "Serial number of certificate to be checked");
+        option.setArgName("serial");
+        options.addOption(option);
+
+        option = new Option(null, "input", true, "Input file containing DER-encoded OCSP request");
+        option.setArgName("input");
+        options.addOption(option);
+
+        option = new Option(null, "output", true, "Output file to store DER-encoded OCSP response");
+        option.setArgName("output");
+        options.addOption(option);
+
+        options.addOption("v", "verbose", false, "Run in verbose mode.");
+        options.addOption(null, "help", false, "Show help message.");
+
+        return options;
     }
 
-    public void sendRequestData(String uri, String nickname, byte request_data[], String output)
-            throws Exception {
-        sendOCSPRequest(uri, _host, _port, request_data, output);
+    public static void printHelp() throws Exception {
+        System.out.println("Usage: OCSPClient [OPTIONS]");
+        System.out.println();
+        System.out.println("Options:");
+        System.out.println("  -d <database>        Security database location (default: current directory)");
+        System.out.println("  -h <hostname>        OCSP server hostname (default: "+ InetAddress.getLocalHost().getCanonicalHostName() + ")");
+        System.out.println("  -p <port>            OCSP server port number (default: 8080)");
+        System.out.println("  -t <path>            OCSP service path (default: /ocsp/ee/ocsp)");
+        System.out.println("  -c <nickname>        CA certificate nickname (defaut: CA Signing Certificate)");
+        System.out.println("  -n <times>           Number of submission times (default: 1)");
+        System.out.println();
+        System.out.println("  --serial <serial>    Serial number of certificate to be checked");
+        System.out.println("  --input <input>      Input file containing DER-encoded OCSP request");
+        System.out.println("  --output <output>    Output file to store DER-encoded OCSP response");
+        System.out.println();
+        System.out.println("  -v, --verbose        Run in verbose mode.");
+        System.out.println("      --help           Show help message.");
     }
 
-    public OCSPRequest getOCSPRequest(X509Certificate caCert, int serialno)
-             throws Exception {
-        MessageDigest md = MessageDigest.getInstance("SHA");
-
-        // calculate issuer key hash
-        X509CertImpl x509Cert = new X509CertImpl(caCert.getEncoded());
-        X509Key x509key = (X509Key) x509Cert.getPublicKey();
-        byte issuerKeyHash[] = md.digest(x509key.getKey());
-
-        // calculate name hash
-        X500Name name = (X500Name) x509Cert.getSubjectDN();
-        byte issuerNameHash[] = md.digest(name.getEncoded());
-        // constructing the OCSP request
-        CertID certid = new CertID(
-                new AlgorithmIdentifier(
-                        new OBJECT_IDENTIFIER("1.3.14.3.2.26"), new NULL()),
-                new OCTET_STRING(issuerNameHash),
-                new OCTET_STRING(issuerKeyHash),
-                new INTEGER(serialno));
-        Request request = new Request(certid, null);
-        SEQUENCE requestList = new SEQUENCE();
-        requestList.addElement(request);
-        TBSRequest tbsRequest = new TBSRequest(null, null, requestList, null);
-        return new OCSPRequest(tbsRequest, null);
+    public static void printError(String message) {
+        System.err.println("ERROR: " + message);
+        System.err.println("Try 'OCSPClient --help' for more information.");
     }
 
-    public void sendOCSPRequest(String uri, String host, int port,
-            byte request_data[], String output) throws Exception {
-        Socket socket = null;
-        DataOutputStream dos = null;
-        InputStream iiss = null;
-        FileOutputStream fof = null;
-        BufferedInputStream fis = null;
+    public static void main(String args[]) throws Exception {
+
+        Options options = createOptions();
+        CommandLine cmd = null;
+
         try {
-            socket = new Socket(host, port);
-
-            // send request
-            System.out.println("URI: " + uri);
-
-            dos = new DataOutputStream(socket.getOutputStream());
-            dos.writeBytes("POST " + uri + " HTTP/1.0\r\n");
-            dos.writeBytes("Content-length: " + request_data.length + "\r\n");
-            dos.writeBytes("\r\n");
-            dos.write(request_data);
-            dos.flush();
-
-            System.out.println("Data Length: " + request_data.length);
-            System.out.println("Data: " + Utils.base64encode(request_data));
-
-            iiss = socket.getInputStream();
-            fof = new FileOutputStream(output);
-            boolean startSaving = false;
-            int sum = 0;
-            boolean hack = false;
-            try {
-                while (true) {
-                    int r = iiss.read();
-                    if (r == -1)
-                        break;
-                    if (r == 10) {
-                        sum++;
-                    }
-                    if (sum == 6) {
-                        startSaving = true;
-                        continue;
-                    }
-                    if (startSaving) {
-                        if (hack) {
-                            fof.write(r);
-                        }
-                        if (hack == false) {
-                            hack = true;
-                        }
-                    }
-                } // while
-            } catch (IOException e) {
-            }
-            // parse OCSPResponse
-            fis = new BufferedInputStream(
-                    new FileInputStream(output));
-            OCSPResponse resp = (OCSPResponse)
-                    OCSPResponse.getTemplate().decode(fis);
-            ResponseBytes bytes = resp.getResponseBytes();
-            BasicOCSPResponse basic = (BasicOCSPResponse)
-                    BasicOCSPResponse.getTemplate().decode(
-                            new ByteArrayInputStream(bytes.getResponse().toByteArray()));
-            ResponseData rd = basic.getResponseData();
-            for (int i = 0; i < rd.getResponseCount(); i++) {
-                SingleResponse rd1 = rd.getResponseAt(i);
-                if (rd1 == null) {
-                    throw new Exception("No OCSP Response data.");
-                }
-                System.out.println("CertID.serialNumber=" +
-                        rd1.getCertID().getSerialNumber());
-                CertStatus status1 = rd1.getCertStatus();
-                if (status1 instanceof GoodInfo) {
-                    System.out.println("CertStatus=Good");
-                }
-                if (status1 instanceof UnknownInfo) {
-                    System.out.println("CertStatus=Unknown");
-                }
-                if (status1 instanceof RevokedInfo) {
-                    System.out.println("CertStatus=Revoked");
-                }
-            }
-        } finally {
-            if (socket != null)
-                socket.close();
-            if (dos != null)
-                dos.close();
-            if (iiss != null)
-                iiss.close();
-            if (fof != null)
-                fof.close();
-            if (fis != null)
-                fis.close();
+            CommandLineParser parser = new PosixParser();
+            cmd = parser.parse(options, args);
 
+        } catch (Exception e) {
+            printError(e.getMessage());
+            System.exit(1);
         }
-    }
-
-    public static void printUsage() {
-        System.out.println("Usage: OCSPClient " +
-                "<host> <port> <dbdir> <nickname> <serialno_or_filename> <output> <times>");
-        System.out.println("  <host>     = OCSP server hostname");
-        System.out.println("  <port>     = OCSP server port number");
-        System.out.println("  <dbdir>    = Certificate Database Directory");
-        System.out.println("  <nickname> = Nickname of CA Certificate");
-        System.out.println(
-                "  <serialno_or_filename> = Serial Number Being Checked, Or Name of file that contains the request");
-        System.out.println("  <output>   = Filename of Response in DER encoding");
-        System.out.println("  <times>    = Submit Request Multiple Times");
-        System.out.println("  [<uri>]    = OCSP Service URI (i.e. /ocsp/ee/ocsp)");
-    }
 
-    public static void main(String args[]) {
-        if (args.length != 7 && args.length != 8) {
-            System.out.println("ERROR: Invalid number of arguments - got "
-                              + args.length + " expected 7!");
-            for (int i = 0; i < args.length; i++) {
-                System.out.println("arg[" + i + "]=" + args[i]);
-            }
-            printUsage();
+        if (cmd.hasOption("help")) {
+            printHelp();
             System.exit(0);
         }
 
-        String host = args[0];
-        int port = -1;
-        try {
-            port = Integer.parseInt(args[1]);
-        } catch (Exception e) {
-            System.out.println("Error: Invalid Port Number");
-            printUsage();
-            System.exit(0);
+        boolean verbose = cmd.hasOption("v");
+
+        String databaseDir = cmd.getOptionValue("d", ".");
+        String hostname = cmd.getOptionValue("h", InetAddress.getLocalHost().getCanonicalHostName());
+        int port = Integer.parseInt(cmd.getOptionValue("p", "8080"));
+        String path = cmd.getOptionValue("t", "/ocsp/ee/ocsp");
+        String caNickname = cmd.getOptionValue("c", "CA Signing Certificate");
+        int times = Integer.parseInt(cmd.getOptionValue("n", "1"));
+
+        String input = cmd.getOptionValue("input");
+        String serial = cmd.getOptionValue("serial");
+        String output = cmd.getOptionValue("output");
+
+        if (times < 1) {
+            printError("Invalid number of submission times");
+            System.exit(1);
         }
-        String dbdir = args[2];
-        String nickname = args[3];
-        int serialno = -1;
-        byte data[] = null;
+
         try {
-            serialno = Integer.parseInt(args[4]);
-        } catch (Exception e) {
-            FileInputStream fis = null;
-            try {
-                System.out.println("Warning: Serial Number not found. It may be a filename.");
-                /* it could be a file name */
-                fis = new FileInputStream(args[4]);
-                System.out.println("File Size: " + fis.available());
-                data = new byte[fis.available()];
-                fis.read(data);
-            } catch (Exception e1) {
-                System.out.println("Error: Invalid Serial Number or File Name");
-                printUsage();
-                System.exit(0);
-            } finally {
-                if (fis != null) {
-                    try {
-                        fis.close();
-                    } catch (IOException e1) {
-                        e1.printStackTrace();
-                    }
+            if (verbose) System.out.println("Initializing security database");
+            CryptoManager.initialize(databaseDir);
+
+            String url = "http://" + hostname + ":" + port + path;
+
+            OCSP ocsp = new OCSP();
+            ocsp.setVerbose(verbose);
+
+            OCSPRequest request;
+            if (serial != null) {
+                if (verbose) System.out.println("Creating request for serial number " + serial);
+
+                BigInteger serialNumber = new BigInteger(serial);
+                request = ocsp.createRequest(caNickname, serialNumber);
+
+            } else if (input != null) {
+                if (verbose) System.out.println("Loading request from " + input);
+
+                try (FileInputStream in = new FileInputStream(input)) {
+                    byte[] data = new byte[in.available()];
+                    in.read(data);
+                    request = ocsp.createRequest(data);
                 }
+
+            } else {
+                throw new Exception("Missing serial number of input file.");
             }
-        }
-        String output = args[5];
-        int times = 1;
-        try {
-            times = Integer.parseInt(args[6]);
-        } catch (Exception e) {
-            System.out.println("Error: Invalid Times");
-            printUsage();
-            System.exit(0);
-        }
-        String uri = "/ocsp/ee/ocsp";
-        if (args.length > 7) {
-            uri = args[7];
-        }
-        try {
-            OCSPClient client =
-                    new OCSPClient(host, port, dbdir);
+
+            OCSPResponse response = null;
             for (int i = 0; i < times; i++) {
-                if (data != null) {
-                    client.sendRequestData(uri, nickname, data, output);
-                } else {
-                    client.send(uri, nickname, serialno, output);
+
+                if (verbose) System.out.println("Submitting OCSP request");
+                response = ocsp.submitRequest(url, request);
+
+                ResponseBytes bytes = response.getResponseBytes();
+                BasicOCSPResponse basic = (BasicOCSPResponse)BasicOCSPResponse.getTemplate().decode(
+                        new ByteArrayInputStream(bytes.getResponse().toByteArray()));
+
+                ResponseData rd = basic.getResponseData();
+                for (int j = 0; j < rd.getResponseCount(); j++) {
+                    SingleResponse sr = rd.getResponseAt(j);
+
+                    if (sr == null) {
+                        throw new Exception("No OCSP Response data.");
+                    }
+
+                    System.out.println("CertID.serialNumber=" +
+                            sr.getCertID().getSerialNumber());
+
+                    CertStatus status = sr.getCertStatus();
+                    if (status instanceof GoodInfo) {
+                        System.out.println("CertStatus=Good");
+
+                    } else if (status instanceof UnknownInfo) {
+                        System.out.println("CertStatus=Unknown");
+
+                    } else if (status instanceof RevokedInfo) {
+                        System.out.println("CertStatus=Revoked");
+                    }
                 }
             }
-            System.out.println("Success: Output " + output);
+
+            if (output != null) {
+                if (verbose) System.out.println("Storing response into " + output);
+
+                try (FileOutputStream out = new FileOutputStream(output)) {
+                    ByteArrayOutputStream os = new ByteArrayOutputStream();
+                    response.encode(os);
+                    out.write(os.toByteArray());
+                }
+
+                System.out.println("Success: Output " + output);
+            }
+
         } catch (Exception e) {
-            System.out.println("Error: " + e.toString());
-            printUsage();
-            System.exit(0);
+            if (verbose) e.printStackTrace();
+            printError(e.getMessage());
+            System.exit(1);
         }
     }
 }
diff --git a/base/java-tools/templates/pki_java_command_wrapper.in b/base/java-tools/templates/pki_java_command_wrapper.in
index 4474084cfe519d0adb1e1eb42ce0ddf323509666..09e059edbbca5d90c1a89261d1f300c87d9c05b4 100644
--- a/base/java-tools/templates/pki_java_command_wrapper.in
+++ b/base/java-tools/templates/pki_java_command_wrapper.in
@@ -134,6 +134,9 @@ CP=${JNI_JAR_DIR}/jss4.jar
 CP=/usr/share/java/commons-cli.jar:${CP}
 CP=/usr/share/java/commons-codec.jar:${CP}
 CP=/usr/share/java/commons-io.jar:${CP}
+CP=/usr/share/java/commons-logging.jar:${CP}
+CP=/usr/share/java/httpcomponents/httpclient.jar:${CP}
+CP=/usr/share/java/httpcomponents/httpcore.jar:${CP}
 CP=/usr/share/java/ldapjdk.jar:${CP}
 CP=/usr/share/java/${PRODUCT}/pki-nsutil.jar:${CP}
 CP=/usr/share/java/${PRODUCT}/pki-cmsutil.jar:${CP}
diff --git a/base/util/src/CMakeLists.txt b/base/util/src/CMakeLists.txt
index 35b8e0a5b55f903876c2f48b1d23feef43ea1bdf..efef8af536bad8a2410c7b64abbfa8868e501612 100644
--- a/base/util/src/CMakeLists.txt
+++ b/base/util/src/CMakeLists.txt
@@ -30,6 +30,20 @@ find_file(COMMONS_CODEC_JAR
         /usr/share/java
 )
 
+find_file(HTTPCLIENT_JAR
+    NAMES
+        httpclient.jar
+    PATHS
+        /usr/share/java/httpcomponents
+)
+
+find_file(HTTPCORE_JAR
+    NAMES
+        httpcore.jar
+    PATHS
+        /usr/share/java/httpcomponents
+)
+
 find_file(XALAN_JAR
     NAMES
         xalan-j2.jar
@@ -92,7 +106,8 @@ javac(pki-cmsutil-classes
     SOURCES
         com/netscape/cmsutil/*.java
     CLASSPATH
-        ${APACHE_COMMONS_LANG_JAR} ${LDAPJDK_JAR} ${XALAN_JAR} ${XERCES_JAR}
+        ${APACHE_COMMONS_LANG_JAR} ${HTTPCORE_JAR} ${HTTPCLIENT_JAR}
+        ${LDAPJDK_JAR} ${XALAN_JAR} ${XERCES_JAR}
         ${JSS_JAR} ${COMMONS_CODEC_JAR}
     OUTPUT_DIR
         ${CMAKE_BINARY_DIR}/classes
diff --git a/base/util/src/com/netscape/cmsutil/ocsp/OCSP.java b/base/util/src/com/netscape/cmsutil/ocsp/OCSP.java
new file mode 100644
index 0000000000000000000000000000000000000000..64614ceacf7473e9bcc66b1e76c47df42f993dab
--- /dev/null
+++ b/base/util/src/com/netscape/cmsutil/ocsp/OCSP.java
@@ -0,0 +1,170 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmsutil.ocsp;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.MessageDigest;
+
+import netscape.security.x509.X500Name;
+import netscape.security.x509.X509CertImpl;
+import netscape.security.x509.X509Key;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.ContentType;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.util.EntityUtils;
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.asn1.INTEGER;
+import org.mozilla.jss.asn1.NULL;
+import org.mozilla.jss.asn1.OBJECT_IDENTIFIER;
+import org.mozilla.jss.asn1.OCTET_STRING;
+import org.mozilla.jss.asn1.SEQUENCE;
+import org.mozilla.jss.crypto.X509Certificate;
+import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier;
+
+import com.netscape.cmsutil.util.Utils;
+
+/**
+ * This class implements an OCSP utility.
+ *
+ * @version $Revision$, $Date$
+ */
+public class OCSP {
+
+    public boolean verbose;
+
+    public OCSP() {
+    }
+
+    public void setVerbose(boolean verbose) {
+        this.verbose = verbose;
+    }
+
+    public boolean isVerbose() {
+        return verbose;
+    }
+
+    /**
+     * Create OCSP request from binary data.
+     */
+    public OCSPRequest createRequest(byte[] data) throws Exception {
+        OCSPRequest.Template template = new OCSPRequest.Template();
+        return (OCSPRequest)template.decode(new ByteArrayInputStream(data));
+    }
+
+    /**
+     * Create OCSP request from nickname of CA certificate and serial number
+     * of certificate to be checked.
+     */
+    public OCSPRequest createRequest(String caNickname, BigInteger serialNumber)
+             throws Exception {
+
+        CryptoManager manager = CryptoManager.getInstance();
+        X509Certificate caCert = manager.findCertByNickname(caNickname);
+        X509CertImpl cert = new X509CertImpl(caCert.getEncoded());
+
+        X500Name issuerName = (X500Name)cert.getSubjectDN();
+        X509Key issuerKey = (X509Key)cert.getPublicKey();
+
+        return createRequest(issuerName, issuerKey, serialNumber);
+    }
+
+    /**
+     * Create OCSP request from issuer name, issuer public key, and serial number
+     * of certificate to be checked.
+     */
+    public OCSPRequest createRequest(X500Name issuerName, X509Key issuerKey, BigInteger serialNumber)
+            throws Exception {
+
+        MessageDigest md = MessageDigest.getInstance("SHA");
+
+        // calculate hashes
+        byte issuerNameHash[] = md.digest(issuerName.getEncoded());
+        byte issuerKeyHash[] = md.digest(issuerKey.getKey());
+
+        // constructing the OCSP request
+        CertID certID = new CertID(
+                new AlgorithmIdentifier(
+                        new OBJECT_IDENTIFIER("1.3.14.3.2.26"), new NULL()),
+                new OCTET_STRING(issuerNameHash),
+                new OCTET_STRING(issuerKeyHash),
+                new INTEGER(serialNumber));
+
+        Request request = new Request(certID, null);
+
+        SEQUENCE requestList = new SEQUENCE();
+        requestList.addElement(request);
+
+        TBSRequest tbsRequest = new TBSRequest(null, null, requestList, null);
+
+        return new OCSPRequest(tbsRequest, null);
+    }
+
+    public OCSPResponse submitRequest(String url, OCSPRequest request) throws Exception {
+
+        if (verbose) System.out.println("URL: " + url);
+
+        HttpClient httpClient = new DefaultHttpClient();
+
+        try {
+            ByteArrayOutputStream os = new ByteArrayOutputStream();
+            request.encode(os);
+            byte[] requestData = os.toByteArray();
+
+            if (verbose) {
+                System.out.println("Data Length: " + requestData.length);
+                System.out.println("Data: " + Utils.base64encode(requestData));
+            }
+
+            ByteArrayEntity requestEntity = new ByteArrayEntity(requestData);
+            requestEntity.setContentType(ContentType.APPLICATION_OCTET_STREAM.getMimeType());
+
+            HttpPost httpPost = new HttpPost(url);
+            httpPost.setEntity(requestEntity);
+
+            HttpResponse response = httpClient.execute(httpPost);
+            HttpEntity responseEntity = response.getEntity();
+
+            try (InputStream is = responseEntity.getContent()) {
+                ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+
+                int b;
+                while ((b = is.read()) != -1) {
+                    buffer.write(b);
+                }
+
+                // construct OCSP response
+                return (OCSPResponse)OCSPResponse.getTemplate().decode(
+                        new ByteArrayInputStream(buffer.toByteArray()));
+
+            } finally {
+                EntityUtils.consume(responseEntity);
+            }
+
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+}
-- 
1.8.4.2



More information about the Pki-devel mailing list