[Pki-devel] [PATCH] 548 Updated CRMFPopClient parameter handling.

Endi Sukma Dewata edewata at redhat.com
Thu Jan 29 18:18:49 UTC 2015


The CRMFPopClient has been modified to use Apache Commons CLI
library to handle the parameters. The help message has been
rewritten to make it more readable. The submitRequest() will
now display the error reason.

The options in ClientCertRequestCLI have been simplified. A new
option was added to generate CRMF request without POP.

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

-- 
Endi S. Dewata
-------------- next part --------------
From 03c82cbf2a7eacfa02f3e6f74fa3a26e70965159 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata at redhat.com>
Date: Thu, 29 Jan 2015 03:08:25 -0500
Subject: [PATCH] Updated CRMFPopClient parameter handling.

The CRMFPopClient has been modified to use Apache Commons CLI
library to handle the parameters. The help message has been
rewritten to make it more readable. The submitRequest() will
now display the error reason.

The options in ClientCertRequestCLI have been simplified. A new
option was added to generate CRMF request without POP.

https://fedorahosted.org/pki/ticket/1074
---
 .../src/com/netscape/cmstools/CRMFPopClient.java   | 447 ++++++++++++---------
 .../src/com/netscape/cmstools/cli/MainCLI.java     |   6 +-
 .../cmstools/client/ClientCertRequestCLI.java      |  75 ++--
 .../templates/pki_java_command_wrapper.in          |   1 +
 4 files changed, 312 insertions(+), 217 deletions(-)

diff --git a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
index dd20cba928ee8659cbfe749c4a30b3ab7c458114..ec4570b1f65928e31d59ee3bd711e4b26639a8b0 100644
--- a/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
+++ b/base/java-tools/src/com/netscape/cmstools/CRMFPopClient.java
@@ -34,6 +34,11 @@ import java.security.PublicKey;
 
 import netscape.security.x509.X500Name;
 
+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.apache.commons.io.FileUtils;
 import org.mozilla.jss.CryptoManager;
 import org.mozilla.jss.asn1.ASN1Util;
@@ -94,187 +99,251 @@ public class CRMFPopClient {
 
     public boolean verbose;
 
-    private static void usage() {
-
-        System.out.println("Usage: CRMFPopClient -d <location of certdb> -p <token password> -h <tokenname> -o <output file which saves the base64 CRMF request> -n <subjectDN> -a <algorithm: 'rsa' or 'ec'> -l <rsa key length> -c <ec curve name> -m <hostname:port> -f <profile name; rsa default caEncUserCert; ec default caEncECUserCert> -u <user name> -r <requestor name> -q <POP_NONE, POP_SUCCESS, or POP_FAIL; default POP_SUCCESS> \n");
-        System.out.println("    Optionally, for ECC key generation per definition in JSS pkcs11.PK11KeyPairGenerator:\n");
-        System.out.println("    -k <true for enabling encoding of attribute values; false for default encoding of attribute values; default is false>\n");
-        System.out.println("    -t <true for temporary(session); false for permanent(token); default is true>\n");
-        System.out.println("    -s <1 for sensitive; 0 for non-sensitive; -1 temporaryPairMode dependent; default is -1>\n");
-        System.out.println("    -e <1 for extractable; 0 for non-extractable; -1 token dependent; default is -1>\n");
-        System.out.println("    Also optional for ECC key generation:\n");
-        System.out.println("    -x <true for SSL cert that does ECDH ECDSA; false otherwise; default false>\n");
-        System.out.println("    --transport-cert <transport cert file; default transport.txt>\n");
-        System.out.println(" note: '-x true' can only be used with POP_NONE");
-        System.out.println("   available ECC curve names (if provided by the crypto module): nistp256 (secp256r1),nistp384 (secp384r1),nistp521 (secp521r1),nistk163 (sect163k1),sect163r1,nistb163 (sect163r2),sect193r1,sect193r2,nistk233 (sect233k1),nistb233 (sect233r1),sect239k1,nistk283 (sect283k1),nistb283 (sect283r1),nistk409 (sect409k1),nistb409 (sect409r1),nistk571 (sect571k1),nistb571 (sect571r1),secp160k1,secp160r1,secp160r2,secp192k1,nistp192 (secp192r1, prime192v1),secp224k1,nistp224 (secp224r1),secp256k1,prime192v2,prime192v3,prime239v1,prime239v2,prime239v3,c2pnb163v1,c2pnb163v2,c2pnb163v3,c2pnb176v1,c2tnb191v1,c2tnb191v2,c2tnb191v3,c2pnb208w1,c2tnb239v1,c2tnb239v2,c2tnb239v3,c2pnb272w1,c2pnb304w1,c2tnb359w1,c2pnb368w1,c2tnb431r1,secp112r1,secp112r2,secp128r1,secp128r2,sect113r1,sect113r2,sect131r1,sect131r2\n");
-
-        System.out.println("\n");
-        System.out.println("IMPORTANT:  The transport certificate file needs to be created to contain the");
-        System.out.println("            transport certificate in its base64 encoded format.");
+    public static Options createOptions() {
+
+        Options options = new Options();
+
+        Option option = new Option("d", true, "Security database location");
+        option.setArgName("database");
+        options.addOption(option);
+
+        option = new Option("p", true, "Security token password");
+        option.setArgName("password");
+        options.addOption(option);
+
+        option = new Option("h", true, "Security token name");
+        option.setArgName("token");
+        options.addOption(option);
+
+        option = new Option("o", true, "Output file to store base-64 CRMF request");
+        option.setArgName("output");
+        options.addOption(option);
+
+        option = new Option("n", true, "Subject DN");
+        option.setArgName("subject DN");
+        options.addOption(option);
+
+        option = new Option("a", true, "Key algorithm");
+        option.setArgName("algorithm");
+        options.addOption(option);
+
+        option = new Option("l", true, "Key length");
+        option.setArgName("length");
+        options.addOption(option);
+
+        option = new Option("c", true, "ECC curve name");
+        option.setArgName("curve");
+        options.addOption(option);
+
+        option = new Option("m", true, "CA server hostname and port");
+        option.setArgName("hostname:port");
+        options.addOption(option);
+
+        option = new Option("f", true, "Certificate profile");
+        option.setArgName("profile");
+        options.addOption(option);
+
+        option = new Option("u", true, "Username");
+        option.setArgName("username");
+        options.addOption(option);
+
+        option = new Option("r", true, "Requestor");
+        option.setArgName("requestor");
+        options.addOption(option);
+
+        option = new Option("q", true, "POP option");
+        option.setArgName("POP option");
+        options.addOption(option);
+
+        option = new Option("b", true, "PEM transport certificate");
+        option.setArgName("transport cert");
+        options.addOption(option);
+
+        option = new Option("k", true, "Attribute encoding");
+        option.setArgName("boolean");
+        options.addOption(option);
+
+        option = new Option("x", true, "SSL certificate with ECDH ECDSA");
+        option.setArgName("boolean");
+        options.addOption(option);
+
+        option = new Option("t", true, "Temporary");
+        option.setArgName("boolean");
+        options.addOption(option);
+
+        option = new Option("s", true, "Sensitive");
+        option.setArgName("sensitive");
+        options.addOption(option);
+
+        option = new Option("e", true, "Extractable");
+        option.setArgName("extractable");
+        options.addOption(option);
+
+        options.addOption("v", "verbose", false, "Run in verbose mode.");
+        options.addOption(null, "help", false, "Show help message.");
+
+        return options;
+    }
+
+    public static void printHelp() {
+
+        System.out.println("Usage: CRMFPopClient [OPTIONS]");
+        System.out.println();
+        System.out.println("Options:");
+        System.out.println("  -d <database>                Security database location (default: current directory)");
+        System.out.println("  -h <token>                   Security token name (default: internal)");
+        System.out.println("  -p <password>                Security token password");
+        System.out.println("  -n <subject DN>              Certificate subject DN");
+        System.out.println("  -k <true|false>              Attribute value encoding in subject DN (default: false)");
+        System.out.println("                               - true: enabled");
+        System.out.println("                               - false: disabled");
+        System.out.println("  -a <rsa|ec>                  Key algorithm (default: rsa)");
+        System.out.println("                               - rsa: RSA");
+        System.out.println("                               - ec: ECC");
+        System.out.println("  -f <profile>                 Certificate profile");
+        System.out.println("                               - RSA default: caEncUserCert");
+        System.out.println("                               - ECC default: caEncECUserCert");
+        System.out.println("  -q <POP option>              POP option (default: POP_SUCCESS)");
+        System.out.println("                               - POP_NONE");
+        System.out.println("                               - POP_SUCCESS");
+        System.out.println("                               - POP_FAIL");
+        System.out.println("  -b <transport cert>          PEM transport certificate (default: transport.txt)");
+        System.out.println("  -v, --verbose                Run in verbose mode.");
+        System.out.println("      --help                   Show help message.");
+        System.out.println();
+        System.out.println("With RSA algorithm the following options can be specified:");
+        System.out.println("  -l <length>                  Key length (default: 2048)");
+        System.out.println();
+        System.out.println("With ECC algorithm the following options can be specified:");
+        System.out.println("  -c <curve>                   ECC curve name (default: nistp256)");
+        System.out.println("  -t <true|false>              Temporary (default: true)");
+        System.out.println("                               - true: temporary (session)");
+        System.out.println("                               - false: permanent (token)");
+        System.out.println("  -s <-1|0|1>                  Sensitive (default: -1)");
+        System.out.println("                               - -1: temporaryPairMode dependent");
+        System.out.println("                               - 0: non-sensitive");
+        System.out.println("                               - 1: sensitive");
+        System.out.println("  -e <-1|0|1>                  Extractable (default: -1)");
+        System.out.println("                               - -1: token dependent");
+        System.out.println("                               - 0: non-extractable");
+        System.out.println("                               - 1: extractable");
+        System.out.println("  -x <true|false>              Certificate type (default: false)");
+        System.out.println("                               - true: SSL certificate with ECDH ECDSA (reqires POP_NONE)");
+        System.out.println("                               - false: otherwise");
+        System.out.println();
+        System.out.println("To store the CRMF request the following options are required:");
+        System.out.println("  -o <output>                  Output file to store base-64 CRMF request");
+        System.out.println();
+        System.out.println("To submit the CRMF request the following options are required:");
+        System.out.println("  -m <hostname:port>           CA server hostname and port");
+        System.out.println("  -u <username>                Username");
+        System.out.println("  -r <requestor>               Requestor");
+        System.out.println();
+        System.out.println("Available ECC curve names:");
+        System.out.println("  nistp256 (secp256r1), nistp384 (secp384r1), nistp521 (secp521r1), nistk163 (sect163k1),");
+        System.out.println("  sect163r1, nistb163 (sect163r2), sect193r1, sect193r2, nistk233 (sect233k1),");
+        System.out.println("  nistb233 (sect233r1), sect239k1, nistk283 (sect283k1), nistb283 (sect283r1),");
+        System.out.println("  nistk409 (sect409k1), nistb409 (sect409r1),nistk571 (sect571k1), nistb571 (sect571r1),");
+        System.out.println("  secp160k1, secp160r1, secp160r2, secp192k1, nistp192 (secp192r1, prime192v1),");
+        System.out.println("  secp224k1, nistp224 (secp224r1), secp256k1, prime192v2, prime192v3, prime239v1,");
+        System.out.println("  prime239v2, prime239v3, c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176v1, c2tnb191v1,");
+        System.out.println("  c2tnb191v2, c2tnb191v3, c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2pnb272w1,");
+        System.out.println("  c2pnb304w1, c2tnb359w1, c2pnb368w1, c2tnb431r1, secp112r1, secp112r2, secp128r1,");
+        System.out.println("  secp128r2, sect113r1, sect113r2, sect131r1, sect131r2");
+    }
+
+    public static void printError(String message) {
+        System.err.println("ERROR: " + message);
+        System.err.println("Try 'CRMFPopClient --help' for more information.");
     }
 
     public static void main(String args[]) throws Exception {
 
+        Options options = createOptions();
+        CommandLine cmd = null;
+
+        try {
+            CommandLineParser parser = new PosixParser();
+            cmd = parser.parse(options, args);
+
+        } catch (Exception e) {
+            printError(e.getMessage());
+            System.exit(1);
+        }
+
+        if (cmd.hasOption("help")) {
+            printHelp();
+            System.exit(0);
+        }
+
         CRMFPopClient client = new CRMFPopClient();
+        client.verbose = cmd.hasOption("v");
 
-        String databaseDir = ".";
-        String tokenPassword = null;
-        String tokenName = null;
+        String databaseDir = cmd.getOptionValue("d", ".");
+        String tokenPassword = cmd.getOptionValue("p");
+        String tokenName = cmd.getOptionValue("h");
 
-        // "rsa" or "ec"
-        String algorithm = "rsa";
+        String algorithm = cmd.getOptionValue("a", "rsa");
+        int keySize = Integer.parseInt(cmd.getOptionValue("l", "2048"));
 
-        /* default RSA key size */
-        int keySize = 2048;
+        String profileID = cmd.getOptionValue("f");
+        String subjectDN = cmd.getOptionValue("n");
+        boolean encodingEnabled = Boolean.parseBoolean(cmd.getOptionValue("k", "false"));
 
-        /* default ECC key curve name */
-        String curve = "nistp256";
+        String transportCertFilename = cmd.getOptionValue("b", "transport.txt");
 
-        boolean encodingEnabled = false; /* enable encoding attribute values if true */
-        boolean temporary = true; /* session if true; token if false */
-        int sensitive = -1; /* -1, 0, or 1 */
-        int extractable = -1; /* -1, 0, or 1 */
-        boolean sslECDH = false;
+        String popOption = cmd.getOptionValue("q", "POP_SUCCESS");
 
-        String username = null;
-        String requestor = null;
-        String profileName = null;
+        String curve = cmd.getOptionValue("c", "nistp256");
+        boolean sslECDH = Boolean.parseBoolean(cmd.getOptionValue("x", "false"));
+        boolean temporary = Boolean.parseBoolean(cmd.getOptionValue("t", "true"));
+        int sensitive = Integer.parseInt(cmd.getOptionValue("s", "-1"));
+        int extractable = Integer.parseInt(cmd.getOptionValue("e", "-1"));
 
-        // format: "host:port"
-        String hostPort = null;
-        String subjectDN = null;
-        boolean submitRequest = false;
+        String output = cmd.getOptionValue("o");
 
-        // POP_NONE, POP_SUCCESS, or POP_FAIL
-        String popOption = "POP_SUCCESS";
-        boolean withPop = true;
+        String hostPort = cmd.getOptionValue("m");
+        String username = cmd.getOptionValue("u");
+        String requestor = cmd.getOptionValue("r");
 
-        String output = null;
-        String transportCertFilename = "transport.txt";
-
-        for (int i=0; i<args.length; i+=2) {
-            String name = args[i];
-
-            if (name.equals("-v")) {
-                client.verbose = Boolean.parseBoolean(args[i+1]);
-
-            } else if (name.equals("-p")) {
-                tokenPassword = args[i+1];
-
-            } else if (name.equals("-d")) {
-                databaseDir = args[i+1];
-
-            } else if (name.equals("-h")) {
-                tokenName = args[i+1];
-
-            } else if (name.equals("-a")) {
-                algorithm = args[i+1];
-                if (!algorithm.equals("rsa") && !algorithm.equals("ec")) {
-                    System.out.println("ERROR: invalid algorithm: " + algorithm);
-                    System.exit(1);
-                }
-
-            } else if (name.equals("-x")) {
-                String temp = args[i+1];
-                if (temp.equals("true"))
-                    sslECDH = true;
-                else
-                    sslECDH = false;
-
-            } else if (name.equals("-t")) {
-                String temp = args[i+1];
-                if (temp.equals("true"))
-                    temporary = true;
-                else
-                    temporary = false;
-            } else if (name.equals("-k")) {
-                String temp = args[i+1];
-                if (temp.equals("true"))
-                    encodingEnabled = true;
-                else
-                    encodingEnabled = false;
-
-            } else if (name.equals("-s")) {
-                String ec_sensitive_s = args[i+1];
-                sensitive = Integer.parseInt(ec_sensitive_s);
-                if ((sensitive != 0) &&
-                    (sensitive != 1) &&
-                    (sensitive != -1)) {
-                      System.out.println("ERROR: Illegal input parameters for -s.");
-                      usage();
-                      System.exit(1);
-                    }
-
-            } else if (name.equals("-e")) {
-                String ec_extractable_s = args[i+1];
-                extractable = Integer.parseInt(ec_extractable_s);
-                if ((extractable != 0) &&
-                    (extractable != 1) &&
-                    (extractable != -1)) {
-                      System.out.println("ERROR: Illegal input parameters for -e.");
-                      usage();
-                      System.exit(1);
-                    }
-
-            } else if (name.equals("-l")) {
-                keySize = Integer.parseInt(args[i+1]);
-
-            } else if (name.equals("-c")) {
-                curve = args[i+1];
-
-            } else if (name.equals("-m")) {
-                hostPort = args[i+1];
-                submitRequest = true;
-
-            } else if (name.equals("-f")) {
-                profileName = args[i+1];
-
-            } else if (name.equals("-u")) {
-                username = args[i+1];
-
-            } else if (name.equals("-r")) {
-                requestor = args[i+1];
-
-            } else if (name.equals("-n")) {
-                subjectDN = args[i+1];
-
-            } else if (name.equals("-q")) {
-                popOption = args[i+1];
-                if (!popOption.equals("POP_SUCCESS") &&
-                    !popOption.equals("POP_FAIL") &&
-                    !popOption.equals("POP_NONE")) {
-                    System.out.println("ERROR: invalid POP option: "+ popOption);
-                    System.exit(1);
-                }
-                if (popOption.equals("POP_NONE"))
-                    withPop = false;
-
-            } else if (name.equals("-o")) {
-                output = args[i+1];
-
-            } else if (name.equals("--transport-cert")) {
-                transportCertFilename = args[i+1];
-
-            } else {
-                System.out.println("Unrecognized argument(" + i + "): "
-                    + name);
-                usage();
-                System.exit(1);
-            }
-        }
+        if (subjectDN == null) {
+            printError("Missing subject DN");
+            System.exit(1);
+         }
 
         if (tokenPassword == null) {
-           System.out.println("missing password");
-           usage();
-           System.exit(1);
+            printError("Missing token password");
+            System.exit(1);
+         }
+
+        if (!algorithm.equals("rsa") && !algorithm.equals("ec")) {
+            printError("Invalid algorithm: " + algorithm);
+            System.exit(1);
+        }
+
+        if (sensitive != 0 && sensitive != 1 && sensitive != -1) {
+            printError("Illegal input parameters for -s: " + sensitive);
+            System.exit(1);
+        }
+
+        if (extractable != 0 && extractable != 1 && extractable != -1) {
+            printError("Illegal input parameters for -e: " + extractable);
+            System.exit(1);
+        }
+
+        if (!popOption.equals("POP_SUCCESS") &&
+                !popOption.equals("POP_FAIL") &&
+                !popOption.equals("POP_NONE")) {
+            printError("Invalid POP option: "+ popOption);
+            System.exit(1);
         }
 
-        if (profileName == null) {
+        if (profileID == null) {
             if (algorithm.equals("rsa")) {
-                profileName = "caEncUserCert";
+                profileID = "caEncUserCert";
 
             } else if (algorithm.equals("ec")) {
-                profileName = "caEncECUserCert";
+                profileID = "caEncECUserCert";
 
             } else {
                 throw new Exception("Unknown algorithm: " + algorithm);
@@ -338,7 +407,7 @@ public class CRMFPopClient {
 
             ProofOfPossession pop = null;
 
-            if (withPop) {
+            if (!popOption.equals("POP_NONE")) {
 
                 if (client.verbose) System.out.println("Creating signer");
                 Signature signer = client.createSigner(token, algorithm, keyPair);
@@ -373,13 +442,13 @@ public class CRMFPopClient {
             }
             String csr = sw.toString();
 
-            if (submitRequest) {
+            if (hostPort != null) {
                 System.out.println("Submitting CRMF request to " + hostPort);
                 client.submitRequest(
                         request,
                         hostPort,
                         username,
-                        profileName,
+                        profileID,
                         requestor);
 
             } else if (output != null) {
@@ -603,22 +672,27 @@ public class CRMFPopClient {
             String request,
             String hostPort,
             String username,
-            String profileName,
+            String profileID,
             String requestor) throws Exception {
 
-        String encodedRequest = URLEncoder.encode(request, "UTF-8");
-
-        URL url = new URL(
-                "http://" + hostPort + "/ca/ee/ca/profileSubmit"
+        String s = "http://" + hostPort + "/ca/ee/ca/profileSubmit"
                 + "?cert_request_type=crmf"
-                + "&cert_request=" + encodedRequest
-                + "&renewal=false&uid=" + username
+                + "&cert_request=" + URLEncoder.encode(request, "UTF-8")
+                + "&renewal=false"
                 + "&xmlOutput=false"
-                + "&profileId=" + profileName
-                + "&sn_uid=" + username
-                + "&SubId=profile"
-                + "&requestor_name=" + requestor);
+                + "&profileId=" + URLEncoder.encode(profileID, "UTF-8")
+                + "&SubId=profile";
 
+        if (username != null) {
+            s += "&uid=" + URLEncoder.encode(username, "UTF-8");
+            s += "&sn_uid=" + URLEncoder.encode(username, "UTF-8");
+        }
+
+        if (requestor != null) {
+            s += "&requestor_name=" + URLEncoder.encode(requestor, "UTF-8");
+        }
+
+        URL url = new URL(s);
         if (verbose) System.out.println("Opening " + url);
 
         URLConnection conn = url.openConnection();
@@ -627,12 +701,18 @@ public class CRMFPopClient {
 
         if (verbose) System.out.println("--------------------");
         String line = null;
+        String requestID = null;
         String status = null;
-        String requestId = null;
+        String reason = null;
         while ((line = reader.readLine()) != null) {
             if (verbose) System.out.println(line);
 
-            if (line.startsWith("errorCode=")) {
+            if (line.startsWith("requestList.requestId=")) {
+                int i = line.indexOf("\"");
+                int j = line.indexOf("\";", i+1);
+                requestID = line.substring(i+1, j);
+
+            } else if (line.startsWith("errorCode=")) {
                 int i = line.indexOf("\"");
                 int j = line.indexOf("\";", i+1);
                 String errorCode = line.substring(i+1, j);
@@ -646,25 +726,32 @@ public class CRMFPopClient {
                 } else if ("2".equals(errorCode)) {
                     status = "pending";
 
+                } else if ("3".equals(errorCode)) {
+                    status = "rejected";
+
                 } else {
                     status = "unknown";
                 }
 
-            } else if (line.startsWith("requestList.requestId=")) {
+            } else if (line.startsWith("errorReason=")) {
                 int i = line.indexOf("\"");
                 int j = line.indexOf("\";", i+1);
-                requestId = line.substring(i+1, j);
+                reason = line.substring(i+1, j);
             }
         }
         if (verbose) System.out.println("--------------------");
 
-        if (requestId != null) {
-            System.out.println("Request ID: " + requestId);
+        if (requestID != null) {
+            System.out.println("Request ID: " + requestID);
         }
 
         if (status != null) {
             System.out.println("Request Status: " + status);
         }
+
+        if (reason != null) {
+            System.out.println("Reason: " + reason);
+        }
     }
 
     public boolean isEncoded(String elementValue) {
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 1dbf027606f9b83e5319284038d31f02248f4cde..17929221bd927454459da907bd2ad5d53ee4b507 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -188,9 +188,9 @@ public class MainCLI extends CLI {
         option.setArgName("format");
         options.addOption(option);
 
-        options.addOption("v", false, "Verbose");
-        options.addOption(null, "help", false, "Help");
-        options.addOption(null, "version", false, "Version");
+        options.addOption("v", "verbose", false, "Run in verbose mode.");
+        options.addOption(null, "help", false, "Show help message.");
+        options.addOption(null, "version", false, "Show version number.");
     }
 
     public String[] readPlaintextPasswordFromFile(String pwfile) throws IOException {
diff --git a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
index 996bcf27586c2dead71d723e2777f6e99ea832fc..ebca55bc0bda2a9dce4b1ca3d9574e848ac698f8 100644
--- a/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/client/ClientCertRequestCLI.java
@@ -73,8 +73,7 @@ public class ClientCertRequestCLI extends CLI {
         option.setArgName("request type");
         options.addOption(option);
 
-        option = new Option(null, "attribute-encoding", true, "Attribute encoding (default: false)");
-        option.setArgName("boolean");
+        option = new Option(null, "attribute-encoding", false, "Enable Attribute encoding");
         options.addOption(option);
 
         option = new Option(null, "algorithm", true, "Algorithm (default: rsa)");
@@ -89,12 +88,10 @@ public class ClientCertRequestCLI extends CLI {
         option.setArgName("curve name");
         options.addOption(option);
 
-        option = new Option(null, "ssl-ecdh", true, "SSL certificate with ECDH ECDSA (default: false)");
-        option.setArgName("boolean");
+        option = new Option(null, "ssl-ecdh", false, "SSL certificate with ECDH ECDSA");
         options.addOption(option);
 
-        option = new Option(null, "temporary", true, "Temporary (default: true)");
-        option.setArgName("boolean");
+        option = new Option(null, "permanent", false, "Permanent");
         options.addOption(option);
 
         option = new Option(null, "sensitive", true, "Sensitive");
@@ -105,15 +102,18 @@ public class ClientCertRequestCLI extends CLI {
         option.setArgName("boolean");
         options.addOption(option);
 
-        option = new Option(null, "transport-cert", true, "Transport certificate");
+        option = new Option(null, "transport", true, "PEM transport certificate");
         option.setArgName("path");
         options.addOption(option);
 
-        option = new Option(null, "profile", true, "Certificate profile (default: caEncUserCert)");
+        option = new Option(null, "profile", true, "Certificate profile (RSA default: caUserCert, ECC default: caECUserCert)");
         option.setArgName("profile");
         options.addOption(option);
 
-        options.addOption(null, "help", false, "Help");
+        option = new Option(null, "without-pop", false, "Do not include Proof-of-Possession in CRMF request");
+        options.addOption(option);
+
+        options.addOption(null, "help", false, "Show help message.");
     }
 
     public void execute(String[] args) throws Exception {
@@ -152,15 +152,15 @@ public class ClientCertRequestCLI extends CLI {
         // pkcs10, crmf
         String requestType = cmd.getOptionValue("type", "pkcs10");
 
-        boolean attributeEncoding = Boolean.parseBoolean(cmd.getOptionValue("attribute-encoding", "false"));
+        boolean attributeEncoding = cmd.hasOption("attribute-encoding");
 
         // rsa, ec
         String algorithm = cmd.getOptionValue("algorithm", "rsa");
         int length = Integer.parseInt(cmd.getOptionValue("length", "1024"));
 
         String curve = cmd.getOptionValue("curve", "nistp256");
-        boolean sslECDH = Boolean.parseBoolean(cmd.getOptionValue("ssl-ecdh", "false"));
-        boolean temporary = Boolean.parseBoolean(cmd.getOptionValue("temporary", "true"));
+        boolean sslECDH = cmd.hasOption("ssl-ecdh");
+        boolean temporary = !cmd.hasOption("permanent");
 
         String s = cmd.getOptionValue("sensitive");
         int sensitive;
@@ -178,17 +178,19 @@ public class ClientCertRequestCLI extends CLI {
             extractable = Boolean.parseBoolean(s) ? 1 : 0;
         }
 
-        String transportCertFilename = cmd.getOptionValue("transport-cert");
+        String transportCertFilename = cmd.getOptionValue("transport");
 
         String profileID = cmd.getOptionValue("profile");
         if (profileID == null) {
-            if ("rsa".equals(algorithm)) {
+            if (algorithm.equals("rsa")) {
                 profileID = "caUserCert";
-            } else if ("ec".equals(algorithm)) {
-                profileID = "caEncECUserCert";
+            } else if (algorithm.equals("ec")) {
+                profileID = "caECUserCert";
             }
         }
 
+        boolean withPop = !cmd.hasOption("without-pop");
+
         MainCLI mainCLI = (MainCLI)parent.getParent();
         File certDatabase = mainCLI.certDatabase;
 
@@ -229,7 +231,8 @@ public class ClientCertRequestCLI extends CLI {
             CryptoManager manager = CryptoManager.getInstance();
             X509Certificate transportCert = manager.importCACertPackage(transportCertData);
 
-            csr = generateCrmfRequest(transportCert, subjectDN, attributeEncoding, algorithm, length, curve, sslECDH, temporary, sensitive, extractable);
+            csr = generateCrmfRequest(transportCert, subjectDN, attributeEncoding,
+                    algorithm, length, curve, sslECDH, temporary, sensitive, extractable, withPop);
 
         } else {
             throw new Exception("Unknown request type: " + requestType);
@@ -257,16 +260,17 @@ public class ClientCertRequestCLI extends CLI {
         csrAttr.setValue(csr);
 
         ProfileInput sn = request.getInput("Subject Name");
+        if (sn != null) {
+            DN dn = new DN(subjectDN);
+            Vector<?> rdns = dn.getRDNs();
 
-        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);
+            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) {
@@ -325,7 +329,8 @@ public class ClientCertRequestCLI extends CLI {
             boolean sslECDH,
             boolean temporary,
             int sensitive,
-            int extractable
+            int extractable,
+            boolean withPop
             ) throws Exception {
 
         CryptoManager manager = CryptoManager.getInstance();
@@ -348,15 +353,17 @@ public class ClientCertRequestCLI extends CLI {
 
         CertRequest certRequest = client.createCertRequest(token, transportCert, algorithm, keyPair, subject);
 
-        Signature signer = client.createSigner(token, algorithm, keyPair);
+        ProofOfPossession pop = null;
+        if (withPop) {
+            Signature signer = client.createSigner(token, algorithm, keyPair);
 
-        ByteArrayOutputStream bo = new ByteArrayOutputStream();
-        certRequest.encode(bo);
-        signer.update(bo.toByteArray());
+            ByteArrayOutputStream bo = new ByteArrayOutputStream();
+            certRequest.encode(bo);
+            signer.update(bo.toByteArray());
+            byte[] signature = signer.sign();
 
-        byte[] signature = signer.sign();
-
-        ProofOfPossession pop = client.createPop(algorithm, signature);
+            pop = client.createPop(algorithm, signature);
+        }
 
         return client.createCRMFRequest(certRequest, pop);
     }
diff --git a/base/java-tools/templates/pki_java_command_wrapper.in b/base/java-tools/templates/pki_java_command_wrapper.in
index dbc4986160241ebe60bfe5538467982d5c393535..4474084cfe519d0adb1e1eb42ce0ddf323509666 100644
--- a/base/java-tools/templates/pki_java_command_wrapper.in
+++ b/base/java-tools/templates/pki_java_command_wrapper.in
@@ -131,6 +131,7 @@ fi
 
 JNI_JAR_DIR=`source /usr/share/pki/etc/pki.conf && source /etc/pki/pki.conf && echo $JNI_JAR_DIR`
 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/ldapjdk.jar:${CP}
-- 
1.8.4.2



More information about the Pki-devel mailing list