>From 4645779e207f32c4588c6bd1eca367dcd93d6fc7 Mon Sep 17 00:00:00 2001
From: Abhishek Koneru <akoneru@redhat.com>
Date: Tue, 1 Apr 2014 10:53:24 -0400
Subject: [PATCH] Added new CLI commands for Key resource.

key-archive, key-retrieve, key-recover, key-generate,
key-request-review, key-template-show, key-template-find
---
 .../src/com/netscape/certsrv/key/Template.java     |  21 +++
 .../com/netscape/cmstools/key/KeyArchiveCLI.java   | 119 ++++++++++++++++
 .../src/com/netscape/cmstools/key/KeyCLI.java      |  24 +++-
 .../com/netscape/cmstools/key/KeyGenerateCLI.java  | 104 ++++++++++++++
 .../com/netscape/cmstools/key/KeyModifyCLI.java    |   4 +-
 .../com/netscape/cmstools/key/KeyRecoverCLI.java   |  88 ++++++++++++
 .../netscape/cmstools/key/KeyRequestReviewCLI.java |  71 ++++++++++
 .../netscape/cmstools/key/KeyRequestShowCLI.java   |   2 +-
 .../cmstools/key/KeyRequestTemplateFindCLI.java    |  43 ++++++
 .../cmstools/key/KeyRequestTemplateShowCLI.java    | 154 +++++++++++++++++++++
 .../com/netscape/cmstools/key/KeyRetrieveCLI.java  | 132 ++++++++++++++++++
 .../src/com/netscape/cmstools/key/KeyShowCLI.java  |  10 +-
 12 files changed, 763 insertions(+), 9 deletions(-)
 create mode 100644 base/common/src/com/netscape/certsrv/key/Template.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/key/KeyRecoverCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/key/KeyRequestReviewCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateFindCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateShowCLI.java
 create mode 100644 base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java

