blob: e25c3766b5040b540f56bfc0cc57503a9df1a5e1 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 */
23
24/*
25 *
26 *
27 * @summary Testing keytool
28 * @author weijun.wang
29 *
30 * Run through autotest.sh and manualtest.sh
31 *
32 * Testing non-PKCS11 keystores:
33 * echo | java -Dfile KeyToolTest
34 *
35 * Testing NSS PKCS11 keystores:
36 * # testing NSS
37 * # make sure the NSS db files are in current directory and writable
38 * echo | java -Dnss -Dnss.lib=/path/to/libsoftokn3.so KeyToolTest
39 *
40 * Testing Solaris Cryptography Framework PKCS11 keystores:
41 * # make sure you've already run pktool and set test12 as pin
42 * echo | java -Dsolaris KeyToolTest
43 *
44 * ATTENTION:
45 * Exception in thread "main" java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_SIZE_RANGE
46 * at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:420)
47 * ...
48 * Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_SIZE_RANGE
49 * at sun.security.pkcs11.wrapper.PKCS11.C_SignFinal(Native Method)
50 * at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:391)
51 * ...
52 * been observed. Possibly a Solaris bug
53 *
54 * ATTENTION:
55 * NSS PKCS11 config file are changed, DSA not supported now.
56 */
57
58import java.security.KeyStore;
59import java.util.Locale;
60import java.util.MissingResourceException;
61import sun.security.tools.KeyTool;
62import sun.security.x509.*;
63import java.io.*;
64
65public class KeyToolTest {
66
67 // The stdout and stderr outputs after a keytool run
68 String out;
69 String err;
70
71 // the output of println() in KeyTool.run
72 String ex;
73
74 String lastInput = "", lastCommand = "";
75 private static final boolean debug =
76 System.getProperty("debug") != null;
77
78 static final String NSS_P11_ARG =
79 "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt ";
80 static final String NSS_SRC_P11_ARG =
81 "-srckeystore NONE -srcstoretype PKCS11 -srcproviderName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt ";
82 static final String NZZ_P11_ARG =
83 "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nzz -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nzz.txt ";
84 static final String NZZ_SRC_P11_ARG =
85 "-srckeystore NONE -srcstoretype PKCS11 -srcproviderName SunPKCS11-nzz -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nzz.txt ";
86 static final String SUN_P11_ARG = "-keystore NONE -storetype PKCS11 ";
87 static final String SUN_SRC_P11_ARG = "-srckeystore NONE -srcstoretype PKCS11 ";
88
89 String p11Arg, srcP11Arg;
90
91 /** Creates a new instance of KeyToolTest */
92 KeyToolTest() {
93 // so that there is "Warning" and not translated into other language
94 Locale.setDefault(Locale.US);
95 }
96
97 /**
98 * Helper, removes a file
99 */
100 void remove(String filename) {
101 if (debug) {
102 System.err.println("Removing " + filename);
103 }
104 new File(filename).delete();
105 if (new File(filename).exists()) {
106 throw new RuntimeException("Error deleting " + filename);
107 }
108 }
109
110 /**
111 * Run a set of keytool command with given terminal input.
112 * @param input the terminal inputs, the characters typed by human
113 * if <code>cmd</code> is running on a terminal
114 * @param cmd the argument of a keytool command line
115 * @throws if keytool goes wrong in some place
116 */
117 void test(String input, String cmd) throws Exception {
118 lastInput = input;
119 lastCommand = cmd;
120
121 // "X" is appened so that we can precisely test how input is consumed
122 HumanInputStream in = new HumanInputStream(input+"X");
123 test(in, cmd);
124 // make sure the input string is no more no less
125 if(in.read() != 'X' || in.read() != -1)
126 throw new Exception("Input not consumed exactly");
127 }
128
129 void test(InputStream in, String cmd) throws Exception {
130
131 // save the original 3 streams
132 if (debug) {
133 System.err.println(cmd);
134 } else {
135 System.err.print(".");
136 }
137 PrintStream p1 = System.out;
138 PrintStream p2 = System.err;
139 InputStream i1 = System.in;
140
141 ByteArrayOutputStream b1 = new ByteArrayOutputStream();
142 ByteArrayOutputStream b2 = new ByteArrayOutputStream();
143
144 try {
145 System.setIn(in);
146 System.setOut(new PrintStream(b1));
147 System.setErr(new PrintStream(b2));
148
149 // since System.in is overrided, the KeyTool.main() method will
150 // never block at user input
151
152 // use -debug so that KeyTool.main() will throw an Exception
153 // instead of calling System.exit()
154 KeyTool.main(("-debug "+cmd).split("\\s+"));
155 } finally {
156 out = b1.toString();
157 err = b2.toString();
158 ex = out; // now it goes to System.out
159 System.setIn(i1);
160 System.setOut(p1);
161 System.setErr(p2);
162 }
163 }
164
165 /**
166 * Call this method if you expect test(input, cmd) should go OK
167 */
168 void testOK(String input, String cmd) throws Exception {
169 try {
170 test(input, cmd);
171 } catch(Exception e) {
172 afterFail(input, cmd, "OK");
173 throw e;
174 }
175 }
176
177 /**
178 * Call this method if you expect test(input, cmd) should fail and throw
179 * an exception
180 */
181 void testFail(String input, String cmd) throws Exception {
182 boolean ok;
183 try {
184 test(input, cmd);
185 ok = true;
186 } catch(Exception e) {
187 if (e instanceof MissingResourceException) {
188 ok = true;
189 } else {
190 ok = false;
191 }
192 }
193 if(ok) {
194 afterFail(input, cmd, "FAIL");
195 throw new RuntimeException();
196 }
197 }
198
199 /**
200 * Call this method if you expect test(input, cmd) should go OK
201 */
202 void testOK(InputStream is, String cmd) throws Exception {
203 try {
204 test(is, cmd);
205 } catch(Exception e) {
206 afterFail("", cmd, "OK");
207 throw e;
208 }
209 }
210
211 /**
212 * Call this method if you expect test(input, cmd) should fail and throw
213 * an exception
214 */
215 void testFail(InputStream is, String cmd) throws Exception {
216 boolean ok;
217 try {
218 test(is, cmd);
219 ok = true;
220 } catch(Exception e) {
221 ok = false;
222 }
223 if(ok) {
224 afterFail("", cmd, "FAIL");
225 throw new RuntimeException();
226 }
227 }
228
229 /**
230 * Call this method if you just want to run the command and does
231 * not care if it succeeds or fails.
232 */
233 void testAnyway(String input, String cmd) {
234 try {
235 test(input, cmd);
236 } catch(Exception e) {
237 ;
238 }
239 }
240
241 /**
242 * Helper method, print some output after a test does not do as expected
243 */
244 void afterFail(String input, String cmd, String should) {
245 System.err.println("\nTest fails for the command ---\n" +
246 "keytool " + cmd + "\nOr its debug version ---\n" +
247 "keytool -debug " + cmd);
248
249 System.err.println("The command result should be " + should +
250 ", but it's not. Try run the command manually and type" +
251 " these input into it: ");
252 char[] inputChars = input.toCharArray();
253
254 for (int i=0; i<inputChars.length; i++) {
255 char ch = inputChars[i];
256 if (ch == '\n') System.err.print("ENTER ");
257 else if (ch == ' ') System.err.print("SPACE ");
258 else System.err.print(ch + " ");
259 }
260 System.err.println("");
261
262 System.err.println("ERR is:\n"+err);
263 System.err.println("OUT is:\n"+out);
264 }
265
266 void assertTrue(boolean bool, String msg) {
267 if(!bool) {
268 afterFail(lastInput, lastCommand, "TRUE");
269 throw new RuntimeException(msg);
270 }
271 }
272
273 /**
274 * Helper method, load a keystore
275 * @param file file for keystore, null or "NONE" for PKCS11
276 * @pass password for the keystore
277 * @type keystore type
278 * @returns the KeyStore object
279 * @exception Exception if anything goes wrong
280 */
281 KeyStore loadStore(String file, String pass, String type) throws Exception {
282 KeyStore ks = KeyStore.getInstance(type);
283 FileInputStream is = null;
284 if (file != null && !file.equals("NONE")) {
285 is = new FileInputStream(file);
286 }
287 ks.load(is, pass.toCharArray());
288 is.close();
289 return ks;
290 }
291
292 /**
293 * The test suite.
294 * Maybe it's better to put this outside the KeyToolTest class
295 */
296 void testAll() throws Exception {
297 KeyStore ks;
298
299 remove("x.jks");
300 remove("x.jceks");
301 remove("x.p12");
302 remove("x2.jceks");
303 remove("x2.jks");
304 remove("x.jks.p1.cert");
305
306 // name changes: genkeypair, importcert, exportcert
307 remove("x.jks");
308 remove("x.jks.p1.cert");
309 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -alias p1 -dname CN=olala");
310 testOK("", "-keystore x.jks -storepass changeit -exportcert -alias p1 -file x.jks.p1.cert");
311 ks = loadStore("x.jks", "changeit", "JKS");
312 assertTrue(ks.getKey("p1", "changeit".toCharArray()) != null,
313 "key not DSA");
314 assertTrue(new File("x.jks.p1.cert").exists(), "p1 export err");
315 testOK("", "-keystore x.jks -storepass changeit -delete -alias p1");
316 testOK("y\n", "-keystore x.jks -storepass changeit -importcert -alias c1 -file x.jks.p1.cert"); // importcert, prompt for Yes/No
317 testOK("", "-keystore x.jks -storepass changeit -importcert -alias c2 -file x.jks.p1.cert -noprompt"); // importcert, -noprompt
318 ks = loadStore("x.jks", "changeit", "JKS");
319 assertTrue(ks.getCertificate("c1") != null, "import c1 err");
320
321 // v3
322 byte[] encoded = ks.getCertificate("c1").getEncoded();
323 X509CertImpl certImpl = new X509CertImpl(encoded);
324 assertTrue(certImpl.getVersion() == 3, "Version is not 3");
325
326 // changealias and keyclone
327 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -alias p1 -dname CN=olala");
328 testOK("changeit\n", "-keystore x.jks -changealias -alias p1 -destalias p11");
329 testOK("changeit\n", "-keystore x.jks -changealias -alias c1 -destalias c11");
330 testOK("changeit\n\n", "-keystore x.jks -keyclone -alias p11 -destalias p111"); // press ENTER when prompt for p111's keypass
331 ks = loadStore("x.jks", "changeit", "JKS");
332 assertTrue(!ks.containsAlias("p1"), "there is no p1");
333 assertTrue(!ks.containsAlias("c1"), "there is no c1");
334 assertTrue(ks.containsAlias("p11"), "there is p11");
335 assertTrue(ks.containsAlias("c11"), "there is c11");
336 assertTrue(ks.containsAlias("p111"), "there is p111");
337
338 // genSecKey
339 remove("x.jceks");
340 testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s1"); // DES, no need keysize
341 testFail("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s11 -keysize 128"); // DES, keysize cannot be 128
342 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -keyalg DESede -alias s2"); // DESede. no need keysize
343 testFail("changeit\n\n", "-keystore x.jceks -storetype AES -genseckey -keyalg Rijndael -alias s3"); // AES, need keysize
344 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -keyalg AES -alias s3 -keysize 128");
345 // about keypass
346 testOK("\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s4"); // can accept storepass
347 testOK("keypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s5"); // or a new one
348 testOK("bad\n\bad\nkeypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s6"); // keypass must be valid (prompt 3 times)
349 testFail("bad\n\bad\nbad\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s7"); // keypass must be valid (prompt 3 times)
350 testFail("bad\n\bad\nbad\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s7"); // keypass must be valid (prompt 3 times)
351 ks = loadStore("x.jceks", "changeit", "JCEKS");
352 assertTrue(ks.getKey("s1", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s1 is DES");
353 assertTrue(ks.getKey("s1", "changeit".toCharArray()).getEncoded().length == 8, "DES is 56");
354 assertTrue(ks.getKey("s2", "changeit".toCharArray()).getEncoded().length == 24, "DESede is 168");
355 assertTrue(ks.getKey("s2", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DESede"), "s2 is DESede");
356 assertTrue(ks.getKey("s3", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("AES"), "s3 is AES");
357 assertTrue(ks.getKey("s4", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s4 is DES");
358 assertTrue(ks.getKey("s5", "keypass".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s5 is DES");
359 assertTrue(ks.getKey("s6", "keypass".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s6 is DES");
360 assertTrue(!ks.containsAlias("s7"), "s7 not created");
361
362 // maybe we needn't test this, one day JKS will support SecretKey
363 //testFail("changeit\nchangeit\n", "-keystore x.jks -genseckey -keyalg AES -alias s3 -keysize 128");
364
365 // importKeyStore
366 remove("x.jks");
367 remove("x.jceks");
368 testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS -genkeypair -alias p1 -dname CN=Olala"); // create 2 entries...
369 testOK("", "-keystore x.jceks -storetype JCEKS -storepass changeit -importcert -alias c1 -file x.jks.p1.cert -noprompt"); // ...
370 ks = loadStore("x.jceks", "changeit", "JCEKS");
371 assertTrue(ks.size() == 2, "2 entries in JCEKS");
372 // import, shouldn't mention destalias/srckeypass/destkeypass if srcalias is no given
373 testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -destalias pp");
374 testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srckeypass changeit");
375 testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -destkeypass changeit");
376 // normal import
377 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS");
378 ks = loadStore("x.jks", "changeit", "JKS");
379 assertTrue(ks.size() == 2, "2 entries in JKS");
380 // import again, type yes to overwrite old entries
381 testOK("changeit\nchangeit\ny\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS");
382 ks = loadStore("x.jks", "changeit", "JKS");
383 // import again, specify -nopromt
384 testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -noprompt");
385 assertTrue(err.indexOf("Warning") != -1, "noprompt will warn");
386 ks = loadStore("x.jks", "changeit", "JKS");
387 assertTrue(ks.size() == 2, "2 entries in JKS");
388 // import again, type into new aliases when prompted
389 testOK("changeit\nchangeit\n\ns1\n\ns2\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS");
390 ks = loadStore("x.jks", "changeit", "JKS");
391 assertTrue(ks.size() == 4, "4 entries in JKS");
392
393 // importkeystore single
394 remove("x.jks");
395 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // normal
396 ks = loadStore("x.jks", "changeit", "JKS");
397 assertTrue(ks.size() == 1, "1 entries in JKS");
398 testOK("changeit\nchangeit\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // overwrite
399 ks = loadStore("x.jks", "changeit", "JKS");
400 assertTrue(ks.size() == 1, "1 entries in JKS");
401 testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1 -noprompt"); // noprompt
402 ks = loadStore("x.jks", "changeit", "JKS");
403 assertTrue(ks.size() == 1, "1 entries in JKS");
404 testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1 -destalias p2"); // rename
405 ks = loadStore("x.jks", "changeit", "JKS");
406 assertTrue(ks.size() == 2, "2 entries in JKS");
407 testOK("changeit\nchangeit\n\nnewalias\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // another rename
408 ks = loadStore("x.jks", "changeit", "JKS");
409 assertTrue(ks.size() == 3, "3 entries in JKS");
410
411 // importkeystore single, different keypass
412 remove("x.jks");
413 testOK("changeit\nkeypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -genkeypair -alias p2 -dname CN=Olala"); // generate entry with different keypass
414 testOK("changeit\nchangeit\nchangeit\nkeypass\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p2"); // prompt
415 ks = loadStore("x.jks", "changeit", "JKS");
416 assertTrue(ks.size() == 1, "1 entries in JKS");
417 testOK("changeit\nchangeit\nkeypass\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p2 -destalias p3 -destkeypass keypass2"); // diff destkeypass
418 ks = loadStore("x.jks", "changeit", "JKS");
419 assertTrue(ks.size() == 2, "2 entries in JKS");
420 assertTrue(ks.getKey("p2", "keypass".toCharArray()) != null, "p2 has old password");
421 assertTrue(ks.getKey("p3", "keypass2".toCharArray()) != null, "p3 has new password");
422
423 // importkeystore single, cert
424 remove("x.jks");
425 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1"); // normal
426 testOK("changeit\n\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1 -destalias c2"); // in fact srcstorepass can be ignored
427 assertTrue(err.indexOf("WARNING") != -1, "But will warn");
428 testOK("changeit\n\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1 -destalias c2"); // 2nd import, press y to overwrite ...
429 testOK("changeit\n\n\nc3\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1 -destalias c2"); // ... or rename
430 ks = loadStore("x.jks", "changeit", "JKS");
431 assertTrue(ks.size() == 3, "3 entries in JKS"); // c1, c2, c3
432
433 // importkeystore, secretkey
434 remove("x.jks");
435 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s1"); // create SecretKeyEntry
436 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s2"); // create SecretKeyEntry
437 testOK("changeit\n", "-keystore x.jceks -storetype JCEKS -delete -alias p2"); // remove the keypass!=storepass one
438 ks = loadStore("x.jceks", "changeit", "JCEKS");
439 assertTrue(ks.size() == 4, "4 entries in JCEKS"); // p1, c1, s1, s2
440 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias s1"); // normal
441 assertTrue(err.indexOf("not imported") != -1, "Not imported");
442 assertTrue(err.indexOf("Cannot store non-PrivateKeys") != -1, "Not imported");
443
444 remove("x.jks");
445 testOK("\n\n", "-srcstorepass changeit -deststorepass changeit -importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); // normal
446 assertTrue(err.indexOf("s1 not") != -1, "s1 not");
447 assertTrue(err.indexOf("s2 not") != -1, "s2 not");
448 assertTrue(err.indexOf("c1 success") != -1, "c1 success");
449 assertTrue(err.indexOf("p1 success") != -1, "p1 success");
450 testOK("yes\n", "-srcstorepass changeit -deststorepass changeit -importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); // normal
451 // maybe c1 or p1 has been imported before s1 or s2 is touched, anyway we know yesNo is only asked once.
452
453 // pkcs12
454 remove("x.jks");
455 testFail("changeit\nchangeit\n", "-keystore x.jks -genkeypair -alias p1 -dname CN=olala"); // JKS prompt for keypass
456 remove("x.jks");
457 testOK("changeit\nchangeit\n\n", "-keystore x.jks -genkeypair -alias p1 -dname CN=olala"); // just type ENTER means keypass=storepass
458 remove("x.p12");
459 testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit -genkeypair -alias p0 -dname CN=olala"); // PKCS12 only need storepass
460 testOK("changeit\n", "-keystore x.p12 -storetype PKCS12 -genkeypair -alias p1 -dname CN=olala");
461 testOK("changeit\n", "-keystore x.p12 -keypass changeit -storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); // when specify keypass, make sure keypass==storepass...
462 assertTrue(err.indexOf("Warning") == -1, "PKCS12 silent when keypass == storepass");
463 testOK("changeit\n", "-keystore x.p12 -keypass another -storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); // otherwise, print a warning
464 assertTrue(err.indexOf("Warning") != -1, "PKCS12 warning when keypass != storepass");
465 testFail("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -keypasswd -new changeit -alias p3"); // no -keypasswd for PKCS12
466 testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -changealias -alias p3 -destalias p33");
467 testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -keyclone -alias p33 -destalias p3");
468
469 // pkcs12
470 remove("x.p12");
471 testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit -genkeypair -alias p0 -dname CN=olala"); // PKCS12 only need storepass
472 testOK("", "-storepass changeit -keystore x.p12 -storetype PKCS12 -genkeypair -alias p1 -dname CN=olala");
473 testOK("", "-storepass changeit -keystore x.p12 -keypass changeit -storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); // when specify keypass, make sure keypass==storepass...
474 assertTrue(err.indexOf("Warning") == -1, "PKCS12 silent when keypass == storepass");
475 testOK("", "-storepass changeit -keystore x.p12 -keypass another -storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); // otherwise, print a warning
476 assertTrue(err.indexOf("Warning") != -1, "PKCS12 warning when keypass != storepass");
477
478 remove("x.jks");
479 remove("x.jceks");
480 remove("x.p12");
481 remove("x2.jceks");
482 remove("x2.jks");
483 remove("x.jks.p1.cert");
484 }
485
486 void testPKCS11() throws Exception {
487 KeyStore ks;
488 // pkcs11, the password maybe different and maybe PKCS11 is not supported
489
490 // in case last test is not executed successfully
491 testAnyway("", p11Arg + "-storepass test12 -delete -alias p1");
492 testAnyway("", p11Arg + "-storepass test12 -delete -alias p2");
493 testAnyway("", p11Arg + "-storepass test12 -delete -alias p3");
494 testAnyway("", p11Arg + "-storepass test12 -delete -alias nss");
495
496 testOK("", p11Arg + "-storepass test12 -list");
497 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE BEFORE THIS TEST ***");
498
499 testOK("", p11Arg + "-storepass test12 -genkeypair -alias p1 -dname CN=olala");
500 testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2");
501 testFail("test12\n", p11Arg + "-keypass test12 -genkeypair -alias p3 -dname CN=olala3"); // cannot provide keypass for PKCS11
502 testFail("test12\n", p11Arg + "-keypass nonsense -genkeypair -alias p3 -dname CN=olala3"); // cannot provide keypass for PKCS11
503
504 testOK("", p11Arg + "-storepass test12 -list");
505 assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11");
506
507 testOK("test12\n", p11Arg + "-alias p1 -changealias -destalias p3");
508 testOK("", p11Arg + "-storepass test12 -list -alias p3");
509 testFail("", p11Arg + "-storepass test12 -list -alias p1");
510
511 testOK("test12\n", p11Arg + "-alias p3 -keyclone -destalias p1");
512 testFail("", p11Arg + "-storepass test12 -list -alias p3"); // in PKCS11, keyclone will delete old
513 testOK("", p11Arg + "-storepass test12 -list -alias p1");
514
515 testFail("test12\n", p11Arg + "-alias p1 -keypasswd -new another"); // cannot change password for PKCS11
516
517 testOK("", p11Arg + "-storepass test12 -list");
518 assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11");
519
520 testOK("", p11Arg + "-storepass test12 -delete -alias p1");
521 testOK("", p11Arg + "-storepass test12 -delete -alias p2");
522
523 testOK("", p11Arg + "-storepass test12 -list");
524 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE BEFORE THIS TEST ***");
525 }
526
527 void testPKCS11ImportKeyStore() throws Exception {
528
529 KeyStore ks;
530 testOK("", p11Arg + "-storepass test12 -genkeypair -alias p1 -dname CN=olala");
531 testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2");
532 // test importkeystore for pkcs11
533
534 remove("x.jks");
535 // pkcs11 -> jks
536 testOK("changeit\nchangeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p1");
537 assertTrue(err.indexOf("not imported") != -1, "cannot import key without destkeypass");
538 ks = loadStore("x.jks", "changeit", "JKS");
539 assertTrue(!ks.containsAlias("p1"), "p1 is not imported");
540
541 testOK("changeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p1 -destkeypass changeit");
542 testOK("changeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p2 -destkeypass changeit");
543 ks = loadStore("x.jks", "changeit", "JKS");
544 assertTrue(ks.containsAlias("p1"), "p1 is imported");
545 assertTrue(ks.containsAlias("p2"), "p2 is imported");
546 // jks -> pkcs11
547 testOK("", p11Arg + "-storepass test12 -delete -alias p1");
548 testOK("", p11Arg + "-storepass test12 -delete -alias p2");
549 testOK("test12\nchangeit\n", p11Arg + "-importkeystore -srckeystore x.jks -srcstoretype JKS");
550 testOK("", p11Arg + "-storepass test12 -list -alias p1");
551 testOK("", p11Arg + "-storepass test12 -list -alias p2");
552 testOK("", p11Arg + "-storepass test12 -list");
553 assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11");
554 // clean up
555 testOK("", p11Arg + "-storepass test12 -delete -alias p1");
556 testOK("", p11Arg + "-storepass test12 -delete -alias p2");
557 testOK("", p11Arg + "-storepass test12 -list");
558 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "empty p11");
559
560 remove("x.jks");
561 }
562
563 // The sqeTest reflects the test suggested by judy.gao and bill.situ at
564 // /net/sqesvr-nfs/global/nfs/sec/ws_6.0_int/security/src/SecurityTools/Keytool
565 //
566 void sqeTest() throws Exception {
567 FileOutputStream fos = new FileOutputStream("badkeystore");
568 for (int i=0; i<100; i++) {
569 fos.write(i);
570 }
571 fos.close();
572
573 sqeCsrTest();
574 sqePrintcertTest();
575 sqeDeleteTest();
576 sqeExportTest();
577 sqeGenkeyTest();
578 sqeImportTest();
579 sqeKeyclonetest();
580 sqeKeypasswdTest();
581 sqeListTest();
582 sqeSelfCertTest();
583 sqeStorepassTest();
584
585 remove("badkeystore");
586 }
587
588 // Import: cacert, prompt, trusted, non-trusted, bad chain, not match
589 void sqeImportTest() throws Exception {
590 KeyStore ks;
591 remove("x.jks");
592 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
593 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
594 /* deleted */ testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
595 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
596 /* deleted */ testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
597 testOK("yes\n", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert");
598 ks = loadStore("x.jks", "changeit", "JKS");
599 assertTrue(ks.containsAlias("mykey"), "imported");
600 /* deleted */ testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
601 testOK("\n", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert");
602 ks = loadStore("x.jks", "changeit", "JKS");
603 assertTrue(!ks.containsAlias("mykey"), "imported");
604 testOK("no\n", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert");
605 ks = loadStore("x.jks", "changeit", "JKS");
606 assertTrue(!ks.containsAlias("mykey"), "imported");
607 testFail("no\n", "-keystore x.jks -storepass changeit -importcert -file nonexist");
608 testFail("no\n", "-keystore x.jks -storepass changeit -importcert -file x.jks");
609 remove("x.jks");
610 }
611 // keyclone: exist. nonexist err, cert err, dest exist, misc
612 void sqeKeyclonetest() throws Exception {
613 remove("x.jks");
614 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
615 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -new newpass -keyclone -dest p0"); // new pass
616 testOK("\n", "-keystore x.jks -storepass changeit -keypass changeit -keyclone -dest p1"); // new pass
617 testOK("\n", "-keystore x.jks -storepass changeit -keyclone -dest p2");
618 testFail("\n", "-keystore x.jks -storepass changeit -keyclone -dest p2");
619 testFail("\n", "-keystore x.jks -storepass changeit -keyclone -dest p3 -alias noexist");
620 // no cert
621 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
622 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
623 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
624 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -new newpass -keyclone -dest p0"); // new pass
625 remove("x.jks");
626 }
627 // keypasswd: exist, short, nonexist err, cert err, misc
628 void sqeKeypasswdTest() throws Exception {
629 remove("x.jks");
630 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
631 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -keypasswd -new newpass");
632 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
633 testOK("newpass\nnewpass\n", "-keystore x.jks -storepass changeit -keypass changeit -keypasswd");
634 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
635 testOK("new\nnew\nnewpass\nnewpass\n", "-keystore x.jks -storepass changeit -keypass changeit -keypasswd");
636 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
637 testOK("", "-keystore x.jks -storepass changeit -keypasswd -new newpass");
638 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
639 testOK("changeit\n", "-keystore x.jks -keypasswd -new newpass");
640 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
641 testFail("", "-keystore x.jks -storepass badpass -keypass changeit -keypasswd -new newpass");
642 testFail("", "-keystore x.jks -storepass changeit -keypass bad -keypasswd -new newpass");
643 // no cert
644 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
645 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
646 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
647 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -keypasswd -new newpass");
648 // diff pass
649 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
650 testOK("", "-keystore x.jks -storepass changeit -keypass keypass -genkeypair -dname CN=olala");
651 testFail("", "-keystore x.jks -storepass changeit -keypasswd -new newpass");
652 testOK("keypass\n", "-keystore x.jks -storepass changeit -keypasswd -new newpass");
653 // i hate those misc test
654 remove("x.jks");
655 }
656 // list: -f -alias, exist, nonexist err; otherwise, check all shows, -rfc shows more, and misc
657 void sqeListTest() throws Exception {
658 remove("x.jks");
659 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
660 testOK("", "-keystore x.jks -storepass changeit -list");
661 testOK("", "-keystore x.jks -storepass changeit -list -alias mykey");
662 testFail("", "-keystore x.jks -storepass changeit -list -alias notexist");
663 testFail("", "-keystore x.jks -storepass badpass -list -alias mykey");
664 testOK("", "-keystore x.jks -storepass changeit -keypass badpass -list -alias mykey"); // keypass ignore
665 testOK("\n", "-keystore x.jks -list");
666 assertTrue(err.indexOf("WARNING") != -1, "no storepass");
667 testOK("changeit\n", "-keystore x.jks -list");
668 assertTrue(err.indexOf("WARNING") == -1, "has storepass");
669 testFail("badpass\n", "-keystore x.jks -list");
670 // misc
671 testFail("", "-keystore aa\\bb//cc -storepass changeit -list");
672 testFail("", "-keystore nonexisting -storepass changeit -list");
673 testFail("", "-keystore badkeystore -storepass changeit -list");
674 remove("x.jks");
675 }
676 // selfcert: exist, non-exist err, cert err, sig..., dname, wrong keypass, misc
677 void sqeSelfCertTest() throws Exception {
678 remove("x.jks");
679 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
680 testOK("", "-keystore x.jks -storepass changeit -selfcert");
681 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert");
682 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert -alias nonexisting"); // not exist
683 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert -dname CN=NewName");
684 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert -sigalg MD5withRSA"); // sig not compatible
685 testFail("", "-keystore x.jks -storepass wrong -keypass changeit -selfcert"); // bad pass
686 testFail("", "-keystore x.jks -storepass changeit -keypass wrong -selfcert"); // bad pass
687 //misc
688 testFail("", "-keystore nonexist -storepass changeit -keypass changeit -selfcert");
689 testFail("", "-keystore aa//dd\\gg -storepass changeit -keypass changeit -selfcert");
690 // diff pass
691 remove("x.jks");
692 testOK("", "-keystore x.jks -storepass changeit -keypass keypass -genkeypair -dname CN=olala");
693 testFail("", "-keystore x.jks -storepass changeit -selfcert");
694 testOK("keypass\n", "-keystore x.jks -storepass changeit -selfcert");
695
696 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
697 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
698 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
699 testFail("", "-keystore x.jks -storepass changeit -selfcert"); // certentry cannot do selfcert
700 remove("x.jks");
701 }
702 // storepass: bad old, short new, misc
703 void sqeStorepassTest() throws Exception {
704 remove("x.jks");
705 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
706 testOK("", "-storepasswd -keystore x.jks -storepass changeit -new newstore"); // all in arg
707 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
708 testOK("changeit\nnewstore\nnewstore\n", "-storepasswd -keystore x.jks"); // all not in arg, new twice
709 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
710 testOK("changeit\n", "-storepasswd -keystore x.jks -new newstore"); // new in arg
711 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
712 testOK("newstore\nnewstore\n", "-storepasswd -keystore x.jks -storepass changeit"); // old in arg
713 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
714 testOK("new\nnew\nnewstore\nnewstore\n", "-storepasswd -keystore x.jks -storepass changeit"); // old in arg
715 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
716 testFail("", "-storepasswd -keystore x.jks -storepass badold -new newstore"); // bad old
717 testFail("", "-storepasswd -keystore x.jks -storepass changeit -new new"); // short new
718 // misc
719 testFail("", "-storepasswd -keystore nonexist -storepass changeit -new newstore"); // non exist
720 testFail("", "-storepasswd -keystore badkeystore -storepass changeit -new newstore"); // bad file
721 testFail("", "-storepasswd -keystore aa\\bb//cc//dd -storepass changeit -new newstore"); // bad file
722 remove("x.jks");
723 }
724
725 void sqeGenkeyTest() throws Exception {
726
727 remove("x.jks");
728 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
729 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
730 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias newentry");
731 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias newentry");
732 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg DSA -alias n1");
733 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -alias n2");
734 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg NoSuchAlg -alias n3");
735 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 56 -alias n4");
736 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 999 -alias n5");
737 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 512 -alias n6");
738 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 1024 -alias n7");
739 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -sigalg NoSuchAlg -alias n8");
740 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg MD2withRSA -alias n9");
741 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg MD5withRSA -alias n10");
742 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg SHA1withRSA -alias n11");
743 testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg NoSuchAlg -alias n12");
744 testFail("", "-keystore badkeystore -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias n14");
745 testFail("", "-keystore x.jks -storepass badpass -keypass changeit -genkeypair -dname CN=olala -alias n16");
746 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CNN=olala -alias n17");
747 remove("x.jks");
748 }
749
750 void sqeExportTest() throws Exception {
751 remove("x.jks");
752 testFail("", "-keystore x.jks -storepass changeit -export -file mykey.cert -alias mykey"); // nonexist
753 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
754 testOK("", "-keystore x.jks -storepass changeit -export -file mykey.cert -alias mykey");
755 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
756 testOK("", "-keystore x.jks -storepass changeit -import -file mykey.cert -noprompt -alias c1");
757 testOK("", "-keystore x.jks -storepass changeit -export -file mykey.cert2 -alias c1");
758 testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -export -file mykey.cert2 -alias c1");
759 testFail("", "-keystore nonexistkeystore -storepass changeit -export -file mykey.cert2 -alias c1");
760 testFail("", "-keystore badkeystore -storepass changeit -export -file mykey.cert2 -alias c1");
761 testFail("", "-keystore x.jks -storepass badpass -export -file mykey.cert2 -alias c1");
762 remove("mykey.cert");
763 remove("mykey.cert2");
764 remove("x.jks");
765 }
766
767 void sqeDeleteTest() throws Exception {
768 remove("x.jks");
769 testFail("", "-keystore x.jks -storepass changeit -delete -alias mykey"); // nonexist
770 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
771 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
772 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
773 testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -delete -alias mykey"); // keystore name illegal
774 testFail("", "-keystore nonexistkeystore -storepass changeit -delete -alias mykey"); // keystore not exist
775 testFail("", "-keystore badkeystore -storepass changeit -delete -alias mykey"); // keystore invalid
776 testFail("", "-keystore x.jks -storepass xxxxxxxx -delete -alias mykey"); // wrong pass
777 remove("x.jks");
778 }
779
780 void sqeCsrTest() throws Exception {
781 remove("x.jks");
782 remove("x.jks.p1.cert");
783 remove("csr1");
784 // PrivateKeyEntry can do certreq
785 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
786 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -alias mykey");
787 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1");
788 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg SHA1withDSA");
789 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg MD5withRSA"); // unmatched sigalg
790 // misc test
791 testFail("", "-keystore x.jks -storepass badstorepass -certreq -file csr1"); // bad storepass
792 testOK("changeit\n", "-keystore x.jks -certreq -file csr1"); // storepass from terminal
793 testFail("\n", "-keystore x.jks -certreq -file csr1"); // must provide storepass
794 testFail("", "-keystore x.jks -storepass changeit -keypass badkeypass -certreq -file csr1"); // bad keypass
795 testFail("", "-keystore x.jks -storepass changeit -certreq -file aa\\bb//cc\\dd"); // bad filepath
796 testFail("", "-keystore noexistks -storepass changeit -certreq -file csr1"); // non-existing keystore
797 // Try the RSA private key
798 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
799 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA");
800 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -alias mykey");
801 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1");
802 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg SHA1withDSA"); // unmatched sigalg
803 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg MD5withRSA");
804 // TrustedCertificateEntry cannot do certreq
805 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
806 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
807 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
808 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1 -alias mykey");
809 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1");
810 remove("x.jks");
811 remove("x.jks.p1.cert");
812 remove("csr1");
813 }
814
815 void sqePrintcertTest() throws Exception {
816 remove("x.jks");
817 remove("mykey.cert");
818 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
819 testOK("", "-keystore x.jks -storepass changeit -export -file mykey.cert -alias mykey");
820 testFail("", "-printcert -file badkeystore");
821 testFail("", "-printcert -file a/b/c/d");
822 testOK("", "-printcert -file mykey.cert");
823 FileInputStream fin = new FileInputStream("mykey.cert");
824 testOK(fin, "-printcert");
825 fin.close();
826 remove("x.jks");
827 remove("mykey.cert");
828 }
829
830 void i18nTest() throws Exception {
831 // 1. keytool -help
832 remove("x.jks");
833 try {
834 test("", "-help");
835 assertTrue(false, "Cannot come here");
836 } catch(RuntimeException e) {
837 assertTrue(e.getMessage().indexOf("NO ERROR, SORRY") != -1, "No error");
838 }
839 // 2. keytool -genkey -v -keysize 512 Enter "a" for the keystore password. Check error (password too short). Enter "password" for the keystore password. Hit 'return' for "first and last name", "organizational unit", "City", "State", and "Country Code". Type "yes" when they ask you if everything is correct. Type 'return' for new key password.
840 testOK("a\npassword\npassword\nMe\nHere\nNow\nPlace\nPlace\nUS\nyes\n\n", "-genkey -v -keysize 512 -keystore x.jks");
841 // 3. keytool -list -v -storepass password
842 testOK("", "-list -v -storepass password -keystore x.jks");
843 // 4. keytool -list -v Type "a" for the keystore password. Check error (wrong keystore password).
844 testFail("a\n", "-list -v -keystore x.jks");
845 assertTrue(ex.indexOf("password was incorrect") != -1, "");
846 // 5. keytool -genkey -v -keysize 512 Enter "password" as the password. Check error (alias 'mykey' already exists).
847 testFail("password\n", "-genkey -v -keysize 512 -keystore x.jks");
848 assertTrue(ex.indexOf("alias <mykey> already exists") != -1, "");
849 // 6. keytool -genkey -v -keysize 512 -alias mykey2 -storepass password Hit 'return' for "first and last name", "organizational unit", "City", "State", and "Country Code". Type "yes" when they ask you if everything is correct. Type 'return' for new key password.
850 testOK("\n\n\n\n\n\nyes\n\n", "-genkey -v -keysize 512 -alias mykey2 -storepass password -keystore x.jks");
851 // 7. keytool -list -v Type 'password' for the store password.
852 testOK("password\n", "-list -v -keystore x.jks");
853 // 8. keytool -keypasswd -v -alias mykey2 -storepass password Type "a" for the new key password. Type "aaaaaa" for the new key password. Type "bbbbbb" when re-entering the new key password. Type "a" for the new key password. Check Error (too many failures).
854 testFail("a\naaaaaa\nbbbbbb\na\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks");
855 assertTrue(ex.indexOf("Too many failures - try later") != -1, "");
856 // 9. keytool -keypasswd -v -alias mykey2 -storepass password Type "aaaaaa" for the new key password. Type "aaaaaa" when re-entering the new key password.
857 testOK("aaaaaa\naaaaaa\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks");
858 // 10. keytool -selfcert -v -alias mykey -storepass password
859 testOK("", "-selfcert -v -alias mykey -storepass password -keystore x.jks");
860 // 11. keytool -list -v -storepass password
861 testOK("", "-list -v -storepass password -keystore x.jks");
862 // 12. keytool -export -v -alias mykey -file cert -storepass password
863 remove("cert");
864 testOK("", "-export -v -alias mykey -file cert -storepass password -keystore x.jks");
865 // 13. keytool -import -v -file cert -storepass password Check error (Certificate reply and cert are the same)
866 testFail("", "-import -v -file cert -storepass password -keystore x.jks");
867 assertTrue(ex.indexOf("Certificate reply and certificate in keystore are identical") != -1, "");
868 // 14. keytool -printcert -file cert
869 testOK("", "-printcert -file cert -keystore x.jks");
870 remove("cert");
871 // 15. keytool -list -storepass password -provider sun.security.provider.Sun
872 testOK("", "-list -storepass password -provider sun.security.provider.Sun -keystore x.jks");
873
874 //Error tests
875
876 // 1. keytool -storepasswd -storepass password -new abc Check error (password too short)
877 testFail("", "-storepasswd -storepass password -new abc");
878 assertTrue(ex.indexOf("New password must be at least 6 characters") != -1, "");
879 // Changed, no NONE needed now
880 // 2. keytool -list -storetype PKCS11 Check error (-keystore must be NONE)
881 //testFail("", "-list -storetype PKCS11");
882 //assertTrue(err.indexOf("keystore must be NONE") != -1, "");
883 // 3. keytool -storepasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation)
884 testFail("", "-storepasswd -storetype PKCS11 -keystore NONE");
885 assertTrue(ex.indexOf("UnsupportedOperationException") != -1, "");
886 // 4. keytool -keypasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation)
887 testFail("", "-keypasswd -storetype PKCS11 -keystore NONE");
888 assertTrue(ex.indexOf("UnsupportedOperationException") != -1, "");
889 // 5. keytool -list -protected -storepass password Check error (password can not be specified with -protected)
890 testFail("", "-list -protected -storepass password -keystore x.jks");
891 assertTrue(ex.indexOf("if -protected is specified, then") != -1, "");
892 // 6. keytool -keypasswd -protected -keypass password Check error (password can not be specified with -protected)
893 testFail("", "-keypasswd -protected -keypass password -keystore x.jks");
894 assertTrue(ex.indexOf("if -protected is specified, then") != -1, "");
895 // 7. keytool -keypasswd -protected -new password Check error (password can not be specified with -protected)
896 testFail("", "-keypasswd -protected -new password -keystore x.jks");
897 assertTrue(ex.indexOf("if -protected is specified, then") != -1, "");
898 remove("x.jks");
899 }
900
901 void i18nPKCS11Test() throws Exception {
902 //PKCS#11 tests
903
904 // 1. sccs edit cert8.db key3.db
905 //Runtime.getRuntime().exec("/usr/ccs/bin/sccs edit cert8.db key3.db");
906 testOK("", p11Arg + "-storepass test12 -genkey -alias genkey -dname cn=genkey -keysize 512 -keyalg rsa");
907 testOK("", p11Arg + "-storepass test12 -list");
908 testOK("", p11Arg + "-storepass test12 -list -alias genkey");
909 testOK("", p11Arg + "-storepass test12 -certreq -alias genkey -file genkey.certreq");
910 testOK("", p11Arg + "-storepass test12 -export -alias genkey -file genkey.cert");
911 testOK("", "-printcert -file genkey.cert");
912 testOK("", p11Arg + "-storepass test12 -selfcert -alias genkey -dname cn=selfCert");
913 testOK("", p11Arg + "-storepass test12 -list -alias genkey -v");
914 assertTrue(out.indexOf("Owner: CN=selfCert") != -1, "");
915 //(check that cert subject DN is [cn=selfCert])
916 testOK("", p11Arg + "-storepass test12 -delete -alias genkey");
917 testOK("", p11Arg + "-storepass test12 -list");
918 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "");
919 //(check for empty database listing)
920 //Runtime.getRuntime().exec("/usr/ccs/bin/sccs unedit cert8.db key3.db");
921 remove("genkey.cert");
922 remove("genkey.certreq");
923 // 12. sccs unedit cert8.db key3.db
924 }
925
926 // tesing new option -srcProviderName
927 void sszzTest() throws Exception {
928 testAnyway("", NSS_P11_ARG+"-delete -alias nss -storepass test12");
929 testAnyway("", NZZ_P11_ARG+"-delete -alias nss -storepass test12");
930 testOK("", NSS_P11_ARG+"-genkeypair -dname CN=NSS -alias nss -storepass test12");
931 testOK("", NSS_SRC_P11_ARG + NZZ_P11_ARG +
932 "-importkeystore -srcstorepass test12 -deststorepass test12");
933 testAnyway("", NSS_P11_ARG+"-delete -alias nss -storepass test12");
934 testAnyway("", NZZ_P11_ARG+"-delete -alias nss -storepass test12");
935 }
936
937 public static void main(String[] args) throws Exception {
938 // first test if HumanInputStream really acts like a human being
939 HumanInputStream.test();
940 KeyToolTest t = new KeyToolTest();
941
942 if (System.getProperty("file") != null) {
943 t.sqeTest();
944 t.testAll();
945 t.i18nTest();
946 }
947
948 if (System.getProperty("nss") != null) {
949 t.srcP11Arg = NSS_SRC_P11_ARG;
950 t.p11Arg = NSS_P11_ARG;
951
952 t.testPKCS11();
953
954 // FAIL:
955 // 1. we still don't have srcprovidername yet
956 // 2. cannot store privatekey into NSS keystore
957 // java.security.KeyStoreException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_TEMPLATE_INCOMPLETE.
958 //t.testPKCS11ImportKeyStore();
959
960 t.i18nPKCS11Test();
961 //FAIL: currently PKCS11-NSS does not support 2 NSS KeyStores to be loaded at the same time
962 //t.sszzTest();
963 }
964
965 if (System.getProperty("solaris") != null) {
966 // For Solaris Cryptography Framework
967 t.srcP11Arg = SUN_SRC_P11_ARG;
968 t.p11Arg = SUN_P11_ARG;
969 t.testPKCS11();
970 t.testPKCS11ImportKeyStore();
971 t.i18nPKCS11Test();
972 }
973
974 System.out.println("Test pass!!!");
975 }
976}
977
978class TestException extends Exception {
979 public TestException(String e) {
980 super(e);
981 }
982}
983
984/**
985 * HumanInputStream tries to act like a human sitting in front of a computer
986 * terminal typing on the keyboard while the keytool program is running.
987 *
988 * keytool has called InputStream.read() and BufferedReader.readLine() in
989 * various places. a call to B.readLine() will try to buffer as much input as
990 * possible. Thus, a trivial InputStream will find it impossible to feed
991 * anything to I.read() after a B.readLine() call.
992 *
993 * This is why i create HumanInputStream, which will only send a single line
994 * to B.readLine(), no more, no less, and the next I.read() can have a chance
995 * to read the exact character right after "\n".
996 *
997 * I don't know why HumanInputStream works.
998 */
999class HumanInputStream extends InputStream {
1000 byte[] src;
1001 int pos;
1002 int length;
1003 boolean inLine;
1004 int stopIt;
1005
1006 public HumanInputStream(String input) {
1007 src = input.getBytes();
1008 pos = 0;
1009 length = src.length;
1010 stopIt = 0;
1011 inLine = false;
1012 }
1013
1014 // the trick: when called through read(byte[], int, int),
1015 // return -1 twice after "\n"
1016
1017 @Override public int read() throws IOException {
1018 int re;
1019 if(pos < length) {
1020 re = src[pos];
1021 if(inLine) {
1022 if(stopIt > 0) {
1023 stopIt--;
1024 re = -1;
1025 } else {
1026 if(re == '\n') {
1027 stopIt = 2;
1028 }
1029 pos++;
1030 }
1031 } else {
1032 pos++;
1033 }
1034 } else {
1035 re = -1;//throw new IOException("NO MORE TO READ");
1036 }
1037 //if (re < 32) System.err.printf("[%02d]", re);
1038 //else System.err.printf("[%c]", (char)re);
1039 return re;
1040 }
1041 @Override public int read(byte[] buffer, int offset, int len) {
1042 inLine = true;
1043 try {
1044 int re = super.read(buffer, offset, len);
1045 return re;
1046 } catch(Exception e) {
1047 throw new RuntimeException("HumanInputStream error");
1048 } finally {
1049 inLine = false;
1050 }
1051 }
1052 @Override public int available() {
1053 if(pos < length) return 1;
1054 return 0;
1055 }
1056
1057 // test part
1058 static void assertTrue(boolean bool) {
1059 if(!bool)
1060 throw new RuntimeException();
1061 }
1062
1063 public static void test() throws Exception {
1064
1065 class Tester {
1066 HumanInputStream is;
1067 BufferedReader reader;
1068 Tester(String s) {
1069 is = new HumanInputStream(s);
1070 reader = new BufferedReader(new InputStreamReader(is));
1071 }
1072
1073 // three kinds of test method
1074 // 1. read byte by byte from InputStream
1075 void testStreamReadOnce(int expection) throws Exception {
1076 assertTrue(is.read() == expection);
1077 }
1078 void testStreamReadMany(String expection) throws Exception {
1079 char[] keys = expection.toCharArray();
1080 for(int i=0; i<keys.length; i++) {
1081 assertTrue(is.read() == keys[i]);
1082 }
1083 }
1084 // 2. read a line with a newly created Reader
1085 void testReaderReadline(String expection) throws Exception {
1086 String s = new BufferedReader(new InputStreamReader(is)).readLine();
1087 if(s == null) assertTrue(expection == null);
1088 else assertTrue(s.equals(expection));
1089 }
1090 // 3. read a line with the old Reader
1091 void testReaderReadline2(String expection) throws Exception {
1092 String s = reader.readLine();
1093 if(s == null) assertTrue(expection == null);
1094 else assertTrue(s.equals(expection));
1095 }
1096 }
1097
1098 Tester test;
1099
1100 test = new Tester("111\n222\n\n444\n\n");
1101 test.testReaderReadline("111");
1102 test.testReaderReadline("222");
1103 test.testReaderReadline("");
1104 test.testReaderReadline("444");
1105 test.testReaderReadline("");
1106 test.testReaderReadline(null);
1107
1108 test = new Tester("111\n222\n\n444\n\n");
1109 test.testReaderReadline2("111");
1110 test.testReaderReadline2("222");
1111 test.testReaderReadline2("");
1112 test.testReaderReadline2("444");
1113 test.testReaderReadline2("");
1114 test.testReaderReadline2(null);
1115
1116 test = new Tester("111\n222\n\n444\n\n");
1117 test.testReaderReadline2("111");
1118 test.testReaderReadline("222");
1119 test.testReaderReadline2("");
1120 test.testReaderReadline2("444");
1121 test.testReaderReadline("");
1122 test.testReaderReadline2(null);
1123
1124 test = new Tester("1\n2");
1125 test.testStreamReadMany("1\n2");
1126 test.testStreamReadOnce(-1);
1127
1128 test = new Tester("12\n234");
1129 test.testStreamReadOnce('1');
1130 test.testReaderReadline("2");
1131 test.testStreamReadOnce('2');
1132 test.testReaderReadline2("34");
1133 test.testReaderReadline2(null);
1134
1135 test = new Tester("changeit\n");
1136 test.testStreamReadMany("changeit\n");
1137 test.testReaderReadline(null);
1138
1139 test = new Tester("changeit\nName\nCountry\nYes\n");
1140 test.testStreamReadMany("changeit\n");
1141 test.testReaderReadline("Name");
1142 test.testReaderReadline("Country");
1143 test.testReaderReadline("Yes");
1144 test.testReaderReadline(null);
1145
1146 test = new Tester("Me\nHere\n");
1147 test.testReaderReadline2("Me");
1148 test.testReaderReadline2("Here");
1149 }
1150}