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 59import java.nio.file.Files; 60import java.nio.file.Paths; 61import java.security.KeyStore; 62import sun.security.x509.*; 63import java.io.*; 64import java.security.KeyPairGenerator; 65import java.security.NoSuchAlgorithmException; 66import java.util.*; 67import java.security.cert.X509Certificate; 68import sun.security.util.ObjectIdentifier; 69 70public 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 1868class 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 */ 1889class 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} 2041