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