/* * 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; } }