rev 13439 : 8213952: Relax DNSName restriction as per RFC 1123
Reviewed-by: weijun, mullan, chegar
1 /*
2 * Copyright (c) 2005, 2017, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * 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
58 import java.nio.file.Files;
59 import java.nio.file.Paths;
60 import java.security.KeyStore;
61 import sun.security.x509.*;
62 import java.io.*;
63 import java.security.KeyPairGenerator;
64 import java.security.NoSuchAlgorithmException;
65 import java.util.*;
66 import java.security.cert.X509Certificate;
67 import sun.security.util.ObjectIdentifier;
68
69 public class KeyToolTest {
70
71 // The stdout and stderr outputs after a keytool run
72 String out;
73 String err;
74
75 // the output of println() in KeyTool.run
76 String ex;
77
78 String lastInput = "", lastCommand = "";
79 private static final boolean debug =
80 System.getProperty("debug") != null;
81
82 static final String NSS_P11_ARG =
83 "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt ";
84 static final String NSS_SRC_P11_ARG =
85 "-srckeystore NONE -srcstoretype PKCS11 -srcproviderName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt ";
86 static final String NZZ_P11_ARG =
87 "-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nzz -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nzz.txt ";
88 static final String NZZ_SRC_P11_ARG =
89 "-srckeystore NONE -srcstoretype PKCS11 -srcproviderName SunPKCS11-nzz -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nzz.txt ";
90 static final String SUN_P11_ARG = "-keystore NONE -storetype PKCS11 ";
91 static final String SUN_SRC_P11_ARG = "-srckeystore NONE -srcstoretype PKCS11 ";
92
93 String p11Arg, srcP11Arg;
94
95 /** Creates a new instance of KeyToolTest */
96 KeyToolTest() {
97 // so that there is "Warning" and not translated into other language
98 Locale.setDefault(Locale.US);
99 }
100
101 /**
102 * Helper, removes a file
103 */
104 void remove(String filename) {
105 if (debug) {
106 System.err.println("Removing " + filename);
107 }
108 new File(filename).delete();
109 if (new File(filename).exists()) {
110 throw new RuntimeException("Error deleting " + filename);
111 }
112 }
113
114 /**
115 * Run a set of keytool command with given terminal input.
116 * @param input the terminal inputs, the characters typed by human
117 * if <code>cmd</code> is running on a terminal
118 * @param cmd the argument of a keytool command line
119 * @throws if keytool goes wrong in some place
120 */
121 void test(String input, String cmd) throws Exception {
122 lastInput = input;
123 lastCommand = cmd;
124
125 // "X" is appended so that we can precisely test how input is consumed
126 HumanInputStream in = new HumanInputStream(input+"X");
127 test(in, cmd);
128 // make sure the input string is no more no less
129 if(in.read() != 'X' || in.read() != -1)
130 throw new Exception("Input not consumed exactly");
131 }
132
133 void test(InputStream in, String cmd) throws Exception {
134
135 // save the original 3 streams
136 if (debug) {
137 System.err.println(cmd);
138 } else {
139 System.err.print(".");
140 }
141 PrintStream p1 = System.out;
142 PrintStream p2 = System.err;
143 InputStream i1 = System.in;
144
145 ByteArrayOutputStream b1 = new ByteArrayOutputStream();
146 ByteArrayOutputStream b2 = new ByteArrayOutputStream();
147
148 try {
149 System.setIn(in);
150 System.setOut(new PrintStream(b1));
151 System.setErr(new PrintStream(b2));
152
153 // since System.in is overrided, the
154 // sun.security.tools.keytool.Main.main() method will
155 // never block at user input
156
157 // use -debug so that main() will throw an Exception
158 // instead of calling System.exit()
159 sun.security.tools.keytool.Main.main(("-debug "+cmd).split("\\s+"));
160 } finally {
161 out = b1.toString();
162 err = b2.toString();
163 ex = out; // now it goes to System.out
164 System.setIn(i1);
165 System.setOut(p1);
166 System.setErr(p2);
167 }
168 }
169
170 /**
171 * Call this method if you expect test(input, cmd) should go OK
172 */
173 void testOK(String input, String cmd) throws Exception {
174 try {
175 // Workaround for "8057810: Make SHA256withDSA the default
176 // jarsigner and keytool algorithm for DSA keys". Unfortunately
177 // SunPKCS11-NSS does not support SHA256withDSA yet.
178 if (cmd.contains("p11-nss.txt") && cmd.contains("-genkey")
179 && !cmd.contains("-keyalg")) {
180 cmd += " -sigalg SHA1withDSA -keysize 1024";
181 }
182 test(input, cmd);
183 } catch(Exception e) {
184 afterFail(input, cmd, "OK");
185 throw e;
186 }
187 }
188
189 /**
190 * Call this method if you expect test(input, cmd) should fail and throw
191 * an exception
192 */
193 void testFail(String input, String cmd) throws Exception {
194 boolean ok;
195 try {
196 test(input, cmd);
197 ok = true;
198 } catch(Exception e) {
199 if (e instanceof MissingResourceException) {
200 ok = true;
201 } else {
202 ok = false;
203 }
204 }
205 if(ok) {
206 afterFail(input, cmd, "FAIL");
207 throw new RuntimeException();
208 }
209 }
210
211 /**
212 * Call this method if you expect test(input, cmd) should go OK
213 */
214 void testOK(InputStream is, String cmd) throws Exception {
215 try {
216 test(is, cmd);
217 } catch(Exception e) {
218 afterFail("", cmd, "OK");
219 throw e;
220 }
221 }
222
223 /**
224 * Call this method if you expect test(input, cmd) should fail and throw
225 * an exception
226 */
227 void testFail(InputStream is, String cmd) throws Exception {
228 boolean ok;
229 try {
230 test(is, cmd);
231 ok = true;
232 } catch(Exception e) {
233 ok = false;
234 }
235 if(ok) {
236 afterFail("", cmd, "FAIL");
237 throw new RuntimeException();
238 }
239 }
240
241 /**
242 * Call this method if you just want to run the command and does
243 * not care if it succeeds or fails.
244 */
245 void testAnyway(String input, String cmd) {
246 try {
247 test(input, cmd);
248 } catch(Exception e) {
249 ;
250 }
251 }
252
253 /**
254 * Helper method, print some output after a test does not do as expected
255 */
256 void afterFail(String input, String cmd, String should) {
257 if (cmd.contains("p11-nss.txt")) {
258 cmd = "-J-Dnss.lib=" + System.getProperty("nss.lib") + " " + cmd;
259 }
260 System.err.println("\nTest fails for the command ---\n" +
261 "keytool " + cmd + "\nOr its debug version ---\n" +
262 "keytool -debug " + cmd);
263
264 System.err.println("The command result should be " + should +
265 ", but it's not. Try run the command manually and type" +
266 " these input into it: ");
267 char[] inputChars = input.toCharArray();
268
269 for (int i=0; i<inputChars.length; i++) {
270 char ch = inputChars[i];
271 if (ch == '\n') System.err.print("ENTER ");
272 else if (ch == ' ') System.err.print("SPACE ");
273 else System.err.print(ch + " ");
274 }
275 System.err.println("");
276
277 System.err.println("ERR is:\n"+err);
278 System.err.println("OUT is:\n"+out);
279 }
280
281 void assertTrue(boolean bool, String msg) {
282 if (debug) {
283 System.err.println("If not " + bool + ", " + msg);
284 } else {
285 System.err.print("v");
286 }
287 if(!bool) {
288 afterFail(lastInput, lastCommand, "TRUE");
289 System.err.println(msg);
290 throw new RuntimeException(msg);
291 }
292 }
293
294 void assertTrue(boolean bool) {
295 assertTrue(bool, "well...");
296 }
297 /**
298 * Helper method, load a keystore
299 * @param file file for keystore, null or "NONE" for PKCS11
300 * @pass password for the keystore
301 * @type keystore type
302 * @returns the KeyStore object
303 * @exception Exception if anything goes wrong
304 */
305 KeyStore loadStore(String file, String pass, String type) throws Exception {
306 KeyStore ks = KeyStore.getInstance(type);
307 FileInputStream is = null;
308 if (file != null && !file.equals("NONE")) {
309 is = new FileInputStream(file);
310 }
311 ks.load(is, pass.toCharArray());
312 is.close();
313 return ks;
314 }
315
316 /**
317 * The test suite.
318 * Maybe it's better to put this outside the KeyToolTest class
319 */
320 void testAll() throws Exception {
321 KeyStore ks;
322
323 remove("x.jks");
324 remove("x.jceks");
325 remove("x.p12");
326 remove("x2.jceks");
327 remove("x2.jks");
328 remove("x.jks.p1.cert");
329
330 // name changes: genkeypair, importcert, exportcert
331 remove("x.jks");
332 remove("x.jks.p1.cert");
333 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -alias p1 -dname CN=olala");
334 testOK("", "-keystore x.jks -storepass changeit -exportcert -alias p1 -file x.jks.p1.cert");
335 ks = loadStore("x.jks", "changeit", "JKS");
336 assertTrue(ks.getKey("p1", "changeit".toCharArray()) != null,
337 "key not DSA");
338 assertTrue(new File("x.jks.p1.cert").exists(), "p1 export err");
339 testOK("", "-keystore x.jks -storepass changeit -delete -alias p1");
340 testOK("y\n", "-keystore x.jks -storepass changeit -importcert -alias c1 -file x.jks.p1.cert"); // importcert, prompt for Yes/No
341 testOK("", "-keystore x.jks -storepass changeit -importcert -alias c2 -file x.jks.p1.cert -noprompt"); // importcert, -noprompt
342 ks = loadStore("x.jks", "changeit", "JKS");
343 assertTrue(ks.getCertificate("c1") != null, "import c1 err");
344
345 // v3
346 byte[] encoded = ks.getCertificate("c1").getEncoded();
347 X509CertImpl certImpl = new X509CertImpl(encoded);
348 assertTrue(certImpl.getVersion() == 3, "Version is not 3");
349
350 // changealias and keyclone
351 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -alias p1 -dname CN=olala");
352 testOK("changeit\n", "-keystore x.jks -changealias -alias p1 -destalias p11");
353 testOK("changeit\n", "-keystore x.jks -changealias -alias c1 -destalias c11");
354 testOK("changeit\n\n", "-keystore x.jks -keyclone -alias p11 -destalias p111"); // press ENTER when prompt for p111's keypass
355 ks = loadStore("x.jks", "changeit", "JKS");
356 assertTrue(!ks.containsAlias("p1"), "there is no p1");
357 assertTrue(!ks.containsAlias("c1"), "there is no c1");
358 assertTrue(ks.containsAlias("p11"), "there is p11");
359 assertTrue(ks.containsAlias("c11"), "there is c11");
360 assertTrue(ks.containsAlias("p111"), "there is p111");
361
362 // genSecKey
363 remove("x.jceks");
364 testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s1"); // DES, no need keysize
365 testFail("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s11 -keysize 128"); // DES, keysize cannot be 128
366 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -keyalg DESede -alias s2"); // DESede. no need keysize
367 testFail("changeit\n\n", "-keystore x.jceks -storetype AES -genseckey -keyalg Rijndael -alias s3"); // AES, need keysize
368 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -keyalg AES -alias s3 -keysize 128");
369 // about keypass
370 testOK("\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s4"); // can accept storepass
371 testOK("keypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s5"); // or a new one
372 testOK("bad\n\bad\nkeypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s6"); // keypass must be valid (prompt 3 times)
373 testFail("bad\n\bad\nbad\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s7"); // keypass must be valid (prompt 3 times)
374 testFail("bad\n\bad\nbad\nkeypass\n", "-keystore x.jceks -storetype JCEKS -storepass changeit -genseckey -alias s7"); // keypass must be valid (prompt 3 times)
375 ks = loadStore("x.jceks", "changeit", "JCEKS");
376 assertTrue(ks.getKey("s1", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s1 is DES");
377 assertTrue(ks.getKey("s1", "changeit".toCharArray()).getEncoded().length == 8, "DES is 56");
378 assertTrue(ks.getKey("s2", "changeit".toCharArray()).getEncoded().length == 24, "DESede is 168");
379 assertTrue(ks.getKey("s2", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DESede"), "s2 is DESede");
380 assertTrue(ks.getKey("s3", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("AES"), "s3 is AES");
381 assertTrue(ks.getKey("s4", "changeit".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s4 is DES");
382 assertTrue(ks.getKey("s5", "keypass".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s5 is DES");
383 assertTrue(ks.getKey("s6", "keypass".toCharArray()).getAlgorithm().equalsIgnoreCase("DES"), "s6 is DES");
384 assertTrue(!ks.containsAlias("s7"), "s7 not created");
385
386 // maybe we needn't test this, one day JKS will support SecretKey
387 //testFail("changeit\nchangeit\n", "-keystore x.jks -genseckey -keyalg AES -alias s3 -keysize 128");
388
389 // importKeyStore
390 remove("x.jks");
391 remove("x.jceks");
392 testOK("changeit\nchangeit\n\n", "-keystore x.jceks -storetype JCEKS -genkeypair -alias p1 -dname CN=Olala"); // create 2 entries...
393 testOK("", "-keystore x.jceks -storetype JCEKS -storepass changeit -importcert -alias c1 -file x.jks.p1.cert -noprompt"); // ...
394 ks = loadStore("x.jceks", "changeit", "JCEKS");
395 assertTrue(ks.size() == 2, "2 entries in JCEKS");
396 // import, shouldn't mention destalias/srckeypass/destkeypass if srcalias is no given
397 testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -destalias pp");
398 testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srckeypass changeit");
399 testFail("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -destkeypass changeit");
400 // normal import
401 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS");
402 ks = loadStore("x.jks", "changeit", "JKS");
403 assertTrue(ks.size() == 2, "2 entries in JKS");
404 // import again, type yes to overwrite old entries
405 testOK("changeit\nchangeit\ny\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS");
406 ks = loadStore("x.jks", "changeit", "JKS");
407 // import again, specify -nopromt
408 testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -noprompt");
409 assertTrue(err.indexOf("Warning") != -1, "noprompt will warn");
410 ks = loadStore("x.jks", "changeit", "JKS");
411 assertTrue(ks.size() == 2, "2 entries in JKS");
412 // import again, type into new aliases when prompted
413 testOK("changeit\nchangeit\n\ns1\n\ns2\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS");
414 ks = loadStore("x.jks", "changeit", "JKS");
415 assertTrue(ks.size() == 4, "4 entries in JKS");
416
417 // importkeystore single
418 remove("x.jks");
419 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // normal
420 ks = loadStore("x.jks", "changeit", "JKS");
421 assertTrue(ks.size() == 1, "1 entries in JKS");
422 testOK("changeit\nchangeit\ny\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // overwrite
423 ks = loadStore("x.jks", "changeit", "JKS");
424 assertTrue(ks.size() == 1, "1 entries in JKS");
425 testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1 -noprompt"); // noprompt
426 ks = loadStore("x.jks", "changeit", "JKS");
427 assertTrue(ks.size() == 1, "1 entries in JKS");
428 testOK("changeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1 -destalias p2"); // rename
429 ks = loadStore("x.jks", "changeit", "JKS");
430 assertTrue(ks.size() == 2, "2 entries in JKS");
431 testOK("changeit\nchangeit\n\nnewalias\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p1"); // another rename
432 ks = loadStore("x.jks", "changeit", "JKS");
433 assertTrue(ks.size() == 3, "3 entries in JKS");
434
435 // importkeystore single, different keypass
436 remove("x.jks");
437 testOK("changeit\nkeypass\nkeypass\n", "-keystore x.jceks -storetype JCEKS -genkeypair -alias p2 -dname CN=Olala"); // generate entry with different keypass
438 testOK("changeit\nchangeit\nchangeit\nkeypass\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p2"); // prompt
439 ks = loadStore("x.jks", "changeit", "JKS");
440 assertTrue(ks.size() == 1, "1 entries in JKS");
441 testOK("changeit\nchangeit\nkeypass\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias p2 -destalias p3 -destkeypass keypass2"); // diff destkeypass
442 ks = loadStore("x.jks", "changeit", "JKS");
443 assertTrue(ks.size() == 2, "2 entries in JKS");
444 assertTrue(ks.getKey("p2", "keypass".toCharArray()) != null, "p2 has old password");
445 assertTrue(ks.getKey("p3", "keypass2".toCharArray()) != null, "p3 has new password");
446
447 // importkeystore single, cert
448 remove("x.jks");
449 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1"); // normal
450 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
451 assertTrue(err.indexOf("WARNING") != -1, "But will warn");
452 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 ...
453 testOK("changeit\n\n\nc3\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias c1 -destalias c2"); // ... or rename
454 ks = loadStore("x.jks", "changeit", "JKS");
455 assertTrue(ks.size() == 3, "3 entries in JKS"); // c1, c2, c3
456
457 // importkeystore, secretkey
458 remove("x.jks");
459 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s1"); // create SecretKeyEntry
460 testOK("changeit\n\n", "-keystore x.jceks -storetype JCEKS -genseckey -alias s2"); // create SecretKeyEntry
461 testOK("changeit\n", "-keystore x.jceks -storetype JCEKS -delete -alias p2"); // remove the keypass!=storepass one
462 ks = loadStore("x.jceks", "changeit", "JCEKS");
463 assertTrue(ks.size() == 4, "4 entries in JCEKS"); // p1, c1, s1, s2
464 testOK("changeit\nchangeit\nchangeit\n", "-importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS -srcalias s1"); // normal
465 assertTrue(err.indexOf("not imported") != -1, "Not imported");
466 assertTrue(err.indexOf("Cannot store non-PrivateKeys") != -1, "Not imported");
467
468 // Importing a JCEKS keystore to a JKS one. Will warn for the 2 SecretKey entries
469
470 remove("x.jks");
471 // Two "no" answers to bypass warnings
472 testOK("\n\n", "-srcstorepass changeit -deststorepass changeit -importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); // normal
473 assertTrue(err.indexOf("s1 not") != -1, "s1 not");
474 assertTrue(err.indexOf("s2 not") != -1, "s2 not");
475 assertTrue(err.indexOf("c1 success") != -1, "c1 success");
476 assertTrue(err.indexOf("p1 success") != -1, "p1 success");
477 remove("x.jks");
478 // One "yes" to stop
479 testOK("yes\n", "-srcstorepass changeit -deststorepass changeit -importkeystore -srckeystore x.jceks -srcstoretype JCEKS -destkeystore x.jks -deststoretype JKS"); // normal
480 // maybe c1 or p1 has been imported before s1 or s2 is touched, anyway we know yesNo is only asked once.
481
482 // pkcs12
483 remove("x.jks");
484 testFail("changeit\nchangeit\n", "-keystore x.jks -genkeypair -alias p1 -dname CN=olala"); // JKS prompt for keypass
485 remove("x.jks");
486 testOK("changeit\nchangeit\n\n", "-keystore x.jks -genkeypair -alias p1 -dname CN=olala"); // just type ENTER means keypass=storepass
487 remove("x.p12");
488 testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit -genkeypair -alias p0 -dname CN=olala"); // PKCS12 only need storepass
489 testOK("changeit\n", "-keystore x.p12 -storetype PKCS12 -genkeypair -alias p1 -dname CN=olala");
490 testOK("changeit\n", "-keystore x.p12 -keypass changeit -storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); // when specify keypass, make sure keypass==storepass...
491 assertTrue(err.indexOf("Warning") == -1, "PKCS12 silent when keypass == storepass");
492 testOK("changeit\n", "-keystore x.p12 -keypass another -storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); // otherwise, print a warning
493 assertTrue(err.indexOf("Warning") != -1, "PKCS12 warning when keypass != storepass");
494 testFail("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -keypasswd -new changeit -alias p3"); // no -keypasswd for PKCS12
495 testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -changealias -alias p3 -destalias p33");
496 testOK("", "-keystore x.p12 -storepass changeit -storetype PKCS12 -keyclone -alias p33 -destalias p3");
497
498 // pkcs12
499 remove("x.p12");
500 testOK("", "-keystore x.p12 -storetype PKCS12 -storepass changeit -genkeypair -alias p0 -dname CN=olala"); // PKCS12 only need storepass
501 testOK("", "-storepass changeit -keystore x.p12 -storetype PKCS12 -genkeypair -alias p1 -dname CN=olala");
502 testOK("", "-storepass changeit -keystore x.p12 -keypass changeit -storetype PKCS12 -genkeypair -alias p3 -dname CN=olala"); // when specify keypass, make sure keypass==storepass...
503 assertTrue(err.indexOf("Warning") == -1, "PKCS12 silent when keypass == storepass");
504 testOK("", "-storepass changeit -keystore x.p12 -keypass another -storetype PKCS12 -genkeypair -alias p2 -dname CN=olala"); // otherwise, print a warning
505 assertTrue(err.indexOf("Warning") != -1, "PKCS12 warning when keypass != storepass");
506
507 remove("x.jks");
508 remove("x.jceks");
509 remove("x.p12");
510 remove("x2.jceks");
511 remove("x2.jks");
512 remove("x.jks.p1.cert");
513 }
514
515 void testPKCS11() throws Exception {
516 KeyStore ks;
517 // pkcs11, the password maybe different and maybe PKCS11 is not supported
518
519 // in case last test is not executed successfully
520 testAnyway("", p11Arg + "-storepass test12 -delete -alias p1");
521 testAnyway("", p11Arg + "-storepass test12 -delete -alias p2");
522 testAnyway("", p11Arg + "-storepass test12 -delete -alias p3");
523 testAnyway("", p11Arg + "-storepass test12 -delete -alias nss");
524
525 testOK("", p11Arg + "-storepass test12 -list");
526 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE BEFORE THIS TEST ***");
527
528 testOK("", p11Arg + "-storepass test12 -genkeypair -alias p1 -dname CN=olala");
529 testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2");
530 testFail("test12\n", p11Arg + "-keypass test12 -genkeypair -alias p3 -dname CN=olala3"); // cannot provide keypass for PKCS11
531 testFail("test12\n", p11Arg + "-keypass nonsense -genkeypair -alias p3 -dname CN=olala3"); // cannot provide keypass for PKCS11
532
533 testOK("", p11Arg + "-storepass test12 -list");
534 assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11");
535
536 testOK("test12\n", p11Arg + "-alias p1 -changealias -destalias p3");
537 testOK("", p11Arg + "-storepass test12 -list -alias p3");
538 testFail("", p11Arg + "-storepass test12 -list -alias p1");
539
540 testOK("test12\n", p11Arg + "-alias p3 -keyclone -destalias p1");
541 testFail("", p11Arg + "-storepass test12 -list -alias p3"); // in PKCS11, keyclone will delete old
542 testOK("", p11Arg + "-storepass test12 -list -alias p1");
543
544 testFail("test12\n", p11Arg + "-alias p1 -keypasswd -new another"); // cannot change password for PKCS11
545
546 testOK("", p11Arg + "-storepass test12 -list");
547 assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11");
548
549 testOK("", p11Arg + "-storepass test12 -delete -alias p1");
550 testOK("", p11Arg + "-storepass test12 -delete -alias p2");
551
552 testOK("", p11Arg + "-storepass test12 -list");
553 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE BEFORE THIS TEST ***");
554 }
555
556 void testPKCS11ImportKeyStore() throws Exception {
557
558 KeyStore ks;
559 testOK("", p11Arg + "-storepass test12 -genkeypair -alias p1 -dname CN=olala");
560 testOK("test12\n", p11Arg + "-genkeypair -alias p2 -dname CN=olala2");
561 // test importkeystore for pkcs11
562
563 remove("x.jks");
564 // pkcs11 -> jks
565 testOK("changeit\nchangeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p1");
566 assertTrue(err.indexOf("not imported") != -1, "cannot import key without destkeypass");
567 ks = loadStore("x.jks", "changeit", "JKS");
568 assertTrue(!ks.containsAlias("p1"), "p1 is not imported");
569
570 testOK("changeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p1 -destkeypass changeit");
571 testOK("changeit\ntest12\n", srcP11Arg + "-importkeystore -destkeystore x.jks -deststoretype JKS -srcalias p2 -destkeypass changeit");
572 ks = loadStore("x.jks", "changeit", "JKS");
573 assertTrue(ks.containsAlias("p1"), "p1 is imported");
574 assertTrue(ks.containsAlias("p2"), "p2 is imported");
575 // jks -> pkcs11
576 testOK("", p11Arg + "-storepass test12 -delete -alias p1");
577 testOK("", p11Arg + "-storepass test12 -delete -alias p2");
578 testOK("test12\nchangeit\n", p11Arg + "-importkeystore -srckeystore x.jks -srcstoretype JKS");
579 testOK("", p11Arg + "-storepass test12 -list -alias p1");
580 testOK("", p11Arg + "-storepass test12 -list -alias p2");
581 testOK("", p11Arg + "-storepass test12 -list");
582 assertTrue(out.indexOf("Your keystore contains 2 entries") != -1, "2 entries in p11");
583 // clean up
584 testOK("", p11Arg + "-storepass test12 -delete -alias p1");
585 testOK("", p11Arg + "-storepass test12 -delete -alias p2");
586 testOK("", p11Arg + "-storepass test12 -list");
587 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1, "empty p11");
588
589 remove("x.jks");
590 }
591
592 // The sqeTest reflects the test suggested by judy.gao and bill.situ at
593 // /net/sqesvr-nfs/global/nfs/sec/ws_6.0_int/security/src/SecurityTools/Keytool
594 //
595 void sqeTest() throws Exception {
596 FileOutputStream fos = new FileOutputStream("badkeystore");
597 for (int i=0; i<100; i++) {
598 fos.write(i);
599 }
600 fos.close();
601
602 sqeCsrTest();
603 sqePrintcertTest();
604 sqeDeleteTest();
605 sqeExportTest();
606 sqeGenkeyTest();
607 sqeImportTest();
608 sqeKeyclonetest();
609 sqeKeypasswdTest();
610 sqeListTest();
611 sqeSelfCertTest();
612 sqeStorepassTest();
613
614 remove("badkeystore");
615 }
616
617 // Import: cacert, prompt, trusted, non-trusted, bad chain, not match
618 void sqeImportTest() throws Exception {
619 KeyStore ks;
620 remove("x.jks");
621 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
622 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
623 /* deleted */ testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
624 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
625 /* deleted */ testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
626 testOK("yes\n", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert");
627 ks = loadStore("x.jks", "changeit", "JKS");
628 assertTrue(ks.containsAlias("mykey"), "imported");
629 /* deleted */ testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
630 testOK("\n", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert");
631 ks = loadStore("x.jks", "changeit", "JKS");
632 assertTrue(!ks.containsAlias("mykey"), "imported");
633 testOK("no\n", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert");
634 ks = loadStore("x.jks", "changeit", "JKS");
635 assertTrue(!ks.containsAlias("mykey"), "imported");
636 testFail("no\n", "-keystore x.jks -storepass changeit -importcert -file nonexist");
637 testFail("no\n", "-keystore x.jks -storepass changeit -importcert -file x.jks");
638 remove("x.jks");
639 }
640 // keyclone: exist. nonexist err, cert err, dest exist, misc
641 void sqeKeyclonetest() throws Exception {
642 remove("x.jks");
643 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
644 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -new newpass -keyclone -dest p0"); // new pass
645 testOK("\n", "-keystore x.jks -storepass changeit -keypass changeit -keyclone -dest p1"); // new pass
646 testOK("\n", "-keystore x.jks -storepass changeit -keyclone -dest p2");
647 testFail("\n", "-keystore x.jks -storepass changeit -keyclone -dest p2");
648 testFail("\n", "-keystore x.jks -storepass changeit -keyclone -dest p3 -alias noexist");
649 // no cert
650 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
651 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
652 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
653 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -new newpass -keyclone -dest p0"); // new pass
654 remove("x.jks");
655 }
656 // keypasswd: exist, short, nonexist err, cert err, misc
657 void sqeKeypasswdTest() 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 -keypass changeit -keypasswd -new newpass");
661 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
662 testOK("newpass\nnewpass\n", "-keystore x.jks -storepass changeit -keypass changeit -keypasswd");
663 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
664 testOK("new\nnew\nnewpass\nnewpass\n", "-keystore x.jks -storepass changeit -keypass changeit -keypasswd");
665 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
666 testOK("", "-keystore x.jks -storepass changeit -keypasswd -new newpass");
667 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
668 testOK("changeit\n", "-keystore x.jks -keypasswd -new newpass");
669 /*change back*/ testOK("", "-keystore x.jks -storepass changeit -keypass newpass -keypasswd -new changeit");
670 testFail("", "-keystore x.jks -storepass badpass -keypass changeit -keypasswd -new newpass");
671 testFail("", "-keystore x.jks -storepass changeit -keypass bad -keypasswd -new newpass");
672 // no cert
673 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
674 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
675 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
676 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -keypasswd -new newpass");
677 // diff pass
678 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
679 testOK("", "-keystore x.jks -storepass changeit -keypass keypass -genkeypair -dname CN=olala");
680 testFail("", "-keystore x.jks -storepass changeit -keypasswd -new newpass");
681 testOK("keypass\n", "-keystore x.jks -storepass changeit -keypasswd -new newpass");
682 // i hate those misc test
683 remove("x.jks");
684 }
685 // list: -f -alias, exist, nonexist err; otherwise, check all shows, -rfc shows more, and misc
686 void sqeListTest() throws Exception {
687 remove("x.jks");
688 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
689 testOK("", "-keystore x.jks -storepass changeit -list");
690 testOK("", "-keystore x.jks -storepass changeit -list -alias mykey");
691 testFail("", "-keystore x.jks -storepass changeit -list -alias notexist");
692 testFail("", "-keystore x.jks -storepass badpass -list -alias mykey");
693 testOK("", "-keystore x.jks -storepass changeit -keypass badpass -list -alias mykey"); // keypass ignore
694 testOK("\n", "-keystore x.jks -list");
695 assertTrue(err.indexOf("WARNING") != -1, "no storepass");
696 testOK("changeit\n", "-keystore x.jks -list");
697 assertTrue(err.indexOf("WARNING") == -1, "has storepass");
698 testFail("badpass\n", "-keystore x.jks -list");
699 // misc
700 testFail("", "-keystore aa\\bb//cc -storepass changeit -list");
701 testFail("", "-keystore nonexisting -storepass changeit -list");
702 testFail("", "-keystore badkeystore -storepass changeit -list");
703 remove("x.jks");
704 }
705 // selfcert: exist, non-exist err, cert err, sig..., dname, wrong keypass, misc
706 void sqeSelfCertTest() throws Exception {
707 remove("x.jks");
708 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
709 testOK("", "-keystore x.jks -storepass changeit -selfcert");
710 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert");
711 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert -alias nonexisting"); // not exist
712 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert -dname CN=NewName");
713 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -selfcert -sigalg MD5withRSA"); // sig not compatible
714 testFail("", "-keystore x.jks -storepass wrong -keypass changeit -selfcert"); // bad pass
715 testFail("", "-keystore x.jks -storepass changeit -keypass wrong -selfcert"); // bad pass
716 //misc
717 testFail("", "-keystore nonexist -storepass changeit -keypass changeit -selfcert");
718 testFail("", "-keystore aa//dd\\gg -storepass changeit -keypass changeit -selfcert");
719 // diff pass
720 remove("x.jks");
721 testOK("", "-keystore x.jks -storepass changeit -keypass keypass -genkeypair -dname CN=olala");
722 testFail("", "-keystore x.jks -storepass changeit -selfcert");
723 testOK("keypass\n", "-keystore x.jks -storepass changeit -selfcert");
724
725 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
726 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
727 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
728 testFail("", "-keystore x.jks -storepass changeit -selfcert"); // certentry cannot do selfcert
729 remove("x.jks");
730 }
731 // storepass: bad old, short new, misc
732 void sqeStorepassTest() throws Exception {
733 remove("x.jks");
734 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
735 testOK("", "-storepasswd -keystore x.jks -storepass changeit -new newstore"); // all in arg
736 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
737 testOK("changeit\nnewstore\nnewstore\n", "-storepasswd -keystore x.jks"); // all not in arg, new twice
738 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
739 testOK("changeit\n", "-storepasswd -keystore x.jks -new newstore"); // new in arg
740 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
741 testOK("newstore\nnewstore\n", "-storepasswd -keystore x.jks -storepass changeit"); // old in arg
742 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
743 testOK("new\nnew\nnewstore\nnewstore\n", "-storepasswd -keystore x.jks -storepass changeit"); // old in arg
744 /* Change back */ testOK("", "-storepasswd -keystore x.jks -storepass newstore -new changeit");
745 testFail("", "-storepasswd -keystore x.jks -storepass badold -new newstore"); // bad old
746 testFail("", "-storepasswd -keystore x.jks -storepass changeit -new new"); // short new
747 // misc
748 testFail("", "-storepasswd -keystore nonexist -storepass changeit -new newstore"); // non exist
749 testFail("", "-storepasswd -keystore badkeystore -storepass changeit -new newstore"); // bad file
750 testFail("", "-storepasswd -keystore aa\\bb//cc//dd -storepass changeit -new newstore"); // bad file
751 remove("x.jks");
752 }
753
754 void sqeGenkeyTest() throws Exception {
755
756 remove("x.jks");
757 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
758 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
759 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias newentry");
760 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias newentry");
761 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg DSA -alias n1");
762 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -alias n2");
763 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg NoSuchAlg -alias n3");
764 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 56 -alias n4");
765 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 999 -alias n5");
766 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 512 -alias n6");
767 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 1024 -alias n7");
768 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -sigalg NoSuchAlg -alias n8");
769 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg MD2withRSA -alias n9");
770 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg MD5withRSA -alias n10");
771 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg SHA1withRSA -alias n11");
772 testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA -sigalg NoSuchAlg -alias n12");
773 testFail("", "-keystore badkeystore -storepass changeit -keypass changeit -genkeypair -dname CN=olala -alias n14");
774 testFail("", "-keystore x.jks -storepass badpass -keypass changeit -genkeypair -dname CN=olala -alias n16");
775 testFail("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CNN=olala -alias n17");
776 remove("x.jks");
777 }
778
779 void sqeExportTest() throws Exception {
780 remove("x.jks");
781 testFail("", "-keystore x.jks -storepass changeit -export -file mykey.cert -alias mykey"); // nonexist
782 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
783 testOK("", "-keystore x.jks -storepass changeit -export -file mykey.cert -alias mykey");
784 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
785 testOK("", "-keystore x.jks -storepass changeit -import -file mykey.cert -noprompt -alias c1");
786 testOK("", "-keystore x.jks -storepass changeit -export -file mykey.cert2 -alias c1");
787 testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -export -file mykey.cert2 -alias c1");
788 testFail("", "-keystore nonexistkeystore -storepass changeit -export -file mykey.cert2 -alias c1");
789 testFail("", "-keystore badkeystore -storepass changeit -export -file mykey.cert2 -alias c1");
790 testFail("", "-keystore x.jks -storepass badpass -export -file mykey.cert2 -alias c1");
791 remove("mykey.cert");
792 remove("mykey.cert2");
793 remove("x.jks");
794 }
795
796 void sqeDeleteTest() throws Exception {
797 remove("x.jks");
798 testFail("", "-keystore x.jks -storepass changeit -delete -alias mykey"); // nonexist
799 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
800 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
801 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
802 testFail("", "-keystore aa\\bb//cc\\dd -storepass changeit -delete -alias mykey"); // keystore name illegal
803 testFail("", "-keystore nonexistkeystore -storepass changeit -delete -alias mykey"); // keystore not exist
804 testFail("", "-keystore badkeystore -storepass changeit -delete -alias mykey"); // keystore invalid
805 testFail("", "-keystore x.jks -storepass xxxxxxxx -delete -alias mykey"); // wrong pass
806 remove("x.jks");
807 }
808
809 void sqeCsrTest() throws Exception {
810 remove("x.jks");
811 remove("x.jks.p1.cert");
812 remove("csr1");
813 // PrivateKeyEntry can do certreq
814 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keysize 1024");
815 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -alias mykey");
816 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1");
817 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg SHA1withDSA");
818 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg MD5withRSA"); // unmatched sigalg
819 // misc test
820 testFail("", "-keystore x.jks -storepass badstorepass -certreq -file csr1"); // bad storepass
821 testOK("changeit\n", "-keystore x.jks -certreq -file csr1"); // storepass from terminal
822 testFail("\n", "-keystore x.jks -certreq -file csr1"); // must provide storepass
823 testFail("", "-keystore x.jks -storepass changeit -keypass badkeypass -certreq -file csr1"); // bad keypass
824 testFail("", "-keystore x.jks -storepass changeit -certreq -file aa\\bb//cc\\dd"); // bad filepath
825 testFail("", "-keystore noexistks -storepass changeit -certreq -file csr1"); // non-existing keystore
826 // Try the RSA private key
827 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
828 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala -keyalg RSA");
829 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -alias mykey");
830 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1");
831 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg SHA1withDSA"); // unmatched sigalg
832 testOK("", "-keystore x.jks -storepass changeit -certreq -file csr1 -sigalg MD5withRSA");
833 // TrustedCertificateEntry cannot do certreq
834 testOK("", "-keystore x.jks -storepass changeit -exportcert -file x.jks.p1.cert");
835 testOK("", "-keystore x.jks -storepass changeit -delete -alias mykey");
836 testOK("", "-keystore x.jks -storepass changeit -importcert -file x.jks.p1.cert -noprompt");
837 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1 -alias mykey");
838 testFail("", "-keystore x.jks -storepass changeit -certreq -file csr1");
839 remove("x.jks");
840 remove("x.jks.p1.cert");
841 remove("csr1");
842 }
843
844 void sqePrintcertTest() throws Exception {
845 remove("x.jks");
846 remove("mykey.cert");
847 testOK("", "-keystore x.jks -storepass changeit -keypass changeit -genkeypair -dname CN=olala");
848 testOK("", "-keystore x.jks -storepass changeit -export -file mykey.cert -alias mykey");
849 testFail("", "-printcert -file badkeystore");
850 testFail("", "-printcert -file a/b/c/d");
851 testOK("", "-printcert -file mykey.cert");
852 FileInputStream fin = new FileInputStream("mykey.cert");
853 testOK(fin, "-printcert");
854 fin.close();
855 remove("x.jks");
856 remove("mykey.cert");
857 }
858
859 // 8074935: jdk8 keytool doesn't validate pem files for RFC 1421 correctness
860 static void checkPem(String file) throws Exception {
861 boolean maybeLast = false;
862 for (String s: Files.readAllLines(Paths.get(file))) {
863 if (s.isEmpty()) continue;
864 if (s.startsWith("---")) continue;
865 if (maybeLast) {
866 throw new Exception("Last line already seen");
867 }
868 if (s.length() > 64) {
869 throw new Exception(s);
870 }
871 if (s.length() < 64) {
872 maybeLast = true;
873 }
874 }
875 }
876
877 void v3extTest(String keyAlg) throws Exception {
878 KeyStore ks;
879 remove("x.jks");
880 String simple = "-keystore x.jks -storepass changeit -keypass changeit -noprompt -keyalg " + keyAlg + " ";
881 String pre = simple + "-genkeypair -dname CN=Olala -alias ";
882
883 // Version and SKID
884 testOK("", pre + "o1");
885
886 ks = loadStore("x.jks", "changeit", "JKS");
887 assertTrue(((X509Certificate)ks.getCertificate("o1")).getVersion() == 3);
888 assertTrue(((X509CertImpl)ks.getCertificate("o1")).getSubjectKeyIdentifierExtension() != null);
889
890 // BC
891 testOK("", pre + "b1 -ext BC:critical");
892 testOK("", pre + "b2 -ext BC");
893 testOK("", pre + "b3 -ext bc");
894 testOK("", pre + "b4 -ext BasicConstraints");
895 testOK("", pre + "b5 -ext basicconstraints");
896 testOK("", pre + "b6 -ext BC=ca:true,pathlen:12");
897 testOK("", pre + "b7 -ext BC=ca:false");
898 testOK("", pre + "b8 -ext BC:critical=ca:false");
899 testOK("", pre + "b9 -ext BC=12");
900
901 ks = loadStore("x.jks", "changeit", "JKS");
902 assertTrue(((X509CertImpl)ks.getCertificate("b1")).getBasicConstraintsExtension().isCritical());
903 assertTrue(!((X509CertImpl)ks.getCertificate("b2")).getBasicConstraintsExtension().isCritical());
904 assertTrue(((X509CertImpl)ks.getCertificate("b8")).getBasicConstraintsExtension().isCritical());
905 assertTrue(((X509Certificate)ks.getCertificate("b1")).getBasicConstraints() == Integer.MAX_VALUE);
906 assertTrue(((X509Certificate)ks.getCertificate("b2")).getBasicConstraints() == Integer.MAX_VALUE);
907 assertTrue(((X509Certificate)ks.getCertificate("b3")).getBasicConstraints() == Integer.MAX_VALUE);
908 assertTrue(((X509Certificate)ks.getCertificate("b4")).getBasicConstraints() == Integer.MAX_VALUE);
909 assertTrue(((X509Certificate)ks.getCertificate("b5")).getBasicConstraints() == Integer.MAX_VALUE);
910 assertTrue(((X509Certificate)ks.getCertificate("b6")).getBasicConstraints() == 12);
911 assertTrue(((X509Certificate)ks.getCertificate("b7")).getBasicConstraints() == -1);
912 assertTrue(((X509Certificate)ks.getCertificate("b9")).getBasicConstraints() == 12);
913
914 // KU
915 testOK("", pre + "ku1 -ext KeyUsage:critical=digitalsignature");
916 testOK("", pre + "ku2 -ext KU=digitalSignature");
917 testOK("", pre + "ku3 -ext KU=ds");
918 testOK("", pre + "ku4 -ext KU=dig");
919 testFail("", pre + "ku5 -ext KU=d"); // ambigous value
920 testFail("", pre + "ku6 -ext KU=cs"); // cRLSign cannot be cs
921 testOK("", pre + "ku11 -ext KU=nr");
922 testFail("", pre + "ku12 -ext KU=ke"); // ke also means keyAgreement
923 testOK("", pre + "ku12 -ext KU=keyE");
924 testFail("", pre + "ku13 -ext KU=de"); // de also means decipherOnly
925 testOK("", pre + "ku13 -ext KU=dataE");
926 testOK("", pre + "ku14 -ext KU=ka");
927 testOK("", pre + "ku15 -ext KU=kcs");
928 testOK("", pre + "ku16 -ext KU=crls");
929 testOK("", pre + "ku17 -ext KU=eo");
930 testOK("", pre + "ku18 -ext KU=do");
931 testOK("", pre + "ku19 -ext KU=cc");
932
933 testOK("", pre + "ku017 -ext KU=ds,cc,eo");
934 testOK("", pre + "ku135 -ext KU=nr,dataEncipherment,keyCertSign");
935 testOK("", pre + "ku246 -ext KU=keyEnc,cRL,keyA");
936 testOK("", pre + "ku1234 -ext KU=ka,da,keyE,nonR");
937
938 ks = loadStore("x.jks", "changeit", "JKS");
939 class CheckKU {
940 void check(KeyStore ks, String alias, int... pos) throws Exception {
941 System.err.print("x");
942 boolean[] bs = ((X509Certificate)ks.getCertificate(alias)).getKeyUsage();
943 bs = Arrays.copyOf(bs, 9);
944 for (int i=0; i<bs.length; i++) {
945 boolean found = false;
946 for (int p: pos) {
947 if (p == i) found = true;
948 }
949 if (!found ^ bs[i]) {
950 // OK
951 } else {
952 throw new RuntimeException("KU not match at " + i +
953 ": " + found + " vs " + bs[i]);
954 }
955 }
956 }
957 }
958 CheckKU c = new CheckKU();
959 assertTrue(((X509CertImpl)ks.getCertificate("ku1")).getExtension(PKIXExtensions.KeyUsage_Id).isCritical());
960 assertTrue(!((X509CertImpl)ks.getCertificate("ku2")).getExtension(PKIXExtensions.KeyUsage_Id).isCritical());
961 c.check(ks, "ku1", 0);
962 c.check(ks, "ku2", 0);
963 c.check(ks, "ku3", 0);
964 c.check(ks, "ku4", 0);
965 c.check(ks, "ku11", 1);
966 c.check(ks, "ku12", 2);
967 c.check(ks, "ku13", 3);
968 c.check(ks, "ku14", 4);
969 c.check(ks, "ku15", 5);
970 c.check(ks, "ku16", 6);
971 c.check(ks, "ku17", 7);
972 c.check(ks, "ku18", 8);
973 c.check(ks, "ku19", 1);
974 c.check(ks, "ku11", 1);
975 c.check(ks, "ku11", 1);
976 c.check(ks, "ku11", 1);
977 c.check(ks, "ku017", 0, 1, 7);
978 c.check(ks, "ku135", 1, 3, 5);
979 c.check(ks, "ku246", 6, 2, 4);
980 c.check(ks, "ku1234", 1, 2, 3, 4);
981
982 // EKU
983 testOK("", pre + "eku1 -ext EKU:critical=sa");
984 testOK("", pre + "eku2 -ext ExtendedKeyUsage=ca");
985 testOK("", pre + "eku3 -ext EKU=cs");
986 testOK("", pre + "eku4 -ext EKU=ep");
987 testOK("", pre + "eku8 -ext EKU=ts");
988 testFail("", pre + "eku9 -ext EKU=os");
989 testOK("", pre + "eku9 -ext EKU=ocsps");
990 testOK("", pre + "eku10 -ext EKU=any");
991 testOK("", pre + "eku11 -ext EKU=1.2.3.4,1.3.5.7,ep");
992 testFail("", pre + "eku12 -ext EKU=c");
993 testFail("", pre + "eku12 -ext EKU=nothing");
994
995 ks = loadStore("x.jks", "changeit", "JKS");
996 class CheckEKU {
997 void check(KeyStore ks, String alias, String... pos) throws Exception {
998 System.err.print("x");
999 List<String> bs = ((X509Certificate)ks.getCertificate(alias)).getExtendedKeyUsage();
1000 int found = 0;
1001 for (String p: pos) {
1002 if (bs.contains(p)) {
1003 found++;
1004 } else {
1005 throw new RuntimeException("EKU: not included " + p);
1006 }
1007 }
1008 if (found != bs.size()) {
1009 throw new RuntimeException("EKU: more items than expected");
1010 }
1011 }
1012 }
1013 CheckEKU cx = new CheckEKU();
1014 assertTrue(((X509CertImpl)ks.getCertificate("eku1")).getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical());
1015 assertTrue(!((X509CertImpl)ks.getCertificate("eku2")).getExtension(PKIXExtensions.ExtendedKeyUsage_Id).isCritical());
1016 cx.check(ks, "eku1", "1.3.6.1.5.5.7.3.1");
1017 cx.check(ks, "eku2", "1.3.6.1.5.5.7.3.2");
1018 cx.check(ks, "eku3", "1.3.6.1.5.5.7.3.3");
1019 cx.check(ks, "eku4", "1.3.6.1.5.5.7.3.4");
1020 cx.check(ks, "eku8", "1.3.6.1.5.5.7.3.8");
1021 cx.check(ks, "eku9", "1.3.6.1.5.5.7.3.9");
1022 cx.check(ks, "eku10", "2.5.29.37.0");
1023 cx.check(ks, "eku11", "1.3.6.1.5.5.7.3.4", "1.2.3.4", "1.3.5.7");
1024
1025 // SAN
1026 testOK("", pre+"san1 -ext san:critical=email:me@me.org");
1027 testOK("", pre+"san2 -ext san=uri:http://me.org");
1028 testOK("", pre+"san3 -ext san=dns:me.org");
1029 testOK("", pre+"san4 -ext san=ip:192.168.0.1");
1030 testOK("", pre+"san5 -ext san=oid:1.2.3.4");
1031 testOK("", pre+"san6 -ext san=dns:1abc.com"); //begin with digit
1032 testOK("", pre+"san235 -ext san=uri:http://me.org,dns:me.org,oid:1.2.3.4");
1033
1034 ks = loadStore("x.jks", "changeit", "JKS");
1035 class CheckSAN {
1036 // Please sort items with name type
1037 void check(KeyStore ks, String alias, int type, Object... items) throws Exception {
1038 int pos = 0;
1039 System.err.print("x");
1040 Object[] names = null;
1041 if (type == 0) names = ((X509Certificate)ks.getCertificate(alias)).getSubjectAlternativeNames().toArray();
1042 else names = ((X509Certificate)ks.getCertificate(alias)).getIssuerAlternativeNames().toArray();
1043 Arrays.sort(names, new Comparator() {
1044 public int compare(Object o1, Object o2) {
1045 int i1 = (Integer)((List)o1).get(0);
1046 int i2 = (Integer)((List)o2).get(0);
1047 return i1 - i2;
1048 }
1049 });
1050 for (Object o: names) {
1051 List l = (List)o;
1052 for (Object o2: l) {
1053 if (!items[pos++].equals(o2)) {
1054 throw new RuntimeException("Not equals at " + pos
1055 + ": " + items[pos-1] + " vs " + o2);
1056 }
1057 }
1058 }
1059 if (pos != items.length) {
1060 throw new RuntimeException("Extra items, pos is " + pos);
1061 }
1062 }
1063 }
1064 CheckSAN csan = new CheckSAN();
1065 assertTrue(((X509CertImpl)ks.getCertificate("san1")).getSubjectAlternativeNameExtension().isCritical());
1066 assertTrue(!((X509CertImpl)ks.getCertificate("san2")).getSubjectAlternativeNameExtension().isCritical());
1067 csan.check(ks, "san1", 0, 1, "me@me.org");
1068 csan.check(ks, "san2", 0, 6, "http://me.org");
1069 csan.check(ks, "san3", 0, 2, "me.org");
1070 csan.check(ks, "san4", 0, 7, "192.168.0.1");
1071 csan.check(ks, "san5", 0, 8, "1.2.3.4");
1072 csan.check(ks, "san235", 0, 2, "me.org", 6, "http://me.org", 8, "1.2.3.4");
1073
1074 // IAN
1075 testOK("", pre+"ian1 -ext ian:critical=email:me@me.org");
1076 testOK("", pre+"ian2 -ext ian=uri:http://me.org");
1077 testOK("", pre+"ian3 -ext ian=dns:me.org");
1078 testOK("", pre+"ian4 -ext ian=ip:192.168.0.1");
1079 testOK("", pre+"ian5 -ext ian=oid:1.2.3.4");
1080 testOK("", pre+"ian235 -ext ian=uri:http://me.org,dns:me.org,oid:1.2.3.4");
1081
1082 ks = loadStore("x.jks", "changeit", "JKS");
1083 assertTrue(((X509CertImpl)ks.getCertificate("ian1")).getIssuerAlternativeNameExtension().isCritical());
1084 assertTrue(!((X509CertImpl)ks.getCertificate("ian2")).getIssuerAlternativeNameExtension().isCritical());
1085 csan.check(ks, "ian1", 1, 1, "me@me.org");
1086 csan.check(ks, "ian2", 1, 6, "http://me.org");
1087 csan.check(ks, "ian3", 1, 2, "me.org");
1088 csan.check(ks, "ian4", 1, 7, "192.168.0.1");
1089 csan.check(ks, "ian5", 1, 8, "1.2.3.4");
1090 csan.check(ks, "ian235", 1, 2, "me.org", 6, "http://me.org", 8, "1.2.3.4");
1091
1092 // SIA
1093 testOK("", pre+"sia1 -ext sia=care:uri:ldap://ca.com/cn=CA");
1094 testOK("", pre+"sia2 -ext sia=ts:email:ts@ca.com");
1095 testFail("SIA never critical", pre+"sia3 -ext sia:critical=ts:email:ts@ca.com");
1096
1097 ks = loadStore("x.jks", "changeit", "JKS");
1098 class CheckSia {
1099 void check(KeyStore ks, String alias, int type, Object... items) throws Exception {
1100 int pos = 0;
1101 System.err.print("x");
1102 AccessDescription[] ads = null;
1103 if (type == 0) {
1104 SubjectInfoAccessExtension siae = (SubjectInfoAccessExtension)((X509CertImpl)ks.getCertificate(alias)).getExtension(PKIXExtensions.SubjectInfoAccess_Id);
1105 ads = siae.getAccessDescriptions().toArray(new AccessDescription[0]);
1106 } else {
1107 AuthorityInfoAccessExtension aiae = (AuthorityInfoAccessExtension)((X509CertImpl)ks.getCertificate(alias)).getExtension(PKIXExtensions.AuthInfoAccess_Id);
1108 ads = aiae.getAccessDescriptions().toArray(new AccessDescription[0]);
1109 }
1110 Arrays.sort(ads, new Comparator<AccessDescription>() {
1111 @Override
1112 public int compare(AccessDescription o1, AccessDescription o2) {
1113 return o1.getAccessMethod().toString().compareTo(o2.getAccessMethod().toString());
1114 }
1115 });
1116 for (AccessDescription ad: ads) {
1117 if (!ad.getAccessMethod().equals(items[pos++]) ||
1118 !new Integer(ad.getAccessLocation().getType()).equals(items[pos++])) {
1119 throw new RuntimeException("Not same type at " + pos);
1120 }
1121 String name = null;
1122 switch (ad.getAccessLocation().getType()) {
1123 case 1:
1124 name = ((RFC822Name)ad.getAccessLocation().getName()).getName();
1125 break;
1126 case 6:
1127 name = ((URIName)ad.getAccessLocation().getName()).getURI().toString();
1128 break;
1129 default:
1130 throw new RuntimeException("Not implemented: " + ad);
1131 }
1132 if (!name.equals(items[pos++])) {
1133 throw new Exception("Name not same for " + ad + " at pos " + pos);
1134 }
1135 }
1136 }
1137 }
1138 CheckSia csia = new CheckSia();
1139 assertTrue(!((X509CertImpl)ks.getCertificate("sia1")).getExtension(PKIXExtensions.SubjectInfoAccess_Id).isCritical());
1140 csia.check(ks, "sia1", 0, AccessDescription.Ad_CAREPOSITORY_Id, 6, "ldap://ca.com/cn=CA");
1141 csia.check(ks, "sia2", 0, AccessDescription.Ad_TIMESTAMPING_Id, 1, "ts@ca.com");
1142
1143 // AIA
1144 testOK("", pre+"aia1 -ext aia=cai:uri:ldap://ca.com/cn=CA");
1145 testOK("", pre+"aia2 -ext aia=ocsp:email:ocsp@ca.com");
1146 testFail("AIA never critical", pre+"aia3 -ext aia:critical=ts:email:ts@ca.com");
1147
1148 ks = loadStore("x.jks", "changeit", "JKS");
1149 assertTrue(!((X509CertImpl)ks.getCertificate("aia1")).getExtension(PKIXExtensions.AuthInfoAccess_Id).isCritical());
1150 csia.check(ks, "aia1", 1, AccessDescription.Ad_CAISSUERS_Id, 6, "ldap://ca.com/cn=CA");
1151 csia.check(ks, "aia2", 1, AccessDescription.Ad_OCSP_Id, 1, "ocsp@ca.com");
1152
1153 // OID
1154 testOK("", pre+"oid1 -ext 1.2.3:critical=0102");
1155 testOK("", pre+"oid2 -ext 1.2.3");
1156 testOK("", pre+"oid12 -ext 1.2.3 -ext 1.2.4=01:02:03");
1157
1158 ks = loadStore("x.jks", "changeit", "JKS");
1159 class CheckOid {
1160 void check(KeyStore ks, String alias, String oid, byte[] value) throws Exception {
1161 int pos = 0;
1162 System.err.print("x");
1163 Extension ex = ((X509CertImpl)ks.getCertificate(alias)).getExtension(new ObjectIdentifier(oid));
1164 if (!Arrays.equals(value, ex.getValue())) {
1165 throw new RuntimeException("Not same content in " + alias + " for " + oid);
1166 }
1167 }
1168 }
1169 CheckOid coid = new CheckOid();
1170 assertTrue(((X509CertImpl)ks.getCertificate("oid1")).getExtension(new ObjectIdentifier("1.2.3")).isCritical());
1171 assertTrue(!((X509CertImpl)ks.getCertificate("oid2")).getExtension(new ObjectIdentifier("1.2.3")).isCritical());
1172 coid.check(ks, "oid1", "1.2.3", new byte[]{1,2});
1173 coid.check(ks, "oid2", "1.2.3", new byte[]{});
1174 coid.check(ks, "oid12", "1.2.3", new byte[]{});
1175 coid.check(ks, "oid12", "1.2.4", new byte[]{1,2,3});
1176
1177 // honored
1178 testOK("", pre+"ca");
1179 testOK("", pre+"a");
1180 // request: BC,KU,1.2.3,1.2.4,1.2.5
1181 testOK("", simple+"-alias a -certreq " +
1182 "-ext BC=1 -ext KU=crl " +
1183 "-ext 1.2.3=01 -ext 1.2.4:critical=0102 -ext 1.2.5=010203 " +
1184 "-rfc -file test.req");
1185 // printcertreq
1186 testOK("", "-printcertreq -file test.req");
1187 checkPem("test.req");
1188 // issue: deny KU, change criticality of 1.2.3 and 1.2.4,
1189 // change content of BC, add 2.3.4
1190 testOK("", simple+"-gencert -alias ca -infile test.req -ext " +
1191 "honored=all,-KU,1.2.3:critical,1.2.4:non-critical " +
1192 "-ext BC=2 -ext 2.3.4=01020304 " +
1193 "-debug -rfc -outfile test.cert");
1194 checkPem("test.cert");
1195 testOK("", simple+"-importcert -file test.cert -alias a");
1196 ks = loadStore("x.jks", "changeit", "JKS");
1197 X509CertImpl a = (X509CertImpl)ks.getCertificate("a");
1198 assertTrue(a.getAuthorityKeyIdentifierExtension() != null);
1199 assertTrue(a.getSubjectKeyIdentifierExtension() != null);
1200 assertTrue(a.getKeyUsage() == null);
1201 assertTrue(a.getExtension(new ObjectIdentifier("1.2.3")).isCritical());
1202 assertTrue(!a.getExtension(new ObjectIdentifier("1.2.4")).isCritical());
1203 assertTrue(!a.getExtension(new ObjectIdentifier("1.2.5")).isCritical());
1204 assertTrue(a.getExtensionValue("1.2.3").length == 3);
1205 assertTrue(a.getExtensionValue("1.2.4").length == 4);
1206 assertTrue(a.getExtensionValue("1.2.5").length == 5);
1207 assertTrue(a.getBasicConstraints() == 2);
1208 assertTrue(!a.getExtension(new ObjectIdentifier("2.3.4")).isCritical());
1209 assertTrue(a.getExtensionValue("2.3.4").length == 6);
1210
1211 remove("x.jks");
1212 remove("test.req");
1213 remove("test.cert");
1214 }
1215
1216 void i18nTest() throws Exception {
1217 // 1. keytool -help
1218 remove("x.jks");
1219 testOK("", "-help");
1220
1221 // 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.
1222 testOK("a\npassword\npassword\nMe\nHere\nNow\nPlace\nPlace\nUS\nyes\n\n", "-genkey -v -keysize 512 -keystore x.jks");
1223 // 3. keytool -list -v -storepass password
1224 testOK("", "-list -v -storepass password -keystore x.jks");
1225 // 4. keytool -list -v Type "a" for the keystore password. Check error (wrong keystore password).
1226 testFail("a\n", "-list -v -keystore x.jks");
1227 assertTrue(ex.indexOf("password was incorrect") != -1);
1228 // 5. keytool -genkey -v -keysize 512 Enter "password" as the password. Check error (alias 'mykey' already exists).
1229 testFail("password\n", "-genkey -v -keysize 512 -keystore x.jks");
1230 assertTrue(ex.indexOf("alias <mykey> already exists") != -1);
1231 // 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.
1232 testOK("\n\n\n\n\n\nyes\n\n", "-genkey -v -keysize 512 -alias mykey2 -storepass password -keystore x.jks");
1233 // 7. keytool -list -v Type 'password' for the store password.
1234 testOK("password\n", "-list -v -keystore x.jks");
1235 // 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).
1236 testFail("a\naaaaaa\nbbbbbb\na\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks");
1237 assertTrue(ex.indexOf("Too many failures - try later") != -1);
1238 // 9. keytool -keypasswd -v -alias mykey2 -storepass password Type "aaaaaa" for the new key password. Type "aaaaaa" when re-entering the new key password.
1239 testOK("aaaaaa\naaaaaa\n", "-keypasswd -v -alias mykey2 -storepass password -keystore x.jks");
1240 // 10. keytool -selfcert -v -alias mykey -storepass password
1241 testOK("", "-selfcert -v -alias mykey -storepass password -keystore x.jks");
1242 // 11. keytool -list -v -storepass password
1243 testOK("", "-list -v -storepass password -keystore x.jks");
1244 // 12. keytool -export -v -alias mykey -file cert -storepass password
1245 remove("cert");
1246 testOK("", "-export -v -alias mykey -file cert -storepass password -keystore x.jks");
1247 // 13. keytool -import -v -file cert -storepass password Check error (Certificate reply and cert are the same)
1248 testFail("", "-import -v -file cert -storepass password -keystore x.jks");
1249 assertTrue(ex.indexOf("Certificate reply and certificate in keystore are identical") != -1);
1250 // 14. keytool -printcert -file cert
1251 testOK("", "-printcert -file cert -keystore x.jks");
1252 remove("cert");
1253 // 15. keytool -list -storepass password -provider sun.security.provider.Sun
1254 testOK("", "-list -storepass password -provider sun.security.provider.Sun -keystore x.jks");
1255
1256 //Error tests
1257
1258 // 1. keytool -storepasswd -storepass password -new abc Check error (password too short)
1259 testFail("", "-storepasswd -storepass password -new abc");
1260 assertTrue(ex.indexOf("New password must be at least 6 characters") != -1);
1261 // Changed, no NONE needed now
1262 // 2. keytool -list -storetype PKCS11 Check error (-keystore must be NONE)
1263 //testFail("", "-list -storetype PKCS11");
1264 //assertTrue(err.indexOf("keystore must be NONE") != -1);
1265 // 3. keytool -storepasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation)
1266 testFail("", "-storepasswd -storetype PKCS11 -keystore NONE");
1267 assertTrue(ex.indexOf("UnsupportedOperationException") != -1);
1268 // 4. keytool -keypasswd -storetype PKCS11 -keystore NONE Check error (unsupported operation)
1269 testFail("", "-keypasswd -storetype PKCS11 -keystore NONE");
1270 assertTrue(ex.indexOf("UnsupportedOperationException") != -1);
1271 // 5. keytool -list -protected -storepass password Check error (password can not be specified with -protected)
1272 testFail("", "-list -protected -storepass password -keystore x.jks");
1273 assertTrue(ex.indexOf("if -protected is specified, then") != -1);
1274 // 6. keytool -keypasswd -protected -keypass password Check error (password can not be specified with -protected)
1275 testFail("", "-keypasswd -protected -keypass password -keystore x.jks");
1276 assertTrue(ex.indexOf("if -protected is specified, then") != -1);
1277 // 7. keytool -keypasswd -protected -new password Check error (password can not be specified with -protected)
1278 testFail("", "-keypasswd -protected -new password -keystore x.jks");
1279 assertTrue(ex.indexOf("if -protected is specified, then") != -1);
1280 remove("x.jks");
1281 }
1282
1283 void i18nPKCS11Test() throws Exception {
1284 //PKCS#11 tests
1285
1286 // 1. sccs edit cert8.db key3.db
1287 //Runtime.getRuntime().exec("/usr/ccs/bin/sccs edit cert8.db key3.db");
1288 testOK("", p11Arg + "-storepass test12 -genkey -alias genkey -dname cn=genkey -keysize 512 -keyalg rsa");
1289 testOK("", p11Arg + "-storepass test12 -list");
1290 testOK("", p11Arg + "-storepass test12 -list -alias genkey");
1291 testOK("", p11Arg + "-storepass test12 -certreq -alias genkey -file genkey.certreq");
1292 testOK("", p11Arg + "-storepass test12 -export -alias genkey -file genkey.cert");
1293 testOK("", "-printcert -file genkey.cert");
1294 testOK("", p11Arg + "-storepass test12 -selfcert -alias genkey -dname cn=selfCert");
1295 testOK("", p11Arg + "-storepass test12 -list -alias genkey -v");
1296 assertTrue(out.indexOf("Owner: CN=selfCert") != -1);
1297 //(check that cert subject DN is [cn=selfCert])
1298 testOK("", p11Arg + "-storepass test12 -delete -alias genkey");
1299 testOK("", p11Arg + "-storepass test12 -list");
1300 assertTrue(out.indexOf("Your keystore contains 0 entries") != -1);
1301 //(check for empty database listing)
1302 //Runtime.getRuntime().exec("/usr/ccs/bin/sccs unedit cert8.db key3.db");
1303 remove("genkey.cert");
1304 remove("genkey.certreq");
1305 // 12. sccs unedit cert8.db key3.db
1306 }
1307
1308 // tesing new option -srcProviderName
1309 void sszzTest() throws Exception {
1310 testAnyway("", NSS_P11_ARG+"-delete -alias nss -storepass test12");
1311 testAnyway("", NZZ_P11_ARG+"-delete -alias nss -storepass test12");
1312 testOK("", NSS_P11_ARG+"-genkeypair -dname CN=NSS -alias nss -storepass test12");
1313 testOK("", NSS_SRC_P11_ARG + NZZ_P11_ARG +
1314 "-importkeystore -srcstorepass test12 -deststorepass test12");
1315 testAnyway("", NSS_P11_ARG+"-delete -alias nss -storepass test12");
1316 testAnyway("", NZZ_P11_ARG+"-delete -alias nss -storepass test12");
1317 }
1318
1319 public static void main(String[] args) throws Exception {
1320 Locale reservedLocale = Locale.getDefault();
1321 try {
1322 // first test if HumanInputStream really acts like a human being
1323 HumanInputStream.test();
1324 KeyToolTest t = new KeyToolTest();
1325
1326 if (System.getProperty("file") != null) {
1327 t.sqeTest();
1328 t.testAll();
1329 t.i18nTest();
1330 t.v3extTest("RSA");
1331 t.v3extTest("DSA");
1332 boolean testEC = true;
1333 try {
1334 KeyPairGenerator.getInstance("EC");
1335 } catch (NoSuchAlgorithmException nae) {
1336 testEC = false;
1337 }
1338 if (testEC) t.v3extTest("EC");
1339 }
1340
1341 if (System.getProperty("nss") != null) {
1342 t.srcP11Arg = NSS_SRC_P11_ARG;
1343 t.p11Arg = NSS_P11_ARG;
1344
1345 t.testPKCS11();
1346
1347 // FAIL:
1348 // 1. we still don't have srcprovidername yet
1349 // 2. cannot store privatekey into NSS keystore
1350 // java.security.KeyStoreException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_TEMPLATE_INCOMPLETE.
1351 //t.testPKCS11ImportKeyStore();
1352
1353 t.i18nPKCS11Test();
1354 //FAIL: currently PKCS11-NSS does not support 2 NSS KeyStores to be loaded at the same time
1355 //t.sszzTest();
1356 }
1357
1358 if (System.getProperty("solaris") != null) {
1359 // For Solaris Cryptography Framework
1360 t.srcP11Arg = SUN_SRC_P11_ARG;
1361 t.p11Arg = SUN_P11_ARG;
1362 t.testPKCS11();
1363 t.testPKCS11ImportKeyStore();
1364 t.i18nPKCS11Test();
1365 }
1366
1367 System.out.println("Test pass!!!");
1368 } finally {
1369 // restore the reserved locale
1370 Locale.setDefault(reservedLocale);
1371 }
1372 }
1373 }
1374
1375 class TestException extends Exception {
1376 public TestException(String e) {
1377 super(e);
1378 }
1379 }
1380
1381 /**
1382 * HumanInputStream tries to act like a human sitting in front of a computer
1383 * terminal typing on the keyboard while the keytool program is running.
1384 *
1385 * keytool has called InputStream.read() and BufferedReader.readLine() in
1386 * various places. a call to B.readLine() will try to buffer as much input as
1387 * possible. Thus, a trivial InputStream will find it impossible to feed
1388 * anything to I.read() after a B.readLine() call.
1389 *
1390 * This is why i create HumanInputStream, which will only send a single line
1391 * to B.readLine(), no more, no less, and the next I.read() can have a chance
1392 * to read the exact character right after "\n".
1393 *
1394 * I don't know why HumanInputStream works.
1395 */
1396 class HumanInputStream extends InputStream {
1397 byte[] src;
1398 int pos;
1399 int length;
1400 boolean inLine;
1401 int stopIt;
1402
1403 public HumanInputStream(String input) {
1404 src = input.getBytes();
1405 pos = 0;
1406 length = src.length;
1407 stopIt = 0;
1408 inLine = false;
1409 }
1410
1411 // the trick: when called through read(byte[], int, int),
1412 // return -1 twice after "\n"
1413
1414 @Override public int read() throws IOException {
1415 int re;
1416 if(pos < length) {
1417 re = src[pos];
1418 if(inLine) {
1419 if(stopIt > 0) {
1420 stopIt--;
1421 re = -1;
1422 } else {
1423 if(re == '\n') {
1424 stopIt = 2;
1425 }
1426 pos++;
1427 }
1428 } else {
1429 pos++;
1430 }
1431 } else {
1432 re = -1;//throw new IOException("NO MORE TO READ");
1433 }
1434 //if (re < 32) System.err.printf("[%02d]", re);
1435 //else System.err.printf("[%c]", (char)re);
1436 return re;
1437 }
1438 @Override public int read(byte[] buffer, int offset, int len) {
1439 inLine = true;
1440 try {
1441 int re = super.read(buffer, offset, len);
1442 return re;
1443 } catch(Exception e) {
1444 throw new RuntimeException("HumanInputStream error");
1445 } finally {
1446 inLine = false;
1447 }
1448 }
1449 @Override public int available() {
1450 if(pos < length) return 1;
1451 return 0;
1452 }
1453
1454 // test part
1455 static void assertTrue(boolean bool) {
1456 if(!bool)
1457 throw new RuntimeException();
1458 }
1459
1460 public static void test() throws Exception {
1461
1462 class Tester {
1463 HumanInputStream is;
1464 BufferedReader reader;
1465 Tester(String s) {
1466 is = new HumanInputStream(s);
1467 reader = new BufferedReader(new InputStreamReader(is));
1468 }
1469
1470 // three kinds of test method
1471 // 1. read byte by byte from InputStream
1472 void testStreamReadOnce(int expection) throws Exception {
1473 assertTrue(is.read() == expection);
1474 }
1475 void testStreamReadMany(String expection) throws Exception {
1476 char[] keys = expection.toCharArray();
1477 for(int i=0; i<keys.length; i++) {
1478 assertTrue(is.read() == keys[i]);
1479 }
1480 }
1481 // 2. read a line with a newly created Reader
1482 void testReaderReadline(String expection) throws Exception {
1483 String s = new BufferedReader(new InputStreamReader(is)).readLine();
1484 if(s == null) assertTrue(expection == null);
1485 else assertTrue(s.equals(expection));
1486 }
1487 // 3. read a line with the old Reader
1488 void testReaderReadline2(String expection) throws Exception {
1489 String s = reader.readLine();
1490 if(s == null) assertTrue(expection == null);
1491 else assertTrue(s.equals(expection));
1492 }
1493 }
1494
1495 Tester test;
1496
1497 test = new Tester("111\n222\n\n444\n\n");
1498 test.testReaderReadline("111");
1499 test.testReaderReadline("222");
1500 test.testReaderReadline("");
1501 test.testReaderReadline("444");
1502 test.testReaderReadline("");
1503 test.testReaderReadline(null);
1504
1505 test = new Tester("111\n222\n\n444\n\n");
1506 test.testReaderReadline2("111");
1507 test.testReaderReadline2("222");
1508 test.testReaderReadline2("");
1509 test.testReaderReadline2("444");
1510 test.testReaderReadline2("");
1511 test.testReaderReadline2(null);
1512
1513 test = new Tester("111\n222\n\n444\n\n");
1514 test.testReaderReadline2("111");
1515 test.testReaderReadline("222");
1516 test.testReaderReadline2("");
1517 test.testReaderReadline2("444");
1518 test.testReaderReadline("");
1519 test.testReaderReadline2(null);
1520
1521 test = new Tester("1\n2");
1522 test.testStreamReadMany("1\n2");
1523 test.testStreamReadOnce(-1);
1524
1525 test = new Tester("12\n234");
1526 test.testStreamReadOnce('1');
1527 test.testReaderReadline("2");
1528 test.testStreamReadOnce('2');
1529 test.testReaderReadline2("34");
1530 test.testReaderReadline2(null);
1531
1532 test = new Tester("changeit\n");
1533 test.testStreamReadMany("changeit\n");
1534 test.testReaderReadline(null);
1535
1536 test = new Tester("changeit\nName\nCountry\nYes\n");
1537 test.testStreamReadMany("changeit\n");
1538 test.testReaderReadline("Name");
1539 test.testReaderReadline("Country");
1540 test.testReaderReadline("Yes");
1541 test.testReaderReadline(null);
1542
1543 test = new Tester("Me\nHere\n");
1544 test.testReaderReadline2("Me");
1545 test.testReaderReadline2("Here");
1546 }
1547 }
--- EOF ---