blob: aa697b4d07646ed6d540a864fe9e9f383fdb5ec2 [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.motorolamobility.studio.android.certmanager.ui.dialogs.importks;
import java.io.File;
import java.security.KeyStore.Entry;
import java.security.KeyStore.PasswordProtection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnLabelProvider;
import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.EditingSupport;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import com.motorola.studio.android.common.log.StudioLogger;
import com.motorolamobility.studio.android.certmanager.CertificateManagerActivator;
import com.motorolamobility.studio.android.certmanager.core.KeyStoreManager;
import com.motorolamobility.studio.android.certmanager.exception.InvalidPasswordException;
import com.motorolamobility.studio.android.certmanager.exception.KeyStoreManagerException;
import com.motorolamobility.studio.android.certmanager.i18n.CertificateManagerNLS;
import com.motorolamobility.studio.android.certmanager.ui.model.IKeyStore;
public class ConvertKeyStoreTypeDialog extends TitleAreaDialog
{
public class EntryModel
{
private final String alias;
private String passwd;
private boolean verified;
public EntryModel(String alias)
{
this.alias = alias;
try
{
String savedPass = keyStore.getPasswordProvider().getPassword(alias, false);
setPasswd(savedPass != null ? savedPass : ""); //$NON-NLS-1$
}
catch (KeyStoreManagerException e)
{
setPasswd(""); //$NON-NLS-1$
}
}
@Override
public String toString()
{
return alias;
}
public String getPasswd()
{
return passwd;
}
public void setPasswd(String passwd)
{
this.passwd = passwd;
try
{
Entry entry =
keyStore.getKeyStore().getEntry(alias,
new PasswordProtection(passwd.toCharArray()));
setVerified(entry != null);
}
catch (Exception e)
{
setVerified(false);
}
aliaseMap.put(alias, passwd);
}
public String getAlias()
{
return alias;
}
public boolean isVerified()
{
return verified;
}
private void setVerified(boolean verified)
{
this.verified = verified;
validateUi();
}
}
public class EntriesContentProvider implements IStructuredContentProvider
{
@Override
public void dispose()
{
//do nothing
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
//do nothing
}
@Override
public Object[] getElements(Object inputElement)
{
List<EntryModel> modelList = null;
if (inputElement instanceof List<?>)
{
List<?> inputList = (List<?>) inputElement;
modelList = new ArrayList<EntryModel>(inputList.size());
Iterator<?> it = inputList.iterator();
while (it.hasNext())
{
Object element = it.next();
if (element instanceof String) //received an alias
{
String alias = (String) element;
EntryModel entryModel = new EntryModel(alias);
modelList.add(entryModel);
}
}
}
return modelList.toArray();
}
}
private final class PasswordEditingSupport extends EditingSupport
{
private PasswordEditingSupport(ColumnViewer viewer)
{
super(viewer);
}
@Override
protected boolean canEdit(Object element)
{
return true;
}
@Override
protected CellEditor getCellEditor(Object element)
{
return new TextCellEditor(entriesTable, SWT.PASSWORD);
}
@Override
protected Object getValue(Object element)
{
return ((EntryModel) element).getPasswd();
}
@Override
protected void setValue(Object element, Object value)
{
EntryModel model = (EntryModel) element;
model.setPasswd((String) value);
getViewer().update(element, null);
}
}
private static final String HELP_ID = CertificateManagerActivator.PLUGIN_ID
+ ".convert_keystore_type"; //$NON-NLS-1$
private static final String WIZARD_BANNER = "icons/wizban/change_keystore_type_wiz.png"; //$NON-NLS-1$
private IKeyStore keyStore;
private String newType = ""; //$NON-NLS-1$
private Text passwdText;
private String password = ""; //$NON-NLS-1$
private Table entriesTable;
private TableViewer entriesTableViewer;
private final Map<String, String> aliaseMap = new HashMap<String, String>();
/**
* Create the dialog.
* @param parentShell
*/
public ConvertKeyStoreTypeDialog(Shell parentShell, IKeyStore keyStore)
{
super(parentShell);
setShellStyle(SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
this.keyStore = keyStore;
setTitleImage(CertificateManagerActivator.imageDescriptorFromPlugin(
CertificateManagerActivator.PLUGIN_ID, WIZARD_BANNER).createImage());
}
/**
* Create contents of the dialog.
* @param parent
*/
@Override
protected Control createDialogArea(Composite parent)
{
parent.getShell().setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_DialogTitle);
setMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_DefaultMessage);
setTitle(CertificateManagerNLS.ConvertKeyStoreTypeDialog_DialogTitle);
Composite area = (Composite) super.createDialogArea(parent);
Composite container = new Composite(area, SWT.NONE);
container.setLayout(new GridLayout(1, false));
container.setLayoutData(new GridData(GridData.FILL_BOTH));
Composite convertTopComposite = new Composite(container, SWT.NONE);
convertTopComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1));
convertTopComposite.setLayout(new GridLayout(1, false));
Composite keyStoreComposite = new Composite(convertTopComposite, SWT.NONE);
keyStoreComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
keyStoreComposite.setLayout(new GridLayout(3, false));
Label keyStoreLabel = new Label(keyStoreComposite, SWT.NONE);
keyStoreLabel.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_KeyStoreLabel);
final Combo keyStoreCombo = new Combo(keyStoreComposite, SWT.READ_ONLY);
keyStoreCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
final KeyStoreManager keyStoreManager = KeyStoreManager.getInstance();
try
{
List<IKeyStore> keyStores = keyStoreManager.getKeyStores();
for (IKeyStore keyStore : keyStores)
{
File ksFile = keyStore.getFile();
String comboItem = ksFile.getName() + " - " + ksFile.getAbsolutePath(); //$NON-NLS-1$
keyStoreCombo.add(comboItem);
keyStoreCombo.setData(comboItem, keyStore);
if (keyStore.equals(this.keyStore))
{
keyStoreCombo.select(keyStoreCombo.indexOf(comboItem));
}
}
}
catch (KeyStoreManagerException e1)
{
setErrorMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_CouldNotLoad_Keystores_Error);
}
Label passwdLabel = new Label(keyStoreComposite, SWT.NONE);
passwdLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
passwdLabel.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Password_Label);
passwdText = new Text(keyStoreComposite, SWT.BORDER | SWT.PASSWORD);
passwdText.addModifyListener(new ModifyListener()
{
@Override
public void modifyText(ModifyEvent e)
{
password = passwdText.getText();
}
});
passwdText.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetDefaultSelected(SelectionEvent e)
{
super.widgetDefaultSelected(e);
loadEntries();
}
});
passwdText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
Button loadButton = new Button(keyStoreComposite, SWT.NONE);
GridData gd_loadButton = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
gd_loadButton.widthHint = 80;
loadButton.setLayoutData(gd_loadButton);
loadButton.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Load_Button);
loadButton.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
loadEntries();
}
});
Composite composite_1 = new Composite(convertTopComposite, SWT.NONE);
GridData gd_composite_1 = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
gd_composite_1.heightHint = 39;
composite_1.setLayoutData(gd_composite_1);
composite_1.setLayout(new GridLayout(4, false));
Label typeLabel = new Label(composite_1, SWT.NONE);
typeLabel.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Original_Type_Label);
final Label currentTypeLabel = new Label(composite_1, SWT.NONE);
GridData gd_currentTypeLabel = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
gd_currentTypeLabel.widthHint = 90;
gd_currentTypeLabel.minimumWidth = 90;
currentTypeLabel.setLayoutData(gd_currentTypeLabel);
currentTypeLabel.setText(keyStore.getType());
Label newTypeLabel = new Label(composite_1, SWT.NONE);
newTypeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
newTypeLabel.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_NewType_Label);
final Combo typeCombo = new Combo(composite_1, SWT.READ_ONLY);
typeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
loadTypeCombo(keyStoreManager, typeCombo);
new Label(composite_1, SWT.NONE);
new Label(composite_1, SWT.NONE);
new Label(composite_1, SWT.NONE);
new Label(composite_1, SWT.NONE);
typeCombo.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
super.widgetSelected(e);
newType = typeCombo.getText();
validateUi();
}
});
keyStoreCombo.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
super.widgetSelected(e);
updateUi(keyStoreCombo, keyStoreManager, currentTypeLabel, typeCombo);
validateUi();
}
});
Group entriesGroup = new Group(container, SWT.NONE);
entriesGroup.setLayout(new GridLayout(1, true));
GridData gd_entriesGroup = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
gd_entriesGroup.heightHint = 230;
gd_entriesGroup.widthHint = 433;
entriesGroup.setLayoutData(gd_entriesGroup);
entriesGroup.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Entries_Group);
entriesTableViewer =
new TableViewer(entriesGroup, SWT.BORDER | SWT.SINGLE | SWT.FULL_SELECTION);
entriesTableViewer.setContentProvider(new EntriesContentProvider());
entriesTable = entriesTableViewer.getTable();
entriesTable.setHeaderVisible(true);
entriesTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TableViewerColumn aliasViewerColumn = new TableViewerColumn(entriesTableViewer, SWT.NONE);
TableColumn tblclmnAlias = aliasViewerColumn.getColumn();
tblclmnAlias.setWidth(100);
tblclmnAlias.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Alias_Column);
aliasViewerColumn.setLabelProvider(new ColumnLabelProvider()
{
@Override
public String getText(Object element)
{
return ((EntryModel) element).getAlias();
}
});
TableViewerColumn passwordViewerColumn_1 =
new TableViewerColumn(entriesTableViewer, SWT.NONE);
passwordViewerColumn_1.setEditingSupport(new PasswordEditingSupport(entriesTableViewer));
TableColumn tblclmnPassword = passwordViewerColumn_1.getColumn();
tblclmnPassword.setWidth(100);
tblclmnPassword.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Password_Column);
passwordViewerColumn_1.setLabelProvider(new ColumnLabelProvider()
{
@Override
public String getText(Object element)
{
return ((EntryModel) element).getPasswd().replaceAll(".", "*"); //$NON-NLS-1$ //$NON-NLS-2$
}
});
TableViewerColumn verifiedViewerColumn_2 =
new TableViewerColumn(entriesTableViewer, SWT.NONE);
TableColumn tblclmnVerified = verifiedViewerColumn_2.getColumn();
tblclmnVerified.setWidth(130);
tblclmnVerified.setText(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Verified_Column);
verifiedViewerColumn_2.setLabelProvider(new ColumnLabelProvider()
{
@Override
public String getText(Object element)
{
return ((EntryModel) element).isVerified()
? CertificateManagerNLS.ConvertKeyStoreTypeDialog_Verified_Pass_Yes
: CertificateManagerNLS.ConvertKeyStoreTypeDialog_Verified_Pass_Wrong;
}
});
updateUi(keyStoreCombo, keyStoreManager, currentTypeLabel, typeCombo);
return area;
}
@Override
protected Control createHelpControl(Composite parent)
{
PlatformUI.getWorkbench().getHelpSystem().setHelp(parent.getShell(), HELP_ID);
return super.createHelpControl(parent);
}
private void updateUi(final Combo keyStoreCombo, final KeyStoreManager keyStoreManager,
final Label currentTypeLabel, final Combo typeCombo)
{
keyStore = (IKeyStore) keyStoreCombo.getData(keyStoreCombo.getText());
try
{
password = keyStore.getPasswordProvider().getKeyStorePassword(false);
}
catch (KeyStoreManagerException e)
{
StudioLogger.error("Error while accessing keystore manager. " + e.getMessage());
}
if (password == null)
{
password = ""; //$NON-NLS-1$
}
passwdText.setText(password);
if (!password.isEmpty())
{
IKeyStore keyStore = (IKeyStore) keyStoreCombo.getData(keyStoreCombo.getText());
currentTypeLabel.setText(keyStore.getType());
loadTypeCombo(keyStoreManager, typeCombo);
aliaseMap.clear();
try
{
if (keyStore.isPasswordValid(password))
{
List<String> aliases;
aliases = keyStore.getAliases(password);
entriesTableViewer.setInput(aliases);
}
else
{
validateUi();
}
}
catch (KeyStoreManagerException e)
{
StudioLogger.error("Error while accessing keystore manager. " + e.getMessage());
}
catch (InvalidPasswordException e)
{
validateUi();
}
}
}
private void loadEntries()
{
try
{
aliaseMap.clear();
List<String> aliases = keyStore.getAliases(password);
entriesTableViewer.setInput(aliases);
}
catch (KeyStoreManagerException e1)
{
setErrorMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Error_Loading_Keystore);
entriesTableViewer.setInput(new ArrayList<String>());
}
catch (InvalidPasswordException e1)
{
setErrorMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Invalid_Keystore_Pass);
entriesTableViewer.setInput(new ArrayList<String>());
}
validateUi();
}
private void loadTypeCombo(KeyStoreManager keyStoreManager, final Combo typeCombo)
{
typeCombo.setItems(new String[0]);
List<String> availableTypes = keyStoreManager.getAvailableTypes();
for (String type : availableTypes)
{
if (!type.equals(keyStore.getType()))
{
typeCombo.add(type);
}
}
typeCombo.clearSelection();
}
@Override
protected Control createButtonBar(Composite parent)
{
Control bar = super.createButtonBar(parent);
getButton(OK).setEnabled(false);
return bar;
}
public void validateUi()
{
boolean isValid = true;
setErrorMessage(null);
if (isValid && (keyStore == null))
{
isValid = false;
setMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Choose_KeyStore_Msg);
}
if (isValid)
{
boolean passwordValid;
try
{
passwordValid = keyStore.isPasswordValid(password);
}
catch (KeyStoreManagerException e)
{
passwordValid = false;
}
catch (InvalidPasswordException e)
{
passwordValid = false;
}
if (!passwordValid)
{
isValid = false;
setErrorMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Invalid_Keystore_Pass);
}
}
if (isValid && newType.isEmpty())
{
isValid = false;
setMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Choose_New_Type_Msg);
}
if (isValid)
{
Object input = entriesTableViewer.getInput();
if (input != null)
{
int itemCount = ((List<?>) input).size();
for (int i = 0; i < itemCount; i++)
{
EntryModel entryModel = (EntryModel) entriesTableViewer.getElementAt(i);
if ((entryModel != null) && !entryModel.isVerified())
{
isValid = false;
setMessage(
CertificateManagerNLS.ConvertKeyStoreTypeDialog_Incorrect_Entry_Pass,
IMessageProvider.WARNING);
break;
}
}
}
}
Button okButton = getButton(OK);
if (okButton != null)
{
if (!isValid)
{
okButton.setEnabled(false);
}
else
{
getButton(OK).setEnabled(true);
setErrorMessage(null);
setMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_DefaultMessage);
}
}
}
public IKeyStore getKeyStore()
{
return keyStore;
}
public String getNewType()
{
return newType;
}
public Map<String, String> getAliases()
{
return aliaseMap;
}
public String getKeystorePassword()
{
return this.password;
}
}