diff --git a/base/common/src/com/netscape/certsrv/key/Template.java b/base/common/src/com/netscape/certsrv/key/Template.java
new file mode 100644
index 0000000000000000000000000000000000000000..bfcf61eb77c46ac54ba469113883b886ac98c79e
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/key/Template.java
@@ -0,0 +1,21 @@
+package com.netscape.certsrv.key;
+
+
+public class Template{
+    String templateID;
+    String templateName;
+    String templateDescription;
+    public Template(String templateID, String templateName, String templateDescription) {
+        super();
+        this.templateID = templateID;
+        this.templateName = templateName;
+        this.templateDescription = templateDescription;
+    }
+
+    public void printTemplateInfo(){
+        System.out.println();
+        System.out.println("  Template ID: " + templateID);
+        System.out.println("  Template Name: " + templateName);
+        System.out.println("  Template Description: " + templateDescription);
+    }
+}
\ No newline at end of file
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..ced51ad74e854be85973feb2d754326b074cabab
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyArchiveCLI.java
@@ -0,0 +1,119 @@
+package com.netscape.cmstools.key;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.key.KeyArchivalRequest;
+import com.netscape.certsrv.key.KeyRequestResponse;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+import com.netscape.cmsutil.util.Utils;
+
+public class KeyArchiveCLI extends CLI {
+    public KeyCLI keyCLI;
+
+    public KeyArchiveCLI(KeyCLI keyCLI) {
+        super("archive", "Archive a secret at the DRM.", keyCLI);
+        this.keyCLI = keyCLI;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) {
+
+        Option option = new Option(null, "clientKeyId", true, "Unique client key identifier.");
+        option.setArgName("Client Key Identifier");
+        options.addOption(option);
+
+        option = new Option(null, "passphrase", true, "Passphrase to be stored.");
+        option.setArgName("Passphrase");
+        options.addOption(option);
+
+        option = new Option(null, "input", true,
+                "Location of the request template file.\nUsed for archiving already encrypted data.");
+        option.setArgName("Input file path");
+        options.addOption(option);
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (ParseException e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        String requestFile = cmd.getOptionValue("input");
+
+        KeyRequestResponse response = null;
+
+        if ((requestFile != null) && (requestFile.trim().length() != 0)) {
+            // Case where the request template file is used. For pre-encrypted data.
+            try {
+                JAXBContext context = JAXBContext.newInstance(KeyArchivalRequest.class);
+                Unmarshaller unmarshaller = context.createUnmarshaller();
+                FileInputStream fis = new FileInputStream(requestFile);
+                KeyArchivalRequest req = (KeyArchivalRequest) unmarshaller.unmarshal(fis);
+
+                if (req.getPKIArchiveOptions() != null) {
+                    response = keyCLI.keyClient.archivePKIOptions(req.getClientKeyId(), req.getDataType(),
+                            req.getKeyAlgorithm(), req.getKeySize(), Utils.base64decode(req.getPKIArchiveOptions()));
+                } else {
+                    response = keyCLI.keyClient.archiveEncryptedData(req.getClientKeyId(), req.getDataType(),
+                            req.getKeyAlgorithm(), req.getKeySize(), req.getAlgorithmOID(),
+                            Utils.base64decode(req.getSymmetricAlgorithmParams()),
+                            Utils.base64decode(req.getWrappedPrivateData()),
+                            Utils.base64decode(req.getTransWrappedSessionKey()));
+                }
+
+            } catch (JAXBException e) {
+                System.err.println("Error: Cannot parse the request file.");
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            } catch (FileNotFoundException e) {
+                System.err.println("Error: Cannot locate file at path: " + requestFile);
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            }
+
+        } else {
+            // Simple case for archiving a passphrase
+            String clientKeyId = cmd.getOptionValue("clientKeyId");
+            String passphrase = cmd.getOptionValue("passphrase");
+            if (clientKeyId == null) {
+                System.err.println("Error: Client Key Id is not specified.");
+                printHelp();
+                System.exit(-1);
+            }
+            if (passphrase == null) {
+                System.err.println("Error: No passphrase provided to archive.");
+                printHelp();
+                System.exit(-1);
+            }
+            try {
+                response = keyCLI.keyClient.archivePassphrase(clientKeyId, passphrase);
+            } catch (Exception e) {
+                System.err.println(e.getMessage());
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            }
+        }
+
+        MainCLI.printMessage("Archival request details");
+        KeyCLI.printKeyRequestInfo(response.getRequestInfo());
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
index 86b6f2407d11c66312c82179ab36c892c3d2e4f4..f64b8d76214cb51a33dd7818d3a6d5ea051404ef 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyCLI.java
@@ -18,9 +18,12 @@
 
 package com.netscape.cmstools.key;
 
+import com.netscape.certsrv.cert.CertData;
 import com.netscape.certsrv.key.KeyClient;
 import com.netscape.certsrv.key.KeyInfo;
 import com.netscape.certsrv.key.KeyRequestInfo;
+import com.netscape.certsrv.system.SystemCertClient;
+import com.netscape.certsrv.util.NSSCryptoProvider;
 import com.netscape.cmstools.cli.CLI;
 import com.netscape.cmstools.cli.MainCLI;
 
@@ -30,6 +33,7 @@ import com.netscape.cmstools.cli.MainCLI;
 public class KeyCLI extends CLI {
 
     public KeyClient keyClient;
+    public SystemCertClient systemCertClient;
 
     public KeyCLI(CLI parent) {
         super("key", "Key management commands", parent);
@@ -39,6 +43,13 @@ public class KeyCLI extends CLI {
         addModule(new KeyShowCLI(this));
         addModule(new KeyRequestShowCLI(this));
         addModule(new KeyModifyCLI(this));
+        addModule(new KeyRequestTemplateFindCLI(this));
+        addModule(new KeyRequestTemplateShowCLI(this));
+        addModule(new KeyArchiveCLI(this));
+        addModule(new KeyRetrieveCLI(this));
+        addModule(new KeyGenerateCLI(this));
+        addModule(new KeyRecoverCLI(this));
+        addModule(new KeyRequestReviewCLI(this));
     }
 
     public String getFullName() {
@@ -56,10 +67,21 @@ public class KeyCLI extends CLI {
 
         // determine the subsystem
         String subsystem = client.getSubsystem();
-        if (subsystem == null) subsystem = "kra";
+        if (subsystem == null)
+            subsystem = "kra";
 
         // create new key client
         keyClient = new KeyClient(client, subsystem);
+        if ((client.getConfig().getCertDatabase() != null) && (client.getConfig().getCertPassword() != null)) {
+            keyClient.setCrypto(new NSSCryptoProvider(client.getConfig()));
+
+            // Set the transport cert for crypto operations
+            systemCertClient = new SystemCertClient(client, subsystem);
+            String transportCert = systemCertClient.getTransportCert().getEncoded();
+            transportCert = transportCert.substring(CertData.HEADER.length(),
+                    transportCert.indexOf(CertData.FOOTER));
+            keyClient.setTransportCert(transportCert);
+        }
 
         super.execute(args);
     }
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..5edf9489c7560d9f96afe9ec9facd0e18ee04591
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyGenerateCLI.java
@@ -0,0 +1,104 @@
+package com.netscape.cmstools.key;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.key.KeyRequestResource;
+import com.netscape.certsrv.key.KeyRequestResponse;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+public class KeyGenerateCLI extends CLI {
+    public KeyCLI keyCLI;
+
+    public KeyGenerateCLI(KeyCLI keyCLI) {
+        super("generate", "Generate key", keyCLI);
+        this.keyCLI = keyCLI;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " <Client Key ID> [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) {
+        Option option = new Option(null, "key-algorithm", true,
+                "Algorithm to be used to create a key.\n Supported types [AES,DES,DES3,RC2,RC4,DESede]");
+        option.setArgName("Key algorithm");
+        option.setRequired(true);
+        options.addOption(option);
+
+        option = new Option(null, "key-size", true,
+                "Size of the key to be generated. Required for all algorithms AES and RC2.\n"
+                        + "Valid size values:\n   AES - 128, 192. 256.\n   RC2 - >=8, <=128");
+        option.setArgName("Key size");
+        options.addOption(option);
+
+        option = new Option(null, "usages", true, "Comma seperated list of usages."
+                + "\n Usage1,Usage2,Usage3.. .\n "
+                + "Valid usages: [wrap, unwrap, sign, verify, encrypt, decrypt].");
+        option.setArgName("Usages");
+        options.addOption(option);
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (ParseException e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        String[] cmdArgs = cmd.getArgs();
+        if (cmdArgs.length < 1) {
+            System.err.println("Error: Missing the Client Key Id");
+            printHelp();
+            System.exit(1);
+        }
+
+        String clientKeyId = cmdArgs[0];
+        String keyAlgorithm = cmd.getOptionValue("key-algorithm");
+        String keySize = cmd.getOptionValue("key-size");
+
+        if (keySize == null) {
+            switch (keyAlgorithm) {
+            case KeyRequestResource.DES3_ALGORITHM:
+            case KeyRequestResource.DESEDE_ALGORITHM:
+                keySize = "168";
+                break;
+            case KeyRequestResource.DES_ALGORITHM:
+                keySize = "56";
+                break;
+            case KeyRequestResource.RC4_ALGORITHM:
+                keySize = "0";
+                break;
+            case KeyRequestResource.AES_ALGORITHM:
+            case KeyRequestResource.RC2_ALGORITHM:
+                System.err.println("Error: Key size must be specified for the algorithm used.");
+                printHelp();
+                System.exit(1);
+            default:
+                System.err.println("Error: Algorithm not supported.");
+                printHelp();
+                System.exit(1);
+            }
+        }
+        List<String> usagesList = null;
+        if (cmd.getOptionValue("usages") != null) {
+            String[] usages = cmd.getOptionValue("usages").split(",");
+            usagesList = new ArrayList<String>(Arrays.asList(usages));
+        }
+
+        KeyRequestResponse response = keyCLI.keyClient.generateSymmetricKey(clientKeyId, keyAlgorithm,
+                Integer.parseInt(keySize),
+                usagesList, null);
+
+        MainCLI.printMessage("Key generation request info");
+        KeyCLI.printKeyRequestInfo(response.getRequestInfo());
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyModifyCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyModifyCLI.java
index 729649e5ca03758c8797c2f727c6b760e88904ba..e5da6e792a489becd10b827a1daeab2b1caa7320 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyModifyCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyModifyCLI.java
@@ -12,7 +12,7 @@
 // with this program; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 //
-// (C) 2012 Red Hat, Inc.
+// (C) 2014 Red Hat, Inc.
 // All rights reserved.
 // --- END COPYRIGHT BLOCK ---
 
@@ -30,7 +30,7 @@ public class KeyModifyCLI extends CLI {
     public KeyCLI keyCLI;
 
     public KeyModifyCLI(KeyCLI keyCLI) {
-        super("mod", "Get key request", keyCLI);
+        super("mod", "Modify the status of a key", keyCLI);
         this.keyCLI = keyCLI;
     }
 
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRecoverCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRecoverCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..9e226cf6588e7852390b0bad77775467561bee0b
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRecoverCLI.java
@@ -0,0 +1,88 @@
+package com.netscape.cmstools.key;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.key.KeyRecoveryRequest;
+import com.netscape.certsrv.key.KeyRequestResponse;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+import com.netscape.cmsutil.util.Utils;
+
+public class KeyRecoverCLI extends CLI {
+    public KeyCLI keyCLI;
+
+    public KeyRecoverCLI(KeyCLI keyCLI) {
+        super("recover", "Recover key", keyCLI);
+        this.keyCLI = keyCLI;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " <Request ID> [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) {
+
+        Option option = new Option(null, "keyId", true, "Key Identifier for the secret to be recovered.");
+        option.setArgName("Key Identifier");
+        options.addOption(option);
+
+        option = new Option(null, "input", true, "Location of the request template file.");
+        option.setArgName("Input file path");
+        options.addOption(option);
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (ParseException e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        String requestFile = cmd.getOptionValue("input");
+
+        KeyRequestResponse response = null;
+
+        if ((requestFile != null) && (requestFile.trim().length() != 0)) {
+            try {
+                JAXBContext context = JAXBContext.newInstance(KeyRecoveryRequest.class);
+                Unmarshaller unmarshaller = context.createUnmarshaller();
+                FileInputStream fis = new FileInputStream(requestFile);
+                KeyRecoveryRequest req = (KeyRecoveryRequest) unmarshaller.unmarshal(fis);
+                response = keyCLI.keyClient.recoverKey(req.getKeyId(),
+                        Utils.base64decode(req.getSessionWrappedPassphrase()),
+                        Utils.base64decode(req.getTransWrappedSessionKey()), Utils.base64decode(req.getNonceData()),
+                        req.getCertificate());
+            } catch (JAXBException e) {
+                System.err.println("Error: Cannot parse the request file.");
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            } catch (FileNotFoundException e) {
+                System.err.println("Error: Cannot locate file at path: " + requestFile);
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            }
+
+        } else {
+            String keyId = cmd.getOptionValue("keyId");
+            response = keyCLI.keyClient.recoverKey(new KeyId(keyId), null, null, null, null);
+        }
+
+        MainCLI.printMessage("Recovered Key Information");
+        KeyCLI.printKeyRequestInfo(response.getRequestInfo());
+
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRequestReviewCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestReviewCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..9f60fff8b4006af90dd71b4fbff457ff96799a53
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestReviewCLI.java
@@ -0,0 +1,71 @@
+package com.netscape.cmstools.key;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.key.KeyRequestInfo;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+public class KeyRequestReviewCLI extends CLI {
+    public KeyCLI keyCLI;
+
+    public KeyRequestReviewCLI(KeyCLI keyCLI) {
+        super("request-review", "Review key request", keyCLI);
+        this.keyCLI = keyCLI;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " <Request ID> [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) {
+        Option option = new Option(null, "action", true,
+                "Action to be performed on the request.\n Available actions - [approve|reject|cancel].");
+        option.setArgName("Action to perform");
+        option.setRequired(true);
+        options.addOption(option);
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (ParseException e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        String[] cmdArgs = cmd.getArgs();
+        if (cmdArgs.length != 1) {
+            System.err.println("Error: Invalid arguements provided.");
+            printHelp();
+            System.exit(1);
+        }
+        RequestId reqId = new RequestId(cmdArgs[0]);
+
+        String action = cmd.getOptionValue("action");
+        switch (action.toLowerCase()) {
+        case "approve":
+            keyCLI.keyClient.approveRequest(reqId);
+            break;
+        case "reject":
+            keyCLI.keyClient.rejectRequest(reqId);
+            break;
+        case "cancel":
+            keyCLI.keyClient.cancelRequest(reqId);
+            break;
+        default:
+            System.err.println("Error: Invalid action.");
+            printHelp();
+            System.exit(1);
+        }
+
+        KeyRequestInfo keyRequestInfo = keyCLI.keyClient.getRequestInfo(reqId);
+
+        MainCLI.printMessage("Result");
+        KeyCLI.printKeyRequestInfo(keyRequestInfo);
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRequestShowCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestShowCLI.java
index 3da5de27923c6202ddedeaf84fd5b162c6fa05cd..412748f873e292d47e2dd8501356c05490f4dd20 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyRequestShowCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestShowCLI.java
@@ -12,7 +12,7 @@
 // with this program; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 //
-// (C) 2012 Red Hat, Inc.
+// (C) 2014 Red Hat, Inc.
 // All rights reserved.
 // --- END COPYRIGHT BLOCK ---
 
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateFindCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateFindCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..375cb61b881293ef766fb2eaa257c34935697e00
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateFindCLI.java
@@ -0,0 +1,43 @@
+package com.netscape.cmstools.key;
+
+import java.util.ArrayList;
+
+import com.netscape.certsrv.key.Template;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+public class KeyRequestTemplateFindCLI extends CLI {
+    public KeyCLI keyCLI;
+
+    public ArrayList<Template> templates = new ArrayList<Template>();
+
+    public KeyRequestTemplateFindCLI(KeyCLI keyCLI) {
+        super("template-find", "List request template IDs", keyCLI);
+        this.keyCLI = keyCLI;
+        createTemplateList();
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) {
+        MainCLI.printMessage("List of templates");
+        for (Template template : templates) {
+            template.printTemplateInfo();
+        }
+    }
+
+    public void createTemplateList() {
+        Template template = new Template("archiveKey", "Key Archival Request",
+                "Template file for submitting a key archival request");
+        templates.add(template);
+        template = new Template("retrieveKey", "Key retrieval request",
+                "Template for submitting a key retrieval or key recovery request.");
+        templates.add(template);
+        template = new Template("generateKey", "Symmetric Key generation request",
+                "Template for submitting a request for generating a symmetric key.");
+        templates.add(template);
+    }
+
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateShowCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateShowCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..87284f4991dcfa5d29c29fee57702112799c9f3f
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRequestTemplateShowCLI.java
@@ -0,0 +1,154 @@
+package com.netscape.cmstools.key;
+
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.base.ResourceMessage;
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.key.KeyArchivalRequest;
+import com.netscape.certsrv.key.KeyRecoveryRequest;
+import com.netscape.certsrv.key.SymKeyGenerationRequest;
+import com.netscape.certsrv.request.RequestId;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+
+public class KeyRequestTemplateShowCLI extends CLI {
+    public KeyCLI keyCLI;
+
+    public KeyRequestTemplateShowCLI(KeyCLI keyCLI) {
+        super("template-show", "Get request template", keyCLI);
+        this.keyCLI = keyCLI;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName()
+                + " <Template ID [archiveKey, retrieveKey, recoverKey, generateKey]> [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) {
+
+        Option option = new Option(null, "output-file", true, "Location where the template has to be stored.");
+        option.setArgName("File to write the template to.");
+        options.addOption(option);
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+        } catch (ParseException e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(-1);
+        }
+        ;
+
+        String[] cmdArgs = cmd.getArgs();
+        if (cmdArgs.length < 1) {
+            printHelp();
+            System.exit(-1);
+        }
+
+        String templateId = cmdArgs[0];
+        String writeToFile = cmd.getOptionValue("output-file");
+
+        ResourceMessage data = null;
+        String message = null;
+        switch (templateId) {
+        case "archiveKey":
+            data = getSampleArchivalRequest();
+            message = "key archival request";
+            break;
+        case "retrieveKey":
+        case "recoverKey":
+            message = "key recover request";
+            data = getSampleRecoveryRequest();
+            break;
+        case "generateKey":
+            message = "symmetric key generation request";
+            data = getSampleGenerationRequest();
+            break;
+        default:
+            System.err.println("Error: Invalid template id.");
+            printHelp();
+            System.exit(-1);
+        }
+
+        if ((writeToFile != null) && (writeToFile.trim().length() != 0)) {
+            try {
+                FileOutputStream fOS = new FileOutputStream(writeToFile);
+                printRequestTemplate(data, fOS);
+            } catch (JAXBException e) {
+                System.err.println("Error: Cannot write the file");
+                if (verbose)
+                    e.printStackTrace();
+            } catch (FileNotFoundException e) {
+                System.err.println("Error: Cannot write the file");
+                if (verbose)
+                    e.printStackTrace();
+            }
+        } else {
+            MainCLI.printMessage("Template for " + message);
+            try {
+                printRequestTemplate(data, System.out);
+            } catch (JAXBException e) {
+                System.err.println(e.getMessage());
+                if (verbose)
+                    e.printStackTrace();
+            }
+        }
+    }
+
+    public <T> void printRequestTemplate(T t, OutputStream os) throws JAXBException {
+        JAXBContext context = JAXBContext.newInstance(t.getClass());
+        Marshaller marshaller = context.createMarshaller();
+        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
+        marshaller.marshal(t, os);
+    }
+
+    public KeyArchivalRequest getSampleArchivalRequest() {
+        KeyArchivalRequest data = new KeyArchivalRequest();
+        data.setClientKeyId("");
+        data.setDataType("symmetricKey/passphrase/asymmetricKey");
+        data.setKeyAlgorithm("");
+        data.setKeySize(0);
+        data.setClientKeyId("");
+        data.setAlgorithmOID("");
+        data.setSymmetricAlgorithmParams("Base64 encoded NonceData");
+        data.setWrappedPrivateData("Base64 encoded session key wrapped secret");
+        data.setTransWrappedSessionKey("Base64 encoded transport key wrapped session key");
+        data.setPKIArchiveOptions("Base 64 encoded PKIArchiveOptions object");
+        return data;
+    }
+
+    public KeyRecoveryRequest getSampleRecoveryRequest() {
+        KeyRecoveryRequest data = new KeyRecoveryRequest();
+        data.setKeyId(new KeyId("1"));
+        data.setRequestId(new RequestId("1"));
+        data.setNonceData("Base64 encoded NonceData");
+        data.setPassphrase("Passphrase to encrypt the secret with/Passphrase for the PKCS12 file returned");
+        data.setSessionWrappedPassphrase("Base64 encoded session key wrapped passphrase");
+        data.setTransWrappedSessionKey("Base64 encoded transport key wrapped session key");
+        data.setCertificate("Base64 certificate used for recoring the key.");
+
+        return data;
+    }
+
+    public SymKeyGenerationRequest getSampleGenerationRequest() {
+        SymKeyGenerationRequest data = new SymKeyGenerationRequest();
+        data.setClientKeyId("");
+        data.setKeyAlgorithm("[AES/DES/DES3/DESede/RC2/RC4]");
+        data.setKeySize(128);
+        data.setUsages(Arrays.asList(new String[] { "wrap", "unwrap", "sign", "verify", "encrypt", "decrypt" }));
+
+        return data;
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b5ddc6a7474177c31aa6d294d3e8a386211c4a9
--- /dev/null
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyRetrieveCLI.java
@@ -0,0 +1,132 @@
+package com.netscape.cmstools.key;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.ParseException;
+
+import com.netscape.certsrv.dbs.keydb.KeyId;
+import com.netscape.certsrv.key.Key;
+import com.netscape.certsrv.key.KeyRecoveryRequest;
+import com.netscape.cmstools.cli.CLI;
+import com.netscape.cmstools.cli.MainCLI;
+import com.netscape.cmsutil.util.Utils;
+
+public class KeyRetrieveCLI extends CLI {
+    public KeyCLI keyCLI;
+
+    public KeyRetrieveCLI(KeyCLI keyCLI) {
+        super("retrieve", "Retrieve key", keyCLI);
+        this.keyCLI = keyCLI;
+    }
+
+    public void printHelp() {
+        formatter.printHelp(getFullName() + " <Request ID> [OPTIONS]", options);
+    }
+
+    public void execute(String[] args) {
+
+        Option option = new Option(null, "keyId", true, "Key Identifier for the secret to be recovered.");
+        option.setArgName("Key Identifier");
+        options.addOption(option);
+
+        option = new Option(null, "passphrase", true, "Passphrase to encrypt the key information.");
+        option.setArgName("Passphrase");
+        options.addOption(option);
+
+        option = new Option(null, "input", true, "Location of the request template file.");
+        option.setArgName("Input file path");
+        options.addOption(option);
+
+        CommandLine cmd = null;
+        try {
+            cmd = parser.parse(options, args);
+
+        } catch (ParseException e) {
+            System.err.println("Error: " + e.getMessage());
+            printHelp();
+            System.exit(1);
+        }
+
+        String requestFile = cmd.getOptionValue("input");
+
+        Key keyData = null;
+
+        if ((requestFile != null) && (requestFile.trim().length() != 0)) {
+            try {
+                JAXBContext context = JAXBContext.newInstance(KeyRecoveryRequest.class);
+                Unmarshaller unmarshaller = context.createUnmarshaller();
+                FileInputStream fis = new FileInputStream(requestFile);
+                KeyRecoveryRequest req = (KeyRecoveryRequest) unmarshaller.unmarshal(fis);
+
+                if (req.getKeyId() == null) {
+                    System.err.println("Error: Key Id must be specified in the request file.");
+                    System.exit(-1);
+                }
+                if (req.getCertificate() != null) {
+                    keyData = keyCLI.keyClient.retrieveKeyByPKCS12(req.getKeyId(), req.getCertificate(),
+                            req.getPassphrase());
+                } else if (req.getPassphrase() != null) {
+                    keyData = keyCLI.keyClient.retrieveKeyByPassphrase(req.getKeyId(), req.getPassphrase());
+                } else if (req.getSessionWrappedPassphrase() != null) {
+                    keyData = keyCLI.keyClient.retrieveKeyUsingWrappedPassphrase(req.getKeyId(),
+                            Utils.base64decode(req.getTransWrappedSessionKey()),
+                            Utils.base64decode(req.getSessionWrappedPassphrase()),
+                            Utils.base64decode(req.getNonceData()));
+                } else if (req.getTransWrappedSessionKey() != null) {
+                    keyData = keyCLI.keyClient.retrieveKey(req.getKeyId(),
+                            Utils.base64decode(req.getTransWrappedSessionKey()));
+                } else {
+                    keyData = keyCLI.keyClient.retrieveKey(req.getKeyId());
+                }
+            } catch (JAXBException e) {
+                System.err.println("Error: Cannot parse the request file.");
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            } catch (FileNotFoundException e) {
+                System.err.println("Error: Cannot locate file at path: " + requestFile);
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            } catch (Exception e) {
+                System.err.println(e.getMessage());
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            }
+
+        } else {
+            String keyId = cmd.getOptionValue("keyId");
+            try {
+                keyData = keyCLI.keyClient.retrieveKey(new KeyId(keyId));
+            } catch (Exception e) {
+                System.err.println(e.getMessage());
+                if (verbose)
+                    e.printStackTrace();
+                System.exit(-1);
+            }
+        }
+        MainCLI.printMessage("Retrieve Key Information");
+        printKeyData(keyData);
+    }
+
+    public void printKeyData(Key key) {
+        System.out.println("  Key Algorithm: " + key.getAlgorithm());
+        System.out.println("  Key Size: " + key.getSize());
+        System.out.println("  Nonce data: " + Utils.base64encode(key.getNonceData()));
+        System.out.println("  Encrypted Data:" + Utils.base64encode(key.getEncryptedData()));
+        if (key.getData() != null) {
+            System.out.println("  Actual archived data: " + Utils.base64encode(key.getData()));
+        }
+        if (key.getP12Data() != null) {
+            System.out.println("  Key data in PKCS12 format: " + key.getP12Data());
+        }
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/key/KeyShowCLI.java b/base/java-tools/src/com/netscape/cmstools/key/KeyShowCLI.java
index 5f9a761874aa1ee91179e264014abc70103c0e54..cc76f4c4be596b1671a0c1646be346904f7fbd98 100644
--- a/base/java-tools/src/com/netscape/cmstools/key/KeyShowCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/key/KeyShowCLI.java
@@ -12,7 +12,7 @@
 // with this program; if not, write to the Free Software Foundation, Inc.,
 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 //
-// (C) 2012 Red Hat, Inc.
+// (C) 2014 Red Hat, Inc.
 // All rights reserved.
 // --- END COPYRIGHT BLOCK ---
 
@@ -22,11 +22,11 @@ import com.netscape.certsrv.dbs.keydb.KeyId;
 import com.netscape.certsrv.key.KeyInfo;
 import com.netscape.cmstools.cli.CLI;
 
-public class KeyShowCLI extends CLI{
+public class KeyShowCLI extends CLI {
 
     public KeyCLI keyCLI;
 
-    public KeyShowCLI(KeyCLI keyCLI){
+    public KeyShowCLI(KeyCLI keyCLI) {
         super("show", "Get key", keyCLI);
         this.keyCLI = keyCLI;
     }
@@ -35,9 +35,9 @@ public class KeyShowCLI extends CLI{
         formatter.printHelp(getFullName() + " <Key Id>", options);
     }
 
-    public void execute(String[] args){
+    public void execute(String[] args) {
 
-        if (args.length != 1){
+        if (args.length != 1) {
             printHelp();
             System.exit(-1);
         }
-- 
1.8.5.3

