Revision: cb90fba8cbff
Branch: default
Author: gm2552
Date: Thu Dec 4 14:12:54 2014 UTC
Log: Adding additional pkcs11 support and tools. Updating to
1.5-SNAPSHOT.
https://code.google.com/p/nhin-d/source/detail?r=cb90fba8cbff
Added:
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/CommandLineTokenLoginCallback.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManagerUI.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/commands/KeyModel.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/commands/PKCS11Commands.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/commands/printers/KeyPrinter.java
/java/direct-common/src/main/java/org/nhindirect/common/tooling/printer/AbstractRecordPrinter.java
/java/direct-common/src/main/java/org/nhindirect/common/tooling/printer/RecordPrinter.java
/java/direct-common/src/test/resources/pkcs11Config/keyStore.cfg
Modified:
/java/direct-common/src/main/java/org/nhindirect/common/crypto/KeyStoreProtectionManager.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/AbstractPKCS11TokenKeyStoreProtectionManager.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/BootstrappedKeyStoreProtectionManager.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/DynamicPKCS11TokenKeyStoreProtectionManager.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/StaticPKCS11TokenKeyStoreProtectionManager.java
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManager.java
=======================================
--- /dev/null
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/CommandLineTokenLoginCallback.java
Thu Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,55 @@
+package org.nhindirect.common.crypto.tools;
+
+import java.io.BufferedReader;
+import java.io.Console;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+
+public class CommandLineTokenLoginCallback implements CallbackHandler
+{
+ public Object waitObject = new Object();
+
+ public boolean loginSuccessful = false;
+
+ public CommandLineTokenLoginCallback()
+ {
+ }
+
+ @Override
+ public synchronized void handle(Callback[] callbacks) throws IOException,
UnsupportedCallbackException
+ {
+ for (Callback callback : callbacks)
+ {
+ if (callback instanceof PasswordCallback)
+ {
+
+ final Console cons = System.console();
+ char[] passwd = null;
+ if (cons != null)
+ {
+ passwd = cons.readPassword("[%s]", "Enter hardware token
password: ");
+ java.util.Arrays.fill(passwd, ' ');
+ }
+ else
+ {
+ System.out.print("Enter hardware token password: ");
+ final BufferedReader reader = new BufferedReader(new
InputStreamReader(
+ System.in));
+ passwd = reader.readLine().toCharArray();
+ }
+
+
+ ((PasswordCallback)callback).setPassword(passwd);
+
+ }
+ }
+
+ this.notifyAll();
+ }
+
+}
=======================================
--- /dev/null
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManagerUI.java
Thu Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,456 @@
+package org.nhindirect.common.crypto.tools;
+
+import java.awt.AWTEvent;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GraphicsEnvironment;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.table.DefaultTableModel;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.exceptions.CryptoException;
+import
org.nhindirect.common.crypto.impl.DynamicPKCS11TokenKeyStoreProtectionManager;
+
+///CLOVER:OFF
+public class PKCS11SecretKeyManagerUI extends JFrame
+{
+
+ private static final long serialVersionUID = 4851276510546674236L;
+
+ protected static String pkcs11ProviderCfg = null;
+ protected static String keyStoreConfigFile = null;
+
+ protected static MutableKeyStoreProtectionManager mgr = null;
+
+ private static String keyStoreType = null;
+ private static String providerName = null;
+ private static String keyStoreSource = null;
+
+ protected JTable keyDataTable;
+ protected JButton removeKeyButton;
+ protected JButton addAESKeyButton;
+ protected JButton addGenericKeyButton;
+ protected DefaultTableModel keyDataModel;
+ protected JButton quitButton;
+
+
+ public static void main(String[] argv)
+ {
+ // need to check if there is a configuration for the PKCS11
+ // provider... if not, assume the JVM has already been configured for one
+ if (argv.length > 0)
+ {
+
+ // Check parameters
+ for (int i = 0; i < argv.length; i++)
+ {
+ String arg = argv[i];
+
+ // Options
+ if (!arg.startsWith("-"))
+ {
+ System.err.println("Error: Unexpected argument [" + arg
+ "]\n");
+ printUsage();
+ System.exit(-1);
+ }
+ else if (arg.equalsIgnoreCase("-pkcscfg"))
+ {
+ if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
+ {
+ System.err.println("Error: Missing pkcs config file");
+ System.exit(-1);
+ }
+
+ pkcs11ProviderCfg = argv[++i];
+
+ }
+ else if (arg.equals("-keyStoreCfg"))
+ {
+ if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
+ {
+ System.err.println("Error: Missing keystore config
file");
+ System.exit(-1);
+ }
+ keyStoreConfigFile = argv[++i];
+ }
+ else if (arg.equals("-help"))
+ {
+ printUsage();
+ System.exit(-1);
+ }
+ else
+ {
+ System.err.println("Error: Unknown argument " + arg
+ "\n");
+ printUsage();
+ System.exit(-1);
+ }
+ }
+ }
+
+ if (keyStoreConfigFile != null)
+ {
+ try
+ {
+ // get additional properties
+ final InputStream inStream = FileUtils.openInputStream(new
File(keyStoreConfigFile));
+
+ final Properties props = new Properties();
+ props.load(inStream);
+
+ keyStoreType = props.getProperty("keyStoreType");
+ providerName = props.getProperty("keyStoreProviderName");
+ keyStoreSource = props.getProperty("keyStoreSource");
+ }
+ catch (IOException e)
+ {
+ System.err.println("Error reading keystore config file to
properties: " + e.getMessage());
+ System.exit(-1);
+ }
+ }
+
+ // need to login
+ try
+ {
+ mgr = tokenLogin();
+ }
+ catch (CryptoException e)
+ {
+ JOptionPane.showMessageDialog(null, "Failed to login to hardware
token: " + e.getMessage(), "Token Login Failure",
+ JOptionPane.ERROR_MESSAGE);
+ System.exit(-1);
+ }
+ final PKCS11SecretKeyManagerUI hi = new PKCS11SecretKeyManagerUI();
+ hi.setVisible(true);
+ }
+
+ /*
+ * Print program usage.
+ */
+ private static void printUsage()
+ {
+ StringBuffer use = new StringBuffer();
+ use.append("Usage:\n");
+ use.append("java PKCS11SecretKeyManagerUI (options)...\n\n");
+ use.append("options:\n");
+ use.append("-pkcscfg PKCS11 Config File Optional location for
the PKCS11 provider configuration. If this is not" +
+ " set, then it is assumed that the JVM has already been
configured to support your PKCS11 token.\n");
+ use.append(" Default: \"\"\n\n");
+
+ System.err.println(use);
+ }
+
+ public static MutableKeyStoreProtectionManager tokenLogin() throws
CryptoException
+ {
+
+ TokenLoginCallback login = new TokenLoginCallback();
+
+ final DynamicPKCS11TokenKeyStoreProtectionManager loginMgr = new
DynamicPKCS11TokenKeyStoreProtectionManager();
+
+ loginMgr.setKeyStoreProviderName(providerName);
+
+ if (!StringUtils.isEmpty(keyStoreType))
+ loginMgr.setKeyStoreType(keyStoreType);
+
+ if (!StringUtils.isEmpty(keyStoreSource))
+ {
+ InputStream str = new ByteArrayInputStream(keyStoreSource.getBytes());
+ loginMgr.setKeyStoreSource(str);
+ }
+
+ if (!StringUtils.isEmpty(pkcs11ProviderCfg))
+ loginMgr.setPcks11ConfigFile(pkcs11ProviderCfg);
+
+ loginMgr.setCallbackHandler(login);
+
+ loginMgr.initTokenStore();
+
+ return loginMgr;
+ }
+
+ public PKCS11SecretKeyManagerUI()
+ {
+ super("DirectProject PKCS11 Secret Key Manager");
+ setDefaultLookAndFeelDecorated(true);
+ setSize(700, 700);
+
+ Point pt =
GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
+
+ this.setLocation(pt.x - (350), pt.y - (350));
+
+ enableEvents(AWTEvent.WINDOW_EVENT_MASK);
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ initUI();
+
+ addActions();
+
+ updateKeyTableData();
+ }
+
+ private void initUI()
+ {
+ this.getContentPane().setLayout(new BorderLayout(5, 5));
+
+ // Top Panel
+ JPanel topPanel = new JPanel();
+ topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+
+ addAESKeyButton = new JButton("Add AES Key");
+ addAESKeyButton.setSize(new Dimension(30, 100));
+ addGenericKeyButton = new JButton("Add Text Key");
+ addGenericKeyButton.setSize(new Dimension(30, 100));
+ removeKeyButton = new JButton("Remove Key(s)");
+ removeKeyButton.setSize(new Dimension(30, 100));
+
+ topPanel.add(addAESKeyButton);
+ topPanel.add(addGenericKeyButton);
+ topPanel.add(removeKeyButton);
+
+ this.getContentPane().add(topPanel, BorderLayout.NORTH);
+
+
+ // Middle and list panel
+ JPanel midPanel = new JPanel();
+ midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ midPanel.setLayout(new BorderLayout(5, 5));
+
+ JLabel keyListLabel = new JLabel("Secret Keys:");
+
+ Object[][] data = {};
+ String[] columnNames = {"Key Alias", "Key Type", "Key Value"};
+
+ keyDataModel = new DefaultTableModel(data, columnNames);
+ keyDataTable = new JTable(keyDataModel);
+ JScrollPane scrollPane = new JScrollPane(keyDataTable);
+ keyDataTable.setFillsViewportHeight(true);
+
+ midPanel.add(keyListLabel, BorderLayout.NORTH);
+ midPanel.add(scrollPane, BorderLayout.CENTER);
+
+ this.getContentPane().add(midPanel, BorderLayout.CENTER);
+
+ // Bottom Panel
+ JPanel bottomPanel = new JPanel();
+ bottomPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
+
+ quitButton = new JButton("Quit");
+ quitButton.setSize(new Dimension(30, 100));
+ bottomPanel.add(quitButton);
+
+ this.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
+ }
+
+ private void addActions()
+ {
+ addAESKeyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ addAESKey();
+ }
+ });
+
+ addGenericKeyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ addTextKey();
+ }
+ });
+
+ removeKeyButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ removeKeys();
+ }
+ });
+
+ quitButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e)
+ {
+ System.exit(-1);
+ }
+ });
+ }
+
+ private void addAESKey()
+ {
+ final String input = JOptionPane.showInputDialog(this, "Key Alias
Name:", "Generate New random AES Secret Key", JOptionPane.OK_CANCEL_OPTION);
+ if (input != null && !input.trim().isEmpty())
+ {
+ // generate a new random secret key
+ try
+ {
+ final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ final SecureRandom random = new SecureRandom(); // cryptograph. secure
random
+ keyGen.init(random);
+ final SecretKey key = keyGen.generateKey();
+
+ mgr.clearKey(input);
+ mgr.setKey(input, key);
+
+ updateKeyTableData();
+ }
+ catch (Exception e)
+ {
+ JOptionPane.showMessageDialog(this, "Failed to add random new AES
key: " + e.getMessage(), "Add Key Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+
+ private void addTextKey()
+ {
+
+ final JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+
+ final JPanel topPanel = new JPanel();
+ final JLabel aliasLabel = new JLabel("Alias:");
+ aliasLabel.setSize(60, 30);
+ final JTextField aliasField = new JTextField(40);
+
+ topPanel.add(aliasLabel);
+ topPanel.add(aliasField);
+
+ final JPanel bottomPanel = new JPanel();
+ final JLabel keyLabel = new JLabel("Key:");
+ keyLabel.setSize(60, 30);
+ final JTextField keyField = new JTextField(40);
+
+ bottomPanel.add(keyLabel);
+ bottomPanel.add(keyField);
+
+
+ panel.add(topPanel, BorderLayout.NORTH);
+ panel.add(bottomPanel, BorderLayout.SOUTH);
+
+ final String[] options = new String[]{"OK", "Cancel"};
+ int option = JOptionPane.showOptionDialog(null, panel, "Generate New
Text Based Secret Key ",
+ JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
+ null, options, options[0]);
+
+ if (option == JOptionPane.OK_OPTION)
+ {
+ final String alias = aliasField.getText();
+ final String keyText = keyField.getText();
+
+
+ if ((alias != null && !alias.trim().isEmpty()) &&
+ keyText != null && !keyText.trim().isEmpty())
+ {
+ // generate a new random secret key
+ try
+ {
+ byte[] key = keyText.getBytes("UTF-8");
+ MessageDigest sha = MessageDigest.getInstance("SHA-1");
+ key = sha.digest(key);
+ key = Arrays.copyOf(key, 16); // use only first 128 bit
+
+ mgr.clearKey(alias);
+ mgr.setKey(alias, new SecretKeySpec(key, "AES"));
+
+ updateKeyTableData();
+ }
+ catch (Exception e)
+ {
+ JOptionPane.showMessageDialog(this, "Failed to add new text based
secret key: " + e.getMessage(), "Add Key Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ }
+ }
+
+ private void removeKeys()
+ {
+ if (keyDataTable.getSelectedRowCount() == 0)
+ {
+ JOptionPane.showMessageDialog(this, "No keys are selected.", "Remove
Keys", JOptionPane.INFORMATION_MESSAGE);
+ return;
+ }
+ else if (JOptionPane.showConfirmDialog(this, "Are you sure you want to
removed the selected Keys?", "Remove Keys", JOptionPane.YES_NO_OPTION) ==
JOptionPane.YES_OPTION)
+ {
+ int[] rows = keyDataTable.getSelectedRows();
+ for (int row : rows)
+ {
+ final String alias = (String)keyDataTable.getValueAt(row, 0);
+
+ try
+ {
+ mgr.clearKey(alias);
+ }
+ catch (Exception e)
+ {
+ JOptionPane.showMessageDialog(this, "Failed to remove key with
alias " + alias + ":" + e.getMessage(),
+ "Remove Key Error", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ updateKeyTableData();
+ }
+
+
+ }
+
+ private void updateKeyTableData()
+ {
+ try
+ {
+ for (int ctx = (keyDataModel.getRowCount() -1 ); ctx >=0; --ctx)
+ {
+ keyDataModel.removeRow(ctx);
+
+ }
+ // get all of the data from the token
+ Map<String, Key> keys = mgr.getAllKeys();
+ for (Entry<String, Key> entry : keys.entrySet())
+ {
+ String type = "";
+ final Object value = entry.getValue();
+ if (value instanceof SecretKey)
+ type = "Secret Key: " + ((Key)value).getAlgorithm();
+ else if (value instanceof PublicKey)
+ type = "Public Key: " + ((Key)value).getAlgorithm();
+ else if (value instanceof PrivateKey)
+ type = "Private Key: " + ((Key)value).getAlgorithm();
+ else
+ type = value.getClass().toString();
+
+ keyDataModel.addRow(new Object[] {entry.getKey(), type ,"***"});
+ keyDataModel.fireTableDataChanged();
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
+///CLOVER:ON
=======================================
--- /dev/null
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/commands/KeyModel.java
Thu Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,34 @@
+package org.nhindirect.common.crypto.tools.commands;
+
+import java.security.Key;
+
+public class KeyModel
+{
+ protected final String keyName;
+ protected final Key key;
+ protected final char[] keyText;
+
+ public KeyModel(String keyName, Key key, char[] keyText)
+ {
+ this.keyName = keyName;
+ this.key = key;
+ this.keyText = keyText;
+ }
+
+ public String getKeyName()
+ {
+ return keyName;
+ }
+
+ public Key getKey()
+ {
+ return key;
+ }
+
+ public char[] getKeyText()
+ {
+ return keyText;
+ }
+
+
+}
=======================================
--- /dev/null
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/commands/PKCS11Commands.java
Thu Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,145 @@
+package org.nhindirect.common.crypto.tools.commands;
+
+import java.security.Key;
+import java.security.MessageDigest;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.tools.commands.printers.KeyPrinter;
+import org.nhindirect.common.tooling.Command;
+import org.nhindirect.common.tooling.StringArrayUtil;
+
+public class PKCS11Commands
+{
+ private static final String LIST_SECRET_KEYS = "Lists secret keys in
the HSM";
+
+ private static final String ADD_RANDOM_SECRET_KEY = "Creates a new
named random AES128 secret key\r\n" +
+ "\r\n keyName" +
+ "\r\n\t keyName: The unique name of the new secret key. Place
the key name in quotes (\"\") if there are spaces in the name.";
+
+ private static final String ADD_USER_SECRET_KEY = "Creates a new named
AES128 secret key via user entered text\r\n" +
+ "\r\n keyName keyText" +
+ "\r\n\t keyName: The unique name of the new secret key. Place
the key name in quotes (\"\") if there are spaces in the name." +
+ "\r\n\t keyText: The user entered key text. Place the text in
quotes (\"\") if there are spaces in the text.";
+
+ private static final String REMOVE_SECRET_KEY = "Removes a new named
secret key\r\n " +
+ "\r\n keyName" +
+ "\r\n\t keyName: The unique name of the secret key. Place the
key name in quotes (\"\") if there are spaces in the name.";
+
+ protected final KeyPrinter keyPrinter;
+
+ protected final MutableKeyStoreProtectionManager mgr;
+
+ public PKCS11Commands(MutableKeyStoreProtectionManager mgr)
+ {
+ this.mgr = mgr;
+ this.keyPrinter = new KeyPrinter();
+ }
+
+ @Command(name = "ListSecretKeys", usage = LIST_SECRET_KEYS)
+ public void listCerts(String[] args)
+ {
+ try
+ {
+ // get all of the data from the token
+ final Map<String, Key> keys = mgr.getAllKeys();
+
+ if (keys.isEmpty())
+ System.out.println("No keys found");
+
+ else
+ {
+ final Collection<KeyModel> models = new ArrayList<KeyModel>();
+
+ for (Entry<String, Key> entry : keys.entrySet())
+ {
+ char[] keyText = (entry.getValue().getEncoded() !=
null) ? "*****".toCharArray() : "Not Extractable".toCharArray();
+
+ final KeyModel keyModel = new KeyModel(entry.getKey(),
entry.getValue(), keyText);
+ models.add(keyModel);
+ }
+
+ keyPrinter.printRecords(models);
+ }
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+
+ }
+
+
+ @Command(name = "CreateRandomSecretKey", usage = ADD_RANDOM_SECRET_KEY)
+ public void addRandomSecretKey(String[] args)
+ {
+ final String keyName = StringArrayUtil.getRequiredValue(args, 0);
+
+ // generate a new random secret key
+ try
+ {
+ final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+ final SecureRandom random = new SecureRandom(); // cryptograph. secure
random
+ keyGen.init(random);
+ final SecretKey key = keyGen.generateKey();
+
+ mgr.clearKey(keyName);
+ mgr.setKey(keyName, key);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Failed to add new random secret key: " +
e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ @Command(name = "CreateUserSecretKey", usage = ADD_USER_SECRET_KEY)
+ public void addUserSecretKey(String[] args)
+ {
+ final String keyName = StringArrayUtil.getRequiredValue(args, 0);
+ final String keyText = StringArrayUtil.getRequiredValue(args, 1);
+
+ try
+ {
+ byte[] key = keyText.getBytes("UTF-8");
+ MessageDigest sha = MessageDigest.getInstance("SHA-1");
+ key = sha.digest(key);
+ key = Arrays.copyOf(key, 16); // use only first 128 bit
+
+ mgr.clearKey(keyName);
+ mgr.setKey(keyName, new SecretKeySpec(key, "AES"));
+ }
+ catch (Exception e)
+ {
+ System.err.println("Failed to add new random secret key: " +
e.getMessage());
+ e.printStackTrace();
+ }
+ }
+
+ @Command(name = "RemoveSecretKey", usage = REMOVE_SECRET_KEY)
+ public void removeSecretKey(String[] args)
+ {
+ String keyName = StringArrayUtil.getRequiredValue(args, 0);
+
+ // remove secret key
+ try
+ {
+
+ mgr.clearKey(keyName);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Failed to add new random secret key: " +
e.getMessage());
+ }
+ }
+
+}
=======================================
--- /dev/null
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/commands/printers/KeyPrinter.java
Thu Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,65 @@
+package org.nhindirect.common.crypto.tools.commands.printers;
+
+import java.security.Key;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.nhindirect.common.crypto.tools.commands.KeyModel;
+import org.nhindirect.common.tooling.printer.AbstractRecordPrinter;
+
+public class KeyPrinter extends AbstractRecordPrinter<KeyModel>
+{
+ protected static final Collection<ReportColumn> REPORT_COLS;
+
+ protected static final String KEY_NAME_COL = "Key Name";
+ protected static final String KEY_TYPE_COL = "Key Type";
+ protected static final String KEY_TEXT_COL = "Key Text";
+
+ static
+ {
+ REPORT_COLS = new ArrayList<ReportColumn>();
+
+ REPORT_COLS.add(new ReportColumn(KEY_NAME_COL, 40, "KeyName"));
+ REPORT_COLS.add(new ReportColumn(KEY_TYPE_COL, 25, "KeyType"));
+ REPORT_COLS.add(new ReportColumn(KEY_TEXT_COL, 16, "KeyText"));
+ }
+
+ public KeyPrinter()
+ {
+ super(81, REPORT_COLS);
+ }
+
+ @Override
+ protected String getColumnValue(ReportColumn column, KeyModel model)
+ {
+
+ try
+ {
+ if (column.getHeader().equals(KEY_TYPE_COL))
+ {
+ String type = "";
+ final Key key = model.getKey();
+ if (key instanceof javax.crypto.SecretKey)
+ type = "Secret Key: " + key.getAlgorithm();
+ else if (key instanceof java.security.PublicKey)
+ type = "Public Key: " + key.getAlgorithm();
+ else if (key instanceof java.security.PrivateKey)
+ type = "Private Key: " + key.getAlgorithm();
+ else
+ type = key.getClass().toString();
+
+ return type;
+ }
+ else if (column.getHeader().equals(KEY_TEXT_COL))
+ {
+ return new String(model.getKeyText());
+ }
+ else
+ return super.getColumnValue(column, model);
+ }
+ catch (Exception e)
+ {
+ return "ERROR: " + e.getMessage();
+ }
+ }
+}
=======================================
--- /dev/null
+++
/java/direct-common/src/main/java/org/nhindirect/common/tooling/printer/AbstractRecordPrinter.java
Thu Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,144 @@
+package org.nhindirect.common.tooling.printer;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+
+
+public abstract class AbstractRecordPrinter<T> implements RecordPrinter<T>
+{
+ protected final Collection<ReportColumn> reportColumns;
+ protected final int tableWidth;
+
+ public static class ReportColumn
+ {
+ protected final String header;
+ protected final int width;
+ protected final String fieldName;
+
+ public ReportColumn(String header, int width, String fieldName)
+ {
+ this.header = header;
+ this.width = width;
+ this.fieldName = fieldName;
+ }
+
+ public String getHeader()
+ {
+ return this.header;
+ }
+ }
+
+ public AbstractRecordPrinter(int tableWidth, Collection<ReportColumn>
reportColumns)
+ {
+ this.tableWidth = tableWidth;
+ this.reportColumns = reportColumns;
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void printRecord(T record)
+ {
+ printRecords(Arrays.asList(record));
+ }
+
+ @Override
+ public void printRecords(Collection<T> records)
+ {
+ printHeader();
+
+ for (T record : records)
+ printRecordInternal(record);
+ }
+
+ protected void printRecordInternal(T record)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ int cnt = 0;
+ for (ReportColumn column : reportColumns)
+ {
+
+
+ builder.append(" ");
+ String colValue = getColumnValue(column, record);
+ builder.append(colValue);
+ // pad the rest with spaces
+ int padSize = (column.width - 2 ) - colValue.length();
+ for (int i = 0; i < padSize; ++i)
+ builder.append(' ');
+
+ if (++cnt < reportColumns.size())
+ builder.append("|");
+ }
+
+ builder.append("\r\n");
+ for (int i = 0; i < tableWidth; ++i)
+ builder.append('-');
+
+ System.out.println(builder.toString());
+ }
+
+ protected String getColumnValue(ReportColumn column, T record)
+ {
+ // default is to get the field value by introspection using
+ // the field name
+ try
+ {
+ Method method = record.getClass().getDeclaredMethod("get" +
column.fieldName);
+ Object obj = method.invoke(record);
+ return obj.toString();
+ }
+ catch (Exception e)
+ {
+ return "ERROR: " + e.getMessage();
+ }
+ }
+
+ protected void printHeader()
+ {
+ StringBuilder builder = new StringBuilder();
+
+ // top of header
+ for (int i = 0; i < tableWidth; ++i)
+ builder.append('-');
+
+ builder.append("\r\n|");
+
+ int cnt = 0;
+ int widthUsed = 0;
+ for (ReportColumn column : reportColumns)
+ {
+ int currentWidth = 0;
+ if (++cnt >= reportColumns.size())
+ currentWidth = tableWidth - widthUsed;
+ else
+ currentWidth = column.width;
+
+ // center the header
+ int padding = (currentWidth - column.header.length()) / 2;
+
+ // add pre padding
+ for (int i = 0; i < padding; ++i)
+ builder.append(' ');
+
+ // print header
+ builder.append(column.header);
+
+ // add post padding
+ for (int i = 0; i < (padding -1); ++i)
+ builder.append(' ');
+
+ builder.append("|");
+
+ widthUsed += currentWidth;
+ }
+
+ // end of header
+ builder.append("\r\n");
+ for (int i = 0; i < tableWidth; ++i)
+ builder.append('-');
+
+ System.out.println(builder.toString());
+ }
+}
=======================================
--- /dev/null
+++
/java/direct-common/src/main/java/org/nhindirect/common/tooling/printer/RecordPrinter.java
Thu Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,10 @@
+package org.nhindirect.common.tooling.printer;
+
+import java.util.Collection;
+
+public interface RecordPrinter<T>
+{
+ public void printRecord(T rec);
+
+ public void printRecords(Collection<T> recs);
+}
=======================================
--- /dev/null
+++ /java/direct-common/src/test/resources/pkcs11Config/keyStore.cfg Thu
Dec 4 14:12:54 2014 UTC
@@ -0,0 +1,1 @@
+keyStoreProviderName=sun.security.pkcs11.SunPKCS11
=======================================
---
/java/direct-common/src/main/java/org/nhindirect/common/crypto/KeyStoreProtectionManager.java
Fri Apr 4 18:50:16 2014 UTC
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/KeyStoreProtectionManager.java
Thu Dec 4 14:12:54 2014 UTC
@@ -61,4 +61,12 @@
* @throws CryptoException
*/
public Map<String, Key> getAllKeys() throws CryptoException;
+
+ /**
+ * Gets a specific key by name.
+ * @param keyName The name of the key to retrieve. Returns null if the
key doesn't exist.
+ * @return They key specified by the name.
+ * @throws CryptoException
+ */
+ public Key getKey(String keyName) throws CryptoException;
}
=======================================
---
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/AbstractPKCS11TokenKeyStoreProtectionManager.java
Fri Apr 4 18:51:13 2014 UTC
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/AbstractPKCS11TokenKeyStoreProtectionManager.java
Thu Dec 4 14:12:54 2014 UTC
@@ -21,15 +21,24 @@
package org.nhindirect.common.crypto.impl;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.InputStream;
import java.security.Key;
import java.security.KeyStore;
+import java.security.Provider;
+import java.security.Security;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
+import java.util.Properties;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
import org.nhindirect.common.crypto.PKCS11Credential;
import org.nhindirect.common.crypto.exceptions.CryptoException;
@@ -43,10 +52,17 @@
public abstract class AbstractPKCS11TokenKeyStoreProtectionManager
implements MutableKeyStoreProtectionManager
{
+ protected static final String SUNPKCS11_KEYSTORE_PROVIDER_NAME
= "sun.security.pkcs11.SunPKCS11";
+ protected static final String DEFAULT_KESTORE_TYPE = "PKCS11";
+
protected PKCS11Credential credential;
protected String keyStorePassPhraseAlias;
protected String privateKeyPassPhraseAlias;
protected KeyStore ks;
+ protected String keyStoreType;
+ protected String keyStoreProviderName;
+ protected String pcks11ConfigFile;
+ protected InputStream keyStoreSource;
/**
* Empty constructor.
@@ -57,6 +73,10 @@
this.credential = null;
this.keyStorePassPhraseAlias = "";
this.privateKeyPassPhraseAlias = "";
+ this.keyStoreType = DEFAULT_KESTORE_TYPE;
+ this.keyStoreProviderName = "";
+ this.pcks11ConfigFile = "";
+ this.keyStoreSource = null;
}
/**
@@ -71,9 +91,75 @@
this.credential = credential;
this.keyStorePassPhraseAlias = keyStorePassPhraseAlias;
this.privateKeyPassPhraseAlias = privateKeyPassPhraseAlias;
+ this.keyStoreType = DEFAULT_KESTORE_TYPE;
+ this.keyStoreProviderName = "";
+ this.pcks11ConfigFile = "";
+ this.keyStoreSource = null;
initTokenStore();
}
+
+ @SuppressWarnings("restriction")
+ protected void loadProvider() throws CryptoException
+ {
+ try
+ {
+ // first see if we need to add a PKCS11 provider or custom provider
+
+ if (!StringUtils.isEmpty(this.keyStoreProviderName))
+ {
+ if (this.keyStoreProviderName.equals(SUNPKCS11_KEYSTORE_PROVIDER_NAME))
+ {
+ // we want to add a SunPKCS11 provider...
+ // this provider requires a config file
+ if (StringUtils.isEmpty(this.pcks11ConfigFile))
+ throw new IllegalStateException("SunPKCS11 providers require a
configuration file. There is not one set.");
+
+ // check and see if this is one of the same providers that is already
loaded
+ final InputStream inStream = FileUtils.openInputStream(new
File(this.pcks11ConfigFile));
+
+ final Properties props = new Properties();
+ props.load(inStream);
+ IOUtils.closeQuietly(inStream);
+
+ boolean providerFound = false;
+
+ final String requestedName = props.getProperty("name");
+
+ // check if this provider exists
+ if (!StringUtils.isEmpty(requestedName) &&
Security.getProvider(requestedName) != null)
+ providerFound = true;
+
+ if (!providerFound)
+ Security.addProvider(new
sun.security.pkcs11.SunPKCS11(this.pcks11ConfigFile));
+ }
+ else
+ {
+ // create the new provider
+ final Class<?> provider =
this.getClass().getClassLoader().loadClass(this.keyStoreProviderName);
+
+ // check if the provider is already loaded
+ boolean providerFound = false;
+ for (Provider existingProv : Security.getProviders())
+ {
+ if (existingProv.getClass().equals(provider))
+ {
+ providerFound = true;
+ break;
+ }
+ }
+
+ if (!providerFound)
+ Security.addProvider((Provider)provider.newInstance());
+
+ }
+ }
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error loading PKCS11 provder", e);
+ }
+ }
/**
* Sets the credential used to log into the token.
@@ -101,6 +187,38 @@
{
this.privateKeyPassPhraseAlias = privateKeyPassPhraseAlias;
}
+
+ public void setKeyStoreType(String keyStoreType)
+ {
+ this.keyStoreType = keyStoreType;
+ }
+
+ public void setKeyStoreSource(InputStream keyStoreSource)
+ {
+ this.keyStoreSource = keyStoreSource;
+ }
+
+ public void setKeyStoreSourceAsString(String keyStoreSource)
+ {
+ try
+ {
+ this.keyStoreSource = new
ByteArrayInputStream(keyStoreSource.getBytes("UTF-8"));
+ }
+ catch (Exception e)
+ {
+ /* do quietly, no-op */
+ }
+ }
+
+ public void setKeyStoreProviderName(String keyStoreProviderName)
+ {
+ this.keyStoreProviderName = keyStoreProviderName;
+ }
+
+ public void setPcks11ConfigFile(String pcks11ConfigFile)
+ {
+ this.pcks11ConfigFile = pcks11ConfigFile;
+ }
/**
* Initializes access to the token. This is implementation specific and
may require user interaction.
@@ -148,6 +266,26 @@
return keys;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Key getKey(String keyName) throws CryptoException
+ {
+ Key theKey = null;
+
+ try
+ {
+ theKey = ks.getKey(keyName, null);
+ }
+ catch (Exception e)
+ {
+ throw new CryptoException("Error extracting key from PKCS11 token", e);
+ }
+
+ return theKey;
+ }
/**
* {@inheritDoc}
@@ -338,11 +476,13 @@
{
try
{
- ks.deleteEntry(alias);
+ // make sure the key exists first
+ if (this.getKey(alias) != null)
+ ks.deleteEntry(alias);
}
catch (Exception e)
{
- throw new CryptoException("Error deleting key store protection from
PKCS11 token", e);
+ throw new CryptoException("Error deleting key from PKCS11 token", e);
}
}
}
=======================================
---
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/BootstrappedKeyStoreProtectionManager.java
Fri Apr 4 18:51:13 2014 UTC
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/BootstrappedKeyStoreProtectionManager.java
Thu Dec 4 14:12:54 2014 UTC
@@ -125,5 +125,11 @@
keys.put("KeyStoreProtKey", getKeyStoreProtectionKey());
return keys;
- }
+ }
+
+ @Override
+ public Key getKey(String keyName) throws CryptoException
+ {
+ return null;
+ }
}
=======================================
---
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/DynamicPKCS11TokenKeyStoreProtectionManager.java
Fri Apr 4 18:51:13 2014 UTC
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/DynamicPKCS11TokenKeyStoreProtectionManager.java
Thu Dec 4 14:12:54 2014 UTC
@@ -21,10 +21,12 @@
package org.nhindirect.common.crypto.impl;
+import java.io.InputStream;
import java.security.KeyStore;
import javax.security.auth.callback.CallbackHandler;
+import org.apache.commons.lang.StringUtils;
import org.nhindirect.common.crypto.exceptions.CryptoException;
/**
@@ -57,10 +59,20 @@
* @throws CryptoException
*/
public DynamicPKCS11TokenKeyStoreProtectionManager(String
keyStorePassPhraseAlias, String privateKeyPassPhraseAlias, CallbackHandler
handler) throws CryptoException
+ {
+ this(keyStorePassPhraseAlias, keyStorePassPhraseAlias, handler, null,
null);
+ }
+
+ public DynamicPKCS11TokenKeyStoreProtectionManager(String
keyStorePassPhraseAlias, String privateKeyPassPhraseAlias, CallbackHandler
handler,
+ String keyStoreType, InputStream inputStream) throws CryptoException
{
this.keyStorePassPhraseAlias = keyStorePassPhraseAlias;
this.privateKeyPassPhraseAlias = privateKeyPassPhraseAlias;
this.handler = handler;
+ if (!StringUtils.isEmpty(keyStoreType))
+ this.keyStoreType = keyStoreType;
+ else
+ this.keyStoreType = DEFAULT_KESTORE_TYPE;
configureKeyStoreBuilder();
@@ -86,7 +98,7 @@
final KeyStore.CallbackHandlerProtection chp =
new KeyStore.CallbackHandlerProtection(handler);
- keyStoreBuilder = KeyStore.Builder.newInstance("PKCS11", null, chp);
+ keyStoreBuilder = KeyStore.Builder.newInstance(keyStoreType, null, chp);
}
/**
@@ -96,7 +108,10 @@
{
try
{
+ loadProvider();
+
ks = keyStoreBuilder.getKeyStore();
+ ks.load(keyStoreSource, null);
}
catch (Exception e)
{
=======================================
---
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/StaticPKCS11TokenKeyStoreProtectionManager.java
Fri Apr 4 18:51:13 2014 UTC
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/impl/StaticPKCS11TokenKeyStoreProtectionManager.java
Thu Dec 4 14:12:54 2014 UTC
@@ -61,10 +61,12 @@
*/
public void initTokenStore() throws CryptoException
{
+ loadProvider();
+
try
{
- ks = KeyStore.getInstance("PKCS11");
- ks.load(null, credential.getPIN());
+ ks = KeyStore.getInstance(keyStoreType);
+ ks.load(keyStoreSource, credential.getPIN());
}
catch (Exception e)
{
=======================================
---
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManager.java
Fri Apr 4 18:50:16 2014 UTC
+++
/java/direct-common/src/main/java/org/nhindirect/common/crypto/tools/PKCS11SecretKeyManager.java
Thu Dec 4 14:12:54 2014 UTC
@@ -1,68 +1,52 @@
package org.nhindirect.common.crypto.tools;
-import java.awt.AWTEvent;
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.GraphicsEnvironment;
-import java.awt.Point;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.security.Key;
-import java.security.PrivateKey;
-import java.security.Provider;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.Security;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.Console;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Properties;
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
-import javax.swing.BorderFactory;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JOptionPane;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.JTextField;
-import javax.swing.table.DefaultTableModel;
-
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
import org.nhindirect.common.crypto.MutableKeyStoreProtectionManager;
import org.nhindirect.common.crypto.exceptions.CryptoException;
-import
org.nhindirect.common.crypto.impl.DynamicPKCS11TokenKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.impl.BootstrappedPKCS11Credential;
+import
org.nhindirect.common.crypto.impl.StaticPKCS11TokenKeyStoreProtectionManager;
+import org.nhindirect.common.crypto.tools.commands.PKCS11Commands;
+import org.nhindirect.common.tooling.Commands;
///CLOVER:OFF
-public class PKCS11SecretKeyManager extends JFrame
+public class PKCS11SecretKeyManager
{
+
+ private static boolean exitOnEndCommands = true;
+ private static String keyStoreType = null;
+ private static String providerName = null;
+ private static String keyStoreSource = null;
- private static final long serialVersionUID = 4851276510546674236L;
+ private final Commands commands;
protected static String pkcs11ProviderCfg = null;
- protected static MutableKeyStoreProtectionManager mgr = null;
-
- protected JTable keyDataTable;
- protected JButton removeKeyButton;
- protected JButton addAESKeyButton;
- protected JButton addGenericKeyButton;
- protected DefaultTableModel keyDataModel;
- protected JButton quitButton;
-
+ protected static String keyStoreConfigFile = null;
public static void main(String[] argv)
{
+ String[] passArgs = null;
+
+
// need to check if there is a configuration for the PKCS11
// provider... if not, assume the JVM has already been configured for one
if (argv.length > 0)
{
+
// Check parameters
for (int i = 0; i < argv.length; i++)
{
String arg = argv[i];
-
+
// Options
if (!arg.startsWith("-"))
{
@@ -74,14 +58,22 @@
{
if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
{
- System.err.println("Error: Missing pkcs11 provider
file name.");
- printUsage();
+ System.err.println("Error: Missing pkcs config file");
System.exit(-1);
}
pkcs11ProviderCfg = argv[++i];
}
+ else if (arg.equals("-keyStoreCfg"))
+ {
+ if (i == argv.length - 1 || argv[i + 1].startsWith("-"))
+ {
+ System.err.println("Error: Missing keystore config
file");
+ System.exit(-1);
+ }
+ keyStoreConfigFile = argv[++i];
+ }
else if (arg.equals("-help"))
{
printUsage();
@@ -93,16 +85,31 @@
printUsage();
System.exit(-1);
}
- }
+ }
}
- if (pkcs11ProviderCfg != null)
+ if (keyStoreConfigFile != null)
{
- // add the security provider
- final Provider p = new sun.security.pkcs11.SunPKCS11(pkcs11ProviderCfg);
- Security.addProvider(p);
+ try
+ {
+ // get additional properties
+ final InputStream inStream = FileUtils.openInputStream(new
File(keyStoreConfigFile));
+
+ final Properties props = new Properties();
+ props.load(inStream);
+
+ keyStoreType = props.getProperty("keyStoreType");
+ providerName = props.getProperty("keyStoreProviderName");
+ keyStoreSource = props.getProperty("keyStoreSource");
+ }
+ catch (IOException e)
+ {
+ System.err.println("Error reading keystore config file to
properties: " + e.getMessage());
+ System.exit(-1);
+ }
}
+ MutableKeyStoreProtectionManager mgr = null;
// need to login
try
{
@@ -110,12 +117,33 @@
}
catch (CryptoException e)
{
- JOptionPane.showMessageDialog(null, "Failed to login to hardware
token: " + e.getMessage(), "Token Login Failure",
- JOptionPane.ERROR_MESSAGE);
+
+ System.out.println("Failed to login to hardware token: " +
e.getMessage());
System.exit(-1);
}
- final PKCS11SecretKeyManager hi = new PKCS11SecretKeyManager();
- hi.setVisible(true);
+ final PKCS11SecretKeyManager mgmt = new PKCS11SecretKeyManager(mgr);
+
+ boolean runCommand = false;
+
+ if (mgmt != null)
+ {
+ runCommand = mgmt.run(passArgs);
+ }
+
+ if (exitOnEndCommands)
+ System.exit(runCommand ? 0 : -1);
+ }
+
+ public boolean run(String[] args)
+ {
+ if (args != null && args.length > 0)
+ {
+ return commands.run(args);
+ }
+
+ commands.runInteractive();
+ System.out.println("Shutting Down Configuration Manager Console");
+ return true;
}
/*
@@ -135,264 +163,61 @@
}
public static MutableKeyStoreProtectionManager tokenLogin() throws
CryptoException
- {
-
- TokenLoginCallback login = new TokenLoginCallback();
-
- final DynamicPKCS11TokenKeyStoreProtectionManager loginMgr = new
DynamicPKCS11TokenKeyStoreProtectionManager("", "", login);
-
-
- return loginMgr;
- }
-
- public PKCS11SecretKeyManager()
- {
- super("DirectProject PKCS11 Secret Key Manager");
- setDefaultLookAndFeelDecorated(true);
- setSize(700, 700);
-
- Point pt =
GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
-
- this.setLocation(pt.x - (350), pt.y - (350));
-
- enableEvents(AWTEvent.WINDOW_EVENT_MASK);
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
- initUI();
-
- addActions();
-
- updateKeyTableData();
- }
-
- private void initUI()
- {
- this.getContentPane().setLayout(new BorderLayout(5, 5));
-
- // Top Panel
- JPanel topPanel = new JPanel();
- topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
-
- addAESKeyButton = new JButton("Add AES Key");
- addAESKeyButton.setSize(new Dimension(30, 100));
- addGenericKeyButton = new JButton("Add Text Key");
- addGenericKeyButton.setSize(new Dimension(30, 100));
- removeKeyButton = new JButton("Remove Key(s)");
- removeKeyButton.setSize(new Dimension(30, 100));
-
- topPanel.add(addAESKeyButton);
- topPanel.add(addGenericKeyButton);
- topPanel.add(removeKeyButton);
-
- this.getContentPane().add(topPanel, BorderLayout.NORTH);
-
-
- // Middle and list panel
- JPanel midPanel = new JPanel();
- midPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
- midPanel.setLayout(new BorderLayout(5, 5));
-
- JLabel keyListLabel = new JLabel("Secret Keys:");
-
- Object[][] data = {};
- String[] columnNames = {"Key Alias", "Key Type", "Key Value"};
-
- keyDataModel = new DefaultTableModel(data, columnNames);
- keyDataTable = new JTable(keyDataModel);
- JScrollPane scrollPane = new JScrollPane(keyDataTable);
- keyDataTable.setFillsViewportHeight(true);
-
- midPanel.add(keyListLabel, BorderLayout.NORTH);
- midPanel.add(scrollPane, BorderLayout.CENTER);
-
- this.getContentPane().add(midPanel, BorderLayout.CENTER);
-
- // Bottom Panel
- JPanel bottomPanel = new JPanel();
- bottomPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
-
- quitButton = new JButton("Quit");
- quitButton.setSize(new Dimension(30, 100));
- bottomPanel.add(quitButton);
-
- this.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
- }
-
- private void addActions()
- {
- addAESKeyButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- addAESKey();
- }
- });
-
- addGenericKeyButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- addTextKey();
- }
- });
-
- removeKeyButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- removeKeys();
- }
- });
-
- quitButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
- System.exit(-1);
- }
- });
- }
-
- private void addAESKey()
- {
- final String input = JOptionPane.showInputDialog(this, "Key Alias
Name:", "Generate New random AES Secret Key", JOptionPane.OK_CANCEL_OPTION);
- if (input != null && !input.trim().isEmpty())
- {
- // generate a new random secret key
- try
- {
- final KeyGenerator keyGen = KeyGenerator.getInstance("AES");
- final SecureRandom random = new SecureRandom(); // cryptograph. secure
random
- keyGen.init(random);
- final SecretKey key = keyGen.generateKey();
+ {
+ try
+ {
+
+ final Console cons = null;//System.console();
+ char[] passwd = null;
+ if (cons != null)
+ {
+ passwd = cons.readPassword("[%s]", "Enter hardware token password: ");
+ java.util.Arrays.fill(passwd, ' ');
+ }
+ else
+ {
+ System.out.print("Enter hardware token password: ");
+ final BufferedReader reader = new BufferedReader(new
InputStreamReader(
+ System.in));
+ passwd = reader.readLine().toCharArray();
+ }
- mgr.clearKey(input);
- mgr.setKey(input, key);
-
- updateKeyTableData();
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(this, "Failed to add random new AES
key: " + e.getMessage(), "Add Key Error", JOptionPane.ERROR_MESSAGE);
- }
- }
- }
-
- private void addTextKey()
- {
-
- final JPanel panel = new JPanel();
- panel.setLayout(new BorderLayout());
-
- final JPanel topPanel = new JPanel();
- final JLabel aliasLabel = new JLabel("Alias:");
- aliasLabel.setSize(60, 30);
- final JTextField aliasField = new JTextField(40);
+ final BootstrappedPKCS11Credential cred = new
BootstrappedPKCS11Credential(new String(passwd));
+ final StaticPKCS11TokenKeyStoreProtectionManager loginMgr = new
StaticPKCS11TokenKeyStoreProtectionManager();
+ loginMgr.setCredential(cred);
+ loginMgr.setKeyStoreProviderName(providerName);
- topPanel.add(aliasLabel);
- topPanel.add(aliasField);
-
- final JPanel bottomPanel = new JPanel();
- final JLabel keyLabel = new JLabel("Key:");
- keyLabel.setSize(60, 30);
- final JTextField keyField = new JTextField(40);
-
- bottomPanel.add(keyLabel);
- bottomPanel.add(keyField);
-
-
- panel.add(topPanel, BorderLayout.NORTH);
- panel.add(bottomPanel, BorderLayout.SOUTH);
-
- final String[] options = new String[]{"OK", "Cancel"};
- int option = JOptionPane.showOptionDialog(null, panel, "Generate New
Text Based Secret Key ",
- JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE,
- null, options, options[0]);
-
- if (option == JOptionPane.OK_OPTION)
- {
- final String alias = aliasField.getText();
- final String keyText = keyField.getText();
+ if (!StringUtils.isEmpty(keyStoreType))
+ loginMgr.setKeyStoreType(keyStoreType);
-
- if ((alias != null && !alias.trim().isEmpty()) &&
- keyText != null && !keyText.trim().isEmpty())
+ if (!StringUtils.isEmpty(keyStoreSource))
{
- // generate a new random secret key
- try
- {
- mgr.clearKey(alias);
- mgr.setKey(alias, new SecretKeySpec(keyText.getBytes(), ""));
-
- updateKeyTableData();
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(this, "Failed to add new text based
secret key: " + e.getMessage(), "Add Key Error", JOptionPane.ERROR_MESSAGE);
- }
- }
- }
- }
-
- private void removeKeys()
- {
- if (keyDataTable.getSelectedRowCount() == 0)
- {
- JOptionPane.showMessageDialog(this, "No keys are selected.", "Remove
Keys", JOptionPane.INFORMATION_MESSAGE);
- return;
- }
- else if (JOptionPane.showConfirmDialog(this, "Are you sure you want to
removed the selected Keys?", "Remove Keys", JOptionPane.YES_NO_OPTION) ==
JOptionPane.YES_OPTION)
- {
- int[] rows = keyDataTable.getSelectedRows();
- for (int row : rows)
- {
- final String alias = (String)keyDataTable.getValueAt(row, 0);
-
- try
- {
- mgr.clearKey(alias);
- }
- catch (Exception e)
- {
- JOptionPane.showMessageDialog(this, "Failed to remove key with
alias " + alias + ":" + e.getMessage(),
- "Remove Key Error", JOptionPane.ERROR_MESSAGE);
- }
+ InputStream str = new ByteArrayInputStream(keyStoreSource.getBytes());
+ loginMgr.setKeyStoreSource(str);
}
- updateKeyTableData();
- }
-
-
+ if (!StringUtils.isEmpty(pkcs11ProviderCfg))
+ loginMgr.setPcks11ConfigFile(pkcs11ProviderCfg);
+
+ loginMgr.initTokenStore();
+
+ return loginMgr;
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException("Error getting password.", e);
+ }
+
+ }
+
+ public PKCS11SecretKeyManager(MutableKeyStoreProtectionManager mgr)
+ {
+ commands = new Commands("PKCS11 Secret Key Management Console");
+ commands.register(new PKCS11Commands(mgr));
}
-
- private void updateKeyTableData()
+ public static void setExitOnEndCommands(boolean exit)
{
- try
- {
- for (int ctx = (keyDataModel.getRowCount() -1 ); ctx >=0; --ctx)
- {
- keyDataModel.removeRow(ctx);
-
- }
- // get all of the data from the token
- Map<String, Key> keys = mgr.getAllKeys();
- for (Entry<String, Key> entry : keys.entrySet())
- {
- String type = "";
- final Object value = entry.getValue();
- if (value instanceof SecretKey)
- type = "Secret Key: " + ((Key)value).getAlgorithm();
- else if (value instanceof PublicKey)
- type = "Public Key: " + ((Key)value).getAlgorithm();
- else if (value instanceof PrivateKey)
- type = "Private Key: " + ((Key)value).getAlgorithm();
- else
- type = value.getClass().toString();
-
- keyDataModel.addRow(new Object[] {entry.getKey(), type ,"***"});
- keyDataModel.fireTableDataChanged();
- }
- }
- catch (Exception e)
- {
- e.printStackTrace();
- }
- }
+ exitOnEndCommands = exit;
+ }
}
///CLOVER:ON