package org.eparapher.rcp.views; import java.security.KeyStoreException; import java.security.cert.X509Certificate; import java.util.Iterator; import org.apache.log4j.Logger; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.ColumnWeightData; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableLayout; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IViewPart; import org.eclipse.ui.IWorkbenchActionConstants; import org.eclipse.ui.part.ViewPart; import org.eparapher.core.EParapherManager; import org.eparapher.core.crypto.EPKeystoreManager; import org.eparapher.core.crypto.cert.CertificateInfo; import org.eparapher.core.crypto.keystore.KeystoreEntry; import org.eparapher.rcp.dialog.CertificateViewerDialog; import org.eparapher.rcp.tools.GUIIcons; import org.eparapher.rcp.tools.RCPGUI; public abstract class AbstractCertificateView extends ViewPart { private static Logger log = Logger.getLogger(AbstractCertificateView.class); protected TableViewer viewer; protected Action importAction; protected Action exportAction; protected Action delecteAction; protected Action refreshAction; protected Action doubleClickAction; //private static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.getDefault()); /* * The content provider class is responsible for * providing objects to the view. It can wrap * existing objects in adapters or simply return * objects as-is. These objects may be sensitive * to the current input of the view, or ignore * it and always show the same content * (like Task List, for example). */ class ViewContentProvider implements IStructuredContentProvider { public void inputChanged(Viewer v, Object oldInput, Object newInput) { } public void dispose() { } public Object[] getElements(Object parent) { return getKeystoreEntries(); } } class ViewLabelProvider extends LabelProvider implements ITableLabelProvider { public String getColumnText(Object obj, int index) { if (obj==null) return ""; KeystoreEntry certchain = (KeystoreEntry) obj; X509Certificate userCert = null; if (certchain.getCertificateChain() == null) { if (index==4) return "Secret Key"; if (index==7) return certchain.getKeystoreAlias(); return "--"; } userCert = certchain.getCertificateChain()[0]; switch (index) { case 0: return CertificateInfo.getSubjectAsShortText(userCert); case 1: return CertificateInfo.getIssuerAsShortText(userCert); case 2: return CertificateInfo.getNotBeforeAsText( userCert ); case 3: return CertificateInfo.getNotAfterAsText( userCert ); case 4: return CertificateInfo.getPublicKeyInfo( userCert.getPublicKey() ); case 5: return CertificateInfo.getKeyUsageAsText(userCert); case 6: return CertificateInfo.getExtendedKeyUsageAsText(userCert); case 7: return certchain.getKeystoreAlias(); default: break; } return ""; } public Image getColumnImage(Object obj, int index) { if (index == 0) return getImage(obj); return null; } public Image getImage(Object obj) { return getCertificateImage(obj); } } class NameComparator extends ViewerComparator { public int compare(Viewer viewer, Object e1, Object e2) { KeystoreEntry k1 = (KeystoreEntry) e1; KeystoreEntry k2 = (KeystoreEntry) e2; if (k1.getCertificateChain()==null || k2.getCertificateChain()==null || k1.getCertificateChain().length ==0 || k2.getCertificateChain().length ==0) return 1; String s1 = CertificateInfo.getSubjectAsShortText(k1.getCertificateChain()[0]); String s2 = CertificateInfo.getSubjectAsShortText(k2.getCertificateChain()[0]); int compare = getComparator().compare(s1, s2); return compare; } public boolean isSorterProperty(Object element, String property) { return false; } } /** * This is a callback that will allow us * to create the viewer and initialize it. */ public void createPartControl(Composite parent) { viewer = new TableViewer(createTable(parent)); viewer.setContentProvider(new ViewContentProvider()); viewer.setLabelProvider(new ViewLabelProvider()); viewer.setComparator(new NameComparator()); viewer.setInput(getViewSite()); makeActions(); hookContextMenu(); hookDoubleClickAction(); contributeToActionBars(); } private Table createTable(Composite parent) { //Table struture Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); table.setLinesVisible(true); table.setHeaderVisible(true); TableLayout layout = new TableLayout(); layout.addColumnData(new ColumnWeightData(1, 100, true)); layout.addColumnData(new ColumnWeightData(1, 100, true)); layout.addColumnData(new ColumnWeightData(1, 100, true)); layout.addColumnData(new ColumnWeightData(1, 100, true)); layout.addColumnData(new ColumnWeightData(1, 100, true)); layout.addColumnData(new ColumnWeightData(1, 100, true)); layout.addColumnData(new ColumnWeightData(1, 100, true)); table.setLayout(layout); TableColumn nameColumn = new TableColumn(table, SWT.NONE); nameColumn.setText("Delivered to"); nameColumn.setWidth(70); nameColumn.setMoveable(true); TableColumn issuerCNColumn = new TableColumn(table, SWT.NONE); issuerCNColumn.setText("Delivered by"); issuerCNColumn.setWidth(70); issuerCNColumn.setMoveable(true); TableColumn deliveryDateColumn = new TableColumn(table, SWT.NONE); deliveryDateColumn.setText("Valid from"); deliveryDateColumn.setWidth(70); deliveryDateColumn.setMoveable(true); TableColumn expiryDateColumn = new TableColumn(table, SWT.NONE); expiryDateColumn.setText("Expires on"); expiryDateColumn.setWidth(70); expiryDateColumn.setMoveable(true); TableColumn keyColumn = new TableColumn(table, SWT.NONE); keyColumn.setText("Key"); keyColumn.setWidth(120); keyColumn.setMoveable(true); TableColumn keyusageColumn = new TableColumn(table, SWT.NONE); keyusageColumn.setText("Key Usage"); keyusageColumn.setWidth(120); keyusageColumn.setMoveable(true); TableColumn issuerDNColumn = new TableColumn(table, SWT.NONE); issuerDNColumn.setText("Extended KeyUsage"); issuerDNColumn.setWidth(120); issuerDNColumn.setMoveable(true); TableColumn aliasColumn = new TableColumn(table, SWT.NONE); aliasColumn.setText("Alias"); aliasColumn.setWidth(60); aliasColumn.setMoveable(true); return table; } private void hookContextMenu() { MenuManager menuMgr = new MenuManager("#PopupMenu"); menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { fillContextMenu(manager); } }); Menu menu = menuMgr.createContextMenu(viewer.getControl()); viewer.getControl().setMenu(menu); getSite().registerContextMenu(menuMgr, viewer); } private void contributeToActionBars() { IActionBars bars = getViewSite().getActionBars(); //fillLocalPullDown(bars.getMenuManager()); fillLocalToolBar(bars.getToolBarManager()); } protected void fillLocalPullDown(IMenuManager manager) { manager.add(importAction); manager.add(exportAction); } protected void fillContextMenu(IMenuManager manager) { manager.add(delecteAction); manager.add(new Separator()); manager.add(importAction); manager.add(exportAction); manager.add(new Separator()); manager.add(refreshAction); // Other plug-ins can contribute there actions here manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS)); } protected void fillLocalToolBar(IToolBarManager manager) { manager.add(refreshAction); manager.add(new Separator()); manager.add(importAction); manager.add(exportAction); } protected void makeActions() { delecteAction = new DeleteAction(this); refreshAction = new RefreshAction(); doubleClickAction = new DoubleClickAction(); } private void hookDoubleClickAction() { viewer.addDoubleClickListener(new IDoubleClickListener() { public void doubleClick(DoubleClickEvent event) { doubleClickAction.run(); } }); } /** * Passing the focus request to the viewer's control. */ public void setFocus() { viewer.getControl().setFocus(); } /** * Refresh the view. */ public void refreshView() { //refresh the view if (viewer!=null) viewer.refresh(); } /** * Passing the focus request to the viewer's control. */ protected abstract Object[] getKeystoreEntries(); protected abstract Image getCertificateImage(Object obj); protected String[] getSelectedAlias() { ISelection selection = viewer.getSelection(); int size = ((IStructuredSelection)selection).size(); String[] selected_aliases = new String[size]; int i=0; IStructuredSelection struct_sel = (IStructuredSelection)selection; for (Iterator iterator = struct_sel.iterator(); iterator.hasNext();) { KeystoreEntry type = iterator.next(); selected_aliases[i++] = type.getKeystoreAlias(); } return selected_aliases; } class RefreshAction extends Action { protected RefreshAction() { setText("Re&fresh"); setToolTipText("Refresh the Tree for added/removed files"); setImageDescriptor(GUIIcons.REFRESH_ICON); setAccelerator(SWT.F5); } public void run() { viewer.refresh(); } } class DoubleClickAction extends Action { public void run() { ISelection selection = viewer.getSelection(); Object obj = ((IStructuredSelection)selection).getFirstElement(); if (obj instanceof KeystoreEntry) { KeystoreEntry ke = (KeystoreEntry) obj; if (ke.getCertificateChain()!=null) { CertificateViewerDialog cvg = new CertificateViewerDialog(ke.getCertificateChain()); cvg.open(); } else { //TODO : For Secret Key, ask password and show it } } } } class DeleteAction extends Action { IViewPart vp; public DeleteAction(IViewPart mvp) { setText("Delete"); setToolTipText("Delete selected keys/certificates"); setImageDescriptor(GUIIcons.TRASH_ICON); vp = mvp; } public void run() { ISelection selection = viewer.getSelection(); if (selection.isEmpty()) RCPGUI.infoMessage("Delete private key(s) and/or certificate(s)","Please select first an entry in the list."); else { String[] aliases_to_del = getSelectedAlias(); String aliases = "alias "; if (aliases_to_del.length>1) aliases = "aliases "; for (int i = 0; i < aliases_to_del.length; i++) { aliases += aliases_to_del[i] + ( i != (aliases_to_del.length-1) ? ", " : "" ); } if ( EParapherManager.getInstance().getUI().askUserYesNo("Please confirm the deletion of keys and/or certificates for " + aliases) ) { for (int i = 0; i < aliases_to_del.length; i++) { try { if (vp instanceof UserCertificateStoreView) EPKeystoreManager.getInstance().getUserkeystore().getKeystore().deleteEntry(aliases_to_del[i]); if (vp instanceof TrustedCertificateStoreView) { EPKeystoreManager.getInstance().getTrustStore().getKeystore().deleteEntry(aliases_to_del[i]); log.info("Alias " + aliases_to_del[i] + " deleted in truststore"); } } catch (KeyStoreException e) { log.error("Cannot delete alias " + aliases_to_del[i] + " in user keystore", e ); } viewer.refresh(); } if (vp instanceof UserCertificateStoreView) EPKeystoreManager.getInstance().getUserkeystore().saveKeyStore(); if (vp instanceof TrustedCertificateStoreView) EPKeystoreManager.getInstance().getTrustStore().saveTrustStore(); } } } } }