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