View Javadoc

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  		viewer.addSelectionChangedListener(new ISelectionChangedListener() {
89  			public void selectionChanged(SelectionChangedEvent event) {
90  				if (pubKeyFound)
91  					setPageComplete(true);
92  				else
93  					setPageComplete(false);
94  			}
95  		});
96  		*/
97          setControl(importFile);
98  		setPageComplete(false);
99  		
100 	}
101 
102 	private void selectFile() {
103 		
104 		//Step 1 : Get the file to import
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 	    //Step 2 : load it as PEM, DER, or p7b
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 		//Warn if no certificate
138 		if (certs_coll==null || certs_coll.isEmpty()) {
139 			String filetype="No certificate found in the selected file\r\n";
140 			//determine if it's another type.
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 			//Build And verify trust (Certificate Chain)
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 				//One certificate : try to rebuild trusted cert chain
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 				//Certificate chain : rebuild/verify trust path
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 				//Find the corresponding alias in user keystore
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 		//TODO : Manage more than two aliases with same public keys
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 }