package org.eparapher.rcp.editors; import java.security.cert.CertStoreException; import java.security.cert.X509Certificate; import java.util.Collection; import org.apache.log4j.Logger; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.cms.ContentInfo; import org.bouncycastle.cms.SignerInformation; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IPathEditorInput; import org.eclipse.ui.forms.widgets.ColumnLayout; 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.TableWrapLayout; import org.eparapher.core.EParapherManager; import org.eparapher.core.crypto.cert.CertificateInfo; import org.eparapher.core.signature.CMSSignatureParameters; import org.eparapher.core.signature.CMSSignedFile; import org.eparapher.rcp.dialog.CertificateViewerDialog; import org.eparapher.rcp.tools.GUIIcons; /** * * resources : * http://www.ibm.com/developerworks/opensource/library/os-eclipse-forms/ * http://www.eclipse.org/articles/Article-Forms/article.html * * @author arnault * */ public class SignatureTabEditor { private static Logger log = Logger.getLogger(SignatureTabEditor.class); private FormToolkit signTK; private Form signForm; private Tree signerCertChain; private Tree signerList; private IPathEditorInput ipei; private Text timeStampValue; private CMSSignedFile csf; private FormText signatureDetails; public SignatureTabEditor(IEditorInput iEditorInput) { super(); //File is signed or encrypted? if (iEditorInput instanceof IPathEditorInput) { ipei = (IPathEditorInput) iEditorInput; //loadSignature(); } } private void loadSignature() { //CMS Signature String filePath = ipei.getName(); csf = new CMSSignedFile(filePath); if ( csf == null || !csf.isCMSSignedFile() ) { } else { for(SignerInformation signer : csf.getSigners()) { TreeItem item = new TreeItem(signerList,SWT.NONE); item.setImage(GUIIcons.FILE_ICON_CMS); String si = signer.getSID().getIssuerAsString(); String ss = signer.getSID().getSubjectAsString(); if (signer.getSID().getCertificate() !=null) item.setText( CertificateInfo.getSubjectAsShortText( signer.getSID().getCertificate()) ); else { Collection certs; try { certs = csf.getSignerCertificates(signer); if (!certs.isEmpty()) { X509Certificate c = certs.iterator().next(); String s = CertificateInfo.getSubjectAsShortText( c ); item.setText( s ); } else item.setText(signer.getSID().toString()); } catch (CertStoreException e) { log.debug("Cannot get signer certificates " + e.getLocalizedMessage()); e.printStackTrace(); } } item.setData(signer); item.setExpanded(true); } } //TODO : Manage XML and PDF Signatures } /** * Creates page 2 of the multi-page editor, * which allows you to change the font used in page 2. * @param parent */ protected Composite createSignatureForm(Composite parent) { Composite composite = new Composite(parent, SWT.NONE); ColumnLayout columnLayout = new ColumnLayout(); columnLayout.minNumColumns = 2; columnLayout.maxNumColumns = 2; composite.setLayout(new FillLayout()); //Use eclipse Forms signTK = new FormToolkit(composite.getDisplay()); signForm = signTK.createForm(composite); signForm.setLayoutData(new GridData(GridData.FILL_BOTH)); //Set title signForm.setText("Signature informations"); signForm.setImage(GUIIcons.CERTIFICATE_SEL_ICON_IMAGE); signTK.decorateFormHeading(signForm); //Set Layout ColumnLayout cl = new ColumnLayout(); cl.minNumColumns = 2; cl.maxNumColumns = 2; signForm.getBody().setLayout(cl); buildSignatureList(); showSignerX509Chain(); //showCRLs(); loadSignature(); buildSignatureDetails(); showTimestamp(); return composite; } private void buildSignatureList() { Section section = signTK.createSection(signForm.getBody(), Section.DESCRIPTION | Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); section.setText("Signatures"); section.setDescription("List of signatures :"); Composite sectionClient = signTK.createComposite(section); sectionClient.setLayout(new FillLayout()); //sectionClient.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); signerList = signTK.createTree(sectionClient, SWT.BORDER ); signerList.addSelectionListener(new SignatureSelection()); section.setClient(sectionClient); } private void showSignerX509Chain() { Section section = signTK.createSection(signForm.getBody(), Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); //section.setLayoutData(new GridData(GridData.FILL_BOTH)); //section.addExpansionListener(new ExpAdaptor()); section.setText("Signer certificate chain"); section.setDescription("Signer certificate chain :"); Composite sectionClient = signTK.createComposite(section); sectionClient.setLayout(new FillLayout()); //sectionClient.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); signerCertChain = signTK.createTree(sectionClient, SWT.BORDER | SWT.BORDER_DASH | SWT.SINGLE); //signerCertChain.setLayout(new ColumnLayoutData()); signerCertChain.addMouseListener(new CertificateSelection()); signTK.paintBordersFor(sectionClient); section.setClient(sectionClient); } private void buildSignatureDetails() { Section section = signTK.createSection(signForm.getBody(), Section.DESCRIPTION | Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); //section.setLayoutData(new ColumnLayoutData()); section.setText("Signature Details"); section.setDescription("signatures fields :"); Composite sectionComposite = signTK.createComposite(section); sectionComposite.setLayout(new FillLayout()); signatureDetails = signTK.createFormText(sectionComposite, true); section.setClient(sectionComposite); } private void showTimestamp() { Section section = signTK.createSection(signForm.getBody(), Section.DESCRIPTION | Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED); //section.setLayoutData(new ColumnLayoutData()); section.setText("Timestamp"); section.setDescription("coming soon..."); Composite sectionComposite = signTK.createComposite(section); sectionComposite.setLayout(new TableWrapLayout()); String text = "
"; //text += "
  • signature date : date
  • "; //text += "
  • certified by : TSA Name/DN/URL
  • "; text += "
    "; FormText formText = signTK.createFormText(sectionComposite, true); formText.setText(text, true, false); /* ExpandableComposite expcomposite = signTK.createExpandableComposite( sectionComposite, ExpandableComposite.TREE_NODE| ExpandableComposite.CLIENT_INDENT); expcomposite.setText("Timestamp Binary Value"); signTK.paintBordersFor(expcomposite); TableWrapData td = new TableWrapData(); td.maxHeight = 200; td.maxWidth = 400; expcomposite.setLayout(new TableWrapLayout()); expcomposite.setLayoutData(td); timeStampValue = signTK.createText(expcomposite, "", SWT.BORDER|SWT.READ_ONLY|SWT.WRAP|SWT.H_SCROLL); expcomposite.setClient(timeStampValue); expcomposite.addExpansionListener(new ExpansionAdapter() { public void expansionStateChanged(ExpansionEvent e) { signForm.update(); } }); String tsvalue = "303e02010106022a033021300906052b0e03021a050004140000000000000000000000000000000000000000" + "020118180f32303035313130313038313732315a"; timeStampValue.setText(tsvalue); timeStampValue.setLayoutData(td); */ section.setClient(sectionComposite); } public void dispose() { signForm.dispose(); signTK.dispose(); } /** * Change Signature details while selecting a new signature * @author arnault * */ class SignatureSelection implements SelectionListener { public void widgetSelected(SelectionEvent e) { log.info("Signature details not implemented Yet! " + (e.item)); SignerInformation signer = (SignerInformation) e.item.getData(); try { // Build Certificate chain Collection certs= csf.getSignerCertificates(signer); if (!certs.isEmpty()) { TreeItem lastItem = null; for (X509Certificate x509Certificate : certs) { TreeItem item; if (lastItem == null) item = new TreeItem(signerCertChain,SWT.NONE); else item = new TreeItem(lastItem,SWT.NONE); item.setImage(GUIIcons.CERTIFICATE_ICON_IMAGE); item.setText(CertificateInfo.getSubjectAsShortText( x509Certificate )); item.setData(x509Certificate); if (lastItem!=null) lastItem.setExpanded(true); else signerCertChain.setTopItem(item); lastItem = item; } } signerCertChain.redraw(); } catch (CertStoreException e1) { log.debug("Cannot get signer certificates " + e1.getLocalizedMessage()); e1.printStackTrace(); } String text = "
    "; text += "
  • Delivered to : test
  • "; text += "
  • Digest algorithm : "+CMSSignatureParameters.getSignatureDigestAlg(signer.getDigestAlgOID())+"
  • "; text += "
  • Content digest : "+signer.getContentDigest()+"
  • "; AttributeTable ats = signer.getSignedAttributes(); AttributeTable atu = signer.getUnsignedAttributes(); ContentInfo ci = csf.getContent(); text += "
    "; signatureDetails.setText(text, true, false); signatureDetails.redraw(); } public void widgetDefaultSelected(SelectionEvent e) { //change things EParapherManager.getInstance().getUI().infoMessage("Not implemented Yet! Come back later..."); } } /** * Show certificate details on double click * @author arnault * */ class CertificateSelection implements MouseListener { public void mouseDoubleClick(MouseEvent me) { X509Certificate cert = (X509Certificate) ((Tree)me.getSource()).getSelection()[0].getData(); CertificateViewerDialog cvg = new CertificateViewerDialog(new X509Certificate[] {cert}); cvg.open(); } public void mouseDown(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseUp(MouseEvent arg0) { // TODO Auto-generated method stub } } }