package org.eparapher.rcp.wizards; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.security.NoSuchProviderException; import java.security.PublicKey; import java.security.cert.CertificateException; import java.security.cert.X509CRL; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.log4j.Logger; import org.bouncycastle.cms.CMSException; import org.bouncycastle.jce.PKCS10CertificationRequest; import org.bouncycastle.openssl.PEMReader; import org.bouncycastle.x509.NoSuchStoreException; import org.eclipse.jface.wizard.IWizardPage; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.ui.PlatformUI; import org.eparapher.core.crypto.EPKeystoreManager; import org.eparapher.core.crypto.cert.CertificateManager; import org.eparapher.core.crypto.cert.X509Util; import org.eparapher.core.crypto.keystore.KeystoreEntry; import org.eparapher.core.interfaces.IUserKeystore; import org.eparapher.core.tools.JVMSettings; import org.eparapher.rcp.tools.BaseWidgetUtils; import org.eparapher.rcp.tools.CertificateView; import org.eparapher.rcp.tools.GUIIcons; import org.eparapher.rcp.tools.RCPGUI; public class ImportKeysCertificatesWizardPageTwo extends WizardPage implements IWizardPage { private static Logger log = Logger.getLogger(ImportKeysCertificatesWizardPageTwo.class); private Button file; private CertificateView viewer; protected ImportKeysCertificatesWizardPageTwo() { super("Importing keys and/or certificates"); setTitle("Importing keys and/or certificates 2/2"); setDescription("Select the certificate(s) and key(s) from PEM/DER/PKCS7 files."); setImageDescriptor(GUIIcons.WIZARD_IMPORT_IMG); } public void createControl(Composite parent) { Group importFile = BaseWidgetUtils.createGroup( parent, "File to import : ", 1 ); GridLayout layout = new GridLayout( 1, false ); layout.marginWidth = 1; layout.marginHeight = 1; importFile.setLayout( layout ); GridData gd = new GridData( GridData.FILL_BOTH ); gd.horizontalSpan = 2; importFile.setLayoutData( gd ); file = BaseWidgetUtils.createButton( importFile, "certificate chain file (PEM format).", GUIIcons.CERTIFICATE_ICON_IMAGE,1 ); file.setSelection(true); file.addSelectionListener( new SelectionAdapter() { public void widgetSelected( SelectionEvent e ) { selectFile(); } } ); Composite certComposite = BaseWidgetUtils.createColumnContainer( importFile, 1, 1 ); certComposite.setLayoutData(new GridData( GridData.FILL_BOTH )); certComposite.setLayout(new FillLayout()); viewer = new CertificateView(certComposite,SWT.MULTI,new KeystoreEntry[]{}); /* viewer.addSelectionChangedListener(new ISelectionChangedListener() { public void selectionChanged(SelectionChangedEvent event) { if (pubKeyFound) setPageComplete(true); else setPageComplete(false); } }); */ setControl(importFile); setPageComplete(false); } private void selectFile() { //Step 1 : Get the file to import FileDialog fd = new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.OPEN); fd.setText("Import X509 Certificate Chain from ..."); fd.setFilterPath( JVMSettings.getUserHome() ); String[] filterExt = { "*.*", "*.cer", "*.crt", "*.pem" }; fd.setFilterExtensions(filterExt); String filename = fd.open(); //Step 2 : load it as PEM, DER, or p7b Collection certs_coll = null; try { certs_coll = X509Util.getCertsFromPEM( filename ); } catch (CertificateException e) { log.debug("Error while importing Certificate as PEM : " + e.getLocalizedMessage(),e); } catch (IOException e) { log.debug("Error while importing Certificate as PEM : " + e.getLocalizedMessage()); } try { if (certs_coll==null) certs_coll = X509Util.getCertsFromPKCS7( filename ); } catch (CertificateException e) { log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e); } catch (IOException e) { log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e); } catch (NoSuchProviderException e) { log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e); } catch (CMSException e) { log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e); } catch (NoSuchStoreException e) { log.debug("Error while importing Certificate : " + e.getLocalizedMessage(),e); } //Warn if no certificate if (certs_coll==null || certs_coll.isEmpty()) { String filetype="No certificate found in the selected file\r\n"; //determine if it's another type. try { PEMReader pemr = new PEMReader(new FileReader(filename)); Object obj = pemr.readObject(); if (obj instanceof X509CRL) filetype="The selected file has been detected as a X509 CRL!\r\n"; if (obj instanceof PKCS10CertificationRequest) filetype="The selected file has been detected as a CSR (Certificate Signing Request)!\r\n"; } catch (FileNotFoundException e) { log.info("Error while trying to dertermine file type of " + filename,e); } catch (IOException e) { log.info("Error while trying to dertermine file type of " + filename,e); } RCPGUI.infoMessage( "No certificates to import", filetype+"It must be PEM(Base 64)/PKCS#7 encoded certificate(s)."); } else { //Build And verify trust (Certificate Chain) log.info("Found "+certs_coll.size()+" certificates : "); ArrayList list = new ArrayList(); for (X509Certificate certificate : certs_coll) { list.add(certificate); log.info(" -> DN='" + certificate.getSubjectDN() + "' serial='"+certificate.getSerialNumber()+"'"); } X509Certificate[] certChain = list.toArray(new X509Certificate[] {}); boolean trusted = false; if (list.size()==1) { //One certificate : try to rebuild trusted cert chain List tmp = null; try { tmp = CertificateManager.establishCertChain( certChain[0], true); certChain = tmp.toArray(new X509Certificate[]{}); trusted = true; } catch (Exception e) { log.warn("Cannot build the trust path. Please insert this certificates CAs in the truststore/keystore.",e); RCPGUI.infoMessage( "Cannot import certificate", "Cannot build certificate chain.\r\nPlease import CA chain for : " + certChain[0].getIssuerDN().toString()); } } else { //Certificate chain : rebuild/verify trust path try { if (!CertificateManager.validateCertChain( certChain, true)) { 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() ); } else { trusted = true; } } catch (Exception e) { log.warn("Certificate Chain is invalid : please add the root CA in the truststore (DN:"+certChain[certChain.length-1].getIssuerDN().toString()+")"); } } if (trusted) { //Find the corresponding alias in user keystore String alias4newcertificate = findCorrespondingPublicKey(certChain); if (alias4newcertificate!=null) { setPageComplete(true); KeystoreEntry ke = new KeystoreEntry(alias4newcertificate,certChain,null); this.viewer.setContent(new KeystoreEntry[] {ke} ); } else { log.warn("Cannot find a valid keypair/alias in the user keystore : Change user keystore or create a new CSR."); 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."); } } } } private String findCorrespondingPublicKey(X509Certificate[] certChain) { IUserKeystore userKeystore = EPKeystoreManager.getInstance().getUserkeystore(); KeystoreEntry[] userke = userKeystore.getKeysEntries(); PublicKey certpk=certChain[0].getPublicKey(); log.debug(" loaded certificate Public Key : " + certpk); //TODO : Manage more than two aliases with same public keys for (int i = 0; i < userke.length; i++) { if (userke[i].getCertificateChain()!= null && !userke[i].isTrustedCertificate()) if (userke[i].getCertificateChain().length>0) { PublicKey userkspk = userke[i].getCertificateChain()[0].getPublicKey(); log.debug(" user keystore, Public Key from alias '"+userke[i].getKeystoreAlias()+"' : " + userkspk); if (userkspk.equals(certpk)){ log.info("Find corresponding Key : " + userke[i].getKeystoreAlias()); return userke[i].getKeystoreAlias(); } } } return null; } public KeystoreEntry[] getKeystoreEntries() { return viewer.getKeystoreEntries(); } }