1 package org.eparapher.rcp.wizards;
2
3 import java.io.FileNotFoundException;
4 import java.io.FileReader;
5 import java.io.IOException;
6 import java.security.NoSuchProviderException;
7 import java.security.PublicKey;
8 import java.security.cert.CertificateException;
9 import java.security.cert.X509CRL;
10 import java.security.cert.X509Certificate;
11 import java.util.ArrayList;
12 import java.util.Collection;
13 import java.util.List;
14
15 import org.apache.log4j.Logger;
16 import org.bouncycastle.cms.CMSException;
17 import org.bouncycastle.jce.PKCS10CertificationRequest;
18 import org.bouncycastle.openssl.PEMReader;
19 import org.bouncycastle.x509.NoSuchStoreException;
20 import org.eclipse.jface.viewers.ISelectionChangedListener;
21 import org.eclipse.jface.viewers.SelectionChangedEvent;
22 import org.eclipse.jface.wizard.IWizardPage;
23 import org.eclipse.jface.wizard.WizardPage;
24 import org.eclipse.swt.SWT;
25 import org.eclipse.swt.events.SelectionAdapter;
26 import org.eclipse.swt.events.SelectionEvent;
27 import org.eclipse.swt.layout.FillLayout;
28 import org.eclipse.swt.layout.GridData;
29 import org.eclipse.swt.layout.GridLayout;
30 import org.eclipse.swt.widgets.Button;
31 import org.eclipse.swt.widgets.Composite;
32 import org.eclipse.swt.widgets.FileDialog;
33 import org.eclipse.swt.widgets.Group;
34 import org.eclipse.ui.PlatformUI;
35 import org.eparapher.core.EParapherManager;
36 import org.eparapher.core.crypto.EPKeystoreManager;
37 import org.eparapher.core.crypto.KeystoreEntry;
38 import org.eparapher.core.crypto.cert.CertificateManager;
39 import org.eparapher.core.crypto.cert.X509Util;
40 import org.eparapher.core.crypto.keystore.IUserKeystore;
41 import org.eparapher.core.tools.JVMSettings;
42 import org.eparapher.rcp.tools.BaseWidgetUtils;
43 import org.eparapher.rcp.tools.CertificateView;
44 import org.eparapher.rcp.tools.GUIIcons;
45 import org.eparapher.rcp.tools.RCPGUI;
46
47 public class ImportKeysCertificatesWizardPageTwo extends WizardPage
48 implements IWizardPage {
49
50 private static Logger log = Logger.getLogger(ImportKeysCertificatesWizardPageTwo.class);
51
52 private Button file;
53
54 private CertificateView viewer;
55
56 protected ImportKeysCertificatesWizardPageTwo() {
57 super("Importing keys and/or certificates");
58 setTitle("Importing keys and/or certificates 2/2");
59 setDescription("Select the certificate(s) and key(s) from PEM/DER/PKCS7 files.");
60 setImageDescriptor(GUIIcons.WIZARD_IMPORT_IMG);
61 }
62
63 public void createControl(Composite parent) {
64
65 Group importFile = BaseWidgetUtils.createGroup( parent, "File to import : ", 1 );
66 GridLayout layout = new GridLayout( 1, false );
67 layout.marginWidth = 1;
68 layout.marginHeight = 1;
69 importFile.setLayout( layout );
70 GridData gd = new GridData( GridData.FILL_BOTH );
71 gd.horizontalSpan = 2;
72 importFile.setLayoutData( gd );
73
74 file = BaseWidgetUtils.createButton( importFile, "certificate chain file (PEM format).", GUIIcons.CERTIFICATE_ICON_IMAGE,1 );
75 file.setSelection(true);
76 file.addSelectionListener(
77 new SelectionAdapter() {
78 public void widgetSelected( SelectionEvent e ) {
79 selectFile();
80 }
81 }
82 );
83 Composite certComposite = BaseWidgetUtils.createColumnContainer( importFile, 1, 1 );
84 certComposite.setLayoutData(new GridData( GridData.FILL_BOTH ));
85 certComposite.setLayout(new FillLayout());
86 viewer = new CertificateView(certComposite,SWT.MULTI,new KeystoreEntry[]{});
87
88
89
90
91
92
93
94
95
96
97 setControl(importFile);
98 setPageComplete(false);
99
100 }
101
102 private void selectFile() {
103
104
105 FileDialog fd = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN);
106 fd.setText("Import X509 Certificate Chain from ...");
107 fd.setFilterPath( JVMSettings.getUserHome() );
108 String[] filterExt = { "*.*", "*.cer", "*.crt", "*.pem" };
109 fd.setFilterExtensions(filterExt);
110 String filename = fd.open();
111
112
113 Collection<X509Certificate> certs_coll = null;
114 try {
115 certs_coll = X509Util.getCertsFromPEM( filename );
116 } catch (CertificateException e) {
117 log.debug("Error while importing Certificate as PEM : " + e.getLocalizedMessage(),e);
118 } catch (IOException e) {
119 log.debug("Error while importing Certificate as PEM : " + e.getLocalizedMessage());
120 }
121
122 try {
123 if (certs_coll==null)
124 certs_coll = X509Util.getCertsFromPKCS7( filename );
125 } catch (CertificateException e) {
126 log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e);
127 } catch (IOException e) {
128 log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e);
129 } catch (NoSuchProviderException e) {
130 log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e);
131 } catch (CMSException e) {
132 log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e);
133 } catch (NoSuchStoreException e) {
134 log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e);
135 }
136
137
138 if (certs_coll==null || certs_coll.isEmpty()) {
139 String filetype="No certificate found in the selected file\r\n";
140
141 try {
142 PEMReader pemr = new PEMReader(new FileReader(filename));
143 Object obj = pemr.readObject();
144 if (obj instanceof X509CRL)
145 filetype="The selected file has been detected as a X509 CRL!\r\n";
146 if (obj instanceof PKCS10CertificationRequest)
147 filetype="The selected file has been detected as a CSR (Certificate Signing Request)!\r\n";
148 } catch (FileNotFoundException e) {
149 log.info("Error while trying to dertermine file type of " + filename,e);
150 } catch (IOException e) {
151 log.info("Error while trying to dertermine file type of " + filename,e);
152 }
153 RCPGUI.infoMessage( "No certificates to import", filetype+"It must be PEM(Base 64)/PKCS#7 encoded certificate(s).");
154 }
155 else {
156
157 log.info("Found "+certs_coll.size()+" certificates : ");
158 ArrayList<X509Certificate> list = new ArrayList<X509Certificate>();
159 for (X509Certificate certificate : certs_coll) {
160 list.add(certificate);
161 log.info(" -> DN='" + certificate.getSubjectDN() + "' serial='"+certificate.getSerialNumber()+"'");
162 }
163 X509Certificate[] certChain = list.toArray(new X509Certificate[] {});
164
165 boolean trusted = false;
166 if (list.size()==1) {
167
168 List<X509Certificate> tmp = null;
169 try {
170 tmp = CertificateManager.establishCertChain( certChain[0], true);
171 certChain = tmp.toArray(new X509Certificate[]{});
172 trusted = true;
173 } catch (Exception e) {
174 log.warn("Impossible to build the trust path. Please insert this certificates CA's in the truststore.",e);
175 RCPGUI.infoMessage( "Cannot import certificate", "Cannot build certificate chain.\r\nPlease import CA chain for : " + certChain[0].getIssuerDN().toString());
176 }
177 } else {
178
179 try {
180 if (!CertificateManager.validateCertChain( certChain, true)) {
181 RCPGUI.infoMessage( "Cannot import certificate", "CA certificate is not trusted.\r\nPlease import as a trusted CA the following certificate : " + certChain[certChain.length-1].getIssuerDN().toString() );
182 } else {
183 trusted = true;
184 }
185 } catch (Exception e) {
186 log.warn("Certificate Chain is invalid : please add the root CA in the truststore (DN:"+certChain[certChain.length-1].getIssuerDN().toString()+")");
187 }
188 }
189 if (trusted) {
190
191 String alias4newcertificate = findCorrespondingPublicKey(certChain);
192 if (alias4newcertificate!=null) {
193 setPageComplete(true);
194 KeystoreEntry ke = new KeystoreEntry(alias4newcertificate,certChain,null);
195 this.viewer.setContent(new KeystoreEntry[] {ke} );
196 } else {
197 log.warn("Cannot find a valid keypair/alias in the user keystore : Change user keystore or create a new CSR.");
198 RCPGUI.infoMessage( "Cannot import this certificate", "This certificate comes from a CSR that has not been generated in your current keystore.\r\nYou have two solutions :\r\n- find the keystore that generate the CSR and change it in eParapher preferences\r\n- or keep this keystore and create a new CSR.");
199 }
200 }
201 }
202 }
203
204 private String findCorrespondingPublicKey(X509Certificate[] certChain) {
205 IUserKeystore userKeystore = EPKeystoreManager.getInstance().getUserkeystore();
206 KeystoreEntry[] userke = userKeystore.getKeystoreEntries();
207 PublicKey certpk=certChain[0].getPublicKey();
208 log.debug(" loaded certificate Public Key : " + certpk);
209
210 for (int i = 0; i < userke.length; i++) {
211 if (userke[i].getCertificateChain()!= null && !userke[i].isTrustedCertificate())
212 if (userke[i].getCertificateChain().length>0) {
213 PublicKey userkspk = userke[i].getCertificateChain()[0].getPublicKey();
214 log.debug(" user keystore, Public Key from alias '"+userke[i].getKeystoreAlias()+"' : " + userkspk);
215 if (userkspk.equals(certpk)){
216 log.info("Find corresponding Key : " + userke[i].getKeystoreAlias());
217 return userke[i].getKeystoreAlias();
218 }
219 }
220 }
221 return null;
222 }
223 public KeystoreEntry[] getKeystoreEntries() {
224 return viewer.getKeystoreEntries();
225 }
226 }