//*****************************************************************************
//*
//* (c) Copyright 2005. Glub Tech, Incorporated. All Rights Reserved.
//*
//* $Id: EditCertificatesDialog.java 128 2009-12-10 09:18:22Z gary $
//*
//*****************************************************************************
package com.glub.secureftp.client.gui;
import com.glub.gui.*;
import com.glub.util.*;
import com.glub.secureftp.common.*;
import com.glub.secureftp.bean.*;
import com.glub.secureftp.client.framework.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import javax.swing.text.Keymap;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.security.*;
import java.util.*;
public class EditCertificatesDialog extends JDialog {
protected static final long serialVersionUID = 1L;
private JTabbedPane tab = null;
private EditCertificatesPanel certPanel;
private JPanel buttonPanel, clientPanel,
certInfoPanel = null;
private JButton deleteButton, closeButton = null;
private JLabel commonNameLabel = null;
private JLabel orgNameLabel = null;
private JLabel orgUnitLabel = null;
private JLabel cityLabel = null;
private JLabel stateLabel = null;
private JLabel countryLabel = null;
private JLabel issOrgNameLabel = null;
private JLabel issOrgUnitLabel = null;
private JLabel issCityLabel = null;
private JLabel issStateLabel = null;
private JLabel issCountryLabel = null;
private JLabel expDateLabel = null;
private JTextField privateKeyTextField = null;
private JTextField publicCertTextField = null;
private JTextField caCertTextField = null;
private JPasswordField certPassField = null;
private JButton generateCertButton = null;
private static final String classPath = "EditCertificatesDialog.";
private ArrayList certList = SecureFTP.getCertificates();
private CertFilter certFilter = null;
private CertFilter keyFilter = null;
public EditCertificatesDialog() {
super(SecureFTP.getBaseFrame(),
LString.getString(classPath + "dialogTitle", "Manage Certificates"),
true);
getContentPane().setLayout(new BorderLayout());
certPanel = new EditCertificatesPanel( this );
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
getButtons();
addButtonListeners();
getContentPane().add(certPanel, BorderLayout.WEST);
tab = new JTabbedPane();
JPanel main = new JPanel();
main.setLayout( new BorderLayout() );
main.add( getCertificateInfoPanel(), BorderLayout.NORTH );
JPanel delButtonPanel = new JPanel();
delButtonPanel.setLayout( new BorderLayout() );
delButtonPanel.add( getDeleteButton(), BorderLayout.WEST );
main.add( delButtonPanel, BorderLayout.SOUTH );
tab.add( LString.getString(classPath + "tab.cert", "Trusted Certificates"),
main );
tab.add( LString.getString(classPath + "tab.client_cert",
"Personal Certificate"),
getClientCertificatePanel() );
addCertificates();
getContentPane().add(tab, BorderLayout.CENTER);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
certPanel.setPreferredSize(new Dimension(150, 280));
certPanel.setSelectedIndex( 0 );
pack();
setLocationRelativeTo(SecureFTP.getBaseFrame());
setResizable(false);
setVisible(true);
}
public void showCertificateInfo( int certIndex ) {
SSLCertificate cert = null;
if ( certIndex < 0 ) {
if ( certPanel.getRowCount() > 0 ) {
certIndex = 0;
certPanel.setSelectedIndex( certIndex );
}
}
if ( certIndex >= 0 && null != certList && certList.size() > 0 ) {
deleteButton.setEnabled( true );
cert = (SSLCertificate)certList.get(certIndex);
}
else {
deleteButton.setEnabled( false );
}
if ( null != cert ) {
commonNameLabel.setText( " " + cert.getCN() );
orgNameLabel.setText( cert.getOrg() );
orgUnitLabel.setText( cert.getOU() );
cityLabel.setText( cert.getLocality() );
stateLabel.setText( cert.getState() );
countryLabel.setText( cert.getCountry() );
issOrgNameLabel.setText( cert.getIssuerOrg() );
issOrgUnitLabel.setText( cert.getIssuerOU() );
issCityLabel.setText( cert.getIssuerLocality() );
issStateLabel.setText( cert.getIssuerState() );
issCountryLabel.setText( cert.getIssuerCountry() );
LString expires =
new LString(classPath + "expires_cert", "Expires: [^0]");
expires.replace( 0, cert.getEndDate().toString() );
expDateLabel.setText( " " + expires.getString() );
}
else {
commonNameLabel.setText( "" );
orgNameLabel.setText( "" );
orgUnitLabel.setText( "" );
cityLabel.setText( "" );
stateLabel.setText( "" );
countryLabel.setText( "" );
issOrgNameLabel.setText( "" );
issOrgUnitLabel.setText( "" );
issCityLabel.setText( "" );
issStateLabel.setText( "" );
issCountryLabel.setText( "" );
expDateLabel.setText ( "" );
}
pack();
tab.setSelectedIndex( 0 );
}
protected JPanel getCertificateInfoPanel() {
if ( null == certInfoPanel ) {
certInfoPanel = new JPanel();
certInfoPanel.setLayout( new BoxLayout(certInfoPanel,
BoxLayout.Y_AXIS) );
commonNameLabel = new JLabel();
Font curFont = commonNameLabel.getFont();
commonNameLabel.setFont(new Font(curFont.getFontName(),
Font.BOLD, curFont.getSize()));
orgNameLabel = new JLabel();
orgUnitLabel = new JLabel();
cityLabel = new JLabel();
stateLabel = new JLabel();
countryLabel = new JLabel();
issOrgNameLabel = new JLabel();
issOrgUnitLabel = new JLabel();
issCityLabel = new JLabel();
issStateLabel = new JLabel();
issCountryLabel = new JLabel();
expDateLabel = new JLabel();
certInfoPanel.add(Box.createVerticalStrut(10));
certInfoPanel.add(commonNameLabel);
certInfoPanel.add(Box.createVerticalStrut(5));
JPanel signee = new JPanel();
signee.setBorder(
BorderFactory.createTitledBorder(
LString.getString("SSLCertificate.issued_to.label",
"Certificate:")) );
signee.setLayout( new BoxLayout(signee, BoxLayout.Y_AXIS) );
signee.add(orgNameLabel);
signee.add(orgUnitLabel);
/*
signee.add(cityLabel);
signee.add(stateLabel);
signee.add(countryLabel);
*/
signee.add(new JLabel(" "));
certInfoPanel.add(signee);
certInfoPanel.add(Box.createVerticalStrut(5));
JPanel signer = new JPanel();
signer.setBorder(
BorderFactory.createTitledBorder(
LString.getString("SSLCertificate.issued_from.label",
"Issued From:")) );
signer.setLayout( new BoxLayout(signer, BoxLayout.Y_AXIS) );
signer.add(issOrgNameLabel);
signer.add(issOrgUnitLabel);
/*
signer.add(issCityLabel);
signer.add(issStateLabel);
signer.add(issCountryLabel);
*/
signer.add(new JLabel(" "));
certInfoPanel.add(signer);
certInfoPanel.add(Box.createVerticalStrut(5));
certInfoPanel.add( expDateLabel );
certInfoPanel.add(Box.createVerticalStrut(5));
}
return certInfoPanel;
}
public JPanel getClientCertificatePanel() {
if ( null == clientPanel ) {
JPanel clientCertPanel = new JPanel( new SpringLayout() ) {
protected static final long serialVersionUID = 1L;
public Dimension getMaximumSize() {
Dimension pref = getPreferredSize();
return new Dimension( Integer.MAX_VALUE, pref.height );
}
};
String[] labelStrings = {
LString.getString( classPath + "cert.private", "Private Key:" ),
LString.getString( classPath + "cert.public", "Public Certificate:" ),
LString.getString( classPath + "cert.ca", "CA Certificate:" ),
LString.getString( classPath + "cert.pass", "Passphrase:" ),
};
JComponent[] fields = new JComponent[ labelStrings.length ];
int fieldNum = 0;
fields[ fieldNum++ ] = getPrivateKeyTextField();
fields[ fieldNum++ ] = getPublicCertTextField();
fields[ fieldNum++ ] = getCACertTextField();
fields[ fieldNum++ ] = getCertPassField();
JButton[] buttons = new JButton[ labelStrings.length ];
int buttonNum = 0;
buttons[ buttonNum++ ] = getBrowseButton( (JTextField)fields[0], false );
buttons[ buttonNum++ ] = getBrowseButton( (JTextField)fields[1], true );
buttons[ buttonNum++ ] = getBrowseButton( (JTextField)fields[2], true );
buttons[ buttonNum++ ] = null;
clientCertPanel.setBorder(
BorderFactory.createTitledBorder(
LString.getString(classPath + "client.border",
"Your Certificate:")) );
buildFields( clientCertPanel , labelStrings, fields, buttons );
JPanel buttonsPanel = new JPanel();
buttonsPanel.setLayout( new BorderLayout() );
buttonsPanel.add( getGenerateCertButton(), BorderLayout.WEST );
clientPanel = new JPanel();
clientPanel.setLayout( new BorderLayout() );
clientPanel.add( clientCertPanel, BorderLayout.NORTH );
clientPanel.add( buttonsPanel, BorderLayout.SOUTH );
}
return clientPanel;
}
protected JTextField getPrivateKeyTextField() {
if ( null == privateKeyTextField ) {
privateKeyTextField = new JTextField( 15 );
File f = Client.getClientPrivateKey();
if ( null != f )
privateKeyTextField.setText( f.getAbsolutePath() );
}
return privateKeyTextField;
}
protected JTextField getPublicCertTextField() {
if ( null == publicCertTextField ) {
publicCertTextField = new JTextField( 15 );
File f = Client.getClientPublicCert();
if ( null != f )
publicCertTextField.setText( f.getAbsolutePath() );
}
return publicCertTextField;
}
protected JTextField getCACertTextField() {
if ( null == caCertTextField ) {
caCertTextField = new JTextField( 15 );
File f = Client.getClientCACert();
if ( null != f )
caCertTextField.setText( f.getAbsolutePath() );
}
return caCertTextField;
}
protected JPasswordField getCertPassField() {
if ( null == certPassField ) {
certPassField = new JPasswordField( 15 );
String s = Client.getClientCertPassword();
if ( null != s )
certPassField.setText( s );
}
return certPassField;
}
protected JButton getBrowseButton( final JTextField textField,
final boolean cert ) {
ImageIcon icon =
new ImageIcon( getClass().getResource("images/browse.png") );
JButton browseButton = new JButton( icon );
browseButton.setToolTipText(
LString.getString("ConnectionDialog.tooltip.browse", "Browse") );
browseButton.setPreferredSize(
new Dimension(icon.getIconWidth() + 20, icon.getIconHeight()) );
browseButton.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
File localDir = Client.getLocalView().getCurrentDirectory();
if ( textField.getText().length() > 0 ) {
File setFile = new File( textField.getText() );
if ( setFile.exists() ) {
if ( setFile.isDirectory() )
localDir = setFile;
else
localDir = setFile.getParentFile();
}
}
JFileChooser fc = new JFileChooser( localDir );
fc.setFileSelectionMode( JFileChooser.FILES_ONLY );
if ( cert ) {
fc.setFileFilter( getCertFilter() );
}
else {
fc.setFileFilter( getKeyFilter() );
}
int result =
fc.showDialog( textField,
LString.getString("Common.button.select_file",
"Select File") );
if ( JFileChooser.APPROVE_OPTION == result ) {
String file = fc.getSelectedFile().getAbsolutePath();
textField.setText( file );
textField.setCaretPosition(0);
}
}
} );
return browseButton;
}
protected JButton getGenerateCertButton() {
if ( null == generateCertButton ) {
generateCertButton =
new JButton( LString.getString(classPath + "button.generate",
"Generate Certificate...") );
final Dialog d = this;
generateCertButton.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e ) {
HashMap map = new HashMap();
new GenerateCertificateDialog( d, map );
File privateKey = (File)map.get("private");
File publicCert = (File)map.get("public");
if ( null != privateKey && null != publicCert ) {
getPrivateKeyTextField().setText( privateKey.getAbsolutePath() );
getPublicCertTextField().setText( publicCert.getAbsolutePath() );
}
}
} );
}
return generateCertButton;
}
private CertFilter getCertFilter() {
if (null == certFilter) {
String[] str = { "pem", "der", "pfx", "p12" };
certFilter =
new CertFilter(new LString(classPath + "filter.cert",
"Certificate Files (*.pem, *.der, *.pfx, *.p12)"), str);
}
return certFilter;
}
private CertFilter getKeyFilter() {
if (null == keyFilter) {
String[] str = { "pk8", "pfx", "p12" };
keyFilter =
new CertFilter( new LString(classPath + "filter.key",
"Private Keys (*.pk8, *.pfx, *.p12)"), str );
}
return keyFilter;
}
protected void buildFields( JPanel panel, String[] labelStrings,
JComponent[] fields, JButton[] buttons ) {
JLabel[] labels = new JLabel[ labelStrings.length ];
for ( int i = 0; i < labelStrings.length; i++ ) {
labels[ i ] = new JLabel( labelStrings[i], JLabel.TRAILING );
labels[ i ].setLabelFor( fields[i] );
fields[ i ].addFocusListener( new FocusListener() {
public void focusGained( FocusEvent e ) {
Component c = e.getComponent();
if ( c instanceof JTextField ) {
((JTextField)c).selectAll();
}
}
public void focusLost( FocusEvent e ) {}
} );
panel.add( labels[i] );
panel.add( fields[i] );
if ( null != buttons[i] ) {
panel.add( buttons[i] );
}
else {
panel.add( new JLabel("") );
}
}
SpringUtilities.makeCompactGrid( panel,
4, 3, // rows, cols
10, 10, // init x, init y
10, 30 // pad x, pad y
);
}
protected void unSetEnterEvent(JTextField obj) {
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
Keymap map = obj.getKeymap();
map.removeKeyStrokeBinding(enter);
}
protected void addCertificates() {
for ( int x = 0; x < certList.size(); x++ ) {
SSLCertificate c = (SSLCertificate)certList.get(x);
certPanel.buildRow(c);
}
}
protected JButton getDeleteButton() {
if ( deleteButton == null ) {
deleteButton =
new JButton( LString.getString("Common.button.remove", "Remove") );
deleteButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
certList.remove( certPanel.getSelectedIndex() );
certPanel.removeSelectedRow();
}
});
}
return deleteButton;
}
protected void getButtons() {
if ( closeButton == null )
closeButton = new JButton( LString.getString("Common.button.close",
"Close") );
SwingUtilities.getRootPane( this ).setDefaultButton( closeButton );
buttonPanel.add(closeButton);
}
public boolean checkFields() {
boolean result = true;
String pk = getPrivateKeyTextField().getText().trim();
String pc = getPublicCertTextField().getText().trim();
String ca = getCACertTextField().getText().trim();
String pass = new String(getCertPassField().getPassword());
if ( pk.length() == 0 && pc.length() == 0 && ca.length() == 0 ) {
Client.setClientPrivateKey( null );
Client.setClientPublicCert( null );
Client.setClientCACert( null );
Client.setClientCertPassword( "" );
}
else if ( pk.length() > 0 && pc.length() > 0 && ca.length() > 0 ) {
File pkf = new File(pk);
File pcf = new File(pc);
File caf = new File(ca);
if ( pkf.exists() && pcf.exists() && caf.exists() ) {
Client.setClientPrivateKey( pkf );
Client.setClientPublicCert( pcf );
Client.setClientCACert( caf );
Client.setClientCertPassword( pass );
}
else
result = false;
}
else if ( pk.length() > 0 && pc.length() > 0 && ca.length() == 0 ) {
File pkf = new File(pk);
File pcf = new File(pc);
if ( pkf.exists() && pcf.exists() ) {
Client.setClientPrivateKey( pkf );
Client.setClientPublicCert( pcf );
Client.setClientCACert( null );
Client.setClientCertPassword( pass );
}
else
result = false;
}
else {
result = false;
}
if ( !result ) {
getToolkit().beep();
LString msg =
new LString(classPath + "client_cert.error",
"There were problems found with your personal certificate.");
ErrorDialog.showDialog( msg );
tab.setSelectedIndex( 1 );
}
return result;
}
protected void addButtonListeners() {
closeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if ( checkFields() ) {
dispose();
}
}
});
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if ( e.getKeyCode() == KeyEvent.VK_ESCAPE ) {
dispose();
}
}
});
}
}
class EditCertificatesPanel extends JPanel {
protected static final long serialVersionUID = 1L;
private KeyStore keyStore = null;
private JTable tableView;
private JScrollPane scrollPane;
private EditCertificatesDialog dialog;
private static final String classPath = "EditCertificatesDialog.";
private FTPSession dummySession = new FTPSession();
private CertificateTableModel model;
protected boolean valid = false;
public EditCertificatesPanel( EditCertificatesDialog dialog ) {
super();
this.dialog = dialog;
setLayout(new BorderLayout());
scrollPane = createTable();
scrollPane.setBackground(Color.white);
try {
keyStore = KeyUtil.getKeyStore( dummySession.getKeyStoreFile(),
"sEcUrEfTp".toCharArray() );
}
catch ( Exception e ) {}
add(scrollPane, BorderLayout.CENTER);
add(Box.createVerticalStrut(5), BorderLayout.NORTH);
add(Box.createHorizontalStrut(5), BorderLayout.WEST);
add(Box.createHorizontalStrut(10), BorderLayout.EAST);
MouseAdapter listMouseListener = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
getECD().showCertificateInfo( tableView.getSelectedRow() );
}
};
setEnterBehavior();
tableView.addMouseListener(listMouseListener);
valid = true;
}
protected EditCertificatesDialog getECD() {
return dialog;
}
public JScrollPane createTable() {
JScrollPane pane = new JScrollPane();
model = new CertificateTableModel();
tableView = new JTable(model) {
protected static final long serialVersionUID = 1L;
public void valueChanged( ListSelectionEvent e ) {
super.valueChanged(e);
if ( valid && null != getECD() ) {
int selectedRow = getSelectedRow();
if ( selectedRow < 0 ) {
selectedRow = 0;
}
getECD().showCertificateInfo( selectedRow );
}
}
};
tableView.setRowHeight(20);
tableView.setRowSelectionAllowed(true);
tableView.setColumnSelectionAllowed(false);
tableView.getTableHeader().setReorderingAllowed(false);
tableView.setIntercellSpacing(new Dimension(0, 0));
tableView.setShowHorizontalLines(true);
tableView.setShowVerticalLines(false);
tableView.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
model.addColumn( LString.getString(classPath + "column.certificate",
"Certificate") );
TableColumnModel tcm = tableView.getColumnModel();
TableColumn tc = tcm.getColumn( 0 );
TableCellRenderer tcr = new CertificateRenderer();
tc.setCellRenderer( tcr );
pane.getViewport().setBackground(Color.white);
pane.getViewport().add(tableView);
return ( pane );
}
public void setSelectedIndex( int index ) {
tableView.changeSelection( index, index, false, false );
}
public int getSelectedIndex() {
return tableView.getSelectedRow();
}
public void removeSelectedRow() {
if ( tableView.getSelectedRowCount() <= 0 ) return;
int tableSelectedRow = tableView.getSelectedRow();
/* remove the cert from the keystore */
if ( null != keyStore ) {
try {
SSLCertificate c =
(SSLCertificate)tableView.getValueAt(tableSelectedRow, 0);
String alias = c.getX509Certificate().getSubjectDN().toString();
keyStore.deleteEntry( alias );
FileOutputStream fos =
new FileOutputStream(dummySession.getKeyStoreFile());
keyStore.store( fos, "sEcUrEfTp".toCharArray() );
}
catch ( Exception e ) { e.printStackTrace(); }
}
/* remove row from table */
model.removeRow(tableSelectedRow);
}
public void buildRow(SSLCertificate cert) {
Vector row = new Vector();
row.add(cert);
model.addRow(row);
setColumnWidths();
}
public void removeAllRows() {
int totalRows = model.getRowCount() ;
for ( int i = totalRows-1; i >= 0; i-- ) {
model.removeRow(i);
}
}
private void setColumnWidths() {
TableColumn bCol =
tableView.getColumn( LString.getString(classPath + "column.certificate",
"Certificate") );
bCol.setMinWidth(60);
bCol.setResizable(false);
tableView.sizeColumnsToFit(0);
}
protected int getRowCount() {
return tableView.getRowCount();
}
protected void clearSelections() {
tableView.removeRowSelectionInterval(0, tableView.getRowCount() - 1);
}
public void setEnterBehavior() {
tableView.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
KeyStroke.getKeyStroke("ENTER"),"stop-and-next-cell");
tableView.getActionMap().put("stop-and-next-cell", new AbstractAction() {
protected static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
if ( dialog.checkFields() ) {
dialog.dispose();
}
}
} );
}
}
class CertificateTableModel extends DefaultTableModel {
protected static final long serialVersionUID = 1L;
public CertificateTableModel() {
super();
}
public boolean isCellEditable(int row, int col) {
return false;
}
}
class CertificateRenderer extends DefaultTableCellRenderer {
protected static final long serialVersionUID = 1L;
protected void setValue( Object value ) {
SSLCertificate cert = (SSLCertificate)value;
if ( null != cert )
setText( cert.getCN() );
}
}
class CertFilter extends javax.swing.filechooser.FileFilter {
private String filter = null;
private String[] filterOn = null;
public CertFilter(LString filterLabel, String[] filterOn) {
super();
filter = filterLabel.getString();
this.filterOn = filterOn;
}
public boolean accept(File f) {
boolean accept = f.isDirectory();
if (! accept) {
String suffix = getSuffix(f);
if (suffix != null) {
for (int i=0; i < filterOn.length; i++) {
if (! accept)
accept = suffix.equals(filterOn[i]);
}
}
}
return accept;
}
public String getDescription() {
return filter;
}
public String getSuffix( File f ) {
String s = f.getPath(), suffix = null;
int i = s.lastIndexOf('.');
if ( i > 0 && i < s.length() - 1 )
suffix = s.substring(i+1).toLowerCase();
return suffix;
}
}