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