View Javadoc

1   /*
2    * The MIT License
3    *
4    * Original work sponsored and donated by National Board of e-Health (NSI), Denmark (http://www.nsi.dk)
5    *
6    * Copyright (C) 2011 National Board of e-Health (NSI), Denmark (http://www.nsi.dk)
7    *
8    * Permission is hereby granted, free of charge, to any person obtaining a copy of
9    * this software and associated documentation files (the "Software"), to deal in
10   * the Software without restriction, including without limitation the rights to
11   * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12   * of the Software, and to permit persons to whom the Software is furnished to do
13   * so, subject to the following conditions:
14   *
15   * The above copyright notice and this permission notice shall be included in all
16   * copies or substantial portions of the Software.
17   *
18   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24   * SOFTWARE.
25   *
26   * $HeadURL: https://svn.softwareborsen.dk/sosi/trunk/modules/seal/src/main/java/dk/sosi/seal/tool/Seal.java $
27   * $Id: Seal.java 8697 2011-09-02 10:33:55Z chg@lakeside.dk $
28   */
29  
30  package dk.sosi.seal.tool;
31  
32  import dk.sosi.seal.model.SignatureUtil;
33  import dk.sosi.seal.ssl.HttpsConnector;
34  import dk.sosi.seal.vault.CredentialVault;
35  import dk.sosi.seal.vault.renewal.CredentialPairRenewer;
36  
37  import java.io.File;
38  import java.io.FileInputStream;
39  import java.util.HashMap;
40  import java.util.Map;
41  import java.util.Properties;
42  
43  
44  /**
45   * SOSI Seal command line tool for importing certificates and private keys into
46   * a keystore, stored inside a .jar file. This .jar file can subsequently be
47   * used to supply the Seal library with the cryptographic elements needed for
48   * signing, validation, etc. via a CredentialVault.
49   * 
50   * @author kkj
51   * @author $LastChangedBy: chg@lakeside.dk $
52   * @since 1.0
53   */
54  public class Seal { // NOPMD
55  
56  	private static final String CMD_IMPORTCERT = "-importcert";
57  	private static final String CMD_IMPORTPKCS12 = "-importpkcs12";
58  	private static final String CMD_LIST = "-list";
59  	private static final String CMD_REMOVEALIAS = "-removealias";
60  	private static final String CMD_RENEW = "-renew";
61  	private static final String CMD_ISSUE = "-issue";
62  
63  	private static final String PARAM_VAULT = "-vault";
64  	private static final String PARAM_ALIAS = "-alias";
65  	private static final String PARAM_VAULTPWD = "-vaultpwd";
66  	private static final String PARAM_PKCS12PWD = "-pkcs12pwd";
67  	
68  	private static final String PARAM_KEYSTORE = "-keystore";
69  	private static final String PARAM_KEYSTOREPWD = "-keystorepwd";
70  	
71  	private static final String PARAM_REFERENCENUMBER = "-referencenumber";
72  	private static final String PARAM_INSTALLATION_CODE = "-installationcode";
73  	private static final String PARAM_TEST = "-test";
74  	private static final String PARAM_PROPS = "-props";
75  	
76  
77  	private static SealCommands sealCommands;
78  	
79  	private static CredentialPairRenewer credentialPairRenewer = null;
80  	private static HttpsConnector httpsConnector = null;
81  
82  	private static Properties properties = SignatureUtil.setupCryptoProviderForJVM();
83  
84  	/**
85  	 * Arguments:
86  	 * 
87  	 * <pre>
88  	 *  
89  	 *  -importcert .pkcs12|.cer 
90  	 *  -alias alias 
91  	 *  -vault vault.jar 
92  	 *  -vaultpwd password 
93  	 *  -importpkcs12 .pkcs12|.cer 
94  	 *  -alias alias 
95  	 *  -vault vault.jar 
96  	 *  -vaultpwd password 
97  	 *  -pkcs12pwd password
98  	 *  -removealias 
99  	 *  -alias alias 
100 	 *  -vault vault.jar
101 	 *  -vaultpwd password 
102 	 *  -list
103 	 *  -vault vault.jar 
104 	 *  -vaultpwd password
105 	 *  -renew
106 	 *  -keystore keystore.jks
107 	 *  -keystorepwd password
108 	 *  -renew
109 	 *  -vault vault.jar 
110 	 *  -vaultpwd password
111 	 *  -issue
112 	 *  -referencenumber refno
113 	 *  -installationcode instcode
114 	 *  -vault vault.jar
115 	 *  -vaultpwd password
116 	 *  [-test]
117 	 * </pre>
118 	 * 
119 	 * @param args
120 	 */
121 	public static void main(String[] args) {
122 		if (args.length == 0) {
123 			error("No arguments supplied");
124 		}
125 
126 		String cmd = args[0];
127 
128 		Map<String, String> argMap = new HashMap<String, String>();
129 		int i = 0;
130 		while (i < args.length) {
131 			String key = args[i++];
132 			String value = null;
133 			if (CMD_LIST.equals(key) || CMD_RENEW.equals(key) || CMD_REMOVEALIAS.equals(key) || CMD_ISSUE.equals(key) || PARAM_TEST.equals(key)) {
134 				value = "";
135 			} else {
136 				if (i < args.length) {
137 					value = args[i++];
138 				}
139 			}
140 			argMap.put(key, value);
141 		}
142 
143 		if(argMap.containsKey(PARAM_PROPS)) {
144 			try {
145 				properties.load(new FileInputStream(argMap.get(PARAM_PROPS)));
146 			} catch (Exception e) {
147 				error(e);
148 			}
149 		}
150 		sealCommands = new SealCommands(properties);
151 
152 		try {
153 			if (CMD_IMPORTCERT.equals(cmd)) {
154 				importCert(argMap);
155 			} else if (CMD_REMOVEALIAS.equals(cmd)) {
156 				removeAlias(argMap);
157 			} else if (CMD_IMPORTPKCS12.equals(cmd)) {
158 				importPkcs12(argMap);
159 			} else if (CMD_LIST.equals(cmd)) {
160 				list(argMap);
161 			} else if (CMD_RENEW.equals(cmd)) {
162 				renew(argMap);
163 			} else if (CMD_ISSUE.equals(cmd)) {
164 				issue(argMap);
165 			} else {
166 				error("Unknown command " + cmd);
167 			}
168 		} catch (SealToolException e) {
169 			error(e);
170 		}
171 	}
172 
173 	public static void setCredentialPairRenewer(CredentialPairRenewer renewer) {
174 		credentialPairRenewer = renewer;
175 	}
176 
177 	public static void setHttpsConnector(HttpsConnector httpsConnector) {
178 		Seal.httpsConnector = httpsConnector;
179 	}
180 
181 	private static void importPkcs12(Map<String, String> argMap) {
182 
183 		File pkcs12Path = new File(argMap.get(CMD_IMPORTPKCS12));
184 		File vaultPath = new File(argMap.get(PARAM_VAULT));
185 		String keystorePassword = argMap.get(PARAM_VAULTPWD);
186 		String pkcs12Password = argMap.get(PARAM_PKCS12PWD);
187 
188 		if (!pkcs12Path.exists()) {
189 			error("The specified pkcs12 file " + pkcs12Path.getAbsolutePath() + " does not exist");
190 		}
191 
192 		if (keystorePassword == null || keystorePassword.length() == 0) {
193 			error("No password for the keystore supplied");
194 		}
195 
196 		sealCommands.importPkcs12Keystore(vaultPath, keystorePassword, pkcs12Path, pkcs12Password);
197 	}
198 
199 	private static void list(Map<String, String> argMap) {
200 
201 		if(!(argMap.containsKey(PARAM_VAULT) || argMap.containsKey(PARAM_KEYSTORE))) {
202  			error("You must specify a vault- or a keystore file name");
203 		}
204 		
205 		if(!argMap.containsKey(PARAM_VAULT)) {
206 			String keystore = argMap.get(PARAM_KEYSTORE);
207 			
208 			if(!argMap.containsKey(PARAM_KEYSTOREPWD)) {
209 				error("You must specify a keystore password");
210 			}
211 			String keystorePassword = argMap.get(PARAM_KEYSTOREPWD);
212 			sealCommands.list(keystore, keystorePassword);
213 			
214 		} else {
215 			File vaultPath = new File(argMap.get(PARAM_VAULT));
216 			String keystorePassword = argMap.get(PARAM_VAULTPWD);
217 			if (keystorePassword == null || keystorePassword.length() == 0) {
218 				error("No password for the keystore supplied");
219 			}
220 
221 			if (!vaultPath.exists()) {
222 				error("The specified credentialvault jar file " + vaultPath + " does not exit");
223 			}
224 
225 			sealCommands.list(vaultPath, keystorePassword);
226 		}
227 	}
228 
229 	private static void removeAlias(Map<String, String> argMap) {
230 
231 		File vaultPath = new File(argMap.get(PARAM_VAULT));
232 		String alias = argMap.get(PARAM_ALIAS);
233 		String keystorePassword = argMap.get(PARAM_VAULTPWD);
234 
235 		if (!vaultPath.exists()) {
236 			error("The specified credential vault .jar file " + vaultPath.getAbsolutePath() + " does not exit");
237 		}
238 
239 		if (alias == null || alias.length() == 0) {
240 			error("No alias for the certificate supplied");
241 		}
242 
243 		if (keystorePassword == null || keystorePassword.length() == 0) {
244 			error("No password for the keystore supplied");
245 		}
246 
247 		sealCommands.removeAlias(vaultPath, keystorePassword, alias);
248 	}
249 
250 	private static void importCert(Map<String, String> argMap) {
251 
252 		File certPath = new File(argMap.get(CMD_IMPORTCERT));
253 		File vaultPath = new File(argMap.get(PARAM_VAULT));
254 		String alias = argMap.get(PARAM_ALIAS);
255 		String keystorePassword = argMap.get(PARAM_VAULTPWD);
256 
257 		if (!certPath.exists()) {
258 			error("The specified certificate file " + certPath.getAbsolutePath() + " does not exit");
259 		}
260 
261 		if (alias == null || alias.length() == 0) {
262 			error("No alias for the certificate supplied");
263 		}
264 
265 		if (CredentialVault.ALIAS_SYSTEM.equals(alias)) {
266 			error("The alias '" + CredentialVault.ALIAS_SYSTEM + "' is reserved for Seal internal usage!");
267 		}
268 
269 		if (keystorePassword == null || keystorePassword.length() == 0) {
270 			error("No password for the keystore supplied");
271 		}
272 
273 		sealCommands.importCertificate(vaultPath, certPath, keystorePassword, alias, true);
274 	}
275 
276 	private static void renew(Map<String, String> argMap) {
277 
278 		if(credentialPairRenewer != null)
279 			sealCommands.setCredentialPairRenewer(credentialPairRenewer);
280 
281 		if(!(argMap.containsKey(PARAM_VAULT) || argMap.containsKey(PARAM_KEYSTORE))) {
282  			error("You must specify a vault- or a keystore file name");
283 		}
284 		
285 		if(!argMap.containsKey(PARAM_VAULT)) {
286 			File keystore = new File(argMap.get(PARAM_KEYSTORE));
287 			if (!keystore.exists()) {
288 				error("The specified keystore file " + keystore.getAbsolutePath() + " does not exit");
289 			}
290 			
291 			if(!argMap.containsKey(PARAM_KEYSTOREPWD)) {
292 				error("You must specify a keystore password");
293 			}
294 			String keystorePassword = argMap.get(PARAM_KEYSTOREPWD);
295 
296 			if (keystorePassword == null || keystorePassword.length() == 0) {
297 				error("No password for the keystore supplied");
298 			}
299 			sealCommands.renewSystemCredentials(keystore, keystorePassword);
300 			
301 		} else {
302 			File vault = new File(argMap.get(PARAM_VAULT));
303 
304 			if (!vault.exists()) {
305 				error("The specified vault file " + vault.getAbsolutePath() + " does not exit");
306 			}
307 			
308 			if(!argMap.containsKey(PARAM_VAULTPWD)) {
309 				error("You must specify a vault password");
310 			}
311 			String vaultPassword = argMap.get(PARAM_VAULTPWD);
312 
313 			if (vaultPassword == null || vaultPassword.length() == 0) {
314 				error("No password for the keystore supplied");
315 			}
316 
317 			sealCommands.renewVaultedSystemCredentials(vault, vaultPassword);
318 		}
319 
320 	}
321 
322 	private static void issue(Map<String, String> argMap) {
323 
324 		if(httpsConnector != null)
325 			sealCommands.setHttpsConnector(httpsConnector);
326 
327 		if(!argMap.containsKey(PARAM_VAULT)) {
328  			error("You must specify a vault- or a keystore file name");
329 		}
330 		
331 		File vault = new File(argMap.get(PARAM_VAULT));
332 
333 		if(!argMap.containsKey(PARAM_VAULTPWD)) {
334 			error("You must specify a vault password");
335 		}
336 		String vaultPassword = argMap.get(PARAM_VAULTPWD);
337 
338 		if (vaultPassword == null || vaultPassword.length() == 0) {
339 			error("No password for the keystore supplied");
340 		}
341 		
342 		String referenceNumber = argMap.get(PARAM_REFERENCENUMBER);
343 		if(referenceNumber == null) {
344 			error("No reference number supplied");
345 		}
346 		String installationCode = argMap.get(PARAM_INSTALLATION_CODE);
347 		if(installationCode == null) {
348 			error("No installation code supplied");
349 		}
350 		
351 		boolean issueTestCertificate = argMap.containsKey(PARAM_TEST);
352 
353 		sealCommands.issueToVault(vault, vaultPassword, referenceNumber, installationCode, issueTestCertificate);
354 
355 	}
356 
357 	private static void error(Exception e) {
358 		String message = e.getMessage();
359 		if (e.getCause() != null) {
360 			message = message + " (" + e.getCause().getMessage() + ")";
361 		}
362 	}
363 
364 	private static void error(String errorText) {
365 
366 		System.err.println("Error: " + errorText + "\n");
367 		System.err.println("Usage: -importcert  <path to .cer> -alias <alias> -vault <vault.jar> -vaultpwd <password> [-props <seal.properties>]");
368 		System.err.println("       -importpkcs12 <path to .pkcs12> -vault <vault.jar> -vaultpwd <password> -pkcs12pwd <password> [-props <seal.properties>]");
369 		System.err.println("       -removealias -alias <alias> -vault <vault.jar> -vaultpwd <password> [-props <seal.properties>]");
370 		System.err.println("       -list -vault <vault.jar> -vaultpwd <password> [-props <seal.properties>]" );
371 		System.err.println("       -list -keystore <keystore.jks> -keystorepwd <password> [-props <seal.properties>]");
372 		System.err.println("       -renew -vault <vault.jar> -vaultpwd <password> [-props <seal.properties>]");
373 		System.err.println("       -renew -keystore <keystore.jks> -keystorepwd <password> [-props <seal.properties>]");
374 		System.err.println("       -issue -referencenumber <refno> -installationcode <instcode> -vault <vault.jar> -vaultpwd <password> [-test] [-props <seal.properties>]\n");
375 		System.exit(1);
376 	}
377 }