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