[Pki-devel] [PATCH] 524 Added client-cert-request CLI.

Endi Sukma Dewata edewata at redhat.com
Wed Sep 10 00:32:21 UTC 2014


A new CLI has been added to simplify the process to request
a user certificate for client certificate authentication.

Ticket #1148

-- 
Endi S. Dewata
-------------- next part --------------
From 3603670a8dea1de69f4cf6a154159eb33761dfed Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata at redhat.com>
Date: Fri, 5 Sep 2014 16:40:47 -0400
Subject: [PATCH] Added client-cert-request CLI.

A new CLI has been added to simplify the process to request
a user certificate for client certificate authentication.

Ticket #1148
---
 base/java-tools/bin/pki                            |   1 +
 base/java-tools/man/man1/pki-client.1              |  10 ++
 base/java-tools/src/CMakeLists.txt                 |  10 +-
 .../src/com/netscape/cmstools/cert/CertCLI.java    |  13 ++
 .../cmstools/cert/CertRequestSubmitCLI.java        |  17 +-
 .../src/com/netscape/cmstools/cli/MainCLI.java     |   6 +-
 .../com/netscape/cmstools/client/ClientCLI.java    |   1 +
 .../cmstools/client/ClientCertRequestCLI.java      | 191 +++++++++++++++++++++
 8 files changed, 230 insertions(+), 19 deletions(-)
 create mode 100644 base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java

diff --git a/base/java-tools/bin/pki b/base/java-tools/bin/pki
index a9f9e5c1e0e74be21b90a9b8369cf97428994382..9fd757844c7f0205ec98d0ca88a7a5a013d9d63d 100644
--- a/base/java-tools/bin/pki
+++ b/base/java-tools/bin/pki
@@ -79,6 +79,7 @@ def run_java_cli(args):
         '/usr/share/java/jackson-jaxrs-providers/jackson-jaxrs-base.jar',
         '/usr/share/java/jackson-jaxrs-providers/jackson-jaxrs-json-provider.jar',
         '/usr/share/java/jaxb-api.jar',
+        '/usr/share/java/ldapjdk.jar',
         '/usr/share/java/servlet.jar',
         resteasy_lib + '/jaxrs-api.jar',
         resteasy_lib + '/resteasy-atom-provider.jar',
diff --git a/base/java-tools/man/man1/pki-client.1 b/base/java-tools/man/man1/pki-client.1
index 9b92c66d6ab7d750d723f057ffe1e8350e09dfcc..8978c8c44331c2bff38d6b22f4d198310d8353a6 100644
--- a/base/java-tools/man/man1/pki-client.1
+++ b/base/java-tools/man/man1/pki-client.1
@@ -21,6 +21,7 @@ pki-client \- Command-Line Interface for managing the security database on Certi
 \fBpki\fR [CLI options] \fBclient\fR
 \fBpki\fR [CLI options] \fBclient-init\fR [command options]
 \fBpki\fR [CLI options] \fBclient-cert-find\fR [command options]
+\fBpki\fR [CLI options] \fBclient-cert-request\fR <subject DN> [command options]
 \fBpki\fR [CLI options] \fBclient-cert-import\fR [command options]
 \fBpki\fR [CLI options] \fBclient-cert-del\fR [command options]
 .fi
@@ -44,6 +45,11 @@ This command is to create a new security database for the client.
 This command is to list certificates in the client security database.
 .RE
 .PP
+\fBpki\fR [CLI options] \fBclient-cert-request\fR <subject DN> [command options]
+.RS 4
+This command is to generate and submit a certificate request.
+.RE
+.PP
 \fBpki\fR [CLI options] \fBclient-cert-import\fR [command options]
 .RS 4
 This command is to view a certificate in the client security database.
@@ -68,6 +74,10 @@ To view certificates in the security database:
 
 .B pki -d <security database location> -c <security database password> client-cert-find
 
+To request a certificate:
+
+.B pki -d <security database location> -c <security database password> client-cert-request <subject DN>
+
 To import a certificate into the security database:
 
 .B pki -d <security database location> -c <security database password> -n <certificate nickname> client-cert-import --cert <certificate file>
diff --git a/base/java-tools/src/CMakeLists.txt b/base/java-tools/src/CMakeLists.txt
index 7c0b695282b4a784a677a4d33b0f9ee3ce6a06c5..ade1ea2b15fa755ac8ddfdbdc022bafeb63bf967 100644
--- a/base/java-tools/src/CMakeLists.txt
+++ b/base/java-tools/src/CMakeLists.txt
@@ -8,6 +8,14 @@ find_file(JSS_JAR
         /usr/share/java
 )
 
