1 package org.eparapher.rcp.dialog;
2
3 import java.io.IOException;
4 import java.security.cert.CertificateParsingException;
5 import java.security.cert.X509Certificate;
6 import java.util.List;
7 import java.util.Set;
8
9 import org.apache.log4j.Logger;
10 import org.bouncycastle.asn1.DERObject;
11 import org.bouncycastle.asn1.x509.X509Extensions;
12 import org.eclipse.jface.dialogs.Dialog;
13 import org.eclipse.jface.dialogs.IDialogConstants;
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.events.SelectionEvent;
16 import org.eclipse.swt.events.SelectionListener;
17 import org.eclipse.swt.graphics.Font;
18 import org.eclipse.swt.graphics.FontData;
19 import org.eclipse.swt.graphics.Point;
20 import org.eclipse.swt.layout.FillLayout;
21 import org.eclipse.swt.layout.GridData;
22 import org.eclipse.swt.layout.GridLayout;
23 import org.eclipse.swt.widgets.Composite;
24 import org.eclipse.swt.widgets.Control;
25 import org.eclipse.swt.widgets.Event;
26 import org.eclipse.swt.widgets.Label;
27 import org.eclipse.swt.widgets.Listener;
28 import org.eclipse.swt.widgets.Shell;
29 import org.eclipse.swt.widgets.TabFolder;
30 import org.eclipse.swt.widgets.TabItem;
31 import org.eclipse.swt.widgets.Table;
32 import org.eclipse.swt.widgets.TableColumn;
33 import org.eclipse.swt.widgets.TableItem;
34 import org.eclipse.swt.widgets.Text;
35 import org.eclipse.swt.widgets.Tree;
36 import org.eclipse.swt.widgets.TreeItem;
37 import org.eclipse.ui.PlatformUI;
38 import org.eclipse.ui.forms.events.ExpansionAdapter;
39 import org.eclipse.ui.forms.events.ExpansionEvent;
40 import org.eclipse.ui.forms.widgets.Form;
41 import org.eclipse.ui.forms.widgets.FormText;
42 import org.eclipse.ui.forms.widgets.FormToolkit;
43 import org.eclipse.ui.forms.widgets.Section;
44 import org.eclipse.ui.forms.widgets.TableWrapData;
45 import org.eclipse.ui.forms.widgets.TableWrapLayout;
46 import org.eparapher.core.crypto.cert.CertificateInfo;
47 import org.eparapher.core.crypto.cert.CertificateManager;
48 import org.eparapher.core.crypto.cert.X509Util;
49 import org.eparapher.rcp.tools.GUIIcons;
50
51
52
53
54
55
56
57
58
59
60
61 public class CertificateViewerDialog extends Dialog implements Listener {
62
63 private static Logger log = Logger.getLogger(CertificateViewerDialog.class);
64
65 private X509Certificate[] certchain;
66
67 private String title;
68
69 private TabFolder tabFolder = null;
70
71 private FormToolkit tab1toolkit;
72 private Form tab1form;
73
74 private FormToolkit tab2toolkit;
75 private Form tab2form;
76
77 private Tree trustchain;
78
79 private Table X509FieldsList;
80 private Text X509FieldValue;
81 private Section X509FieldValueSection;
82
83 public CertificateViewerDialog(X509Certificate[] mcertchain) {
84 super(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
85 this.setShellStyle(SWT.DIALOG_TRIM | getDefaultOrientation());
86
87 List<X509Certificate> tmp = null;
88 try {
89 tmp = CertificateManager.establishCertChain( mcertchain[0], true);
90 } catch (Exception e) {
91 log.warn("Building certificate chain failed (subject DN:" + mcertchain[0].getSubjectDN().getName() + ")");
92 }
93
94 if (tmp!=null)
95 this.certchain = tmp.toArray(new X509Certificate[]{});
96 else this.certchain = mcertchain;
97
98 title = CertificateInfo.getSubjectAsShortText( certchain[0] );
99
100 }
101
102 protected Control createDialogArea(Composite parent) {
103 Composite container = (Composite) super.createDialogArea(parent);
104
105 container.setLayout(new FillLayout());
106
107 tabFolder = new TabFolder(container,SWT.NONE);
108 tabFolder.setLayout(new FillLayout());
109
110
111 TabItem one = new TabItem(tabFolder, SWT.NONE);
112 one.setText("General");
113
114
115 one.setControl(getTabOneControl(tabFolder));
116
117 TabItem two = new TabItem(tabFolder, SWT.NONE);
118 two.setText("Details");
119 two.setToolTipText("Detailed certificate information");
120
121 two.setControl(getTabTwoControl(tabFolder));
122
123
124 tabFolder.setSelection(0);
125
126 return container;
127 }
128
129 protected void createButtonsForButtonBar(Composite parent) {
130 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
131 createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
132 }
133
134 protected Point getInitialSize() {
135 return new Point(450, 600);
136 }
137
138
139
140
141
142
143
144 private Control getTabOneControl(TabFolder tabFolder) {
145
146 Composite composite = new Composite(tabFolder, SWT.NONE);
147 composite.setLayout(new FillLayout());
148
149
150 tab1toolkit = new FormToolkit(composite.getDisplay());
151 tab1form = tab1toolkit.createForm(composite);
152 tab1form.getBody().setLayout(new GridLayout());
153
154 tab1form.setText("Certificate informations");
155 tab1toolkit.decorateFormHeading(tab1form);
156
157
158
159 showToFromValidity();
160
161
162 showX509RolesSection();
163
164
165 showX509Chain();
166
167 return composite;
168 }
169
170 private void showX509Chain() {
171 Section section = tab1toolkit.createSection(tab1form.getBody(), Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED);
172 section.setLayoutData(new GridData(GridData.FILL_BOTH));
173 section.addExpansionListener(new ExpAdaptor());
174 section.setText("Trust Path");
175
176 Composite sectionClient = tab1toolkit.createComposite(section);
177 sectionClient.setLayout(new FillLayout());
178 sectionClient.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
179
180 trustchain = tab1toolkit.createTree(sectionClient, SWT.NONE);
181
182
183 TreeItem lastItem = null;
184 for (int i = 0; i < certchain.length ; i++) {
185 TreeItem item;
186 if (i == 0)
187 item = new TreeItem(trustchain,SWT.NONE);
188 else {
189 item = new TreeItem(lastItem,SWT.NONE);
190 lastItem.setExpanded(true);
191 }
192 item.setImage(GUIIcons.CERTIFICATE_ICON_IMAGE);
193 item.setText(CertificateInfo.getSubjectAsShortText( certchain[i] ));
194 item.setData(new Integer(i));
195 lastItem = item;
196 }
197 trustchain.addSelectionListener(new TCListner());
198
199 section.setClient(sectionClient);
200
201 }
202
203 private void showX509RolesSection() {
204 Section section = tab1toolkit.createSection(tab1form.getBody(), Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED);
205 section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
206 section.addExpansionListener(new ExpAdaptor());
207 section.setText("Certificate roles");
208
209 Composite sectionClient = tab1toolkit.createComposite(section);
210 sectionClient.setLayout(new TableWrapLayout());
211
212 String eku = CertificateInfo.getExtendedKeyUsageAsText( certchain[0] );
213 String eu = CertificateInfo.getKeyUsageAsText( certchain[0] );
214 String text = "<form>";
215
216 if ( eu.indexOf("digitalSignature")>=0 && eu.indexOf("nonRepudiation")>=0)
217 text += "<li>Digital Signature</li>";
218 if ( eu.indexOf("keyEncipherment")>=0 )
219 text += "<li>Key encypherment</li>";
220 if ( eu.indexOf("dataEncipherment")>=0 )
221 text += "<li>Data Encypherment</li>";
222 if ( eu.indexOf("keyAgreement")>=0 )
223 text += "<li>Key exchange</li>";
224 if ( eu.indexOf("keyCertSign")>=0 )
225 text += "<li>Certificate delivery</li>";
226 if ( eu.indexOf("cRLSign")>=0 )
227 text += "<li>CRL delivery</li>";
228 if ( eu.indexOf("encipherOnly")>=0 )
229 text += "<li>Encipher only</li>";
230 if ( eu.indexOf("decipherOnly")>=0 )
231 text += "<li>Decipher only</li>";
232
233 if ( eku.indexOf("Server authentication")>=0 )
234 text += "<li>Server authentication</li>";
235 if ( eku.indexOf("Client authentication")>=0 )
236 text += "<li>Client authentication</li>";
237 if ( eku.indexOf("Code signing")>=0 )
238 text += "<li>Code signing</li>";
239 if ( eku.indexOf("Email protection")>=0 )
240 text += "<li>Email protection</li>";
241 if ( eku.indexOf("IPSec end system")>=0 )
242 text += "<li>IPSec end system</li>";
243 if ( eku.indexOf("IPSec tunnel")>=0 )
244 text += "<li>IPSec tunnel</li>";
245 if ( eku.indexOf("IPSec user")>=0 )
246 text += "<li>IPSec user</li>";
247 if ( eku.indexOf("Timestamping")>=0 )
248 text += "<li>Timestamping</li>";
249 if ( eku.indexOf("Smartcard Logon")>=0 )
250 text += "<li>Smartcard Logon</li>";
251 if ( eku.indexOf("OCSP signer")>=0 )
252 text += "<li>OCSP signer</li>";
253 text += "</form>";
254
255 FormText formText = tab1toolkit.createFormText(sectionClient, true);
256 formText.setText(text, true, false);
257 formText.setLayoutData(new TableWrapData(TableWrapData.FILL));
258
259 section.setClient(sectionClient);
260
261 }
262
263 private void showToFromValidity() {
264 Section section = tab1toolkit.createSection(tab1form.getBody(), Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED);
265 section.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
266 section.addExpansionListener(new ExpAdaptor());
267 section.setText("General");
268
269 Composite sectionClient = tab1toolkit.createComposite(section);
270 sectionClient.setLayout(new TableWrapLayout());
271
272 String text = "<form>";
273 text += "<li>Delivered to : <b>" + CertificateInfo.getSubjectAsShortText( certchain[0] ) + "</b></li>";
274 text += "<li>Delivered by : <b>" + CertificateInfo.getIssuerAsShortText( certchain[0] ) + "</b></li>";
275 text += "<li>Valid from <b>" + CertificateInfo.getNotBeforeAsFullText( certchain[0] ) + "</b></li>";
276 text += "<li>Valid until <b>" + CertificateInfo.getNotAfterAsFullText( certchain[0] ) + "</b></li>";
277 text += "<li>Keypair : <b> " + CertificateInfo.getPublicKeyInfo( certchain[0].getPublicKey() ) + "</b></li>";
278
279 text += "</form>";
280
281 FormText formText = tab1toolkit.createFormText(sectionClient, true);
282 formText.setText(text, true, false);
283 formText.setLayoutData(new TableWrapData(TableWrapData.FILL));
284
285 section.setClient(sectionClient);
286 }
287
288
289
290
291
292
293
294 private Control getTabTwoControl(TabFolder tabFolder) {
295
296 Composite composite = new Composite(tabFolder, SWT.NONE);
297 composite.setLayout(new FillLayout());
298
299 tab2toolkit = new FormToolkit(composite.getDisplay());
300 tab2form = tab1toolkit.createForm(composite);
301 tab2form.setText("Details");
302 tab2toolkit.decorateFormHeading(tab2form);
303
304 GridLayout layout = new GridLayout();
305 tab2form.getBody().setLayout(layout);
306
307
308 showX509Fields();
309
310
311 showX509SelectedFieldValue();
312
313 return composite;
314 }
315
316 private void showX509Fields() {
317 Section section = tab2toolkit.createSection(tab2form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED);
318 section.setText("X509 Fields");
319 section.setDescription("List of all certificate fields :");
320 section.addExpansionListener(new ExpAdaptor());
321 section.setLayoutData(new GridData(GridData.FILL_BOTH));
322
323 Composite sectionClient = tab2toolkit.createComposite(section);
324 GridLayout gl = new GridLayout(1,true);
325 gl.marginLeft = 0;
326 gl.marginRight= 0;
327 sectionClient.setLayout(gl);
328 sectionClient.setLayoutData(new GridData(GridData.FILL_BOTH));
329
330 X509FieldsList = tab2toolkit.createTable(sectionClient, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION |SWT.READ_ONLY);
331 GridData gd = new GridData(GridData.FILL_BOTH);
332 gd.heightHint = 10;
333 gd.widthHint = 100;
334 X509FieldsList.setLayoutData(gd);
335 X509FieldsList.setLayout(new FillLayout());
336 X509FieldsList.setHeaderVisible(true);
337 X509FieldsList.setLinesVisible(true);
338 tab2toolkit.paintBordersFor(sectionClient);
339
340
341 Font smallFont = new Font(X509FieldsList.getFont().getDevice(),X509FieldsList.getFont().getFontData()[0].name,8,SWT.NORMAL);
342 X509FieldsList.setFont(smallFont);
343
344
345 TableColumn column1 = new TableColumn(X509FieldsList, SWT.CENTER, 0);
346 column1.setText("Value");
347 column1.setWidth(260);
348 column1.setResizable(true);
349 TableColumn column2 = new TableColumn(X509FieldsList, SWT.CENTER, 0);
350 column2.setText("Name");
351 column2.setWidth(120);
352 column2.setResizable(true);
353
354 populateTable(X509FieldsList);
355
356 X509FieldsList.addListener(SWT.Selection, this );
357
358 section.setClient(sectionClient);
359
360 }
361
362 private void showX509SelectedFieldValue() {
363
364 X509FieldValueSection = tab2toolkit.createSection(tab2form.getBody(), Section.DESCRIPTION|Section.TITLE_BAR| Section.TWISTIE|Section.EXPANDED);
365 X509FieldValueSection.setText("Field Value");
366 X509FieldValueSection.setDescription("Value of selected field :");
367 X509FieldValueSection.addExpansionListener(new ExpAdaptor());
368 X509FieldValueSection.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
369 GridLayout gl = new GridLayout(1,true);
370 gl.marginLeft = 0;
371 gl.marginRight = 0;
372 X509FieldValueSection.setLayout(gl);
373
374 Composite sectionClient = tab2toolkit.createComposite(X509FieldValueSection);
375 sectionClient.setLayout(gl);
376 sectionClient.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
377 tab2toolkit.paintBordersFor(sectionClient);
378
379 X509FieldValue = tab2toolkit.createText(sectionClient, "", SWT.BORDER|SWT.READ_ONLY|SWT.WRAP|SWT.H_SCROLL);
380 GridData gd = new GridData(GridData.FILL_HORIZONTAL);
381 gd.heightHint = 70;
382 X509FieldValue.setLayoutData(gd);
383
384
385
386
387
388
389 X509FieldValueSection.setClient(sectionClient);
390 }
391
392 public void populateTable(Table table) {
393
394 CertificateInfo ci = new CertificateInfo( certchain[0] );
395
396
397 TableItem version = new TableItem(table,SWT.LEFT);
398 version.setText(new String[] {"Version", ""+certchain[0].getVersion()});
399
400 TableItem serial = new TableItem(table,SWT.LEFT);
401 serial.setText(new String[] {"Serial number", ""+certchain[0].getSerialNumber().toString(16)});
402
403 TableItem sigalg = new TableItem(table,SWT.LEFT);
404 sigalg.setText(new String[] {"Signature algorithm", certchain[0].getSigAlgName()});
405
406 TableItem subject = new TableItem(table,SWT.LEFT);
407 subject.setText(new String[] {"Subject", certchain[0].getSubjectDN().toString()});
408
409 TableItem issuer = new TableItem(table,SWT.LEFT);
410 issuer.setText(new String[] {"Issuer", certchain[0].getIssuerDN().toString() });
411
412 TableItem validfrom = new TableItem(table,SWT.LEFT);
413 validfrom.setText(new String[] {"Valid from", CertificateInfo.getNotBeforeAsFullText( certchain[0] ) });
414
415 TableItem validuntil = new TableItem(table,SWT.LEFT);
416 validuntil.setText(new String[] {"Valid Until", CertificateInfo.getNotAfterAsFullText( certchain[0] ) });
417
418 TableItem pubkey = new TableItem(table,SWT.LEFT);
419 pubkey.setText(new String[] {"Public key", CertificateInfo.getPublicKeyInfo( certchain[0].getPublicKey() ) });
420 pubkey.setData(certchain[0].getPublicKey().toString());
421
422
423
424
425 Set<String> criticalextentions = certchain[0].getCriticalExtensionOIDs();
426 for (String oid : criticalextentions) {
427 insertX509ExtAsTableItem(oid,ci,table,true);
428 }
429
430 Set<String> noncriticalextentions = certchain[0].getNonCriticalExtensionOIDs();
431 for (String oid : noncriticalextentions) {
432 insertX509ExtAsTableItem(oid,ci,table,false);
433 }
434 }
435
436 private void insertX509ExtAsTableItem(String oid, CertificateInfo ci, Table table, boolean b) {
437
438 TableItem certext = new TableItem(table,SWT.LEFT);
439
440 if (oid.equals(X509Extensions.KeyUsage.getId())) {
441 String value = CertificateInfo.getKeyUsageAsText( certchain[0] );
442 certext.setText(new String[] { "key usage", value });
443 }
444
445 else if (oid.equals(X509Extensions.ExtendedKeyUsage.getId())) {
446 certext.setText(new String[] {"Extended key usage", CertificateInfo.getExtendedKeyUsageAsText( certchain[0] ) });
447 try {
448 certext.setData(certchain[0].getExtendedKeyUsage());
449 } catch (CertificateParsingException e) {
450 log.error("Error while reading X.509 Extended key usage.",e);
451 }
452 }
453
454 else if (oid.equals(X509Extensions.CRLDistributionPoints.getId())) {
455 try {
456 if ( X509Util.getCrlDistributionPoint( certchain[0] ).length != 0 ) {
457 certext.setText(new String[] {"CRL Distribution Point", ci.getCDPAsText() });
458 certext.setData( ci.getCDPAsText() );
459 }
460 } catch (CertificateParsingException e) {
461 log.warn("Error while parsing CDP from certificate : " + certchain[0].getSubjectDN());
462 }
463 }
464
465 else if (oid.equals(X509Extensions.SubjectAlternativeName.getId())) {
466 certext.setText(new String[] {"Subject alternative names", ci.getSubjectAltName() });
467 }
468
469 else if (oid.equals(X509Extensions.SubjectKeyIdentifier.getId())) {
470 try {
471 DERObject obj = X509Util.getExtensionValue(certchain[0], oid);
472 certext.setText(new String[] {"Subject key identifier", obj.toString() });
473 } catch (IOException e) {
474 log.warn("Error while parsing SubjectKeyIdentifier from certificate : " + certchain[0].getSubjectDN());
475 }
476 }
477
478 else if (oid.equals(X509Extensions.AuthorityKeyIdentifier.getId())) {
479 try {
480 DERObject obj = X509Util.getExtensionValue(certchain[0], oid);
481 certext.setText(new String[] {"Authority key identifier", obj.toString() });
482 } catch (IOException e) {
483 log.warn("Error while parsing AuthorityKeyIdentifier from certificate : " + certchain[0].getSubjectDN());
484 }
485 }
486
487 else if (oid.equals(X509Extensions.BasicConstraints.getId())) {
488 try {
489 DERObject obj = X509Util.getExtensionValue(certchain[0], oid);
490 certext.setText(new String[] {"Basic constraints", obj.toString() });
491 } catch (IOException e) {
492 log.warn("Error while parsing BasicConstraints from certificate : " + certchain[0].getSubjectDN());
493 }
494 }
495 else {
496 try {
497 DERObject obj = X509Util.getExtensionValue(certchain[0], oid);
498 certext.setText(new String[] {oid, obj.toString() });
499 } catch (IOException e) {
500 log.warn("Error while parsing AuthorityKeyIdentifier from certificate : " + certchain[0].getSubjectDN());
501 }
502 }
503
504 }
505
506
507
508
509 public void dispose() {
510 tab1toolkit.dispose();
511 tab2toolkit.dispose();
512 }
513
514
515
516
517 protected void configureShell(Shell shell) {
518 super.configureShell(shell);
519 if (title != null) {
520 shell.setText(title);
521 }
522 shell.setImage(GUIIcons.CERTIFICATE_ICON_IMAGE);
523 }
524
525
526
527
528
529
530 class ExpAdaptor extends ExpansionAdapter {
531 public void expansionStateChanged(ExpansionEvent e) {
532 if (tabFolder != null) {
533 if (tabFolder.getSelectionIndex()==0) {
534 tabFolder.setSelection(1);
535 tabFolder.setSelection(0);
536 }
537 if (tabFolder.getSelectionIndex()==1) {
538 tabFolder.setSelection(0);
539 tabFolder.setSelection(1);
540 }
541 }
542 }
543 }
544
545 class TCListner implements SelectionListener {
546
547 public void widgetSelected(SelectionEvent e) { }
548
549 public void widgetDefaultSelected(SelectionEvent e) {
550 int selCertindex = ((Integer) e.item.getData()).intValue();
551 if (selCertindex!=0) {
552 X509Certificate[] newcertchaintoview = new X509Certificate[certchain.length-selCertindex];
553 for (int i = selCertindex; i <certchain.length ; i++) {
554 newcertchaintoview[i-selCertindex] = certchain[i];
555 }
556 CertificateViewerDialog cvg = new CertificateViewerDialog(newcertchaintoview);
557 cvg.open();
558 }
559 }
560 }
561
562 public void handleEvent(Event event) {
563 if (event.widget instanceof Table) {
564 TableItem ti = (TableItem)event.item;
565 X509FieldValueSection.setDescription(ti.getText(0));
566 if (ti.getData()==null) {
567 String FieldValue = ti.getText(1);
568 X509FieldValue.setText(FieldValue);
569
570 } else {
571 X509FieldValue.setText(ti.getData().toString());;
572 }
573 }
574 }
575 }