| /******************************************************************************* |
| * Copyright (C) 2007 The University of Manchester |
| * |
| * Modifications to the initial code base are copyright of their |
| * respective authors, or their employers as appropriate. |
| * |
| * This program is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public License |
| * as published by the Free Software Foundation; either version 2.1 of |
| * the License, or (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, but |
| * WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
| ******************************************************************************/ |
| package net.sf.taverna.t2.workbench.ui.credentialmanager; |
| |
| import java.awt.BorderLayout; |
| //import java.awt.Component; |
| //import java.awt.Cursor; |
| import java.awt.Dimension; |
| import java.awt.FlowLayout; |
| import java.awt.Image; |
| import java.awt.Point; |
| import java.awt.Toolkit; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.awt.event.MouseAdapter; |
| import java.awt.event.MouseEvent; |
| import java.awt.event.WindowAdapter; |
| import java.awt.event.WindowEvent; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileWriter; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| |
| import java.security.Key; |
| import java.security.KeyStore; |
| import java.security.cert.Certificate; |
| import java.security.cert.CertificateFactory; |
| import java.security.cert.X509Certificate; |
| |
| import net.sf.taverna.t2.security.credentialmanager.CMException; |
| import net.sf.taverna.t2.security.credentialmanager.CMX509Util; |
| import net.sf.taverna.t2.security.credentialmanager.CredentialManager; |
| import net.sf.taverna.t2.security.credentialmanager.SetMasterPasswordDialog; |
| |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.CredentialManagerUI; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.CryptoFileFilter; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.EditKeyPairEntryDialog; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.GetPasswordDialog; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.KeyPairsTableModel; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.NewEditPasswordEntryDialog; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.NewKeyPairEntryDialog; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.NewTrustCertsDialog; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.PasswordsTableModel; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.TableCellRenderer; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.TableHeaderRenderer; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.TrustedCertsTableModel; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.ViewCertDetailsDialog; |
| import net.sf.taverna.t2.workbench.ui.credentialmanager.ViewUsernamePasswordEntryDialog; |
| |
| import org.apache.log4j.Logger; |
| import org.bouncycastle.openssl.PEMReader; |
| import org.bouncycastle.openssl.PEMWriter; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Iterator; |
| |
| import javax.swing.JButton; |
| import javax.swing.JFileChooser; |
| import javax.swing.JFrame; |
| import javax.swing.JOptionPane; |
| import javax.swing.JPanel; |
| import javax.swing.JScrollPane; |
| import javax.swing.JTabbedPane; |
| import javax.swing.JTable; |
| import javax.swing.WindowConstants; |
| import javax.swing.border.EmptyBorder; |
| import javax.swing.table.TableColumn; |
| |
| /** |
| * Provides a UI for the Credential Manager for users to manage their credentials |
| * saved by the Credential Manager in Taverna's Keystore and Trustore. Credentials |
| * include username and passwords pairs, key pairs, proxy key pairs and trusted |
| * certificates of CA's and s. |
| * Credentials are stored in two Bouncy Castle "UBER"-type keystores: the |
| * Keystore (containing passwords and (normal and proxy) key pairs) and the Truststore |
| * (containing trusted certificates). |
| * |
| * @author Alex Nenadic |
| */ |
| |
| @SuppressWarnings("serial") |
| public class CredentialManagerUI extends JFrame { |
| |
| // Credential Manager UI singleton |
| private static CredentialManagerUI INSTANCE; |
| |
| // Logger |
| private static Logger logger = Logger.getLogger(CredentialManagerUI.class); |
| |
| // Default tabbed pane width - dictates width of this frame |
| private static final int DEFAULT_FRAME_WIDTH = 600; |
| |
| // Default tabbed pane height - dictates height of this frame |
| private static final int DEFAULT_FRAME_HEIGHT = 400; |
| |
| // Credential Manager icon (when frame minimised) |
| private static final Image credManagerIconImage = Toolkit.getDefaultToolkit() |
| .createImage(CredentialManagerUI.class.getResource("/images/cred_manager_transparent.png")); |
| |
| // Credential Manager - manages all operations on the Keystore and Truststore |
| public static CredentialManager credManager; |
| |
| // Keystore tab and table controls |
| |
| // Tabbed pane to hold keystore entries tables |
| private JTabbedPane keyStoreTabbedPane; |
| |
| // Tab 1: holds passwords table |
| private JPanel passwordsTab = new JPanel(new BorderLayout(10, 10)); |
| |
| // Tab 1: name |
| public static final String PASSWORDS = "Passwords"; |
| |
| // Tab 2: holds key pairs (user certificates) table |
| private JPanel keyPairsTab = new JPanel(new BorderLayout(10, 10)); |
| |
| // Tab 2: name |
| public static final String KEYPAIRS = "Key Pairs"; |
| |
| // Tab 3: holds key pairs (user certificates) table |
| private JPanel proxiesTab = new JPanel(new BorderLayout(10, 10)); |
| |
| // Tab 3: name |
| public static final String PROXIES = "Proxies"; |
| |
| // Tab 4: holds trusted certificates table |
| private JPanel trustedCertificatesTab = new JPanel(new BorderLayout(10, 10)); |
| |
| // Tab 4: name |
| public static final String TRUSTED_CERTIFICATES = "Trusted Certificates"; |
| |
| // Tables |
| |
| // Password entries' table |
| private JTable passwordsTable; |
| |
| // Key Pair entries' table |
| private JTable keyPairsTable; |
| |
| // Proxy entries' table |
| private JTable proxiesTable; |
| |
| // Trusted Certificate entries' table |
| private JTable trustedCertsTable; |
| |
| // Value to place in the Type column for a password entry |
| public static final String PASSWORD_ENTRY_TYPE = "Password"; |
| |
| // Value to place in the Type column for a key pair entry |
| public static final String KEY_PAIR_ENTRY_TYPE = "Key Pair"; |
| |
| // Value to place in the Type column for a proxy entry |
| public static final String PROXY_ENTRY_TYPE = "Proxy"; |
| |
| // Value to place in the Type column for a trusted certificate entry |
| public static final String TRUST_CERT_ENTRY_TYPE = "Trusted Certificate"; |
| |
| |
| /** |
| * Returns a CredentialManagerUI singleton. |
| */ |
| public static CredentialManagerUI getInstance(){ |
| synchronized (CredentialManagerUI.class) { |
| if (INSTANCE == null) |
| try { |
| INSTANCE = new CredentialManagerUI(); |
| } catch (CMException cme) { |
| // Failed to instantiate Credential Manager - warn the user and exit |
| String exMessage = "Failed to instantiate Credential Manager. " + cme.getMessage(); |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(new JFrame(), exMessage, |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| return INSTANCE; |
| } |
| |
| /** |
| * Overrides the ObjectÕs clone method to prevent the singleton object to be |
| * cloned. |
| */ |
| @Override |
| public Object clone() throws CloneNotSupportedException { |
| throw new CloneNotSupportedException(); |
| } |
| |
| /** |
| * Creates a new Credential Manager UI's frame. |
| */ |
| private CredentialManagerUI() throws CMException |
| { |
| |
| // Instantiate Credential Manager that will perform all |
| // operations on the Keystore and Truststore |
| credManager = CredentialManager.getInstance(); |
| |
| // Initialise the UI components |
| initComponents(); |
| } |
| |
| private void initComponents(){ |
| |
| // Initialise the tabbed pane that contains the tabs with tabular |
| // representations of the Keystore's content. |
| keyStoreTabbedPane = new JTabbedPane(); |
| // Initialise the tab containing the table for username/password entries from the |
| // Keystore |
| passwordsTable = initTable(PASSWORDS, passwordsTab); |
| // Initialise the tab containing the table for key pair entries from the |
| // Keystore |
| keyPairsTable = initTable(KEYPAIRS, keyPairsTab); |
| // Initialise the tab containing the table for proxy entries from the |
| // Keystore |
| proxiesTable = initTable(PROXIES, proxiesTab); |
| // Initialise the tab containing the table for trusted certificate |
| // entries from the Truststore |
| trustedCertsTable = initTable(TRUSTED_CERTIFICATES, |
| trustedCertificatesTab); |
| // Set the size of the tabbed pane to the preferred size - the size of |
| // the main application frame depends on it. |
| keyStoreTabbedPane.setPreferredSize(new Dimension(DEFAULT_FRAME_WIDTH, |
| DEFAULT_FRAME_HEIGHT)); |
| |
| // Button for changing Credential Manager's master password |
| JButton changeMasterPasswordButton = new JButton("Change master password"); |
| changeMasterPasswordButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| changeMasterPassword(); |
| }}); |
| JPanel changeMasterPasswordPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); |
| changeMasterPasswordPanel.add(changeMasterPasswordButton); |
| |
| // Add change master password to the main application frame |
| getContentPane().add(changeMasterPasswordPanel, BorderLayout.NORTH); |
| // Add tabbed pane to the main application frame |
| getContentPane().add(keyStoreTabbedPane, BorderLayout.CENTER); |
| |
| // Handle application close |
| addWindowListener(new WindowAdapter() { |
| public void windowClosing(WindowEvent evt) { |
| closeFrame(); |
| } |
| }); |
| setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); |
| |
| pack(); |
| |
| // Centre the frame in the centre of the desktop |
| setLocationRelativeTo(null); |
| |
| // Set the frame's icon |
| setIconImage(credManagerIconImage); |
| |
| // Set the frame's title |
| setTitle("Credential Manager"); |
| |
| //setModal(true); |
| //setVisible(true); |
| } |
| |
| protected void changeMasterPassword() { |
| |
| SetMasterPasswordDialog changePasswordDialog = new SetMasterPasswordDialog(this, "Change master password", true , "Change master password for Credential Manager"); |
| changePasswordDialog.setLocationRelativeTo(null); |
| changePasswordDialog.setVisible(true); |
| String password = changePasswordDialog.getPassword(); |
| if (password == null){ // user cancelled |
| return; // do nothing |
| } |
| else{ |
| try { |
| credManager.changeMasterPassword(password); |
| JOptionPane.showMessageDialog(new JFrame(), "Master password changed sucessfully", |
| "Credential Manager Error", JOptionPane.INFORMATION_MESSAGE); |
| } catch (CMException cme) { |
| // Failed to change the master password for Credential Manager - warn the user |
| String exMessage = "Failed to change master password for Credential Manager"; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(new JFrame(), exMessage, |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| |
| /** |
| * Initialise the tab on the tabbed pane and its tabular content. |
| */ |
| private JTable initTable(String tableType, JPanel tab) { |
| |
| JTable table = null; |
| |
| if (tableType.equals(PASSWORDS)) { // Passwords table |
| // The Passwords table's data model |
| PasswordsTableModel passwordsTableModel = new PasswordsTableModel(); |
| // The table itself |
| table = new JTable(passwordsTableModel); |
| |
| // Set the password and alias columns of the Passwords table to be |
| // invisible by removing them from the column model (they will still present |
| // in the table model) |
| // Remove the last column first |
| TableColumn aliasColumn = table.getColumnModel().getColumn(5); |
| table.getColumnModel().removeColumn(aliasColumn); |
| TableColumn passwordColumn = table.getColumnModel().getColumn(4); |
| table.getColumnModel().removeColumn(passwordColumn); |
| |
| // Buttons |
| JButton newPasswordButton = new JButton("New"); |
| newPasswordButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| newPassword(); |
| }}); |
| JButton viewPasswordButton = new JButton("Details"); |
| viewPasswordButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| viewPassword(); |
| }}); |
| JButton editPasswordButton = new JButton("Edit"); |
| editPasswordButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| editPassword(); |
| }}); |
| JButton deletePasswordButton = new JButton("Delete"); |
| deletePasswordButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| deletePassword(); |
| }}); |
| |
| // Panel to hold the buttons |
| JPanel bp = new JPanel(); |
| bp.add(viewPasswordButton); |
| bp.add(editPasswordButton); |
| bp.add(newPasswordButton); |
| bp.add(deletePasswordButton); |
| |
| // Add button panel to the tab |
| tab.add(bp, BorderLayout.PAGE_END); |
| |
| } |
| else if (tableType.equals(KEYPAIRS)) { // Key Pairs tab |
| // The Key Pairs table's data model |
| KeyPairsTableModel keyPairsTableModel = new KeyPairsTableModel(); |
| // The table itself |
| table = new JTable(keyPairsTableModel); |
| |
| // Set the alias and service URLs columns of the KayPairs table to be |
| // invisible by removing them from the column model (they will still present |
| // in the table model) |
| // Remove the last column first |
| TableColumn aliasColumn = table.getColumnModel().getColumn(6); |
| table.getColumnModel().removeColumn(aliasColumn); |
| TableColumn serviceURLsColumn = table.getColumnModel().getColumn(5); |
| table.getColumnModel().removeColumn(serviceURLsColumn); |
| |
| // Buttons |
| JButton viewKeyPairButton = new JButton("Details"); |
| viewKeyPairButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| viewCertificate(); |
| }}); |
| JButton editServiceURLKeyPairButton = new JButton("Edit"); |
| editServiceURLKeyPairButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| editKeyPair(); |
| }}); |
| JButton importKeyPairButton = new JButton("Import"); |
| importKeyPairButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| newKeyPair(); |
| }}); |
| JButton exportKeyPairButton = new JButton("Export"); |
| exportKeyPairButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| exportKeyPair(); |
| }}); |
| JButton deleteKeyPairButton = new JButton("Delete"); |
| deleteKeyPairButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| deleteKeyPair(); |
| }}); |
| |
| // Panel to hold the buttons |
| JPanel bp = new JPanel(); |
| bp.add(viewKeyPairButton); |
| bp.add(editServiceURLKeyPairButton); |
| bp.add(importKeyPairButton); |
| bp.add(exportKeyPairButton); |
| bp.add(deleteKeyPairButton); |
| |
| // Add button panel to the tab |
| tab.add(bp, BorderLayout.PAGE_END); |
| |
| } |
| else if (tableType.equals(PROXIES)) { // Proxies tab |
| // The Proxies table's data model |
| ProxiesTableModel proxiesTableModel = new ProxiesTableModel(); |
| |
| // The table itself |
| table = new JTable(proxiesTableModel); |
| |
| // Set alias column of the Proxies table to be |
| // invisible by removing it from the column model (it will still present |
| // in the table model) |
| TableColumn aliasColumn = table.getColumnModel().getColumn(5); |
| table.getColumnModel().removeColumn(aliasColumn); |
| |
| // Buttons |
| JButton viewProxyButton = new JButton("Details"); |
| viewProxyButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| viewProxyCertificate(); |
| }}); |
| JButton deleteProxyButton = new JButton("Delete"); |
| deleteProxyButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| deleteProxy(); |
| }}); |
| |
| |
| // Panel to hold the buttons |
| JPanel bp = new JPanel(); |
| bp.add(viewProxyButton); |
| bp.add(deleteProxyButton); |
| |
| // Add button panel to the tab |
| tab.add(bp, BorderLayout.PAGE_END); |
| |
| } |
| else if (tableType.equals(TRUSTED_CERTIFICATES)) { // Trusted Certificates tab |
| // The Trusted Certificate table's data model |
| TrustedCertsTableModel trustedCertificatesTableModel = new TrustedCertsTableModel(); |
| // The table itself |
| table = new JTable(trustedCertificatesTableModel); |
| |
| // Set the alias column of the Trusted Certs table to be invisible |
| // by removing it from the column model (it is still present in the |
| // table model) |
| TableColumn aliasColumn = table.getColumnModel().getColumn(5); |
| table.getColumnModel().removeColumn(aliasColumn); |
| |
| // Buttons |
| JButton viewTrustedCertificateButton = new JButton("Details"); |
| viewTrustedCertificateButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| viewCertificate(); |
| }}); |
| JButton importTrustedCertificateButton = new JButton("Import"); |
| importTrustedCertificateButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| importTrustedCertificate(); |
| }}); |
| JButton exportTrustedCertificateButton = new JButton("Export"); |
| exportTrustedCertificateButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| exportTrustedCertificate(); |
| }}); |
| JButton deleteTrustedCertificateButton = new JButton("Delete"); |
| deleteTrustedCertificateButton.addActionListener(new ActionListener(){ |
| public void actionPerformed(ActionEvent e) { |
| deleteTrustedCertificate(); |
| }}); |
| |
| // Panel to hold the buttons |
| JPanel bp = new JPanel(); |
| bp.add(viewTrustedCertificateButton); |
| bp.add(importTrustedCertificateButton); |
| bp.add(exportTrustedCertificateButton); |
| bp.add(deleteTrustedCertificateButton); |
| |
| // Add button panel to the tab |
| tab.add(bp, BorderLayout.PAGE_END); |
| } |
| |
| table.setShowGrid(false); |
| table.setRowMargin(0); |
| table.getColumnModel().setColumnMargin(0); |
| table.getTableHeader().setReorderingAllowed(false); |
| table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); |
| // Top accommodates entry icons with 2 pixels spare space (images are 16x16 pixels) |
| table.setRowHeight(18); |
| |
| // Add custom renderrers for the table headers and cells |
| for (int iCnt = 0; iCnt < table.getColumnCount(); iCnt++) { |
| TableColumn column = table.getColumnModel().getColumn(iCnt); |
| column.setHeaderRenderer(new TableHeaderRenderer()); |
| column.setCellRenderer(new TableCellRenderer()); |
| } |
| |
| // Make the first column small and not resizable (it holds icons to |
| // represent different entry types) |
| TableColumn typeCol = table.getColumnModel().getColumn(0); |
| typeCol.setResizable(false); |
| typeCol.setMinWidth(20); |
| typeCol.setMaxWidth(20); |
| typeCol.setPreferredWidth(20); |
| |
| // Set the size for the second column |
| // (i.e. Service URL column of Passwords and Key Pairs tables, and |
| // Certificate Name column of the Trusted Certificates table) |
| TableColumn secondCol = table.getColumnModel().getColumn(1); |
| secondCol.setMinWidth(20); |
| secondCol.setMaxWidth(10000); |
| secondCol.setPreferredWidth(300); |
| |
| // Don't care about the size of other columns |
| |
| // Put the table into a scroll pane |
| JScrollPane jspTableScrollPane = new JScrollPane(table, |
| JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, |
| JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); |
| jspTableScrollPane.getViewport().setBackground(table.getBackground()); |
| |
| // Put the scroll pane on the tab panel |
| tab.add(jspTableScrollPane, BorderLayout.CENTER); |
| jspTableScrollPane.setBorder(new EmptyBorder(3, 3, 3, 3)); |
| |
| // Add mouse listeners to show an entry's details if it is |
| // double-clicked |
| table.addMouseListener(new MouseAdapter() { |
| public void mouseClicked(MouseEvent evt) { |
| tableDoubleClick(evt); |
| } |
| }); |
| |
| // Add the tab to the tabbed pane |
| keyStoreTabbedPane.addTab(tableType, tab); |
| |
| return table; |
| } |
| |
| /** |
| * Display the username/password pair entry from the Keystore. |
| */ |
| private void viewPassword() { |
| // Which username/password pair entry has been selected, if any? |
| int iRow = passwordsTable.getSelectedRow(); |
| if (iRow == -1) { // no row currently selected |
| return; |
| } |
| |
| // Get current values for service URL, username and password |
| String serviceURL = (String) passwordsTable.getValueAt(iRow, 1); // current entry's service URL |
| |
| String username = (String) passwordsTable.getValueAt(iRow, 2); // current entry's username |
| |
| // Because the password column is not visible we call |
| // the getValueAt method on the table model rather than at the JTable |
| String password = (String) passwordsTable.getModel().getValueAt(iRow,4); // current entry's password value |
| |
| // Let the user view service URL, username and password of the entry |
| ViewUsernamePasswordEntryDialog viewServicePassDialog = new ViewUsernamePasswordEntryDialog( |
| this, serviceURL, username, password); |
| |
| viewServicePassDialog.setLocationRelativeTo(this); |
| viewServicePassDialog.setVisible(true); |
| } |
| |
| /** |
| * Insert a new username/password pair for a service URL in the Keystore. |
| */ |
| private void newPassword() { |
| |
| String serviceURL = null; // service URL |
| String username = null; // username |
| String password = null; // password |
| |
| // Loop until the user cancels or enters everything correctly |
| while (true) { |
| |
| // Let the user insert a new password entry (by specifying service |
| // URL, username and password) |
| NewEditPasswordEntryDialog newPasswordDialog = new NewEditPasswordEntryDialog( |
| this, "New username and password for a service", true, serviceURL, username, |
| password); |
| newPasswordDialog.setLocationRelativeTo(this); |
| newPasswordDialog.setVisible(true); |
| |
| serviceURL = newPasswordDialog.getServiceURL(); // get service URL |
| username = newPasswordDialog.getUsername(); // get username |
| password = newPasswordDialog.getPassword(); // get password |
| |
| if (password == null) { // user cancelled - any of the above three fields is null |
| // do nothing |
| return; |
| } |
| |
| // Check if a password entry with the given service URL |
| // already exists in the Keystore. |
| // We ask this here as the user may wish to overwrite the |
| // existing password entry. |
| // Checking for key pair entries' URLs is done in the |
| // NewEditPasswordEntry dialog. |
| |
| // Get list of service URLs for all the password entries in the Keystore |
| ArrayList<String> serviceURLs = null; |
| try{ |
| serviceURLs = credManager.getServiceURLsforUsernameAndPasswords(); |
| } |
| catch(CMException cme){ |
| String exMessage = "Failed to get service URLs for all username and password pairs to check if the entered service URL already exists"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| return; |
| } |
| if (serviceURLs.contains(serviceURL)) { // if such a URL already exists |
| // Ask if the user wants to overwrite it |
| int iSelected = JOptionPane.showConfirmDialog(this, |
| "The Keystore already contains a password entry with the same service URL.\n" |
| + "Do you want to overwrite it?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| // Add the new password entry in the Keystore |
| if (iSelected == JOptionPane.YES_OPTION) { |
| try{ |
| credManager.saveUsernameAndPasswordForService(username, password, serviceURL); |
| break; |
| } |
| catch (CMException cme){ |
| String exMessage = "Failed to insert a new username and password pair in the Keystore"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| // Otherwise show the same window with the entered service |
| // URL, username and password values |
| } |
| else { |
| // Add the new password entry in the Keystore |
| try{ |
| credManager.saveUsernameAndPasswordForService(username, password, serviceURL); |
| break; |
| } |
| catch (CMException cme){ |
| String exMessage = "Failed to insert a new username and password pair in the Keystore"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| } |
| |
| |
| /** |
| * Edit a username and password entry or their related service URL in the Keystore. |
| */ |
| private void editPassword() { |
| |
| // Which password entry has been selected? |
| int iRow = passwordsTable.getSelectedRow(); |
| if (iRow == -1) { // no row currently selected |
| return; |
| } |
| |
| // Get current values for service URL, username and password |
| String serviceURL = (String) passwordsTable.getValueAt(iRow, 1); // current entry's service URL |
| |
| String username = (String) passwordsTable.getValueAt(iRow, 2); // current entry's username |
| |
| // Because the password column is not visible we call |
| // the getValueAt method on the table model rather than at the JTable |
| String password = (String) passwordsTable.getModel().getValueAt(iRow, 4); // current entry's password value |
| |
| while (true) { // loop until user cancels or enters everything correctly |
| // Let the user edit service URL, username or password of a password entry |
| NewEditPasswordEntryDialog editPasswordDialog = new NewEditPasswordEntryDialog( |
| this, "Edit username and password for a service", true, serviceURL, username, |
| password); |
| |
| editPasswordDialog.setLocationRelativeTo(this); |
| editPasswordDialog.setVisible(true); |
| |
| // New values |
| String nServiceURL = editPasswordDialog.getServiceURL(); // get new service URL |
| String nUsername = editPasswordDialog.getUsername(); // get new username |
| String nPassword = editPasswordDialog.getPassword(); // get new password |
| |
| if (nPassword == null) { // user cancelled - any of the above three fields is null |
| // do nothing |
| return; |
| } |
| |
| // Is anything actually modified? |
| boolean isModified = (!serviceURL.equals(nServiceURL) |
| || !username.equals(nUsername) || !password |
| .equals(nPassword)); |
| |
| if (isModified) { |
| // Check if a different password entry with the new URL |
| // (i.e. alias) already exists in the Keystore |
| // We ask this here as the user may wish to overwrite that |
| // other password entry. |
| |
| // Get list of URLs for all passwords in the Keystore |
| ArrayList<String> serviceURLs = null; |
| try{ |
| serviceURLs = credManager.getServiceURLsforUsernameAndPasswords(); |
| } |
| catch(CMException cme){ |
| String exMessage = "Failed to get service URLs for all username and password pairs to check if the modified entry already exists"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| return; |
| } |
| |
| // If the modified service URL already exists and is not the currently selected one |
| if ( (!nServiceURL.equals(serviceURL)) && serviceURLs.contains(nServiceURL)) { |
| |
| int iSelected = JOptionPane.showConfirmDialog(this, |
| "The Keystore already contains username and password pair for the entered service URL.\n" |
| + "Do you want to overwrite it?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected == JOptionPane.YES_OPTION) { |
| |
| // Overwrite that other entry entry and save the new |
| // one in its place. |
| // Also remove the current one that we are editing - |
| // as it is replacing the other entry. |
| try{ |
| credManager.deleteUsernameAndPasswordForService(serviceURL); |
| credManager.saveUsernameAndPasswordForService(nUsername, nPassword, nServiceURL); |
| break; |
| } |
| catch (CMException cme){ |
| String exMessage = "Failed to update the username and password pair in the Keystore"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| // Otherwise show the same window with the entered |
| // service URL, username and password values |
| } |
| else { |
| try{ |
| if ( !nServiceURL.equals(serviceURL)) { |
| credManager.deleteUsernameAndPasswordForService(serviceURL); |
| } |
| credManager.saveUsernameAndPasswordForService(nUsername, nPassword, nServiceURL); |
| break; |
| } |
| catch (CMException cme){ |
| String exMessage = "Failed to update the username and password pair in the Keystore"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| else{ // nothing actually modified by OK pressed |
| break; |
| } |
| } |
| } |
| |
| /** |
| * Delete the selected username and password entries from the Keystore. |
| */ |
| private void deletePassword() { |
| |
| // Which entries have been selected? |
| int[] iRows = passwordsTable.getSelectedRows(); |
| if (iRows.length == 0) { // no password entry selected |
| return; |
| } |
| |
| // Ask user to confirm the deletion |
| int iSelected = JOptionPane |
| .showConfirmDialog( |
| null, |
| "Are you sure you want to delete the selected username and password entries?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected != JOptionPane.YES_OPTION) { |
| return; |
| } |
| |
| for (int i = iRows.length - 1; i >= 0; i--) { // delete from backwards |
| // Get service URL for the current entry |
| String serviceURL = (String) passwordsTable.getValueAt(iRows[i], 1); // current entry's service URL |
| try { |
| // Delete the password entry from the Keystore |
| credManager.deleteUsernameAndPasswordForService(serviceURL); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to delete the username and password pair from the Keystore"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| |
| /** |
| * Show the contents of a (user or trusted) certificate. |
| */ |
| @SuppressWarnings("unchecked") |
| private void viewCertificate() { |
| |
| int iRow = -1; |
| String alias = null; |
| X509Certificate certToView = null; |
| ArrayList<String> serviceURLs = null; |
| String keystoreType = null; |
| |
| // Are we showing user's public key certificate? |
| if (keyPairsTab.isShowing()){ |
| keystoreType = CredentialManager.KEYSTORE; |
| iRow = keyPairsTable.getSelectedRow(); |
| |
| if (iRow != - 1){ |
| // Because the alias column is not visible we call the |
| // getValueAt method on the table model rather than at the JTable |
| alias = (String) keyPairsTable.getModel().getValueAt(iRow, 6); // current entry's Keystore alias |
| |
| // Get the list of service URLs for the entry |
| serviceURLs = (ArrayList<String>) keyPairsTable.getModel().getValueAt(iRow, 5); |
| } |
| } |
| // Are we showing trusted certificate? |
| else if(trustedCertificatesTab.isShowing()){ |
| keystoreType = CredentialManager.TRUSTSTORE; |
| iRow = trustedCertsTable.getSelectedRow(); |
| |
| if (iRow != - 1){ |
| |
| // Get the selected trusted certificate entry's Truststore alias |
| // Alias column is invisible so we get the value from the table model |
| alias = (String) trustedCertsTable.getModel() |
| .getValueAt(iRow, 5); |
| } |
| } |
| |
| if (iRow != -1) { // something has been selected |
| try { |
| // Get the entry's certificate |
| certToView = CMX509Util.convertCertificate(credManager |
| .getCertificate(keystoreType, alias)); |
| |
| // Supply the certificate and list of URLs to the view |
| // certificate dialog. |
| ViewCertDetailsDialog viewCertDetailsDialog = new ViewCertDetailsDialog( |
| this, "Certificate details", true, certToView, |
| serviceURLs); |
| viewCertDetailsDialog.setLocationRelativeTo(this); |
| viewCertDetailsDialog.setVisible(true); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to get certificate details to display to the user"; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| |
| /** |
| * Import a key pair from a PKCS #12 keystore file to the Keystore. |
| */ |
| private void newKeyPair() { |
| |
| // Let the user choose a PKCS #12 file (keystore) containing a public |
| // and private key pair to import |
| File importFile = selectImportExportFile( |
| "PKCS #12 file to import from", // title |
| new String[] { ".p12", ".pfx" }, // array of file extensions |
| // for the file filter |
| "PKCS#12 Files (*.p12, *.pfx)", // description of the filter |
| "Import"); // text for the file chooser's approve button |
| |
| if (importFile == null) { |
| return; |
| } |
| |
| // The PKCS #12 keystore is not a file |
| if (!importFile.isFile()) { |
| JOptionPane.showMessageDialog(this, "Your selection is not a file", |
| "Credential Manager Alert", JOptionPane.WARNING_MESSAGE); |
| return; |
| } |
| |
| // Get the user to enter the password that was used to encrypt the |
| // private key contained in the PKCS #12 file |
| GetPasswordDialog dGetPassword = new GetPasswordDialog(this, |
| "Import key pair entry", true, |
| "Enter the password that was used to encrypt the PKCS #12 file"); |
| dGetPassword.setLocationRelativeTo(this); |
| dGetPassword.setVisible(true); |
| |
| String pkcs12Password = dGetPassword.getPassword(); |
| |
| if (pkcs12Password == null) { // user cancelled |
| return; |
| } else if (pkcs12Password.length() == 0) { // empty password |
| // FIXME: Maybe user did not have the password set for the private key??? |
| return; |
| } |
| |
| try { |
| // Load the PKCS #12 keystore from the file using BC provider |
| KeyStore pkcs12 = credManager.loadPKCS12Keystore(importFile, pkcs12Password); |
| |
| // Display the import key pair dialog supplying all the private keys |
| // stored in the PKCS #12 file |
| // and a field for the user to enter service URL associated with the |
| // selected key pair |
| // Typically there will be only one private key inside, but could be |
| // more |
| NewKeyPairEntryDialog dImportKeyPair = new NewKeyPairEntryDialog( |
| this, "Credential Manager", true, pkcs12); |
| dImportKeyPair.setLocationRelativeTo(this); |
| dImportKeyPair.setVisible(true); |
| |
| // Get the private key and certificate chain of the key pair |
| Key privateKey = dImportKeyPair.getPrivateKey(); |
| Certificate[] certChain = dImportKeyPair.getCertificateChain(); |
| |
| // Get the service URLs |
| ArrayList<String> serviceURLs = dImportKeyPair.getServiceURLs(); |
| |
| if (privateKey == null || certChain == null) { |
| // User did not select a key pair for import or cancelled |
| return; |
| } |
| |
| // Check if a key pair entry with the same alias already exists in |
| // the Keystore |
| if (credManager.containsKeyPair(privateKey, certChain)) { |
| int iSelected = JOptionPane |
| .showConfirmDialog( |
| this, |
| "The keystore already contains the key pair entry with the same private key.\nDo you want to overwrite it?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected != JOptionPane.YES_OPTION) { |
| return; |
| } |
| } |
| |
| // Place the private key and certificate chain into the Keystore |
| // and save the service URLs list associated with this key pair |
| credManager.saveKeyPair(privateKey, certChain, serviceURLs); |
| |
| // Display success message |
| JOptionPane |
| .showMessageDialog(this, "Key pair import successful", |
| "Credential Manager Alert", |
| JOptionPane.INFORMATION_MESSAGE); |
| } |
| catch (Exception ex) { // too many exceptions to catch separately |
| String exMessage = "Failed to import the key pair entry to the Keystore. " |
| + ex.getMessage(); |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| |
| |
| /** |
| * Edit service URLs for a given key pair entry. |
| */ |
| @SuppressWarnings("unchecked") |
| private void editKeyPair() { |
| // Which key pair entry has been selected? |
| int iRow = keyPairsTable.getSelectedRow(); |
| if (iRow == -1) { // no row currently selected |
| return; |
| } |
| |
| // Because the alias column is not visible we call the |
| // getValueAt method on the table model rather than at the JTable |
| String alias = (String) keyPairsTable.getModel().getValueAt(iRow, 6); // current entry's Keystore alias |
| |
| // Get the list of URLs for the alias |
| ArrayList<String> serviceURLs = (ArrayList<String>) keyPairsTable.getModel().getValueAt(iRow, 5); |
| |
| // Let the user edit the list of service urls this key pair is |
| // associated to |
| EditKeyPairEntryDialog dEditKeyPair = new EditKeyPairEntryDialog(this, |
| "Edit key pair's service URLs", true, serviceURLs); |
| |
| dEditKeyPair.setLocationRelativeTo(this); |
| dEditKeyPair.setVisible(true); |
| |
| ArrayList<String> newServiceURLs = dEditKeyPair.getServiceURLs(); // new service URLs list |
| |
| if (newServiceURLs == null) { // user cancelled |
| return; |
| } |
| |
| // Is anything actually modified? |
| boolean isModified = (!serviceURLs.equals(newServiceURLs)); |
| |
| if (isModified) { |
| try { |
| // Add the new list of URLs for the alias |
| credManager.saveServiceURLsForKeyPair(alias, newServiceURLs); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to update service URLs for the key pair entry"; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| |
| /** |
| * Export user's private and public key pair to a PKCS #12 |
| * keystore file. |
| */ |
| private void exportKeyPair() { |
| |
| // Which key pair entry has been selected? |
| int iRow = keyPairsTable.getSelectedRow(); |
| if (iRow == -1) { // no row currently selected |
| return; |
| } |
| |
| // Get the key pair entry's Keystore alias |
| String alias = (String) keyPairsTable.getModel().getValueAt(iRow, 6); |
| |
| // Let the user choose a PKCS #12 file (keystore) to export public and |
| // private key pair to |
| File exportFile = selectImportExportFile("Select a file to export to", // title |
| new String[] { ".p12", ".pfx" }, // array of file extensions |
| // for the file filter |
| "PKCS#12 Files (*.p12, *.pfx)", // description of the filter |
| "Export"); // text for the file chooser's approve button |
| |
| if (exportFile == null) { |
| return; |
| } |
| |
| // If file already exist - ask the user if he wants to overwrite it |
| if (exportFile.isFile()) { |
| int iSelected = JOptionPane |
| .showConfirmDialog( |
| this, |
| "The file with the given name already exists.\nDo you want to overwrite it?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected == JOptionPane.NO_OPTION) { |
| return; |
| } |
| } |
| |
| // Get the user to enter the password for the PKCS #12 keystore file |
| GetPasswordDialog dGetPassword = new GetPasswordDialog(this, |
| "Credential Manager", true, |
| "Enter the password for protecting the exported key pair"); |
| dGetPassword.setLocationRelativeTo(this); |
| dGetPassword.setVisible(true); |
| |
| String pkcs12Password = dGetPassword.getPassword(); |
| |
| if (pkcs12Password == null) { // user cancelled or empty password |
| // Warn the user |
| JOptionPane |
| .showMessageDialog( |
| this, |
| "You must supply a password for protecting the exported key pair.", |
| "Credential Manager Alert", |
| JOptionPane.INFORMATION_MESSAGE); |
| return; |
| } |
| |
| // Export the key pair |
| try { |
| credManager.exportKeyPair(alias, exportFile, pkcs12Password); |
| JOptionPane.showMessageDialog(this, "Key pair export successful", |
| "Credential Manager Alert", |
| JOptionPane.INFORMATION_MESSAGE); |
| } |
| catch (CMException cme) { |
| JOptionPane.showMessageDialog(this, cme.getMessage(), |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| |
| /** |
| * Delete selected key pair entries from the Keystore. |
| */ |
| private void deleteKeyPair() { |
| |
| // Which entries have been selected? |
| int[] iRows = keyPairsTable.getSelectedRows(); |
| if (iRows.length == 0) { // no key pair entry selected |
| return; |
| } |
| |
| // Ask user to confirm the deletion |
| int iSelected = JOptionPane |
| .showConfirmDialog( |
| null, |
| "Are you sure you want to delete the selected key pairs?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected != JOptionPane.YES_OPTION) { |
| return; |
| } |
| |
| for (int i = iRows.length - 1; i >= 0; i--) { // delete from backwards |
| // Get the alias for the current entry |
| String alias = (String) keyPairsTable.getModel().getValueAt( |
| iRows[i], 6); |
| try { |
| // Delete the key pair entry from the Keystore |
| // and URLs associated with this key pair entry |
| credManager.deleteKeyPair(alias); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to delete the key pair(s) from the Keystore"; |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| |
| /** |
| * Show the contents of a proxy certificate. |
| */ |
| private void viewProxyCertificate() { |
| |
| int iRow = proxiesTable.getSelectedRow(); |
| |
| if (iRow != -1) { // something has been selected |
| String alias = (String) proxiesTable.getModel().getValueAt(iRow, 5); |
| |
| if (alias.startsWith("cagridproxy#")){ // cagrid proxy |
| try { |
| // Get the entry's certificate |
| X509Certificate certToView = CMX509Util.convertCertificate(credManager |
| .getCertificate(CredentialManager.KEYSTORE, alias)); |
| |
| String authNServiceURL = alias.substring(alias.indexOf('#') + 1, alias.indexOf(' ')); |
| String dorianServiceURL = alias.substring(alias.indexOf(' ') +1); |
| // Supply the certificate and list of URLs to the view |
| // certificate dialog. |
| ViewCaGridProxyCertDetailsDialog viewCaGridProxyCertDetailsDialog = new ViewCaGridProxyCertDetailsDialog( |
| this, "Certificate details", true, certToView, authNServiceURL, dorianServiceURL); |
| viewCaGridProxyCertDetailsDialog.setLocationRelativeTo(this); |
| viewCaGridProxyCertDetailsDialog.setVisible(true); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to get proxy certificate details to display to the user"; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| //else{} // some other proxy |
| } |
| } |
| |
| /** |
| * Delete selected proxy entries from the Keystore. |
| */ |
| private void deleteProxy() { |
| |
| // Which entries have been selected? |
| int[] iRows = proxiesTable.getSelectedRows(); |
| if (iRows.length == 0) { // no key pair entry selected |
| return; |
| } |
| |
| // Ask user to confirm the deletion |
| int iSelected = JOptionPane |
| .showConfirmDialog( |
| null, |
| "Are you sure you want to delete the selected proxy(ies)?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected != JOptionPane.YES_OPTION) { |
| return; |
| } |
| |
| for (int i = iRows.length - 1; i >= 0; i--) { // delete from backwards |
| // Get the alias for the current entry |
| String alias = (String) proxiesTable.getModel().getValueAt( |
| iRows[i], 5); |
| try { |
| // Delete the proxy entry from the Keystore |
| credManager.deleteCaGridProxy(alias); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to delete the proxy(ies) from the Keystore"; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| |
| /** |
| * Import a trusted certificate from a PEM or DER encoded file |
| * into the Truststore. |
| */ |
| private void importTrustedCertificate() { |
| // Let the user choose a file containing trusted certificate(s) to |
| // import |
| File certFile = selectImportExportFile( |
| "Certificate file to import from", // title |
| new String[] { ".pem", "crt", ".cer", ".der", ".p7c" }, // file extensions filters |
| "Certificate Files (*.pem, *.crt, , *.cer, *.der, *.p7c)", // filter description |
| "Import"); // text for the file chooser's approve button |
| |
| if (certFile == null) { |
| return; |
| } |
| |
| // Load the certificate(s) from the file |
| ArrayList<X509Certificate> trustCertsList = new ArrayList<X509Certificate>(); |
| FileInputStream fis = null; |
| |
| try { |
| fis = new FileInputStream(certFile); |
| CertificateFactory cf = CertificateFactory.getInstance("X.509"); |
| // The following should be able to load PKCS #7 certificate chain files |
| // as well as ASN.1 DER or PEM-encoded (sequences of) certificates |
| Collection<? extends Certificate> c = cf.generateCertificates(fis); |
| Iterator<? extends Certificate> i = c.iterator(); |
| while (i.hasNext()) { |
| trustCertsList.add((X509Certificate) i.next()); |
| } |
| } |
| catch (Exception cex) { |
| // Do nothing |
| } |
| finally { |
| try { |
| fis.close(); |
| } catch (Exception ex) { |
| // ignore |
| } |
| } |
| |
| if (trustCertsList.size() == 0) { // Could not load certificates as |
| // any of the above types |
| try { |
| // Try as openssl PEM format - which sligtly differs from the |
| // one supported by JCE |
| fis = new FileInputStream(certFile); |
| CertificateFactory cf = CertificateFactory.getInstance("X.509"); |
| PEMReader pr = new PEMReader(new InputStreamReader(fis), null, |
| cf.getProvider().getName()); |
| Object cert; |
| while ((cert = pr.readObject()) != null) { |
| if (cert instanceof X509Certificate) { |
| trustCertsList.add((X509Certificate) cert); |
| } |
| } |
| } catch (Exception cex) { |
| // do nothing |
| } finally { |
| try { |
| fis.close(); |
| } catch (Exception ex) { |
| // ignore |
| } |
| } |
| } |
| |
| if (trustCertsList.size() == 0) { // Failed to load certifcate(s) |
| // using any of the known encodings |
| JOptionPane |
| .showMessageDialog( |
| this, |
| "Failed to load certificate(s) using any of the known encodings -\nfile format not recognised.", |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| return; |
| } |
| |
| // Show the list of certificates contained in the file for the user to |
| // select the ones to import |
| NewTrustCertsDialog dImportTrustCerts = new NewTrustCertsDialog(this, |
| "Credential Manager", true, trustCertsList); |
| |
| dImportTrustCerts.setLocationRelativeTo(this); |
| dImportTrustCerts.setVisible(true); |
| ArrayList<X509Certificate> selectedTrustCerts = dImportTrustCerts |
| .getTrustedCertificates(); // user-selected trusted certs to import |
| |
| // If user cancelled or did not select any cert to import |
| if ((selectedTrustCerts) == null || (selectedTrustCerts.size() == 0)) { |
| return ; |
| } |
| |
| try { |
| |
| for (int i = selectedTrustCerts.size() - 1; i >= 0; i--) { |
| // Import the selected trusted certificates |
| credManager.saveTrustedCertificate(selectedTrustCerts.get(i)); |
| } |
| |
| // Display success message |
| JOptionPane |
| .showMessageDialog(this, |
| "Trusted certificate(s) import successful", |
| "Credential Manager Alert", |
| JOptionPane.INFORMATION_MESSAGE); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to import trusted certificate(s) to the Truststore"; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| |
| |
| /** |
| * Lets the user export one (at the moment) or more (in future) trusted |
| * certificate entries to a PEM-encoded file. |
| * |
| * @return True if the export is successful, false otherwise |
| */ |
| private boolean exportTrustedCertificate() { |
| |
| // Which trusted certificate has been selected? |
| int iRow = trustedCertsTable.getSelectedRow(); |
| if (iRow == -1) { // no row currently selected |
| return false; |
| } |
| |
| // Get the trust certificate entry's Keystore alias |
| String alias = (String) trustedCertsTable.getModel().getValueAt(iRow, 3); |
| // the alias column is invisible so we get the value from the table model |
| |
| // Let the user choose a file to export public and private key pair to |
| File exportFile = selectImportExportFile("Select a file to export to", // title |
| new String[] { ".pem" }, // array of file extensions for the |
| // file filter |
| "Certificate Files (*.pem)", // description of the filter |
| "Export"); // text for the file chooser's approve button |
| |
| if (exportFile == null) { |
| return false; |
| } |
| |
| // If file already exist - ask the user if he wants to overwrite it |
| if (exportFile.isFile()) { |
| int iSelected = JOptionPane |
| .showConfirmDialog( |
| this, |
| "The file with the given name already exists.\nDo you want to overwrite it?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected == JOptionPane.NO_OPTION) { |
| return false; |
| } |
| } |
| |
| // Export the trusted certificate |
| PEMWriter pw = null; |
| try { |
| // Get the trusted certificate |
| Certificate certToExport = credManager.getCertificate( |
| CredentialManager.TRUSTSTORE, alias); |
| pw = new PEMWriter(new FileWriter(exportFile)); |
| pw.writeObject(certToExport); |
| |
| JOptionPane |
| .showMessageDialog(this, |
| "Trusted certificate export successful", |
| "Credential Manager Alert", |
| JOptionPane.INFORMATION_MESSAGE); |
| |
| return true; |
| } |
| catch (Exception ex) { |
| String exMessage = "Failed to export the trusted certificate from the Truststore."; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog( |
| this, |
| exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| return false; |
| } |
| finally { |
| if (pw != null) { |
| try { |
| pw.close(); |
| } catch (IOException ex) { |
| // ignore |
| } |
| } |
| } |
| } |
| |
| /** |
| * Delete selected trusted certificate entries from the Truststore. |
| */ |
| private void deleteTrustedCertificate() { |
| |
| // Which entries have been selected? |
| int[] iRows = trustedCertsTable.getSelectedRows(); |
| if (iRows.length == 0) { // no trusted cert entry selected |
| return; |
| } |
| |
| // Ask user to confirm the deletion |
| int iSelected = JOptionPane |
| .showConfirmDialog( |
| null, |
| "Are you sure you want to delete the selected trusted certificate(s)?", |
| "Credential Manager Alert", |
| JOptionPane.YES_NO_OPTION); |
| |
| if (iSelected != JOptionPane.YES_OPTION) { |
| return; |
| } |
| |
| for (int i = iRows.length - 1; i >= 0; i--) { // delete from backwards |
| // Get the alias for the current entry |
| String alias = (String) trustedCertsTable.getModel().getValueAt( |
| iRows[i], 5); |
| try { |
| // Delete the trusted certificate entry from the Truststore |
| credManager.deleteTrustedCertificate(alias); |
| } |
| catch (CMException cme) { |
| String exMessage = "Failed to delete the trusted certificate(s) from the Truststore"; |
| logger.error(exMessage); |
| JOptionPane.showMessageDialog(this, exMessage, |
| "Credential Manager Error", |
| JOptionPane.ERROR_MESSAGE); |
| } |
| } |
| } |
| |
| /** |
| * Handle double click on the Keystore tables. If it has occurred, show the |
| * details of the entry clicked upon. |
| */ |
| private void tableDoubleClick(MouseEvent evt) { |
| if (evt.getClickCount() > 1) { // is it double click? |
| |
| // What row and column were clicked upon (if any)? |
| Point point = new Point(evt.getX(), evt.getY()); |
| int iRow = ((JTable) evt.getSource()).rowAtPoint(point); |
| if (iRow == -1) { |
| return; |
| } |
| // Which table the click occured on? |
| if (((JTable) evt.getSource()).getModel() instanceof PasswordsTableModel) { // Passwords table |
| viewPassword(); |
| } |
| else if (((JTable) evt.getSource()).getModel() instanceof KeyPairsTableModel) { // Key pairs table |
| viewCertificate(); |
| } |
| else if (((JTable) evt.getSource()).getModel() instanceof ProxiesTableModel) { //Proxies table |
| viewProxyCertificate(); |
| } |
| else { // Trusted certificates table |
| viewCertificate(); |
| } |
| } |
| } |
| |
| /** |
| * Let the user select a file to export to or import from a key pair or a |
| * certificate. The file types are filtered according to their extensions: |
| * .p12 or .pfx are PKCS #12 keystore files containing private key and its |
| * public key (+cert chain) .crt are ASN.1 PEM-encoded files containing one |
| * (or more concatenated) public key certificate(s) .der are ASN.1 |
| * DER-encoded files containing one public key certificate .cer are |
| * CER-encoded files containing one ore more DER-encoded certificates |
| */ |
| private File selectImportExportFile(String title, String[] filter, |
| String description, String approveButtonText) { |
| |
| JFileChooser chooser = new JFileChooser(); |
| chooser |
| .addChoosableFileFilter(new CryptoFileFilter(filter, |
| description)); |
| chooser.setDialogTitle(title); |
| chooser.setMultiSelectionEnabled(false); |
| |
| int rtnValue = chooser.showDialog(this, approveButtonText); |
| if (rtnValue == JFileChooser.APPROVE_OPTION) { |
| File selectedFile = chooser.getSelectedFile(); |
| return selectedFile; |
| } |
| return null; |
| } |
| |
| /** |
| * Exit the UI's frame. |
| */ |
| private void closeFrame() { |
| setVisible(false); |
| dispose(); |
| } |
| |
| |
| // /** |
| // * Set cursor to busy and disable application input. This can be reversed by |
| // * a subsequent call to setCursorFree. |
| // */ |
| // private void setCursorBusy() { |
| // // Block all mouse events using glass pane |
| // Component glassPane = getRootPane().getGlassPane(); |
| // glassPane.addMouseListener(new MouseAdapter() { |
| // }); |
| // glassPane.setVisible(true); |
| // |
| // // Set cursor to busy |
| // glassPane.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); |
| // } |
| // |
| // |
| // /** |
| // * Set cursor to free and enable application input. Called after a call to |
| // * setCursorBusy. |
| // */ |
| // private void setCursorFree() { |
| // // Accept mouse events |
| // Component glassPane = getRootPane().getGlassPane(); |
| // glassPane.setVisible(false); |
| // |
| // // Revert cursor to default |
| // glassPane.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); |
| // } |
| // |
| // /** |
| // * Action helper class. |
| // */ |
| // private abstract class AbstractAction extends javax.swing.AbstractAction { |
| // protected abstract void act(); |
| // |
| // public void actionPerformed(ActionEvent evt) { |
| // setCursorBusy(); |
| // repaint(); |
| // new Thread(new Runnable() { |
| // public void run() { |
| // try { |
| // act(); |
| // } finally { |
| // setCursorFree(); |
| // } |
| // } |
| // }).start(); |
| // } |
| // } |
| |
| } |