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 }