/*
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6251120 8231950 8242151
* @summary Testing keytool
*
* Run through autotest.sh and manualtest.sh
*
* Testing non-PKCS11 keystores:
* echo | java -Dfile KeyToolTest
*
* Testing NSS PKCS11 keystores:
* # testing NSS
* # make sure the NSS db files are in current directory and writable
* echo | java -Dnss -Dnss.lib=/path/to/libsoftokn3.so KeyToolTest
*
* ATTENTION:
* Exception in thread "main" java.security.ProviderException:
* sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_SIZE_RANGE
* at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:420)
* ...
* Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_KEY_SIZE_RANGE
* at sun.security.pkcs11.wrapper.PKCS11.C_SignFinal(Native Method)
* at sun.security.pkcs11.P11Signature.engineSign(P11Signature.java:391)
* ...
* been observed. Possibly a Solaris bug
*
* ATTENTION:
* NSS PKCS11 config file are changed, DSA not supported now.
*
* @library /test/lib
* @modules java.base/sun.security.tools.keytool
* java.base/sun.security.util
* java.base/sun.security.x509
* @run main/othervm/timeout=600 -Dfile KeyToolTest
*/
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyStore;
import sun.security.x509.*;
import java.io.*;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.security.cert.X509Certificate;
import jdk.test.lib.util.FileUtils;
import sun.security.util.ObjectIdentifier;
public class KeyToolTest {
// The stdout and stderr outputs after a keytool run
String out;
String err;
// the output of println() in KeyTool.run
String ex;
String lastInput = "" , lastCommand = "" ;
private static final boolean debug =
System.getProperty("debug" ) != null ;
static final String NSS_P11_ARG =
"-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nss " +
"-addprovider SunPKCS11 " +
"-providerArg p11-nss.txt " ;
// Use -providerClass here, to confirm it still works for SunPKCS11.
static final String NSS_SRC_P11_ARG =
"-srckeystore NONE -srcstoretype PKCS11 " +
"-srcproviderName SunPKCS11-nss " +
"-providerClass sun.security.pkcs11.SunPKCS11 " +
"-providerArg p11-nss.txt " ;
static final String NZZ_P11_ARG =
"-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nzz " +
"-addprovider SunPKCS11 " +
"-providerArg p11-nzz.txt " ;
static final String NZZ_SRC_P11_ARG =
"-srckeystore NONE -srcstoretype PKCS11 " +
"-srcproviderName SunPKCS11-nzz " +
"-addprovider SunPKCS11 " +
"-providerArg p11-nzz.txt " ;
String p11Arg, srcP11Arg;
/** Creates a new instance of KeyToolTest */
KeyToolTest() {
// so that there is "Warning" and not translated into other language
Locale.setDefault(Locale.US);
}
/**
* Helper, removes a file
*/
void remove(String filename) {
if (debug) {
System.err.println("Removing " + filename);
}
try {
FileUtils.deleteFileIfExistsWithRetry(Paths.get(filename));
}catch (IOException e) {
throw new RuntimeException("Error deleting " + filename, e);
}
}
/**
* Run a set of keytool command with given terminal input.
* @param input the terminal inputs, the characters typed by human
* if <code>cmd</code> is running on a terminal
* @param cmd the argument of a keytool command line
* @throws if keytool goes wrong in some place
*/
void test(String input, String cmd) throws Exception {
lastInput = input;
lastCommand = cmd;
// "X" is appended so that we can precisely test how input is consumed
HumanInputStream in = new HumanInputStream(input+"X" );
test(in, cmd);
// make sure the input string is no more no less
if (in.read() != 'X' || in.read() != -1)
throw new Exception("Input not consumed exactly" );
}
void test(InputStream in, String cmd) throws Exception {
// save the original 3 streams
if (debug) {
System.err.println(cmd);
} else {
System.err.print("." );
}
PrintStream p1 = System.out;
PrintStream p2 = System.err;
InputStream i1 = System.in;
ByteArrayOutputStream b1 = new ByteArrayOutputStream();
ByteArrayOutputStream b2 = new ByteArrayOutputStream();
try {
System.setIn(in);
System.setOut(new PrintStream(b1));
System.setErr(new PrintStream(b2));
// since System.in is overrided, the
// sun.security.tools.keytool.Main.main() method will
// never block at user input
// use -debug so that main() will throw an Exception
// instead of calling System.exit()
sun.security.tools.keytool.Main.main(("-debug " +cmd).split("\\s+" ));
} finally {
out = b1.toString();
err = b2.toString();
ex = out; // now it goes to System.out
System.setIn(i1);
System.setOut(p1);
System.setErr(p2);
}
}
/**
* Call this method if you expect test(input, cmd) should go OK
*/
void testOK(String input, String cmd) throws Exception {
try {
// Workaround for "8057810: Make SHA256withDSA the default
// jarsigner and keytool algorithm for DSA keys". Unfortunately
// SunPKCS11-NSS does not support SHA256withDSA yet.
if (cmd.contains("p11-nss.txt" ) && cmd.contains("-genkey" )
&& cmd.contains("DSA" )) {
cmd += " -sigalg SHA1withDSA -keysize 1024" ;
}
test(input, cmd);
} catch (Exception e) {
afterFail(input, cmd, "OK" );
throw e;
}
}
/**
* Call this method if you expect test(input, cmd) should fail and throw
* an exception
*/
void testFail(String input, String cmd) throws Exception {
boolean ok;
try {
test(input, cmd);
ok = true ;
} catch (Exception e) {
if (e instanceof MissingResourceException) {
ok = true ;
} else {
ok = false ;
}
}
if (ok) {
afterFail(input, cmd, "FAIL" );
throw new RuntimeException();
}
}
/**
* Call this method if you expect test(input, cmd) should go OK
*/
void testOK(InputStream is, String cmd) throws Exception {
try {
test(is, cmd);
} catch (Exception e) {
afterFail("" , cmd, "OK" );
throw e;
}
}
/**
* Call this method if you expect test(input, cmd) should fail and throw
* an exception
*/
void testFail(InputStream is, String cmd) throws Exception {
boolean ok;
try {
test(is, cmd);
ok = true ;
} catch (Exception e) {
ok = false ;
}
if (ok) {
afterFail("" , cmd, "FAIL" );
throw new RuntimeException();
}
}
/**
* Call this method if you just want to run the command and does
* not care if it succeeds or fails.
*/
void testAnyway(String input, String cmd) {
try {
test(input, cmd);
} catch (Exception e) {
;
}
}
/**
* Helper method, print some output after a test does not do as expected
*/
void afterFail(String input, String cmd, String should) {
if (cmd.contains("p11-nss.txt" )) {
cmd = "-J-Dnss.lib=" + System.getProperty("nss.lib" ) + " " + cmd;
}
System.err.println("\nTest fails for the command ---\n" +
"keytool " + cmd + "\nOr its debug version ---\n" +
"keytool -debug " + cmd);
System.err.println("The command result should be " + should +
", but it's not. Try run the command manually and type" +
" these input into it: " );
char [] inputChars = input.toCharArray();
for (int i=0; i<inputChars.length; i++) {
char ch = inputChars[i];
if (ch == '\n' ) System.err.print("ENTER " );
else if (ch == ' ' ) System.err.print("SPACE " );
else System.err.print(ch + " " );
}
System.err.println("" );
System.err.println("ERR is:\n" +err);
System.err.println("OUT is:\n" +out);
}
void assertTrue(boolean bool, String msg) {
if (debug) {
System.err.println("If not " + bool + ", " + msg);
} else {
System.err.print("v" );
}
if (!bool) {
afterFail(lastInput, lastCommand, "TRUE" );
System.err.println(msg);
throw new RuntimeException(msg);
}
}
void assertTrue(boolean bool) {
assertTrue(bool, "well..." );
}
/**
* Helper method, load a keystore
* @param file file for keystore, null or "NONE" for PKCS11
* @pass password for the keystore
* @type keystore type
* @returns the KeyStore object
* @exception Exception if anything goes wrong
*/
KeyStore loadStore(String file, String pass, String type) throws Exception {
KeyStore ks = KeyStore.getInstance(type);
FileInputStream is = null ;
if (file != null && !file.equals("NONE" )) {
is = new FileInputStream(file);
}
ks.load(is, pass.toCharArray());
is.close();
return ks;
}
/**
* The test suite.
* Maybe it's better to put this outside the KeyToolTest class
*/
void testAll() throws Exception {
KeyStore ks;
remove("x.jks" );
remove("x.jceks" );
remove("x.p12" );
remove("x2.jceks" );
remove("x2.jks" );
remove("x.jks.p1.cert" );
// name changes: genkeypair, importcert, exportcert
remove("x.jks" );
remove("x.jks.p1.cert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -alias p1 -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-exportcert -alias p1 -file x.jks.p1.cert" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.getKey("p1" , "changeit" .toCharArray()) != null ,
"key not DSA" );
assertTrue(new File("x.jks.p1.cert" ).exists(), "p1 export err" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias p1" );
// importcert, prompt for Yes/No
testOK("y\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -alias c1 -file x.jks.p1.cert" );
// importcert, -noprompt
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -alias c2 -file x.jks.p1.cert -noprompt" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.getCertificate("c1" ) != null , "import c1 err" );
// v3
byte [] encoded = ks.getCertificate("c1" ).getEncoded();
X509CertImpl certImpl = new X509CertImpl(encoded);
assertTrue(certImpl.getVersion() == 3, "Version is not 3" );
// changealias and keyclone
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -alias p1 -dname CN=olala" );
testOK("changeit\n" , "-keystore x.jks -storetype JKS " +
"-changealias -alias p1 -destalias p11" );
testOK("changeit\n" , "-keystore x.jks -storetype JKS " +
"-changealias -alias c1 -destalias c11" );
// press ENTER when prompt for p111's keypass
testOK("changeit\n\n" , "-keystore x.jks -storetype JKS " +
"-keyclone -alias p11 -destalias p111" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(!ks.containsAlias("p1" ), "there is no p1" );
assertTrue(!ks.containsAlias("c1" ), "there is no c1" );
assertTrue(ks.containsAlias("p11" ), "there is p11" );
assertTrue(ks.containsAlias("c11" ), "there is c11" );
assertTrue(ks.containsAlias("p111" ), "there is p111" );
// genSecKey
remove("x.jceks" );
// DES, no need keysize
testOK("changeit\nchangeit\n\n" , "-keystore x.jceks -storetype JCEKS " +
"-genseckey -keyalg DES -alias s1" );
// DES, keysize cannot be 128
testFail("changeit\n\n" , "-keystore x.jceks -storetype JCEKS " +
"-genseckey -keyalg DES -alias s11 -keysize 128" );
// DESede. no need keysize
testOK("changeit\n\n" , "-keystore x.jceks -storetype JCEKS " +
"-genseckey -keyalg DESede -alias s2" );
// AES, need keysize
testFail("changeit\n\n" , "-keystore x.jceks -storetype AES " +
"-genseckey -keyalg Rijndael -alias s3" );
testOK("changeit\n\n" , "-keystore x.jceks -storetype JCEKS " +
"-genseckey -keyalg AES -alias s3 -keysize 128" );
// about keypass
// can accept storepass
testOK("\n" , "-keystore x.jceks -storetype JCEKS -storepass changeit " +
"-genseckey -keyalg DES -alias s4" );
// or a new one
testOK("keypass\nkeypass\n" , "-keystore x.jceks -storetype JCEKS " +
"-storepass changeit -genseckey -keyalg DES -alias s5" );
// keypass must be valid (prompt 3 times)
testOK("bad\n\bad\nkeypass\nkeypass\n" , "-keystore x.jceks " +
"-storetype JCEKS -storepass changeit -genseckey " +
"-keyalg DES -alias s6" );
// keypass must be valid (prompt 3 times)
testFail("bad\n\bad\nbad\n" , "-keystore x.jceks -storetype JCEKS " +
"-storepass changeit -genseckey -keyalg DES -alias s7" );
// keypass must be valid (prompt 3 times)
testFail("bad\n\bad\nbad\nkeypass\n" , "-keystore x.jceks " +
"-storetype JCEKS -storepass changeit -genseckey -keyalg DES -alias s7" );
ks = loadStore("x.jceks" , "changeit" , "JCEKS" );
assertTrue(ks.getKey("s1" , "changeit" .toCharArray())
.getAlgorithm().equalsIgnoreCase("DES" ), "s1 is DES" );
assertTrue(ks.getKey("s1" , "changeit" .toCharArray())
.getEncoded().length == 8, "DES is 56" );
assertTrue(ks.getKey("s2" , "changeit" .toCharArray())
.getEncoded().length == 24, "DESede is 168" );
assertTrue(ks.getKey("s2" , "changeit" .toCharArray())
.getAlgorithm().equalsIgnoreCase("DESede" ), "s2 is DESede" );
assertTrue(ks.getKey("s3" , "changeit" .toCharArray())
.getAlgorithm().equalsIgnoreCase("AES" ), "s3 is AES" );
assertTrue(ks.getKey("s4" , "changeit" .toCharArray())
.getAlgorithm().equalsIgnoreCase("DES" ), "s4 is DES" );
assertTrue(ks.getKey("s5" , "keypass" .toCharArray())
.getAlgorithm().equalsIgnoreCase("DES" ), "s5 is DES" );
assertTrue(ks.getKey("s6" , "keypass" .toCharArray())
.getAlgorithm().equalsIgnoreCase("DES" ), "s6 is DES" );
assertTrue(!ks.containsAlias("s7" ), "s7 not created" );
// maybe we needn't test this, one day JKS will support SecretKey
//testFail("changeit\nchangeit\n", "-keystore x.jks -storetype JKS " +
// "-genseckey -keyalg AES -alias s3 -keysize 128");
// importKeyStore
remove("x.jks" );
remove("x.jceks" );
// create 2 entries...
testOK("changeit\nchangeit\n\n" , "-keystore x.jceks -storetype JCEKS " +
"-genkeypair -keyalg DSA -alias p1 -dname CN=Olala" );
testOK("" , "-keystore x.jceks -storetype JCEKS -storepass changeit " +
"-importcert -alias c1 -file x.jks.p1.cert -noprompt" );
ks = loadStore("x.jceks" , "changeit" , "JCEKS" );
assertTrue(ks.size() == 2, "2 entries in JCEKS" );
// import, shouldn't mention destalias/srckeypass/destkeypass
// if srcalias is no given
testFail("changeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -destalias pp" );
testFail("changeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -srckeypass changeit" );
testFail("changeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -destkeypass changeit" );
// normal import
testOK("changeit\nchangeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 2, "2 entries in JKS" );
// import again, type yes to overwrite old entries
testOK("changeit\nchangeit\ny\ny\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
// import again, specify -nopromt
testOK("changeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -noprompt" );
assertTrue(err.indexOf("Warning" ) != -1, "noprompt will warn" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 2, "2 entries in JKS" );
// import again, type into new aliases when prompted
testOK("changeit\nchangeit\n\ns1\n\ns2\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 4, "4 entries in JKS" );
// importkeystore single
// normal
remove("x.jks" );
testOK("changeit\nchangeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -srcalias p1" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 1, "1 entries in JKS" );
// overwrite
testOK("changeit\nchangeit\ny\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -srcalias p1" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 1, "1 entries in JKS" );
// noprompt
testOK("changeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS " +
"-srcalias p1 -noprompt" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 1, "1 entries in JKS" );
// rename
testOK("changeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS " +
"-srcalias p1 -destalias p2" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 2, "2 entries in JKS" );
// another rename
testOK("changeit\nchangeit\n\nnewalias\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -srcalias p1" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 3, "3 entries in JKS" );
// importkeystore single, different keypass
remove("x.jks" );
// generate entry with different keypass
testOK("changeit\nkeypass\nkeypass\n" , "-keystore x.jceks " +
"-storetype JCEKS -genkeypair -keyalg DSA -alias p2 -dname CN=Olala" );
// prompt
testOK("changeit\nchangeit\nchangeit\nkeypass\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -srcalias p2" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 1, "1 entries in JKS" );
// diff destkeypass
testOK("changeit\nchangeit\nkeypass\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS " +
"-srcalias p2 -destalias p3 -destkeypass keypass2" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.size() == 2, "2 entries in JKS" );
assertTrue(ks.getKey("p2" , "keypass" .toCharArray()) != null ,
"p2 has old password" );
assertTrue(ks.getKey("p3" , "keypass2" .toCharArray()) != null ,
"p3 has new password" );
// importkeystore single, cert
remove("x.jks" );
// normal
testOK("changeit\nchangeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -srcalias c1" );
// in fact srcstorepass can be ignored
testOK("changeit\n\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS " +
"-srcalias c1 -destalias c2" );
assertTrue(err.indexOf("WARNING" ) != -1, "But will warn" );
// 2nd import, press y to overwrite ...
testOK("changeit\n\ny\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS " +
"-srcalias c1 -destalias c2" );
// ... or rename
testOK("changeit\n\n\nc3\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS " +
"-srcalias c1 -destalias c2" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
// c1, c2, c3
assertTrue(ks.size() == 3, "3 entries in JKS" );
// importkeystore, secretkey
remove("x.jks" );
// create SecretKeyEntry
testOK("changeit\n\n" , "-keystore x.jceks -storetype JCEKS " +
"-genseckey -keyalg DES -alias s1" );
// create SecretKeyEntry
testOK("changeit\n\n" , "-keystore x.jceks -storetype JCEKS " +
"-genseckey -keyalg DES -alias s2" );
// remove the keypass!=storepass one
testOK("changeit\n" , "-keystore x.jceks -storetype JCEKS " +
"-delete -alias p2" );
ks = loadStore("x.jceks" , "changeit" , "JCEKS" );
// p1, c1, s1, s2
assertTrue(ks.size() == 4, "4 entries in JCEKS" );
// normal
testOK("changeit\nchangeit\nchangeit\n" , "-importkeystore " +
"-srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS -srcalias s1" );
assertTrue(err.indexOf("not imported" ) != -1, "Not imported" );
assertTrue(err.indexOf("Cannot store non-PrivateKeys" ) != -1,
"Not imported" );
// Importing a JCEKS keystore to a JKS one. Will warn
// for the 2 SecretKey entries
remove("x.jks" );
// Two "no" answers to bypass warnings
// normal
testOK("\n\n" , "-srcstorepass changeit -deststorepass changeit " +
"-importkeystore -srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS" );
assertTrue(err.indexOf("s1 not" ) != -1, "s1 not" );
assertTrue(err.indexOf("s2 not" ) != -1, "s2 not" );
assertTrue(err.indexOf("c1 success" ) != -1, "c1 success" );
assertTrue(err.indexOf("p1 success" ) != -1, "p1 success" );
remove("x.jks" );
// One "yes" to stop
// normal
testOK("yes\n" , "-srcstorepass changeit -deststorepass changeit " +
"-importkeystore -srckeystore x.jceks -srcstoretype JCEKS " +
"-destkeystore x.jks -deststoretype JKS" );
// maybe c1 or p1 has been imported before s1 or s2 is touched,
// anyway we know yesNo is only asked once.
// pkcs12
remove("x.jks" );
// JKS prompt for keypass
testFail("changeit\nchangeit\n" , "-keystore x.jks -storetype JKS " +
"-genkeypair -alias p1 -dname CN=olala" );
remove("x.jks" );
// just type ENTER means keypass=storepass
testOK("changeit\nchangeit\n\n" , "-keystore x.jks -storetype JKS " +
"-genkeypair -keyalg DSA -alias p1 -dname CN=olala" );
remove("x.p12" );
// PKCS12 only need storepass
testOK("" , "-keystore x.p12 -storetype PKCS12 -storepass changeit " +
"-genkeypair -keyalg DSA -alias p0 -dname CN=olala" );
testOK("changeit\n" , "-keystore x.p12 -storetype PKCS12 " +
"-genkeypair -keyalg DSA -alias p1 -dname CN=olala" );
// when specify keypass, make sure keypass==storepass...
testOK("changeit\n" , "-keystore x.p12 -keypass changeit " +
"-storetype PKCS12 -genkeypair -keyalg DSA -alias p3 -dname CN=olala" );
assertTrue(err.indexOf("Warning" ) == -1,
"PKCS12 silent when keypass == storepass" );
// otherwise, print a warning
testOK("changeit\n" , "-keystore x.p12 -keypass another" +
" -storetype PKCS12 -genkeypair -keyalg DSA -alias p2 -dname CN=olala" );
assertTrue(err.indexOf("Warning" ) != -1,
"PKCS12 warning when keypass != storepass" );
// no -keypasswd for PKCS12
testFail("" , "-keystore x.p12 -storepass changeit -storetype PKCS12" +
" -keypasswd -new changeit -alias p3" );
testOK("" , "-keystore x.p12 -storepass changeit -storetype PKCS12 " +
"-changealias -alias p3 -destalias p33" );
testOK("" , "-keystore x.p12 -storepass changeit -storetype PKCS12 " +
"-keyclone -alias p33 -destalias p3" );
// pkcs12
remove("x.p12" );
// PKCS12 only need storepass
testOK("" , "-keystore x.p12 -storetype PKCS12 -storepass changeit " +
"-genkeypair -keyalg DSA -alias p0 -dname CN=olala" );
testOK("" , "-storepass changeit -keystore x.p12 -storetype PKCS12 " +
"-genkeypair -keyalg DSA -alias p1 -dname CN=olala" );
// when specify keypass, make sure keypass==storepass...
testOK("" , "-storepass changeit -keystore x.p12 -keypass changeit " +
"-storetype PKCS12 -genkeypair -keyalg DSA -alias p3 -dname CN=olala" );
assertTrue(err.indexOf("Warning" ) == -1,
"PKCS12 silent when keypass == storepass" );
// otherwise, print a warning
testOK("" , "-storepass changeit -keystore x.p12 -keypass another " +
"-storetype PKCS12 -genkeypair -keyalg DSA -alias p2 -dname CN=olala" );
assertTrue(err.indexOf("Warning" ) != -1,
"PKCS12 warning when keypass != storepass" );
remove("x.jks" );
remove("x.jceks" );
remove("x.p12" );
remove("x2.jceks" );
remove("x2.jks" );
remove("x.jks.p1.cert" );
}
void testPKCS11() throws Exception {
KeyStore ks;
// pkcs11, the password maybe different and maybe PKCS11 not supported
// in case last test is not executed successfully
testAnyway("" , p11Arg + "-storepass test12 -delete -alias p1" );
testAnyway("" , p11Arg + "-storepass test12 -delete -alias p2" );
testAnyway("" , p11Arg + "-storepass test12 -delete -alias p3" );
testAnyway("" , p11Arg + "-storepass test12 -delete -alias nss" );
testOK("" , p11Arg + "-storepass test12 -list" );
assertTrue(out.indexOf("Your keystore contains 0 entries" ) != -1,
"*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE " +
"BEFORE THIS TEST ***" );
testOK("" , p11Arg +
"-storepass test12 -genkeypair -keyalg DSA -alias p1 -dname CN=olala" );
testOK("test12\n" , p11Arg + "-genkeypair -keyalg DSA -alias p2 -dname CN=olala2" );
// cannot provide keypass for PKCS11
testFail("test12\n" , p11Arg +
"-keypass test12 -genkeypair -keyalg DSA -alias p3 -dname CN=olala3" );
// cannot provide keypass for PKCS11
testFail("test12\n" , p11Arg +
"-keypass nonsense -genkeypair -keyalg DSA -alias p3 -dname CN=olala3" );
testOK("" , p11Arg + "-storepass test12 -list" );
assertTrue(out.indexOf("Your keystore contains 2 entries" ) != -1,
"2 entries in p11" );
testOK("test12\n" , p11Arg + "-alias p1 -changealias -destalias p3" );
testOK("" , p11Arg + "-storepass test12 -list -alias p3" );
testFail("" , p11Arg + "-storepass test12 -list -alias p1" );
testOK("test12\n" , p11Arg + "-alias p3 -keyclone -destalias p1" );
// in PKCS11, keyclone will delete old
testFail("" , p11Arg + "-storepass test12 -list -alias p3" );
testOK("" , p11Arg + "-storepass test12 -list -alias p1" );
// cannot change password for PKCS11
testFail("test12\n" , p11Arg + "-alias p1 -keypasswd -new another" );
testOK("" , p11Arg + "-storepass test12 -list" );
assertTrue(out.indexOf("Your keystore contains 2 entries" ) != -1,
"2 entries in p11" );
testOK("" , p11Arg + "-storepass test12 -delete -alias p1" );
testOK("" , p11Arg + "-storepass test12 -delete -alias p2" );
testOK("" , p11Arg + "-storepass test12 -list" );
assertTrue(out.indexOf("Your keystore contains 0 entries" ) != -1,
"*** MAKE SURE YOU HAVE NO ENTRIES IN YOUR PKCS11 KEYSTORE" +
" BEFORE THIS TEST ***" );
}
void testPKCS11ImportKeyStore() throws Exception {
KeyStore ks;
testOK("" , p11Arg +
"-storepass test12 -genkeypair -keyalg DSA -alias p1 -dname CN=olala" );
testOK("test12\n" , p11Arg + "-genkeypair -keyalg DSA -alias p2 -dname CN=olala2" );
// test importkeystore for pkcs11
remove("x.jks" );
// pkcs11 -> jks
testOK("changeit\nchangeit\ntest12\n" , srcP11Arg +
("-importkeystore -destkeystore x.jks -deststoretype JKS " +
"-srcalias p1" ));
assertTrue(err.indexOf("not imported" ) != -1,
"cannot import key without destkeypass" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(!ks.containsAlias("p1" ), "p1 is not imported" );
testOK("changeit\ntest12\n" , srcP11Arg +
("-importkeystore -destkeystore x.jks -deststoretype JKS " +
"-srcalias p1 -destkeypass changeit" ));
testOK("changeit\ntest12\n" , srcP11Arg +
("-importkeystore -destkeystore x.jks -deststoretype JKS " +
"-srcalias p2 -destkeypass changeit" ));
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.containsAlias("p1" ), "p1 is imported" );
assertTrue(ks.containsAlias("p2" ), "p2 is imported" );
// jks -> pkcs11
testOK("" , p11Arg + "-storepass test12 -delete -alias p1" );
testOK("" , p11Arg + "-storepass test12 -delete -alias p2" );
testOK("test12\nchangeit\n" , p11Arg +
"-importkeystore -srckeystore x.jks -srcstoretype JKS" );
testOK("" , p11Arg + "-storepass test12 -list -alias p1" );
testOK("" , p11Arg + "-storepass test12 -list -alias p2" );
testOK("" , p11Arg + "-storepass test12 -list" );
assertTrue(out.indexOf("Your keystore contains 2 entries" ) != -1,
"2 entries in p11" );
// clean up
testOK("" , p11Arg + "-storepass test12 -delete -alias p1" );
testOK("" , p11Arg + "-storepass test12 -delete -alias p2" );
testOK("" , p11Arg + "-storepass test12 -list" );
assertTrue(out.indexOf("Your keystore contains 0 entries" ) != -1,
"empty p11" );
remove("x.jks" );
}
// Selected sqeTest
void sqeTest() throws Exception {
FileOutputStream fos = new FileOutputStream("badkeystore" );
for (int i=0; i<100; i++) {
fos.write(i);
}
fos.close();
sqeCsrTest();
sqePrintcertTest();
sqeDeleteTest();
sqeExportTest();
sqeGenkeyTest();
sqeImportTest();
sqeKeyclonetest();
sqeKeypasswdTest();
sqeListTest();
sqeSelfCertTest();
sqeStorepassTest();
remove("badkeystore" );
}
// Import: cacert, prompt, trusted, non-trusted, bad chain, not match
void sqeImportTest() throws Exception {
KeyStore ks;
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-exportcert -file x.jks.p1.cert" );
/* deleted */ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert -noprompt" );
/* deleted */ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -delete -alias mykey" );
testOK("yes\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(ks.containsAlias("mykey" ), "imported" );
/* deleted */ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -delete -alias mykey" );
testOK("\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(!ks.containsAlias("mykey" ), "imported" );
testOK("no\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(!ks.containsAlias("mykey" ), "imported" );
testFail("no\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file nonexist" );
testFail("no\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks" );
remove("x.jks" );
}
// keyclone: exist. nonexist err, cert err, dest exist, misc
void sqeKeyclonetest() throws Exception {
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
// new pass
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -new newpass -keyclone -dest p0" );
// new pass
testOK("\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -keyclone -dest p1" );
testOK("\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keyclone -dest p2" );
testFail("\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keyclone -dest p2" );
testFail("\n" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keyclone -dest p3 -alias noexist" );
// no cert
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-exportcert -file x.jks.p1.cert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert -noprompt" );
// new pass
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -new newpass -keyclone -dest p0" );
remove("x.jks" );
}
// keypasswd: exist, short, nonexist err, cert err, misc
void sqeKeypasswdTest() throws Exception {
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -keypasswd -new newpass" );
/*change back*/ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -keypass newpass -keypasswd -new changeit" );
testOK("newpass\nnewpass\n" , "-keystore x.jks -storetype JKS " +
"-storepass changeit -keypass changeit -keypasswd" );
/*change back*/ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -keypass newpass -keypasswd -new changeit" );
testOK("new\nnew\nnewpass\nnewpass\n" , "-keystore x.jks " +
"-storetype JKS -storepass changeit -keypass changeit -keypasswd" );
/*change back*/ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -keypass newpass -keypasswd -new changeit" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypasswd -new newpass" );
/*change back*/ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -keypass newpass -keypasswd -new changeit" );
testOK("changeit\n" , "-keystore x.jks -storetype JKS " +
"-keypasswd -new newpass" );
/*change back*/ testOK("", "-keystore x.jks -storetype JKS " +
"-storepass changeit -keypass newpass -keypasswd -new changeit" );
testFail("" , "-keystore x.jks -storetype JKS -storepass badpass " +
"-keypass changeit -keypasswd -new newpass" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass bad -keypasswd -new newpass" );
// no cert
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-exportcert -file x.jks.p1.cert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert -noprompt" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -keypasswd -new newpass" );
// diff pass
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass keypass -genkeypair -keyalg DSA -dname CN=olala" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypasswd -new newpass" );
testOK("keypass\n" , "-keystore x.jks -storetype JKS " +
"-storepass changeit -keypasswd -new newpass" );
// i hate those misc test
remove("x.jks" );
}
// list: -f -alias, exist, nonexist err;
// otherwise, check all shows, -rfc shows more, and misc
void sqeListTest() throws Exception {
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit -list" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-list -alias mykey" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-list -alias notexist" );
testFail("" , "-keystore x.jks -storetype JKS -storepass badpass " +
"-list -alias mykey" );
// keypass ignore
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass badpass -list -alias mykey" );
testOK("\n" , "-keystore x.jks -storetype JKS -list" );
assertTrue(err.indexOf("WARNING" ) != -1, "no storepass" );
testOK("changeit\n" , "-keystore x.jks -storetype JKS -list" );
assertTrue(err.indexOf("WARNING" ) == -1, "has storepass" );
testFail("badpass\n" , "-keystore x.jks -storetype JKS -list" );
// misc
testFail("" , "-keystore aa\\bb//cc -storepass changeit -list");
testFail("" , "-keystore nonexisting -storepass changeit -list" );
testFail("" , "-keystore badkeystore -storepass changeit -list" );
remove("x.jks" );
}
// selfcert: exist, non-exist err, cert err, sig, dname, wrong keypass, misc
void sqeSelfCertTest() throws Exception {
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit -selfcert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -selfcert" );
// not exist
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -selfcert -alias nonexisting" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -selfcert -dname CN=NewName" );
// sig not compatible
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -selfcert -sigalg MD5withRSA" );
// bad pass
testFail("" , "-keystore x.jks -storetype JKS -storepass wrong " +
"-keypass changeit -selfcert" );
// bad pass
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass wrong -selfcert" );
//misc
testFail("" , "-keystore nonexist -storepass changeit " +
"-keypass changeit -selfcert" );
testFail("" , "-keystore aa//dd\\gg -storepass changeit " +
"-keypass changeit -selfcert" );
// diff pass
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass keypass -genkeypair -keyalg DSA -dname CN=olala" );
testFail("" , "-keystore x.jks -storetype JKS " +
"-storepass changeit -selfcert" );
testOK("keypass\n" , "-keystore x.jks -storetype JKS " +
"-storepass changeit -selfcert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-exportcert -file x.jks.p1.cert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert -noprompt" );
// certentry cannot do selfcert
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-selfcert" );
remove("x.jks" );
}
// storepass: bad old, short new, misc
void sqeStorepassTest() throws Exception {
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
// all in arg
testOK("" , "-storepasswd -keystore x.jks -storetype JKS " +
"-storepass changeit -new newstore" );
/* Change back */ testOK("", "-storepasswd -keystore x.jks" +
" -storetype JKS -storepass newstore -new changeit" );
// all not in arg, new twice
testOK("changeit\nnewstore\nnewstore\n" , "-storepasswd " +
"-keystore x.jks -storetype JKS" );
/* Change back */ testOK("", "-storepasswd -keystore x.jks " +
"-storetype JKS -storepass newstore -new changeit" );
// new in arg
testOK("changeit\n" , "-storepasswd -keystore x.jks " +
"-storetype JKS -new newstore" );
/* Change back */ testOK("", "-storepasswd -keystore x.jks " +
"-storetype JKS -storepass newstore -new changeit" );
// old in arg
testOK("newstore\nnewstore\n" , "-storepasswd -keystore x.jks " +
"-storetype JKS -storepass changeit" );
/* Change back */ testOK("", "-storepasswd -keystore x.jks " +
"-storetype JKS -storepass newstore -new changeit" );
// old in arg
testOK("new\nnew\nnewstore\nnewstore\n" , "-storepasswd " +
"-keystore x.jks -storetype JKS -storepass changeit" );
/* Change back */ testOK("", "-storepasswd -keystore x.jks " +
"-storetype JKS -storepass newstore -new changeit" );
// bad old
testFail("" , "-storepasswd -keystore x.jks -storetype JKS " +
"-storepass badold -new newstore" );
// short new
testFail("" , "-storepasswd -keystore x.jks -storetype JKS " +
"-storepass changeit -new new" );
// misc
// non exist
testFail("" , "-storepasswd -keystore nonexist " +
"-storepass changeit -new newstore" );
// bad file
testFail("" , "-storepasswd -keystore badkeystore " +
"-storepass changeit -new newstore" );
// bad file
testFail("" , "-storepasswd -keystore aa\\bb//cc//dd " +
"-storepass changeit -new newstore" );
remove("x.jks" );
}
void sqeGenkeyTest() throws Exception {
remove("x.jks" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -alias newentry" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -alias newentry" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala -keyalg DSA " +
"-alias n1" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " +
"-alias n2" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala " +
"-keyalg NoSuchAlg -alias n3" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 56 " +
"-alias n4" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 999 " +
"-alias n5" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 512 " +
"-alias n6" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 1024 " +
"-alias n7" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala " +
"-sigalg NoSuchAlg -alias n8" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " +
"-sigalg MD2withRSA -alias n9" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " +
"-sigalg MD5withRSA -alias n10" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " +
"-sigalg SHA1withRSA -alias n11" );
testFail("" , "-keystore aa\\bb//cc\\dd -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala -keyalg RSA " +
"-sigalg NoSuchAlg -alias n12" );
testFail("" , "-keystore badkeystore -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala " +
"-alias n14" );
testFail("" , "-keystore x.jks -storetype JKS -storepass badpass " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -alias n16" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CNN=olala -alias n17" );
remove("x.jks" );
}
void sqeExportTest() throws Exception {
remove("x.jks" );
// nonexist
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-export -file mykey.cert -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-export -file mykey.cert -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-import -file mykey.cert -noprompt -alias c1" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-export -file mykey.cert2 -alias c1" );
testFail("" , "-keystore aa\\bb//cc\\dd -storepass changeit " +
"-export -file mykey.cert2 -alias c1" );
testFail("" , "-keystore nonexistkeystore -storepass changeit " +
"-export -file mykey.cert2 -alias c1" );
testFail("" , "-keystore badkeystore -storepass changeit " +
"-export -file mykey.cert2 -alias c1" );
testFail("" , "-keystore x.jks -storetype JKS -storepass badpass " +
"-export -file mykey.cert2 -alias c1" );
remove("mykey.cert" );
remove("mykey.cert2" );
remove("x.jks" );
}
void sqeDeleteTest() throws Exception {
remove("x.jks" );
// nonexist
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
// keystore name illegal
testFail("" , "-keystore aa\\bb//cc\\dd -storepass changeit " +
"-delete -alias mykey" );
// keystore not exist
testFail("" , "-keystore nonexistkeystore -storepass changeit " +
"-delete -alias mykey" );
// keystore invalid
testFail("" , "-keystore badkeystore -storepass changeit " +
"-delete -alias mykey" );
// wrong pass
testFail("" , "-keystore x.jks -storetype JKS -storepass xxxxxxxx " +
"-delete -alias mykey" );
remove("x.jks" );
}
void sqeCsrTest() throws Exception {
remove("x.jks" );
remove("x.jks.p1.cert" );
remove("csr1" );
// PrivateKeyEntry can do certreq
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala -keysize 1024" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1 -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1 -sigalg SHA1withDSA" );
// unmatched sigalg
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1 -sigalg MD5withRSA" );
// misc test
// bad storepass
testFail("" , "-keystore x.jks -storetype JKS -storepass badstorepass " +
"-certreq -file csr1" );
// storepass from terminal
testOK("changeit\n" , "-keystore x.jks -storetype JKS " +
"-certreq -file csr1" );
// must provide storepass
testFail("\n" , "-keystore x.jks -storetype JKS " +
"-certreq -file csr1" );
// bad keypass
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass badkeypass -certreq -file csr1" );
// bad filepath
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file aa\\bb//cc\\dd");
// non-existing keystore
testFail("" , "-keystore noexistks -storepass changeit " +
"-certreq -file csr1" );
// Try the RSA private key
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=olala -keyalg RSA" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1 -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1" );
// unmatched sigalg
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1 -sigalg SHA1withDSA" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1 -sigalg MD5withRSA" );
// TrustedCertificateEntry cannot do certreq
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-exportcert -file x.jks.p1.cert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-delete -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-importcert -file x.jks.p1.cert -noprompt" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1 -alias mykey" );
testFail("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-certreq -file csr1" );
remove("x.jks" );
remove("x.jks.p1.cert" );
remove("csr1" );
}
void sqePrintcertTest() throws Exception {
remove("x.jks" );
remove("mykey.cert" );
remove("myweakkey.cert" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -keyalg DSA -dname CN=olala" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-export -file mykey.cert -alias mykey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -genkeypair -dname CN=weak -keyalg rsa " +
"-keysize 512 -sigalg MD5withRSA -alias myweakkey" );
testOK("" , "-keystore x.jks -storetype JKS -storepass changeit " +
"-export -file myweakkey.cert -alias myweakkey" );
testFail("" , "-printcert -file badkeystore" );
testFail("" , "-printcert -file a/b/c/d" );
testOK("" , "-printcert -file mykey.cert" );
testOK("" , "-printcert -file myweakkey.cert" );
FileInputStream fin = new FileInputStream("mykey.cert" );
testOK(fin, "-printcert" );
fin.close();
remove("x.jks" );
remove("mykey.cert" );
remove("myweakkey.cert" );
}
// 8074935: jdk8 keytool doesn't validate pem files for RFC 1421 correctness
static void checkPem(String file) throws Exception {
boolean maybeLast = false ;
for (String s: Files.readAllLines(Paths.get(file))) {
if (s.isEmpty()) continue ;
if (s.startsWith("---" )) continue ;
if (maybeLast) {
throw new Exception("Last line already seen" );
}
if (s.length() > 64) {
throw new Exception(s);
}
if (s.length() < 64) {
maybeLast = true ;
}
}
}
void v3extTest(String keyAlg) throws Exception {
KeyStore ks;
remove("x.jks" );
String simple = "-keystore x.jks -storetype JKS -storepass changeit " +
"-keypass changeit -noprompt -keyalg " + keyAlg + " " ;
String pre = simple + "-genkeypair -keyalg DSA -dname CN=Olala -alias " ;
// Version and SKID
testOK("" , pre + "o1" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(((X509Certificate)ks.getCertificate("o1" )).getVersion() == 3);
assertTrue(((X509CertImpl)ks.getCertificate("o1" ))
.getSubjectKeyIdentifierExtension() != null );
// BC
testOK("" , pre + "b1 -ext BC:critical" );
testOK("" , pre + "b2 -ext BC" );
testOK("" , pre + "b3 -ext bc" );
testOK("" , pre + "b4 -ext BasicConstraints" );
testOK("" , pre + "b5 -ext basicconstraints" );
testOK("" , pre + "b6 -ext BC=ca:true,pathlen:12" );
testOK("" , pre + "b7 -ext BC=ca:false" );
testOK("" , pre + "b8 -ext BC:critical=ca:false" );
testOK("" , pre + "b9 -ext BC=12" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
assertTrue(((X509CertImpl)ks.getCertificate("b1" ))
.getBasicConstraintsExtension().isCritical());
assertTrue(!((X509CertImpl)ks.getCertificate("b2" ))
.getBasicConstraintsExtension().isCritical());
assertTrue(((X509CertImpl)ks.getCertificate("b8" ))
.getBasicConstraintsExtension().isCritical());
assertTrue(((X509Certificate)ks.getCertificate("b1" ))
.getBasicConstraints() == Integer.MAX_VALUE);
assertTrue(((X509Certificate)ks.getCertificate("b2" ))
.getBasicConstraints() == Integer.MAX_VALUE);
assertTrue(((X509Certificate)ks.getCertificate("b3" ))
.getBasicConstraints() == Integer.MAX_VALUE);
assertTrue(((X509Certificate)ks.getCertificate("b4" ))
.getBasicConstraints() == Integer.MAX_VALUE);
assertTrue(((X509Certificate)ks.getCertificate("b5" ))
.getBasicConstraints() == Integer.MAX_VALUE);
assertTrue(((X509Certificate)ks.getCertificate("b6" ))
.getBasicConstraints() == 12);
assertTrue(((X509Certificate)ks.getCertificate("b7" ))
.getBasicConstraints() == -1);
assertTrue(((X509Certificate)ks.getCertificate("b9" ))
.getBasicConstraints() == 12);
// KU
testOK("" , pre + "ku1 -ext KeyUsage:critical=digitalsignature" );
testOK("" , pre + "ku2 -ext KU=digitalSignature" );
testOK("" , pre + "ku3 -ext KU=ds" );
testOK("" , pre + "ku4 -ext KU=dig" );
// ambigous value
testFail("" , pre + "ku5 -ext KU=d" );
// cRLSign cannot be cs
testFail("" , pre + "ku6 -ext KU=cs" );
testOK("" , pre + "ku11 -ext KU=nr" );
// ke means keyAgreement and keyCertSign...
testFail("" , pre + "ku12 -ext KU=ke" );
testOK("" , pre + "ku12 -ext KU=keyE" );
testOK("" , pre + "ku12a -ext KU=kE" ); // kE is only keyEncipherment
// de also means decipherOnly
testOK("" , pre + "ku13a -ext KU=de" ); // de is decipherOnly
testOK("" , pre + "ku13b -ext KU=dE" ); // dE is dataEncipherment
testOK("" , pre + "ku13 -ext KU=dataE" );
testOK("" , pre + "ku14 -ext KU=ka" );
testOK("" , pre + "ku15 -ext KU=kcs" );
testOK("" , pre + "ku16 -ext KU=crls" );
testOK("" , pre + "ku17 -ext KU=eo" );
testOK("" , pre + "ku18 -ext KU=do" );
testOK("" , pre + "ku19 -ext KU=cc" );
testOK("" , pre + "ku017 -ext KU=ds,cc,eo" );
testOK("" , pre + "ku135 -ext KU=nr,dataEncipherment,keyCertSign" );
testOK("" , pre + "ku246 -ext KU=keyEnc,cRL,keyA" );
testOK("" , pre + "ku1234 -ext KU=ka,da,keyE,nonR" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
class CheckKU {
void check(KeyStore ks, String alias, int ... pos) throws Exception {
System.err.print("x" );
boolean [] bs = ((X509Certificate)ks.getCertificate(alias))
.getKeyUsage();
bs = Arrays.copyOf(bs, 9);
for (int i=0; i<bs.length; i++) {
boolean found = false ;
for (int p: pos) {
if (p == i) found = true ;
}
if (!found ^ bs[i]) {
// OK
} else {
throw new RuntimeException("KU not match at " + i +
": " + found + " vs " + bs[i]);
}
}
}
}
CheckKU c = new CheckKU();
assertTrue(((X509CertImpl)ks.getCertificate("ku1" ))
.getExtension(PKIXExtensions.KeyUsage_Id).isCritical());
assertTrue(!((X509CertImpl)ks.getCertificate("ku2" ))
.getExtension(PKIXExtensions.KeyUsage_Id).isCritical());
c.check(ks, "ku1" , 0);
c.check(ks, "ku2" , 0);
c.check(ks, "ku3" , 0);
c.check(ks, "ku4" , 0);
c.check(ks, "ku11" , 1);
c.check(ks, "ku12" , 2);
c.check(ks, "ku13" , 3);
c.check(ks, "ku14" , 4);
c.check(ks, "ku15" , 5);
c.check(ks, "ku16" , 6);
c.check(ks, "ku17" , 7);
c.check(ks, "ku18" , 8);
c.check(ks, "ku19" , 1);
c.check(ks, "ku11" , 1);
c.check(ks, "ku11" , 1);
c.check(ks, "ku11" , 1);
c.check(ks, "ku017" , 0, 1, 7);
c.check(ks, "ku135" , 1, 3, 5);
c.check(ks, "ku246" , 6, 2, 4);
c.check(ks, "ku1234" , 1, 2, 3, 4);
// EKU
testOK("" , pre + "eku1 -ext EKU:critical=sa" );
testOK("" , pre + "eku2 -ext ExtendedKeyUsage=ca" );
testOK("" , pre + "eku3 -ext EKU=cs" );
testOK("" , pre + "eku4 -ext EKU=ep" );
testOK("" , pre + "eku8 -ext EKU=ts" );
testFail("" , pre + "eku9 -ext EKU=os" );
testOK("" , pre + "eku9 -ext EKU=ocsps" );
testOK("" , pre + "eku10 -ext EKU=any" );
testOK("" , pre + "eku11 -ext EKU=1.2.3.4,1.3.5.7,ep" );
testFail("" , pre + "eku12 -ext EKU=c" );
testFail("" , pre + "eku12 -ext EKU=nothing" );
ks = loadStore("x.jks" , "changeit" , "JKS" );
class CheckEKU {
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5 C=87 H=69 G=78
¤ Dauer der Verarbeitung: 0.21 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland