From af921ae8042eda6bbb833f4d3c2fa4e022d00269 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" 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 | 503 +++++++++++++-------- .../src/com/netscape/cmstools/cli/MainCLI.java | 6 +- .../cmstools/client/ClientCertRequestCLI.java | 75 +-- 3 files changed, 360 insertions(+), 224 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..81b9c4370f244f234153b14980460bf866b42294 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,282 @@ public class CRMFPopClient { public boolean verbose; - private static void usage() { - - System.out.println("Usage: CRMFPopClient -d -p -h -o -n -a -l -c -m -f -u -r -q \n"); - System.out.println(" Optionally, for ECC key generation per definition in JSS pkcs11.PK11KeyPairGenerator:\n"); - System.out.println(" -k \n"); - System.out.println(" -t \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 \n"); - System.out.println(" --transport-cert \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 Security database location (default: current directory)"); + System.out.println(" -h Security token name (default: internal)"); + System.out.println(" -p Security token password"); + System.out.println(" -n Certificate subject DN"); + System.out.println(" -k Attribute value encoding in subject DN (default: false)"); + System.out.println(" - true: enabled"); + System.out.println(" - false: disabled"); + System.out.println(" -a Key algorithm (default: rsa)"); + System.out.println(" - rsa: RSA"); + System.out.println(" - ec: ECC"); + System.out.println(" -f Certificate profile"); + System.out.println(" - RSA default: caEncUserCert"); + System.out.println(" - ECC default: caEncECUserCert"); + System.out.println(" -q POP option (default: POP_SUCCESS)"); + System.out.println(" - POP_NONE: without POP"); + System.out.println(" - POP_SUCCESS: with valid POP"); + System.out.println(" - POP_FAIL: with invalid POP (for testing)"); + System.out.println(" -b 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 Key length (default: 2048)"); + System.out.println(); + System.out.println("With ECC algorithm the following options can be specified:"); + System.out.println(" -c ECC curve name (default: nistp256)"); + System.out.println(" -t 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 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 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 CA server hostname and port"); + System.out.println(" -u Username"); + System.out.println(" -r 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 { - CRMFPopClient client = new CRMFPopClient(); + Options options = createOptions(); + CommandLine cmd = null; - String databaseDir = "."; - String tokenPassword = null; - String tokenName = null; + try { + CommandLineParser parser = new PosixParser(); + cmd = parser.parse(options, args); - // "rsa" or "ec" - String algorithm = "rsa"; - - /* default RSA key size */ - int keySize = 2048; - - /* default ECC key curve name */ - String curve = "nistp256"; - - 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 username = null; - String requestor = null; - String profileName = null; - - // format: "host:port" - String hostPort = null; - String subjectDN = null; - boolean submitRequest = false; - - // POP_NONE, POP_SUCCESS, or POP_FAIL - String popOption = "POP_SUCCESS"; - boolean withPop = true; - - String output = null; - String transportCertFilename = "transport.txt"; - - for (int i=0; i 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); } -- 1.8.4.2