View Javadoc

1   package org.eparapher.rcp.wizards;
2   
3   import java.util.ArrayList;
4   import java.util.Date;
5   import java.util.Iterator;
6   
7   import org.apache.log4j.Logger;
8   import org.eclipse.core.runtime.IStatus;
9   import org.eclipse.core.runtime.Status;
10  import org.eclipse.jface.wizard.IWizardPage;
11  import org.eclipse.jface.wizard.WizardPage;
12  import org.eclipse.swt.SWT;
13  import org.eclipse.swt.layout.GridData;
14  import org.eclipse.swt.layout.GridLayout;
15  import org.eclipse.swt.widgets.Button;
16  import org.eclipse.swt.widgets.Combo;
17  import org.eclipse.swt.widgets.Composite;
18  import org.eclipse.swt.widgets.Event;
19  import org.eclipse.swt.widgets.Label;
20  import org.eclipse.swt.widgets.Listener;
21  import org.eclipse.swt.widgets.Text;
22  import org.eparapher.core.crypto.EPKeystoreManager;
23  import org.eparapher.core.crypto.cert.X509Util;
24  import org.eparapher.rcp.tools.GUIIcons;
25  import org.eparapher.rcp.tools.eParapherTools;
26  
27  /**
28   * This Wizard can create new certificates with RSA, DSA and ECDSA keypair
29   * It can generate directly usable selfsigned certificate, or can generate a CSR file.
30   * 
31   * @author arnault
32   *
33   */
34  public class NewCertificateWizardPageOne
35  			extends WizardPage implements IWizardPage, Listener {
36  
37  	private static Logger log = Logger.getLogger(NewCertificateWizardPageOne.class);
38  	
39  	private static final String[] ALL_KEYPAIR_ALGS    = { "RSA", "DSA", "ECDSA" };
40  	private static final String[] MSCAPI_KEYPAIR_ALGS = { "RSA" };
41  
42  	private static final String[] RSA_KEYPAIR_SIZES = { "512", "1024", "2048", "4096" };
43  	private static final String[] DSA_KEYPAIR_SIZES = { "512", "576", "640", "704", "768", "896", "960", "1024" };
44  
45  	private static final String[] VALIDITY = { "3 months", "6 months", "1 year", "2 years", "3 years", "4 years", "6 years", "10 years" };
46  
47  
48  	private String[] sigalgs;
49  
50  	private Button selfSignedCertificate;
51  	private Button certificateWithCSR;
52  
53  	private Text   aliasText;
54  	
55  	private Combo  keypairAlg;
56  	private Combo  keypairsize;
57  	private Combo  ecspecs;
58  
59  	private Text   userCNText;
60  	private Text   userOUText;
61  	private Text   userOText;
62  	private Text   userSTText;
63  	private Text   userCText;
64  	
65  	private Combo  certValidity;
66  	private Combo  certsigalg;
67  
68  	private Text   userSANMailText;
69  	private Text   userSANOtherNameText;
70  	private Text   userSANDNSNameText;
71  	
72  	protected NewCertificateWizardPageOne() {
73  		super("New Certificate");
74  		setTitle("New Certificate Wizard");
75  		setDescription("Please select your keypair and certificate settings.");
76  		setImageDescriptor(GUIIcons.WIZARD_NEW_KEYCERT);
77  	}
78  
79  	public void createControl(Composite parent) {
80  
81  		Composite container = new Composite(parent, SWT.NONE);
82  
83  	    // create the desired layout for this wizard page
84  		GridLayout gl = new GridLayout();
85  		gl.numColumns = 2;
86  		container.setLayout(gl);
87  
88  		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
89  		gd.horizontalSpan = gl.numColumns;
90  
91  		//Self Signed certificate or generate a CSR
92  		Label label = new Label (container, SWT.NONE);
93  		label.setText("Certificate Type :");
94  		label.setLayoutData(gd);
95  
96  		selfSignedCertificate = new Button(container, SWT.RADIO);
97  		selfSignedCertificate.setText("Self-Signed Certificate");
98  		selfSignedCertificate.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
99  	    selfSignedCertificate.setSelection(true);
100 
101 	    certificateWithCSR = new Button(container, SWT.RADIO);
102 	    certificateWithCSR.setText("Certificate issued by a CA (generate CSR)");
103 	    certificateWithCSR.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
104 	    certificateWithCSR.setSelection(false);
105 	    //certificateWithCSR.setEnabled(false);
106 
107 	    eParapherTools.createGUILine(container, gl.numColumns);
108 	    
109 		//Keystore Alias
110 		Label labelksalias = new Label (container, SWT.NONE);
111 		labelksalias.setText("Keystore Alias :");
112 		labelksalias.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
113 		
114 		aliasText = new Text(container, SWT.BORDER);
115 		aliasText.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
116 		aliasText.setText("signature");
117 		
118 	    eParapherTools.createGUILine(container, gl.numColumns);
119 
120 	    //Keypair Settings
121 		Label labelkeypair = new Label (container, SWT.NONE);
122 		labelkeypair.setText("Keypair Settings :");
123 		gd = new GridData(GridData.FILL_HORIZONTAL);
124 		gd.horizontalSpan = gl.numColumns;
125 		labelkeypair.setLayoutData(gd);
126 
127 		Label labelKeypairAlg = new Label(container, SWT.NULL);
128 		labelKeypairAlg.setText("Keypair algorithm : ");
129 		labelKeypairAlg.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
130 		keypairAlg = new Combo(container, SWT.READ_ONLY |SWT.BORDER);
131 		if ( EPKeystoreManager.isCAPICOMUsed() )
132 			keypairAlg.setItems(MSCAPI_KEYPAIR_ALGS);
133 		else
134 			keypairAlg.setItems(ALL_KEYPAIR_ALGS);
135 		keypairAlg.select(0);
136 		keypairAlg.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
137 
138 		Label labelKeypairSize = new Label(container, SWT.NULL);
139 		labelKeypairSize.setText("Keypair size : ");
140 		labelKeypairSize.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
141 		keypairsize = new Combo(container, SWT.READ_ONLY |SWT.BORDER);
142 		keypairsize.setItems(RSA_KEYPAIR_SIZES);
143 		keypairsize.select(2);
144 		keypairsize.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
145 		
146 		Label labelECSpecs = new Label(container, SWT.NULL);
147 		labelECSpecs.setText("Elliptic curve specs : ");
148 		labelECSpecs.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
149 		ecspecs = new Combo(container, SWT.READ_ONLY |SWT.BORDER);
150 		ecspecs.setItems(X509Util.getECSpecsNames());
151 		ecspecs.select(0);
152 		ecspecs.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
153 		ecspecs.setEnabled(false);
154 
155 	    eParapherTools.createGUILine(container, gl.numColumns);
156 
157 	    //Certificate Settings
158 		Label labelcertsettings = new Label (container, SWT.NONE);
159 		labelcertsettings.setText("Certificate Settings :");
160 		gd = new GridData(GridData.FILL_HORIZONTAL);
161 		gd.horizontalSpan = gl.numColumns;
162 		labelcertsettings.setLayoutData(gd);
163 
164 		Label labelCertValidity = new Label(container, SWT.NULL);
165 		labelCertValidity.setText("Validity : ");
166 		labelCertValidity.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
167 		certValidity = new Combo(container, SWT.READ_ONLY |SWT.BORDER);
168 		certValidity.setItems(VALIDITY);
169 		certValidity.select(5);
170 		certValidity.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
171 		
172 		Label labelCertSigAlg = new Label(container, SWT.NULL);
173 		labelCertSigAlg.setText("Signature algorythm : ");
174 		labelCertSigAlg.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
175 		certsigalg = new Combo(container, SWT.READ_ONLY |SWT.BORDER);
176 		certsigalg.setItems(getCertSigAlgs());
177 		certsigalg.select(0);
178 		certsigalg.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING)); 
179 
180 	    eParapherTools.createGUILine(container, gl.numColumns);
181 
182 	    //User Info
183 		Label labeluserinfo = new Label (container, SWT.NONE);
184 		labeluserinfo.setText("Personnal information for DN:");
185 		gd = new GridData(GridData.FILL_HORIZONTAL);
186 		gd.horizontalSpan = gl.numColumns;
187 		labeluserinfo.setLayoutData(gd);
188 		
189 		userCNText = createDNField(container, "Common name (CN) : ",         64, System.getProperty("user.name"));
190 		userOUText = createDNField(container, "Organizational unit (OU) : ", 64, null);
191 		userOText  = createDNField(container, "Organization (O) :",			 64, null);
192 		userSTText = createDNField(container, "State or province (ST) :",	 64, null);
193 		userCText  = createDNField(container, "Country code (C) :",			 2,  "FR");
194 
195 	    eParapherTools.createGUILine(container, gl.numColumns);
196 
197 	    //User Subject Alternative Name Info
198 		Label labelsubaltname = new Label (container, SWT.NONE);
199 		labelsubaltname.setText("Personnal information for subject alternative name:");
200 		gd = new GridData(GridData.FILL_HORIZONTAL);
201 		gd.horizontalSpan = gl.numColumns;
202 		labelsubaltname.setLayoutData(gd);
203 		
204 		userSANMailText      = createDNField(container, "EMail : ",		 128, null);
205 		userSANDNSNameText   = createDNField(container, "DNS name : ", 128, null);
206 		userSANOtherNameText = createDNField(container, "Other name : ", 128, null);
207 		
208 	    setControl(container);
209 
210 	    addListeners();
211 	    
212 	    handleEvent(null);
213 	}
214 
215 	private void addListeners()
216 	{
217 		selfSignedCertificate.addListener(SWT.Selection, this);
218 		certificateWithCSR.addListener(SWT.Selection, this);
219 		userCNText.addListener(SWT.KeyUp, this);
220 		userCText.addListener(SWT.KeyUp, this);
221 		userOText.addListener(SWT.KeyUp, this);
222 		userOUText.addListener(SWT.KeyUp, this);
223 		userSTText.addListener(SWT.KeyUp, this);
224 		aliasText.addListener(SWT.KeyUp, this);
225 		keypairAlg.addListener(SWT.Selection, this);
226 	}
227 
228 	/**
229 	 * @see Listener#handleEvent(Event)
230 	 */
231 	public void handleEvent(Event event) {
232 		
233 	    // Initialize a variable with the no error status
234 	    Status status = new Status(IStatus.OK, "not_used", 0, "", null);
235 
236 	    //Change signature algorithms if keypair algorithm change
237 	    if ( event !=null && (event.widget == keypairAlg)) {
238 	    	certsigalg.setItems(getCertSigAlgs());
239 	    	certsigalg.select(0);
240 	    	if (getKeypairAlg().equals("ECDSA")) {
241 	    		keypairsize.setEnabled(false);
242 	    		ecspecs.setEnabled(true);
243 	    	} else if (getKeypairAlg().equals("DSA")){
244 	    		keypairsize.setEnabled(true);
245 	    		keypairsize.setItems(DSA_KEYPAIR_SIZES);
246 	    		keypairsize.select(7);
247 	    		ecspecs.setEnabled(false);
248 	    	} else if (getKeypairAlg().equals("RSA")){
249 	    		keypairsize.setEnabled(true);
250 	    		keypairsize.setItems(RSA_KEYPAIR_SIZES);
251 	    		keypairsize.select(1);
252 	    		ecspecs.setEnabled(false);
253 	    	}
254 	    }
255 
256 	    //if ((event.widget == aliasText)) {
257 	    	// Alias cannot be empty
258 	        if ( !isTextNonEmpty(aliasText) )
259 	            status = new Status(IStatus.ERROR, "not_used", 0, "You must set a Keystore Alias", null);
260 	        else {
261 	        	//Verify if the alias already exists
262 	    		if ( EPKeystoreManager.getInstance().getUserkeystore().containsAlias( getAliasName() ))
263 	    			status = new Status(IStatus.WARNING, "not_used", 0, "Alias '"+getAliasName()+"' already exists. It will be overwrite.", null);        
264 	        }
265 	    //}
266 	        if ( event !=null && (event.widget == certificateWithCSR)) {
267 	        	if (certificateWithCSR.getSelection()) {
268 	        		certValidity.setEnabled(false);
269 	        		userSANMailText.setEnabled(false);
270 	        		userSANOtherNameText.setEnabled(false);
271 	        		userSANDNSNameText.setEnabled(false);
272 	        	} else {
273 	        		certValidity.setEnabled(true);
274 	        		userSANMailText.setEnabled(true);
275 	        		userSANOtherNameText.setEnabled(true);
276 	        		userSANDNSNameText.setEnabled(true);
277 	        	}
278 	        }
279 	    //if ((event.widget == userCNText)) {
280 	        if ( !isTextNonEmpty(userCNText) )
281 	            status = new Status(IStatus.WARNING, "not_used", 0, "Common Name might not be empty", null);
282 	        if ( getUserDNasString().equals("") )
283 	        	status = new Status(IStatus.ERROR, "not_used", 0, "DN must not be empty", null);
284 	    //}
285 	    
286 	    // Show the most serious error
287 		String message= status.getMessage();
288 		if (message.length() == 0) message= null;
289 		switch (status.getSeverity()) {
290 			case IStatus.OK:
291 				setErrorMessage(null);
292 				setMessage(message);
293 				setPageComplete(true);
294 				break;
295 			case IStatus.WARNING:
296 				setErrorMessage(null);
297 				setMessage(message, WizardPage.WARNING);
298 				setPageComplete(true);
299 				break;				
300 			case IStatus.INFO:
301 				setErrorMessage(null);
302 				setMessage(message, WizardPage.INFORMATION);
303 				setPageComplete(true);
304 				break;			
305 			default:
306 				setErrorMessage(message);
307 				setMessage(null);
308 				setPageComplete(false);
309 				break;		
310 		}
311 		//getWizard().getContainer().updateButtons();
312 	}
313 	/**
314 	 * Applies the status to the status line of a dialog page.
315 	 */
316 	private static boolean isTextNonEmpty(Text t)
317 	{
318 		String s = t.getText();
319 		if ((s!=null) && (s.trim().length() >0)) return true;
320 		return false;
321 	}
322 	
323 	private Text createDNField(Composite container, String labelvalue, int textLimit, String defaultValue) {
324 		
325 		Label label = new Label (container, SWT.NONE);
326 		label.setText(labelvalue);
327 		label.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
328 		
329 		Text textfield = new Text(container, SWT.BORDER);
330 		textfield.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
331 		textfield.setTextLimit(textLimit);
332 		if (defaultValue!=null)
333 			if (!defaultValue.equals(""))
334 				textfield.setText(defaultValue);
335 		
336 		return textfield;
337 	}
338 
339 	private String[] getCertSigAlgs() {
340 
341 		Iterator<String> it = X509Util.getAlgNames();
342 		ArrayList<String> filteredAlgs = new ArrayList<String>();
343 		String endswith = "WITH"+getKeypairAlg();
344 
345 		while (it.hasNext()) {
346 			String alg = (String) it.next();
347 			if (alg.endsWith(endswith)) {
348 				//With CAPI, just use simple SHA1, md2 and md5
349 				if ( EPKeystoreManager.isCAPICOMUsed() ) {
350 					if (alg.toLowerCase().startsWith("sha1") || alg.toLowerCase().startsWith("md")) 
351 						filteredAlgs.add(alg);
352 				} else if ( EPKeystoreManager.isPKCS11Used() ) {
353 					//With PKCS#11, use SHA1, SHA256, SHA384, SHA512, md2 and md5
354 					if (alg.toLowerCase().startsWith("sha") || alg.toLowerCase().startsWith("md")) 
355 						filteredAlgs.add(alg);
356 				} else filteredAlgs.add(alg);
357 				
358 			}
359 		}
360 
361 		sigalgs = new String[filteredAlgs.size()];
362 		for (int i = 0; i < sigalgs.length; i++) {
363 			sigalgs[i] = filteredAlgs.get(i);
364 		}
365 
366 		return sigalgs;
367 	}
368 	
369 	public String getKeypairAlg() {
370 		if ( EPKeystoreManager.isCAPICOMUsed() )
371 			return MSCAPI_KEYPAIR_ALGS[keypairAlg.getSelectionIndex()];
372 		else
373 			return ALL_KEYPAIR_ALGS[keypairAlg.getSelectionIndex()];
374 	}
375 
376 	public int getKeypairSize() {
377 		if (getKeypairAlg().equals("RSA")) {
378 			return new Integer( RSA_KEYPAIR_SIZES[keypairsize.getSelectionIndex()] ).intValue();
379     	} else if (getKeypairAlg().equals("DSA")) {
380 			return new Integer( DSA_KEYPAIR_SIZES[keypairsize.getSelectionIndex()] ).intValue();
381     	} else return 0;
382 			
383 	}
384 
385 	public String getUserDNasString() {
386 		String dn = "";
387 		if (userCText.getText()!= null && !userCText.getText().equals("") && !userCText.getText().equals(".") )
388 			dn += (!dn.equals("")?",":"") + "C="+userCText.getText();
389 		if (userSTText.getText()!= null && !userSTText.getText().equals("") && !userSTText.getText().equals(".") )
390 			dn += (!dn.equals("")?",":"") + "ST="+userSTText.getText();
391 		if (userOText.getText()!= null && !userOText.getText().equals("") && !userOText.getText().equals(".") )
392 			dn += (!dn.equals("")?",":"") + "O="+userOText.getText();
393 		if (userOUText.getText()!= null && !userOUText.getText().equals("") && !userOUText.getText().equals(".") )
394 			dn += (!dn.equals("")?",":"") + "OU="+userOUText.getText();
395 		if (userCNText.getText()!= null && !userCNText.getText().equals("") && !userCNText.getText().equals(".") )
396 			dn += (!dn.equals("")?",":"") + "CN="+userCNText.getText();
397 		return dn;
398 	}
399 
400 	public Date getEndofValidityDate(Date validFrom) {
401 
402 		Date endOfValidity = (Date) validFrom.clone();
403 		
404 		switch (certValidity.getSelectionIndex()) {
405 		case 0 : endOfValidity.setMonth(endOfValidity.getMonth()+3);
406 			break;
407 		case 1 : endOfValidity.setMonth(endOfValidity.getMonth()+6);
408 			break;
409 		case 2 : endOfValidity.setYear(endOfValidity.getYear()+1);
410 			break;
411 		case 3 : endOfValidity.setYear(endOfValidity.getYear()+2);
412 			break;
413 		case 4 : endOfValidity.setYear(endOfValidity.getYear()+3);
414 			break;
415 		case 5 : endOfValidity.setYear(endOfValidity.getYear()+4);
416 			break;
417 		case 6 : endOfValidity.setYear(endOfValidity.getYear()+6);
418 			break;
419 		case 7 : endOfValidity.setYear(endOfValidity.getYear()+10);
420 			break;
421 		}
422 		
423 		return endOfValidity;
424 	}
425 	public String getCertSigAlg() {
426 		int index = certsigalg.getSelectionIndex();
427 		return sigalgs[index];
428 	}
429 	public String getAliasName() {
430 		return aliasText.getText();
431 	}
432 
433 	public String getSubjAltNameEMail() {
434 		return userSANMailText.getText();
435 	}
436 	public String getSubjAltNameOtherName() {
437 		return userSANOtherNameText.getText();
438 	}
439 
440 	public String getSubjAltNameDNSName() {
441 		return userSANDNSNameText.getText();
442 	}
443 	public String getECSpecsName() {
444 		return ecspecs.getItem(ecspecs.getSelectionIndex());
445 	}
446 
447 	public boolean isSelfSigned() {
448 		return selfSignedCertificate.getSelection();
449 	}
450 	public boolean isCSR() {
451 		return certificateWithCSR.getSelection();
452 	}
453 }