blob: 75898eba2b3496f661ab2a53a4ad621e1f54355c [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.wizards;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
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.core.PasswordProvider;
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.EntryNode;
import com.motorolamobility.studio.android.certmanager.ui.model.IKeyStore;
import com.motorolamobility.studio.android.certmanager.ui.model.IKeyStoreEntry;
import com.motorolamobility.studio.android.certmanager.ui.model.KeyStoreNode;
/**
* This class implements the page of signature of external packages wizard It
* extends the page that removes the signature and implements the needed fields
*/
public class SignExternalPackagePage extends RemoveExternalPackageSignaturePage
{
private Label keystoreLabel = null;
private Label keysLabel = null;
private Combo keystoreCombo = null;
private Text keystorePassword = null;
private Button loadKeystore = null;
private Button savePassword = null;
private Combo keysCombo = null;
private String keyEntryPassword;
private String keyStoreType;
PasswordProvider pP = null;
private IKeyStore initialSelectedKeyStore = null;
private IKeyStoreEntry initialSelectedEntry = null;
private IKeyStore selectedKeystore = null;
SelectionAdapter loadKeysSelectionAdapter = new SelectionAdapter()
{
@Override
public void widgetDefaultSelected(SelectionEvent e)
{
widgetSelected(e);
};
/* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e)
{
setKeyEntries();
}
};
/**
* Create a new wizard page based on selection
*
* @param pageName
* the page name
* @param selection
* the selection
*/
public SignExternalPackagePage(String pageName, IStructuredSelection selection,
IKeyStore selectedIKeyStore, IKeyStoreEntry selectedEntry)
{
super(pageName, selection);
this.initialSelectedKeyStore = selectedIKeyStore;
this.initialSelectedEntry = selectedEntry;
setDescription(CertificateManagerNLS.SIGN_EXTERNAL_PKG_WIZARD_DESCRIPTION);
setTitle(CertificateManagerNLS.SIGN_EXTERNAL_PKG_WIZARD_WINDOW_TITLE);
}
private HashMap<String, IKeyStore> getAvailableKeystores()
{
HashMap<String, IKeyStore> keystores = new HashMap<String, IKeyStore>();
Iterator<IKeyStore> iterator = null;
try
{
if ((KeyStoreManager.getInstance() != null)
&& (KeyStoreManager.getInstance().getKeyStores() != null))
{
iterator = KeyStoreManager.getInstance().getKeyStores().iterator();
}
}
catch (KeyStoreManagerException e)
{
StudioLogger.error(this.getClass(), "Error retrieving keystore list", e); //$NON-NLS-1$
}
while ((iterator != null) && (iterator.hasNext()))
{
KeyStoreNode keystore = (KeyStoreNode) iterator.next();
keystores.put(keystore.toString(), keystore);
}
return keystores;
}
/**
* @param keystorePath
* @return key strings for the selected keystore
*/
private final String[] getAvailableEntriesForKeystore(IKeyStore keystore)
{
ArrayList<String> entries = new ArrayList<String>();
if (keystore != null)
{
pP = new PasswordProvider(keystore.getFile());
String password = null;
try
{
// retrieve the saved password
password = pP.getKeyStorePassword(false);
}
catch (KeyStoreManagerException e1)
{
StudioLogger.error(this.getClass(), "Error retrieving keys from keystore", e1); //$NON-NLS-1$
}
if (password == null)
{
// password is not saved
if (!this.keystorePassword.getText().isEmpty())
{
// get the password from the wizard
password = this.keystorePassword.getText();
}
}
else
{
// the password was saved
try
{
keystore.isPasswordValid(password);
}
catch (InvalidPasswordException e)
{
if (!this.keystorePassword.getText().isEmpty())
{
// the saved password is invalid, get the password from the wizard
password = this.keystorePassword.getText();
}
}
catch (KeyStoreManagerException e)
{
//this exception should never happen here as it was handled at some point before
StudioLogger.error("This keystore was imported with wrong store type"); //$NON-NLS-1$
}
}
try
{
try
{
if (password != null)
{
// validate the password that was saved or from the wizard
keystore.isPasswordValid(password);
if (this.keystorePassword.getText().isEmpty())
{
// block the password fields if the password saved is valid
this.keystorePassword.setText(password);
this.keystorePassword.setEnabled(false);
this.savePassword.setSelection(true);
this.savePassword.setEnabled(false);
this.loadKeystore.setEnabled(false);
}
}
List<IKeyStoreEntry> keys = keystore.getEntries(password);
if ((keys.size() > 0) && (password != null))
{
this.keyStoreType = keystore.getType();
Iterator<IKeyStoreEntry> iterator2 = keys.iterator();
while ((iterator2 != null) && (iterator2.hasNext()))
{
EntryNode keyEntry = (EntryNode) iterator2.next();
entries.add(keyEntry.getId());
}
}
}
catch (KeyStoreManagerException e)
{
StudioLogger.error(this.getClass(), "Error retrieving keys from keystore", e); //$NON-NLS-1$
}
}
catch (InvalidPasswordException e)
{
setErrorMessage(CertificateManagerNLS.ConvertKeyStoreTypeDialog_Invalid_Keystore_Pass);
this.keystorePassword.setText(""); //$NON-NLS-1$
this.keystorePassword.setFocus(); //select the password text box so the user can retype the password
}
}
return entries.toArray(new String[0]);
}
/**
* Fill the key entries combo
*
*/
private void setKeyEntries()
{
setErrorMessage(null);
String keystoreSelected = keystoreCombo.getItem(keystoreCombo.getSelectionIndex());
this.selectedKeystore = (IKeyStore) keystoreCombo.getData(keystoreSelected);
String[] availableKeys = getAvailableEntriesForKeystore(this.selectedKeystore);
if (availableKeys.length > 0)
{
keysCombo.setItems(availableKeys);
int selectedEntryIndex = 0;
if (initialSelectedEntry != null)
{
selectedEntryIndex = keysCombo.indexOf(initialSelectedEntry.getAlias());
initialSelectedEntry = null; //the selectedEntry only serves as first selection
}
keysCombo.select(selectedEntryIndex > 0 ? selectedEntryIndex : 0);
updatePageComplete();
}
}
/*
* (non-Javadoc)
*
* @see
* com.motorola.studio.android.packaging.ui.wizards.RemoveExternalPackageSignaturePage
* #createExtendedArea(org.eclipse.swt.widgets.Composite)
*/
@Override
protected void createExtendedArea(Composite parent)
{
GridData layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
// Keystore label
this.keystoreLabel = new Label(parent, SWT.NONE);
this.keystoreLabel.setText(CertificateManagerNLS.SIGN_WIZARD_AREA_SIGN_KEYSTORE_LABEL);
this.keystoreLabel.setLayoutData(layoutData);
// Keystore combo
this.keystoreCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.SINGLE);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1);
this.keystoreCombo.setLayoutData(layoutData);
keystoreCombo.addSelectionListener(new SelectionAdapter()
{
/* (non-Javadoc)
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
*/
@Override
public void widgetSelected(SelectionEvent e)
{
keystorePassword.setText(""); //$NON-NLS-1$
keystorePassword.setEnabled(true);
savePassword.setSelection(false);
savePassword.setEnabled(false);
loadKeystore.setEnabled(false);
keysCombo.removeAll();
setKeyEntries();
if (keystorePassword.getEnabled())
{
keystorePassword.setFocus();
}
//it only serves as
initialSelectedKeyStore = null;
}
});
// Keystore password label
Label keystorePasswordLabel = new Label(parent, SWT.NONE);
keystorePasswordLabel
.setText(CertificateManagerNLS.CreateKeystorePage_KeystorePasswordLabel);
layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
keystorePasswordLabel.setLayoutData(layoutData);
// Keystore password combo
this.keystorePassword = new Text(parent, SWT.BORDER | SWT.PASSWORD);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1);
this.keystorePassword.setLayoutData(layoutData);
this.keystorePassword.addListener(SWT.Modify, new Listener()
{
@Override
public void handleEvent(Event event)
{
if (keystorePassword.getText().isEmpty())
{
loadKeystore.setEnabled(false);
savePassword.setEnabled(false);
}
else
{
loadKeystore.setEnabled(true);
savePassword.setEnabled(true);
}
keysCombo.removeAll();
updatePageComplete();
}
});
this.keystorePassword.addSelectionListener(loadKeysSelectionAdapter);
// Load key entries Button
this.loadKeystore = new Button(parent, SWT.PUSH);
layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
this.loadKeystore.setLayoutData(layoutData);
this.loadKeystore.setText(CertificateManagerNLS.SIGN_EXTERNAL_PKG_WIZARD_LOAD);
this.loadKeystore.setEnabled(false);
this.loadKeystore.addSelectionListener(loadKeysSelectionAdapter);
// Save Keystore Password checkbox
this.savePassword = new Button(parent, SWT.CHECK);
layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false, 4, 1);
this.savePassword.setLayoutData(layoutData);
this.savePassword.setText(CertificateManagerNLS.PasswordProvider_SaveThisPassword);
this.savePassword.setEnabled(false);
this.savePassword.setSelection(false);
// key entry label
this.keysLabel = new Label(parent, SWT.NONE);
this.keysLabel.setText(CertificateManagerNLS.SIGN_WIZARD_AREA_SIGN_KEYS_LABEL);
layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
this.keysLabel.setLayoutData(layoutData);
// key entry combo
this.keysCombo = new Combo(parent, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.SINGLE);
layoutData = new GridData(SWT.FILL, SWT.CENTER, true, false, 3, 1);
this.keysCombo.setLayoutData(layoutData);
PlatformUI
.getWorkbench()
.getHelpSystem()
.setHelp(parent,
CertificateManagerActivator.SIGN_EXTERNAL_PKG_WIZARD_CONTEXT_HELP_ID);
populateKeyStoreCombo();
}
@Override
protected void createPackageTreeLabel()
{
GridData layoutData;
Label packagesLabel = new Label(this.mainComposite, SWT.NONE);
packagesLabel.setText(CertificateManagerNLS.SignExternalPackagePage_Package_Tree_Label);
layoutData = new GridData(SWT.FILL, SWT.CENTER, false, false, 4, 1);
packagesLabel.setLayoutData(layoutData);
}
protected void populateKeyStoreCombo()
{
HashMap<String, IKeyStore> availableKeystores = getAvailableKeystores();
if (availableKeystores.size() > 0)
{
for (String keystoreKey : availableKeystores.keySet())
{
IKeyStore newKeystore = availableKeystores.get(keystoreKey);
this.keystoreCombo.setData(keystoreKey, availableKeystores.get(keystoreKey));
this.keystoreCombo.add(newKeystore.toString());
if (initialSelectedKeyStore != null)
{
if (initialSelectedKeyStore.equals(newKeystore))
{
//select combo with the item selected in Signing and keys view
keystoreCombo.select(keystoreCombo.indexOf(newKeystore.toString()));
setKeyEntries();
}
}
}
if (initialSelectedKeyStore == null)
{
this.keystoreCombo.select(0);
}
}
}
/**
*
* @return the key entry selected by user
*/
public IKeyStoreEntry getSelectedKeyEntry()
{
IKeyStoreEntry result = null;
try
{
result =
this.selectedKeystore.getEntry(
this.keysCombo.getItem(this.keysCombo.getSelectionIndex()),
getKeystorePassword());
}
catch (KeyStoreManagerException e)
{
// should never happen
StudioLogger.error("Could not retrieve entry while signing package"); //$NON-NLS-1$
}
catch (InvalidPasswordException e)
{
// should never happen
StudioLogger.error("Invalid password while retrieving entry to sign package"); //$NON-NLS-1$
}
return result;
}
/**
*
* @return the keystore selected by user
*/
public IKeyStore getSelectedKeyStore()
{
return this.selectedKeystore;
}
/**
*
* @return the keystore password entered by user
*/
public String getKeystorePassword()
{
return this.keystorePassword.getText();
}
/**
*
* @return key entry password
*/
public String getKeyEntryPassword()
{
try
{
this.keyEntryPassword =
pP.getPassword(this.keysCombo.getItem(this.keysCombo.getSelectionIndex()), true);
}
catch (KeyStoreManagerException e)
{
StudioLogger.error(this.getClass(), "Error retrieving keys entry password", e); //$NON-NLS-1$
}
return this.keyEntryPassword;
}
public PasswordProvider getPasswordProvider()
{
return pP;
}
/**
*
* @return the keystore type
*/
public String getKeyStoreType()
{
return this.keyStoreType;
}
/**
* Update the page status, validating each field of this page The basic
* validation is made by superclass
*/
@Override
public void updatePageComplete()
{
super.updatePageComplete();
int severity = getMessageType();
String messageAux = severity == IMessageProvider.NONE ? null : getMessage();
if (messageAux == null)
{
if (!(((this.keystoreCombo != null) && (this.keystoreCombo.getItemCount() > 0)
&& (this.keystoreCombo.getItem(this.keystoreCombo.getSelectionIndex()) != null) && !this.keystoreCombo
.getItem(this.keystoreCombo.getSelectionIndex()).equalsIgnoreCase("")) && ((this.keysCombo != null) //$NON-NLS-1$
&& (this.keysCombo.getItemCount() > 0)
&& (this.keysCombo.getItem(this.keysCombo.getSelectionIndex()) != null) && !this.keysCombo
.getItem(this.keysCombo.getSelectionIndex()).equalsIgnoreCase("")))) //$NON-NLS-1$
{
messageAux =
CertificateManagerNLS.SIGN_EXTERNAL_PKG_WIZARD_NO_CERTIFICATE_ERROR;
severity = IMessageProvider.ERROR;
}
if (messageAux == null)
{
messageAux =
CertificateManagerNLS.SIGN_EXTERNAL_PKG_WIZARD_DESCRIPTION;
severity = IMessageProvider.NONE;
}
setMessage(messageAux, severity);
setPageComplete(severity == IMessageProvider.NONE);
}
}
/**
* @return checkbox save password
*/
public boolean getSavePasswordSelection()
{
return this.savePassword.getSelection();
}
}