/* * EditKeyStoreChangePassDialog.java * * * ==================================================== Professional Data Security (PDS) http://crypto.brettlee.com ==================================================== Copyright (c) 2009-2011, Brett Lee All rights reserved. Portions Copyright (C) 1995-2008, Sun Microsystems, Inc. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the ORGANIZATION nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ============================================================================= */ package com.brettlee.crypto; import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.security.KeyStore; import javax.swing.GroupLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.border.TitledBorder; import javax.swing.filechooser.FileNameExtensionFilter; /** * EditKeyStoreChangePassDialog - File-> Edit-> KeyStore-> Change Passphrase "Dialog" * */ class EditKeyStoreChangePassDialog { /** * */ private final Gui mGui; final JTextField keyStoreNameField = new JTextField("", 20); final JPasswordField oldpw = new JPasswordField(15); final JPasswordField newpw1 = new JPasswordField(15); final JPasswordField newpw2 = new JPasswordField(15); JDialog editKeyStorePass; String newline = System.getProperty("line.separator"); public EditKeyStoreChangePassDialog (Gui theGui) { mGui = theGui; editKeyStorePass = new JDialog(mGui.mainFrame, "Modify a KeyStore Passphrase", true); int n = JOptionPane.showOptionDialog( frame, "IMPORTANT NOTICE:" + newline + newline + "Changing a KeyStore passphrase is a VERY risky operation." + newline + "Before proceeding you SHOULD make a backup copy of this KeyStore." + newline + newline + "OTHERWISE, YOU RUN THE RISK OF LOSING ALL YOUR ENCRYPTED DATA." + newline + newline + "If you have not made a backup of this KeyStore, please " + newline + "select NO and make a backup copy." + newline + newline + "Are you ready to continue?" + newline + newline, "Please backup this KeyStore !", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, new String[] {"Yes", "No"}, "No"); if ( n != 0 ) { // System.out.println("Canceling..."); return; } ///////////////////////////////////////////////////////////// // Build the Dialog JPanel contentPane = new JPanel(); GroupLayout layout = new GroupLayout(contentPane); contentPane.setLayout(layout); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); editKeyStorePass.add(contentPane); FlowLayout flowLayoutLeft = new FlowLayout(); flowLayoutLeft.setAlignment(FlowLayout.LEFT); JPanel p1 = new JPanel(); JPanel p2 = new JPanel( flowLayoutLeft ); JPanel p3 = new JPanel( flowLayoutLeft ); JPanel p4 = new JPanel( new GridLayout(0,1) ); JPanel p5 = new JPanel(); layout.setHorizontalGroup( layout.createSequentialGroup() .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(p1) .addComponent(p2) .addComponent(p3) .addComponent(p4) .addComponent(p5) ) ); layout.setVerticalGroup( layout.createSequentialGroup() .addComponent(p1) .addComponent(p2) .addComponent(p3) .addComponent(p4) .addComponent(p5) ); ///////////////////////////////////////////////////////////// // p1 - Title JLabel jlabel = new JLabel("Modify a KeyStore Passphrase"); p1.add(jlabel); // p2 - KeyStore name JPanel p2SubPanel = new JPanel( flowLayoutLeft ); p2.add(p2SubPanel); p2.setBorder(new TitledBorder("KeyStore Name")); JLabel p2Label = new JLabel("KeyStore to modify: "); p2SubPanel.add(p2Label); p2SubPanel.add(keyStoreNameField); keyStoreNameField.setEnabled(false); JButton iconOpen = new JButton(Gui.createImageIcon("images/folder.gif", 28)); iconOpen.setFocusable(false); Gui.enterPressesWhenFocused(iconOpen); iconOpen.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { openMenuItemActionPerformed(evt); } }); iconOpen.setToolTipText("Open"); p2SubPanel.add(iconOpen); // p3 - Old passphrase JPanel p3SubPanel = new JPanel( new GridLayout(1,2) ); p3.add(p3SubPanel); p3.setBorder(new TitledBorder("Current Passphrase")); p3SubPanel.add(new JLabel("Passphrase: "), BorderLayout.WEST); p3SubPanel.add(oldpw, BorderLayout.WEST); // p4 - New passphrase JPanel p4SubPanel2a = new JPanel(flowLayoutLeft); p4.add(p4SubPanel2a); JPanel p4SubPanel2b = new JPanel(new GridLayout(2,2)); p4SubPanel2a.add(p4SubPanel2b); p4.setBorder(new TitledBorder("New Passphrase")); p4SubPanel2b.add(new JLabel("Passphrase: "), BorderLayout.WEST); p4SubPanel2b.add(newpw1, BorderLayout.WEST); p4SubPanel2b.add(new JLabel("Passphrase (again): "), BorderLayout.WEST); newpw2.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent evt) { if ( newpw2.getPassword().length > 0 ) { modifyKeyStoreActionPerformed(evt); } } } ); p4SubPanel2b.add(newpw2, BorderLayout.WEST); // p5 - Modify & Cancel Buttons JButton jButtonModify = new JButton("Modify"); jButtonModify.setMnemonic(KeyEvent.VK_M); Gui.enterPressesWhenFocused(jButtonModify); jButtonModify.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { modifyKeyStoreActionPerformed(evt); } }); p5.add(jButtonModify); JButton jButtonCancel = new JButton("Cancel"); jButtonCancel.setMnemonic(KeyEvent.VK_C); Gui.enterPressesWhenFocused(jButtonCancel); jButtonCancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // System.out.println("Canceling..."); editKeyStorePass.setVisible(false); editKeyStorePass.dispose(); } }); p5.add(jButtonCancel); ///////////////////////////////////////////////////////////// // Finish up editKeyStorePass.setTitle("Professional Data Security (PDS) - Edit KeyStore Passphrase"); editKeyStorePass.pack(); editKeyStorePass.setLocationRelativeTo(null); editKeyStorePass.setVisible(true); } /////////////////////////////////////////////////////////////////////// /** * Listeners for the EditKeyStorePass inner class * */ /////////////////////////////////////////////////////////////////////// JFrame chooserFrame = new JFrame(); JFrame frame = new JFrame(); String ksName; // Listener Action Item for Browse to KeyStore private void openMenuItemActionPerformed(ActionEvent evt) { JFileChooser fileChooser; if ( mGui.stateObject.getDefaultKeyStoreDir() != null ) { fileChooser = new JFileChooser ( mGui.stateObject.getDefaultKeyStoreDir() ); } else { fileChooser = new JFileChooser ( mGui.runTimePath ); } fileChooser.setDialogTitle( "KeyStore Location" ); fileChooser.setApproveButtonText("Select"); FileNameExtensionFilter filterPDS = new FileNameExtensionFilter("Professional Data Security Files (PDS)", "PDS"); FileNameExtensionFilter filterJCEKS = new FileNameExtensionFilter("Java Cryptographic Extension (JCE) KeyStores (JCEKS)", "JCEKS"); FileNameExtensionFilter filterJKS = new FileNameExtensionFilter("Java KeyStores (JKS)", "JKS"); FileNameExtensionFilter filterKeyStores = new FileNameExtensionFilter("Java KeyStores (JCEKS, JKS)", "JCEKS", "JKS"); fileChooser.addChoosableFileFilter( filterJKS ); fileChooser.addChoosableFileFilter( filterJCEKS ); fileChooser.addChoosableFileFilter( filterPDS ); fileChooser.addChoosableFileFilter(filterKeyStores); int returnVal = fileChooser.showOpenDialog(chooserFrame); if ( returnVal == 0 ) { // Get Absolute Path: ksName = fileChooser.getSelectedFile().getPath(); // System.out.print("KeyStore: " + ksName + newline); keyStoreNameField.setText( ksName ); keyStoreNameField.setEnabled(true); keyStoreNameField.repaint(); } else if ( returnVal == 1 ) { // System.out.print("Canceling..." + newline); } else { System.out.print("Error: " + returnVal + newline); } } private void modifyKeyStoreActionPerformed(ActionEvent evt) { // System.out.println("Begin create new KeyStore.."); String keyStoreName = keyStoreNameField.getText(); // System.out.println("KeyStore Name: " + keyStoreName); if ( keyStoreName.length() == 0 ) { // notify if failure JOptionPane.showMessageDialog( frame, "KeyStore name cannot be empty.", "KeyStore Name", JOptionPane.WARNING_MESSAGE); return; } char[] oldPass = oldpw.getPassword(); char[] newPass1 = newpw1.getPassword(); char[] newPass2 = newpw2.getPassword(); // System.out.print("Old Passphrase : "); // for ( int i = 0; i < oldPass.length; i++ ) { // System.out.print( oldPass[i] ); // } // System.out.println(); // System.out.print("First Passphrase : "); // for ( int i = 0; i < newPass1.length; i++ ) { // System.out.print( newPass1[i] ); // } // System.out.println(); // System.out.print("Next Passphrase : "); // for ( int i = 0; i < newPass2.length; i++ ) { // System.out.print( newPass2[i] ); // } // System.out.println(); // Was the first key pass provided and correct if ( ! (newPass1.length >= 8) ) { // notify if failure JOptionPane.showMessageDialog( frame, "Key passphrase must be at least 8 characters, " + newline + "containing both upper case and lower case characters " + newline + "as well as some other character.", "Passphrase empty", JOptionPane.WARNING_MESSAGE); return; } // Check for correct syntax boolean upper = false; // set to true if test passes boolean lower = false; // set to true if test passes boolean other = false; // set to true if test passes // Check for upper case first for ( int i = 0; i < newPass1.length; i++ ) { for ( int n = 65; n <= 90; n++ ) { if ( ( (int) newPass1[i] ) == n ) { upper = true; n = 91; i = newPass1.length; } } } // System.out.println("Contained upper: " + upper); // Check for lower case next for ( int i = 0; i < newPass1.length; i++ ) { for ( int n = 97; n <= 122; n++ ) { if ( ( (int) newPass1[i] ) == n ) { lower = true; n = 123; i = newPass1.length; } } } // System.out.println("Contained lower: " + lower); // Check for existance of another char last for ( int i = 0; i < newPass1.length; i++ ) { boolean otherUpper = false; boolean otherLower = false; // Is it an upper case char ? for ( int n = 65; n <= 90; n++ ) { if ( ( (int) newPass1[i] ) == n ) { otherUpper = true; n = 91; } } // If not upper, then is it lower case char? if ( ! otherUpper ) { for ( int j = 97; j <= 122; j++ ) { if ( ( (int) newPass1[i] ) == j ) { otherLower = true; j = 123; } } } if ( ( ! otherUpper ) && ( ! otherLower ) ) { other = true; i = newPass1.length; } } // System.out.println("Contained other: " + other); if( ! ( upper && lower && other ) ) { // notify if failure JOptionPane.showMessageDialog( frame, "KeyStore passphrase must be at least 8 characters, " + newline + "containing both upper case and lower case characters " + newline + "as well as some other character.", "Passphrase empty", JOptionPane.WARNING_MESSAGE); return; } // Did the passwords match if ( ! java.util.Arrays.equals(newPass1,newPass2) ) { // notify if failure JOptionPane.showMessageDialog( frame, "Passphrases did not match.", "Passphrase mismatch", JOptionPane.WARNING_MESSAGE); return; } // System.out.println("Modifying KeyStore Passphrase..."); // System.out.println("KeyStore Name: "); try { // Load the KeyStore KeyStore ks = CryptoKeyStore.loadKeyStore( keyStoreName, oldPass ); // Save it with a new passphrase if ( CryptoKeyStore.saveKeyStore( ks, newPass1, keyStoreName) ) { JOptionPane.showMessageDialog( frame, "KeyStore passphrase changed successfully." , "Success", JOptionPane.INFORMATION_MESSAGE, Gui.createImageIcon("images/PDS_Logo-32.png")); } } catch (Exception createKeyStoreException) { // notify if failure System.out.println("Error Creating KeyStore: " + createKeyStoreException); JOptionPane.showMessageDialog( frame, "Error changing KeyStore passphrase: " + createKeyStoreException, "KeyStore Error" , JOptionPane.ERROR_MESSAGE); } finally { // Scrub the passphrases // System.out.println("Scrubbing passphrases in Gui.editKeyStorePass()..."); for ( int i = 0; i < oldPass.length; i++ ) { oldPass[i] = '0'; } for ( int i = 0; i < newPass1.length; i++ ) { newPass1[i] = '0'; } for ( int i = 0; i < newPass2.length; i++ ) { newPass2[i] = '0'; } // System.out.println("Closing Create Key Dialog"); editKeyStorePass.setVisible(false); editKeyStorePass.dispose(); } } }