package org.eparapher.rcp.dialog; import java.io.IOException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.List; import java.util.Set; import org.apache.log4j.Logger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.misc.MiscObjectIdentifiers; import org.bouncycastle.asn1.misc.NetscapeCertType; import org.bouncycastle.asn1.x509.X509Extensions; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.events.ExpansionAdapter; import org.eclipse.ui.forms.events.ExpansionEvent; import org.eclipse.ui.forms.widgets.Form; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; import org.eparapher.core.crypto.cert.CertificateInfo; import org.eparapher.core.crypto.cert.CertificateManager; import org.eparapher.core.crypto.cert.X509Util; import org.eparapher.core.tools.HexCodec; import org.eparapher.rcp.tools.GUIIcons; /** This is a Dialog that parse and display X.509 certificate fields, extentions and properties *

Based On :

* * * @author Arnault MICHEL * */ public class CertificateViewerDialog extends Dialog implements Listener { private static Logger log = Logger.getLogger(CertificateViewerDialog.class); private X509Certificate[] certchain; private String title; private TabFolder tabFolder = null; private FormToolkit tab1toolkit; private Form tab1form; private FormToolkit tab2toolkit; private Form tab2form; private Tree trustchain; private Table X509FieldsList; private Text X509FieldValue; private Section X509FieldValueSection; public CertificateViewerDialog(X509Certificate[] mcertchain) { super(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell()); this.setShellStyle(SWT.DIALOG_TRIM | getDefaultOrientation()); List tmp = null; try { tmp = CertificateManager.establishCertChain( mcertchain[0], true); } catch (Exception e) { if (log.isDebugEnabled()) log.warn("Building certificate chain failed (subject DN:" + mcertchain[0].getSubjectDN().getName() + ")",e); else log.warn("Building certificate chain failed (subject DN:" + mcertchain[0].getSubjectDN().getName() + ")"); } if (tmp!=null) this.certchain = tmp.toArray(new X509Certificate[]{}); else this.certchain = mcertchain; title = CertificateInfo.getSubjectAsShortText( certchain[0] ); } protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); container.setLayout(new FillLayout()); tabFolder = new TabFolder(container,SWT.NONE); tabFolder.setLayout(new FillLayout()); // Create each tab and set its text, tool tip text, image, and control TabItem one = new TabItem(tabFolder, SWT.NONE); one.setText("General"); //one.setToolTipText("Certificate is valid and trusted"); //one.setImage(); one.setControl(getTabOneControl(tabFolder)); TabItem two = new TabItem(tabFolder, SWT.NONE); two.setText("Details"); two.setToolTipText("Detailed certificate information"); //two.setImage(square); two.setControl(getTabTwoControl(tabFolder)); // Select the third tab (index is zero-based) tabFolder.setSelection(0); return container; } protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); } protected Point getInitialSize() { return new Point(450, 600); } /** * Gets the control for tab one * * @param tabFolder the parent tab folder * @return Control */ private Control getTabOneControl(TabFolder tabFolder) { // Create a composite and add four buttons to it Composite composite = new Composite(tabFolder, SWT.NONE); composite.setLayout(new FillLayout()); //title tab1toolkit = new FormToolkit(composite.getDisplay()); tab1form = tab1toolkit.createForm(composite); tab1form.getBody().setLayout(new GridLayout()); tab1form.setText("Certificate informations"); tab1toolkit.decorateFormHeading(tab1form); //tab1form.setImage(GUIIcons.DLG_ICON_VALID_CERT); //to, from, valid from to showToFromValidity(); //Certificate Roles showX509RolesSection(); //Certificate Chain showX509Chain(); return composite; } private void showX509Chain() { Section section = tab1toolkit.createSection(tab1form.getBody(), Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); section.setLayoutData(new GridData(GridData.FILL_BOTH)); section.addExpansionListener(new ExpAdaptor()); section.setText("Trust Path"); Composite sectionClient = tab1toolkit.createComposite(section); sectionClient.setLayout(new FillLayout()); sectionClient.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); trustchain = tab1toolkit.createTree(sectionClient, SWT.NONE); //trustchain.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // Build tree items TreeItem lastItem = null; for (int i = 0; i < certchain.length ; i++) { TreeItem item; if (i == 0) item = new TreeItem(trustchain,SWT.NONE); else { item = new TreeItem(lastItem,SWT.NONE); lastItem.setExpanded(true); } item.setImage(GUIIcons.CERTIFICATE_ICON_IMAGE); item.setText(CertificateInfo.getSubjectAsShortText( certchain[i] )); item.setData(new Integer(i)); lastItem = item; } trustchain.addSelectionListener(new TCListner()); section.setClient(sectionClient); } private void showX509RolesSection() { Section section = tab1toolkit.createSection(tab1form.getBody(), Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); section.addExpansionListener(new ExpAdaptor()); section.setText("Certificate roles"); Composite sectionClient = tab1toolkit.createComposite(section); sectionClient.setLayout(new TableWrapLayout()); String eku = CertificateInfo.getExtendedKeyUsageAsText( certchain[0] ); String eu = CertificateInfo.getKeyUsageAsText( certchain[0] ); String text = "
"; if ( eu.indexOf("digitalSignature")>=0 && eu.indexOf("nonRepudiation")>=0) text += "
  • Digital Signature
  • "; if ( eu.indexOf("keyEncipherment")>=0 ) text += "
  • Key encypherment
  • "; if ( eu.indexOf("dataEncipherment")>=0 ) text += "
  • Data Encypherment
  • "; if ( eu.indexOf("keyAgreement")>=0 ) text += "
  • Key exchange
  • "; if ( eu.indexOf("keyCertSign")>=0 ) text += "
  • Certificate delivery
  • "; if ( eu.indexOf("cRLSign")>=0 ) text += "
  • CRL delivery
  • "; if ( eu.indexOf("encipherOnly")>=0 ) text += "
  • Encipher only
  • "; if ( eu.indexOf("decipherOnly")>=0 ) text += "
  • Decipher only
  • "; if ( eku.indexOf("Server authentication")>=0 ) text += "
  • Server authentication
  • "; if ( eku.indexOf("Client authentication")>=0 ) text += "
  • Client authentication
  • "; if ( eku.indexOf("Code signing")>=0 ) text += "
  • Code signing
  • "; if ( eku.indexOf("Email protection")>=0 ) text += "
  • Email protection
  • "; if ( eku.indexOf("IPSec end system")>=0 ) text += "
  • IPSec end system
  • "; if ( eku.indexOf("IPSec tunnel")>=0 ) text += "
  • IPSec tunnel
  • "; if ( eku.indexOf("IPSec user")>=0 ) text += "
  • IPSec user
  • "; if ( eku.indexOf("Timestamping")>=0 ) text += "
  • Timestamping
  • "; if ( eku.indexOf("Smartcard Logon")>=0 ) text += "
  • Smartcard Logon
  • "; if ( eku.indexOf("OCSP signer")>=0 ) text += "
  • OCSP signer
  • "; text += "
    "; FormText formText = tab1toolkit.createFormText(sectionClient, true); formText.setText(text, true, false); formText.setLayoutData(new TableWrapData(TableWrapData.FILL)); section.setClient(sectionClient); } private void showToFromValidity() { Section section = tab1toolkit.createSection(tab1form.getBody(), Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); section.addExpansionListener(new ExpAdaptor()); section.setText("General"); Composite sectionClient = tab1toolkit.createComposite(section); sectionClient.setLayout(new TableWrapLayout()); String text = "
    "; text += "
  • Delivered to : " + CertificateInfo.getSubjectAsShortText( certchain[0] ) + "
  • "; text += "
  • Delivered by : " + CertificateInfo.getIssuerAsShortText( certchain[0] ) + "
  • "; text += "
  • Valid from " + CertificateInfo.getNotBeforeAsFullText( certchain[0] ) + "
  • "; text += "
  • Valid until " + CertificateInfo.getNotAfterAsFullText( certchain[0] ) + "
  • "; text += "
  • Keypair : " + CertificateInfo.getPublicKeyInfo( certchain[0].getPublicKey() ) + "
  • "; //text += "
  • Status is : " + CertificateManager.verify(certchain) + "
  • "; text += "
    "; FormText formText = tab1toolkit.createFormText(sectionClient, true); formText.setText(text, true, false); formText.setLayoutData(new TableWrapData(TableWrapData.FILL)); section.setClient(sectionClient); } /** * Gets the control for tab two * * @param tabFolder the parent tab folder * @return Control */ private Control getTabTwoControl(TabFolder tabFolder) { // Create a composite and add four buttons to it Composite composite = new Composite(tabFolder, SWT.NONE); composite.setLayout(new FillLayout()); tab2toolkit = new FormToolkit(composite.getDisplay()); tab2form = tab1toolkit.createForm(composite); tab2form.setText("Details"); tab2toolkit.decorateFormHeading(tab2form); GridLayout layout = new GridLayout(); tab2form.getBody().setLayout(layout); //Table of certificate fields showX509Fields(); //Fields details showX509SelectedFieldValue(); return composite; } private void showX509Fields() { Section section = tab2toolkit.createSection(tab2form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); section.setText("X509 Fields"); section.setDescription("List of all certificate fields :"); section.addExpansionListener(new ExpAdaptor()); section.setLayoutData(new GridData(GridData.FILL_BOTH)); Composite sectionClient = tab2toolkit.createComposite(section); GridLayout gl = new GridLayout(1,true); gl.marginLeft = 0; gl.marginRight= 0; sectionClient.setLayout(gl); sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH)); X509FieldsList = tab2toolkit.createTable(sectionClient, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION |SWT.READ_ONLY); GridData gd = new GridData(GridData.FILL_BOTH); gd.heightHint = 10; gd.widthHint = 100; X509FieldsList.setLayoutData(gd); X509FieldsList.setLayout(new FillLayout()); X509FieldsList.setHeaderVisible(true); X509FieldsList.setLinesVisible(true); tab2toolkit.paintBordersFor(sectionClient); //Reduce Font size if (X509FieldsList.getFont()!=null && X509FieldsList.getFont().getFontData()[0].getName() != null) { Font smallFont = new Font(X509FieldsList.getFont().getDevice(),X509FieldsList.getFont().getFontData()[0].getName(),8,SWT.NORMAL); X509FieldsList.setFont(smallFont); } //x509FieldsTable.set TableColumn column1 = new TableColumn(X509FieldsList, SWT.CENTER, 0); column1.setText("Value"); column1.setWidth(260); column1.setResizable(true); TableColumn column2 = new TableColumn(X509FieldsList, SWT.CENTER, 0); column2.setText("Name"); column2.setWidth(120); column2.setResizable(true); populateTable(X509FieldsList); X509FieldsList.addListener(SWT.Selection, this ); section.setClient(sectionClient); } private void showX509SelectedFieldValue() { X509FieldValueSection = tab2toolkit.createSection(tab2form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); X509FieldValueSection.setText("Field Value"); X509FieldValueSection.setDescription("Value of selected field :"); X509FieldValueSection.addExpansionListener(new ExpAdaptor()); X509FieldValueSection.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); GridLayout gl = new GridLayout(1,true); gl.marginLeft = 0; gl.marginRight = 0; X509FieldValueSection.setLayout(gl); Composite sectionClient = tab2toolkit.createComposite(X509FieldValueSection); sectionClient.setLayout(gl); sectionClient.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); tab2toolkit.paintBordersFor(sectionClient); X509FieldValue = tab2toolkit.createText(sectionClient, "", SWT.BORDER|SWT.READ_ONLY|SWT.WRAP|SWT.H_SCROLL); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.heightHint = 70; X509FieldValue.setLayoutData(gd); /*X509FieldValue = tab2toolkit.createFormText(sectionClient, true); GridData gd = new GridData(GridData.FILL_HORIZONTAL); gd.heightHint = 50; X509FieldValue.setLayoutData(gd);*/ X509FieldValueSection.setClient(sectionClient); } public void populateTable(Table table) { CertificateInfo ci = new CertificateInfo( certchain[0] ); //X509 v1 fields TableItem version = new TableItem(table,SWT.LEFT); version.setText(new String[] {"Version", ""+certchain[0].getVersion()}); TableItem serial = new TableItem(table,SWT.LEFT); serial.setText(new String[] {"Serial number", ""+certchain[0].getSerialNumber().toString(16)}); TableItem sigalg = new TableItem(table,SWT.LEFT); sigalg.setText(new String[] {"Signature algorithm", certchain[0].getSigAlgName()}); TableItem subject = new TableItem(table,SWT.LEFT); subject.setText(new String[] {"Subject", certchain[0].getSubjectDN().toString()}); TableItem issuer = new TableItem(table,SWT.LEFT); issuer.setText(new String[] {"Issuer", certchain[0].getIssuerDN().toString() }); TableItem validfrom = new TableItem(table,SWT.LEFT); validfrom.setText(new String[] {"Valid from", CertificateInfo.getNotBeforeAsFullText( certchain[0] ) }); TableItem validuntil = new TableItem(table,SWT.LEFT); validuntil.setText(new String[] {"Valid Until", CertificateInfo.getNotAfterAsFullText( certchain[0] ) }); TableItem pubkey = new TableItem(table,SWT.LEFT); pubkey.setText(new String[] {"Public key", CertificateInfo.getPublicKeyInfo( certchain[0].getPublicKey() ) }); pubkey.setData(certchain[0].getPublicKey().toString()); //X509 v3 extentions //Processing Critical Extentions Set criticalextentions = certchain[0].getCriticalExtensionOIDs(); if (criticalextentions!=null) for (String oid : criticalextentions) { insertX509ExtAsTableItem(oid,ci,table,true); } //Processing Non Critical Extentions Set noncriticalextentions = certchain[0].getNonCriticalExtensionOIDs(); if (noncriticalextentions!=null) for (String oid : noncriticalextentions) { insertX509ExtAsTableItem(oid,ci,table,false); } } private void insertX509ExtAsTableItem(String oid, CertificateInfo ci, Table table, boolean b) { //TODO : Manage critical extentions TableItem certext = new TableItem(table,SWT.LEFT); if (b) { certext.setImage(GUIIcons.WARN_ICON_IMAGE); } if (oid.equals(X509Extensions.KeyUsage.getId())) { String value = CertificateInfo.getKeyUsageAsText( certchain[0] ); certext.setText(new String[] { "key usage", value }); } else if (oid.equals(X509Extensions.ExtendedKeyUsage.getId())) { certext.setText(new String[] {"Extended key usage", CertificateInfo.getExtendedKeyUsageAsText( certchain[0] ) }); try { certext.setData(certchain[0].getExtendedKeyUsage()); } catch (CertificateParsingException e) { log.error("Error while reading X.509 Extended key usage.",e); } } else if (oid.equals(X509Extensions.CRLDistributionPoints.getId())) { try { if ( X509Util.getCrlDistributionPoint( certchain[0] ).length != 0 ) { certext.setText(new String[] {"CRL Distribution Point", ci.getCDPAsText() }); certext.setData( ci.getCDPAsText() ); } } catch (CertificateParsingException e) { log.warn("Error while parsing CDP from certificate : " + certchain[0].getSubjectDN()); } } else if (oid.equals(X509Extensions.SubjectAlternativeName.getId())) { certext.setText(new String[] {"Subject alternative names", ci.getSubjectAltName() }); } else if (oid.equals(X509Extensions.SubjectKeyIdentifier.getId())) { byte[] ski = certchain[0].getExtensionValue(oid); certext.setText(new String[] {"Subject key identifier", HexCodec.printHexString(ski) }); } else if (oid.equals(X509Extensions.AuthorityKeyIdentifier.getId())) { byte[] aki = certchain[0].getExtensionValue(oid); certext.setText(new String[] {"Authority key identifier", HexCodec.printHexString(aki) }); } else if (oid.equals(X509Extensions.PrivateKeyUsagePeriod.getId())) { //byte[] aki = certchain[0].getExtensionValue(oid); DERObject obj; try { obj = X509Util.getExtensionValue(certchain[0], oid); certext.setText(new String[] {"Private Key Usage Period", obj.toString() }); } catch (IOException e) { log.warn("Error while parsing Private Key Usage Period extention from certificate : " + certchain[0].getSubjectDN()); } } else if (oid.equals(MiscObjectIdentifiers.netscapeCertType.getId())) { byte[] nct = certchain[0].getExtensionValue(oid); NetscapeCertType nst = new NetscapeCertType(nct[5]); certext.setText(new String[] {"Netscape certificate type", nst.toString() }); } else if (oid.equals(MiscObjectIdentifiers.entrustVersionExtension.getId())) { //byte[] ev = certchain[0].getExtensionValue(oid); DERObject obj; try { obj = X509Util.getExtensionValue(certchain[0], oid); certext.setText(new String[] {"Entrust version info", obj.toString() }); } catch (IOException e) { log.warn("Error while parsing Entrust version info extention from certificate : " + certchain[0].getSubjectDN()); } } else if (oid.equals(X509Extensions.BasicConstraints.getId())) { int pathlength = certchain[0].getBasicConstraints(); if (pathlength == -1 ) certext.setText(new String[] {"Basic constraints", "This is not a CA Certificate" }); else certext.setText(new String[] {"Basic constraints", "This certificate is a CA\nAllowed length of the certification path : " + ((pathlength==2147483647)?"unlimited":""+pathlength) }); } else { try { DERObject obj = X509Util.getExtensionValue(certchain[0], oid); //TODO : try OID online resolver certext.setText(new String[] {oid, obj.toString() }); } catch (IOException e) { log.warn("Error while parsing "+oid+" extention from certificate : " + certchain[0].getSubjectDN()); } } } /** * Disposes the toolkit */ public void dispose() { tab1toolkit.dispose(); tab2toolkit.dispose(); } /** * Setting title */ protected void configureShell(Shell shell) { super.configureShell(shell); if (title != null) { shell.setText(title); } shell.setImage(GUIIcons.CERTIFICATE_ICON_IMAGE); } /** * * @author arnault * */ //TODO : method reflaw from eclipse site not found, class ExpAdaptor extends ExpansionAdapter { public void expansionStateChanged(ExpansionEvent e) { if (tabFolder != null) { if (tabFolder.getSelectionIndex()==0) { tabFolder.setSelection(1); tabFolder.setSelection(0); } if (tabFolder.getSelectionIndex()==1) { tabFolder.setSelection(0); tabFolder.setSelection(1); } } } } class TCListner implements SelectionListener { public void widgetSelected(SelectionEvent e) { } public void widgetDefaultSelected(SelectionEvent e) { int selCertindex = ((Integer) e.item.getData()).intValue(); if (selCertindex!=0) { X509Certificate[] newcertchaintoview = new X509Certificate[certchain.length-selCertindex]; for (int i = selCertindex; i