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