+find_file(LDAPJDK_JAR
+    NAMES
+        ldapjdk.jar
+    PATHS
+        ${JAVA_LIB_INSTALL_DIR}
+        /usr/share/java
+)
+
 find_file(APACHE_COMMONS_CLI_JAR
     NAMES
         apache-commons-cli.jar
@@ -94,7 +102,7 @@ javac(pki-tools-classes
     CLASSPATH
         ${PKI_NSUTIL_JAR} ${PKI_CMSUTIL_JAR} ${PKI_CERTSRV_JAR}
         ${XALAN_JAR} ${XERCES_JAR}
-        ${JSS_JAR} ${COMMONS_CODEC_JAR} ${COMMONS_IO_JAR}
+        ${JSS_JAR} ${LDAPJDK_JAR} ${COMMONS_CODEC_JAR} ${COMMONS_IO_JAR}
         ${APACHE_COMMONS_CLI_JAR} ${APACHE_COMMONS_LANG_JAR}
         ${JAXRS_API_JAR} ${RESTEASY_JAXRS_JAR} ${RESTEASY_ATOM_PROVIDER_JAR}
         ${HTTPCLIENT_JAR} ${HTTPCORE_JAR}
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
index 30a808b0675601be57ccc79215c1bc8aef35b36b..9ffa3ad4501bed4fc6102e5b80ab11113883d74e 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertCLI.java
@@ -26,6 +26,7 @@ import com.netscape.certsrv.cert.CertClient;
 import com.netscape.certsrv.cert.CertData;
 import com.netscape.certsrv.cert.CertDataInfo;
 import com.netscape.certsrv.cert.CertRequestInfo;
+import com.netscape.certsrv.cert.CertRequestInfos;
 import com.netscape.certsrv.cert.CertReviewResponse;
 import com.netscape.cmstools.cli.CLI;
 import com.netscape.cmstools.cli.MainCLI;
@@ -158,6 +159,18 @@ public class CertCLI extends CLI {
         }
     }
 
+    public static void printCertRequestInfos(CertRequestInfos infos) {
+        boolean first = true;
+        for (CertRequestInfo info : infos.getEntries()) {
+            if (first) {
+                first = false;
+            } else {
+                System.out.println();
+            }
+            printCertRequestInfo(info);
+        }
+    }
+
     public static void printCertRequestInfo(CertRequestInfo info) {
         System.out.println("  Request ID: " + info.getRequestId());
         System.out.println("  Type: " + info.getRequestType());
diff --git a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java
index fe2b806b0c324a2790093702344a0f8ca00b5995..608490bb73d7df482d87e67e9c15322ddc2e5f5a 100644
--- a/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cert/CertRequestSubmitCLI.java
@@ -3,7 +3,6 @@ package com.netscape.cmstools.cert;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Scanner;
 
 import javax.xml.bind.JAXBException;
@@ -12,7 +11,6 @@ import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.ParseException;
 
 import com.netscape.certsrv.cert.CertEnrollmentRequest;
-import com.netscape.certsrv.cert.CertRequestInfo;
 import com.netscape.certsrv.cert.CertRequestInfos;
 import com.netscape.cmstools.cli.CLI;
 import com.netscape.cmstools.cli.MainCLI;
@@ -61,7 +59,7 @@ public class CertRequestSubmitCLI extends CLI {
             CertEnrollmentRequest erd = getEnrollmentRequest(cmdArgs[0]);
             CertRequestInfos cri = certCLI.certClient.enrollRequest(erd);
             MainCLI.printMessage("Submitted certificate request");
-            printRequestInformation(cri);
+            CertCLI.printCertRequestInfos(cri);
 
         } catch (FileNotFoundException e) {
             System.err.println("Error: " + e.getMessage());
@@ -79,17 +77,4 @@ public class CertRequestSubmitCLI extends CLI {
             return CertEnrollmentRequest.fromXML(xml);
         }
     }
-
-    private void printRequestInformation(CertRequestInfos cri) {
-        Collection<CertRequestInfo> allRequests = cri.getEntries();
-        boolean first = true;
-        for (CertRequestInfo x : allRequests) {
-            if (first) {
-                first = false;
-            } else {
-                System.out.println();
-            }
-            CertCLI.printCertRequestInfo(x);
-        }
-    }
 }
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index e7097e8cae952fac075cb8ac9386feb5d74be789..066a7d580553836df62f68188929afc4de20d536 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -489,10 +489,12 @@ public class MainCLI extends CLI {
             System.out.println();
         }
 
-        // Do not call CryptoManager.initialize() on client-init and client-cert-import
+        // Do not call CryptoManager.initialize() on some commands
         // because otherwise the database will be locked.
         String command = cmdArgs[0];
-        if (!command.equals("client-init") && !command.equals("client-cert-import")) {
+        if (!command.equals("client-init") &&
+                !command.equals("client-cert-import") &&
+                !command.equals("client-cert-request")) {
             init();
         }
 
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
index 11ede895f727977b30381344146c2e55b3989a92..443d48bdfbe87253bb9f64e7eae5302c4dcce85c 100644
--- a/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCLI.java
@@ -36,6 +36,7 @@ public class ClientCLI extends CLI {
         addModule(new ClientCertFindCLI(this));
         addModule(new ClientCertImportCLI(this));
         addModule(new ClientCertRemoveCLI(this));
+        addModule(new ClientCertRequestCLI(this));
     }
 
     public String getFullName() {
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..f7d60f1f03ea45288473f88b6dcf369bcfd68629
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
@@ -0,0 +1,191 @@
+// --- 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) 2014 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cmstools.client;
+
+import java.io.File;
+import java.util.Vector;
+
+import netscape.ldap.util.DN;
+import netscape.ldap.util.RDN;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.io.FileUtils;
+
+import com.netscape.certsrv.cert.CertClient;
+import com.netscape.certsrv.cert.CertEnrollmentRequest;
+import com.netscape.certsrv.cert.CertRequestInfos;
+import com.netscape.certsrv.profile.ProfileAttribute;
+import com.netscape.certsrv.profile.ProfileInput;
+import com.netscape.cmstools.cert.CertCLI;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class ClientCertRequestCLI extends CLI {
+
+    public ClientCLI clientCLI;
+
+    public ClientCertRequestCLI(ClientCLI clientCLI) {
+        super("cert-request", "Request a certificate", clientCLI);
+        this.clientCLI = clientCLI;
+
+        createOptions();
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " <Subject DN> [OPTIONS...]", options);
+    }
+
+    public void createOptions() {
+        Option option = new Option(null, "algorithm", true, "Algorithm (default: rsa)");
+        option.setArgName("algorithm");
+        options.addOption(option);
+
+        option = new Option(null, "length", true, "RSA key length (default: 1024)");
+        option.setArgName("length");
+        options.addOption(option);
+
+        option = new Option(null, "profile", true, "Certificate profile (default: caUserCert)");
+        option.setArgName("profile");
+        options.addOption(option);
+
+        options.addOption(null, "help", false, "Help");
+    }
+
+    public void execute(String[] args) throws Exception {
+        CommandLine cmd = null;
+
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (Exception e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(-1);
+        }
+
+        String[] cmdArgs = cmd.getArgs();
+
+        if (cmd.hasOption("help")) {
+            printHelp();
+            System.exit(0);
+        }
+
+        if (cmdArgs.length > 1) {
+            System.err.println("Error: Too many arguments specified.");
+            printHelp();
+            System.exit(-1);
+        }
+
+        if (cmdArgs.length < 1) {
+            System.err.println("Error: Missing subject DN.");
+            printHelp();
+            System.exit(-1);
+        }
+
+        String subjectDN = cmdArgs[0];
+
+        String algorithm = cmd.getOptionValue("algorithm", "rsa");
+        String length = cmd.getOptionValue("length", "1024");
+        String profileID = cmd.getOptionValue("profile", "caUserCert");
+        String requestType = "pkcs10";
+
+        MainCLI mainCLI = (MainCLI)parent.getParent();
+        File certDatabase = mainCLI.certDatabase;
+
+        String password = mainCLI.config.getCertPassword();
+        if (password == null) {
+            System.err.println("Error: Missing security database password.");
+            System.exit(-1);
+        }
+
+        File csrFile = File.createTempFile("pki-client-cert-request-", ".csr", certDatabase);
+        csrFile.deleteOnExit();
+
+        String[] commands = {
+                "/usr/bin/PKCS10Client",
+                "-d", certDatabase.getAbsolutePath(),
+                "-p", password,
+                "-a", algorithm,
+                "-l", length,
+                "-o", csrFile.getAbsolutePath(),
+                "-n", subjectDN
+        };
+
+        Runtime rt = Runtime.getRuntime();
+        Process p = rt.exec(commands);
+
+        int rc = p.waitFor();
+        if (rc != 0) {
+            MainCLI.printMessage("CSR generation failed");
+            return;
+        }
+
+        if (verbose) {
+            System.out.println("CSR generated: " + csrFile);
+        }
+
+        String csr = FileUtils.readFileToString(csrFile);
+
+        // late initialization
+        mainCLI.init();
+        client = mainCLI.getClient();
+
+        CertClient certClient = new CertClient(client, "ca");
+
+        if (verbose) {
+            System.out.println("Retrieving " + profileID + " profile.");
+        }
+
+        CertEnrollmentRequest request = certClient.getEnrollmentTemplate(profileID);
+
+        ProfileInput kg = request.getInput("Key Generation");
+
+        ProfileAttribute typeAttr = kg.getAttribute("cert_request_type");
+        typeAttr.setValue(requestType);
+
+        ProfileAttribute csrAttr = kg.getAttribute("cert_request");
+        csrAttr.setValue(csr);
+
+        ProfileInput sn = request.getInput("Subject Name");
+
+        DN dn = new DN(subjectDN);
+        Vector<?> rdns = dn.getRDNs();
+
+        for (int i=0; i< rdns.size(); i++) {
+            RDN rdn = (RDN)rdns.elementAt(i);
+            String type = rdn.getTypes()[0].toLowerCase();
+            String value = rdn.getValues()[0];
+            ProfileAttribute uidAttr = sn.getAttribute("sn_" + type);
+            uidAttr.setValue(value);
+        }
+
+        if (verbose) {
+            System.out.println("Sending certificate request.");
+        }
+
+        CertRequestInfos infos = certClient.enrollRequest(request);
+
+        MainCLI.printMessage("Submitted certificate request");
+        CertCLI.printCertRequestInfos(infos);
+    }
+}
-- 
1.8.4.2



More information about the Pki-devel mailing list