6868579: RFE: jarsigner to support reading password from environment variable
Reviewed-by: xuelei, wetmore
--- a/jdk/src/share/classes/sun/security/tools/JarSigner.java Fri Oct 02 18:49:05 2009 +0800
+++ b/jdk/src/share/classes/sun/security/tools/JarSigner.java Fri Oct 02 18:49:46 2009 +0800
@@ -291,13 +291,21 @@
for (n=0; n < args.length; n++) {
String flags = args[n];
+ String modifier = null;
+ if (flags.charAt(0) == '-') {
+ int pos = flags.indexOf(':');
+ if (pos > 0) {
+ modifier = flags.substring(pos+1);
+ flags = flags.substring(0, pos);
+ }
+ }
if (collator.compare(flags, "-keystore") == 0) {
if (++n == args.length) usageNoArg();
keystore = args[n];
} else if (collator.compare(flags, "-storepass") ==0) {
if (++n == args.length) usageNoArg();
- storepass = args[n].toCharArray();
+ storepass = getPass(modifier, args[n]);
} else if (collator.compare(flags, "-storetype") ==0) {
if (++n == args.length) usageNoArg();
storetype = args[n];
@@ -329,7 +337,7 @@
debug = true;
} else if (collator.compare(flags, "-keypass") ==0) {
if (++n == args.length) usageNoArg();
- keypass = args[n].toCharArray();
+ keypass = getPass(modifier, args[n]);
} else if (collator.compare(flags, "-sigfile") ==0) {
if (++n == args.length) usageNoArg();
sigfile = args[n];
@@ -355,13 +363,7 @@
} else if (collator.compare(flags, "-verify") ==0) {
verify = true;
} else if (collator.compare(flags, "-verbose") ==0) {
- verbose = "all";
- } else if (collator.compare(flags, "-verbose:all") ==0) {
- verbose = "all";
- } else if (collator.compare(flags, "-verbose:summary") ==0) {
- verbose = "summary";
- } else if (collator.compare(flags, "-verbose:grouped") ==0) {
- verbose = "grouped";
+ verbose = (modifier != null) ? modifier : "all";
} else if (collator.compare(flags, "-sigalg") ==0) {
if (++n == args.length) usageNoArg();
sigalg = args[n];
@@ -465,18 +467,25 @@
}
}
- void usageNoArg() {
+ static char[] getPass(String modifier, String arg) {
+ char[] output = KeyTool.getPassWithModifier(modifier, arg);
+ if (output != null) return output;
+ usage();
+ return null; // Useless, usage() already exit
+ }
+
+ static void usageNoArg() {
System.out.println(rb.getString("Option lacks argument"));
usage();
}
- void usage() {
+ static void usage() {
System.out.println();
System.out.println(rb.getString("Please type jarsigner -help for usage"));
System.exit(1);
}
- void fullusage() {
+ static void fullusage() {
System.out.println(rb.getString
("Usage: jarsigner [options] jar-file alias"));
System.out.println(rb.getString
--- a/jdk/src/share/classes/sun/security/tools/KeyTool.java Fri Oct 02 18:49:05 2009 +0800
+++ b/jdk/src/share/classes/sun/security/tools/KeyTool.java Fri Oct 02 18:49:46 2009 +0800
@@ -352,6 +352,15 @@
}
/*
+ * Check modifiers
+ */
+ String modifier = null;
+ int pos = flags.indexOf(':');
+ if (pos > 0) {
+ modifier = flags.substring(pos+1);
+ flags = flags.substring(0, pos);
+ }
+ /*
* command modes
*/
boolean isCommand = false;
@@ -387,18 +396,18 @@
ksfname = args[++i];
} else if (collator.compare(flags, "-storepass") == 0 ||
collator.compare(flags, "-deststorepass") == 0) {
- storePass = args[++i].toCharArray();
+ storePass = getPass(modifier, args[++i]);
passwords.add(storePass);
} else if (collator.compare(flags, "-storetype") == 0 ||
collator.compare(flags, "-deststoretype") == 0) {
storetype = args[++i];
} else if (collator.compare(flags, "-srcstorepass") == 0) {
- srcstorePass = args[++i].toCharArray();
+ srcstorePass = getPass(modifier, args[++i]);
passwords.add(srcstorePass);
} else if (collator.compare(flags, "-srcstoretype") == 0) {
srcstoretype = args[++i];
} else if (collator.compare(flags, "-srckeypass") == 0) {
- srckeyPass = args[++i].toCharArray();
+ srckeyPass = getPass(modifier, args[++i]);
passwords.add(srckeyPass);
} else if (collator.compare(flags, "-srcprovidername") == 0) {
srcProviderName = args[++i];
@@ -408,13 +417,13 @@
} else if (collator.compare(flags, "-providerpath") == 0) {
pathlist = args[++i];
} else if (collator.compare(flags, "-keypass") == 0) {
- keyPass = args[++i].toCharArray();
+ keyPass = getPass(modifier, args[++i]);
passwords.add(keyPass);
} else if (collator.compare(flags, "-new") == 0) {
- newPass = args[++i].toCharArray();
+ newPass = getPass(modifier, args[++i]);
passwords.add(newPass);
} else if (collator.compare(flags, "-destkeypass") == 0) {
- destKeyPass = args[++i].toCharArray();
+ destKeyPass = getPass(modifier, args[++i]);
passwords.add(destKeyPass);
} else if (collator.compare(flags, "-alias") == 0 ||
collator.compare(flags, "-srcalias") == 0) {
@@ -3842,6 +3851,61 @@
rb.getString("Command option <flag> needs an argument.")).format(source));
tinyHelp();
}
+
+ private char[] getPass(String modifier, String arg) {
+ char[] output = getPassWithModifier(modifier, arg);
+ if (output != null) return output;
+ tinyHelp();
+ return null; // Useless, tinyHelp() already exits.
+ }
+
+ // This method also used by JarSigner
+ public static char[] getPassWithModifier(String modifier, String arg) {
+ if (modifier == null) {
+ return arg.toCharArray();
+ } else if (collator.compare(modifier, "env") == 0) {
+ String value = System.getenv(arg);
+ if (value == null) {
+ System.err.println(rb.getString(
+ "Cannot find environment variable: ") + arg);
+ return null;
+ } else {
+ return value.toCharArray();
+ }
+ } else if (collator.compare(modifier, "file") == 0) {
+ try {
+ URL url = null;
+ try {
+ url = new URL(arg);
+ } catch (java.net.MalformedURLException mue) {
+ File f = new File(arg);
+ if (f.exists()) {
+ url = f.toURI().toURL();
+ } else {
+ System.err.println(rb.getString(
+ "Cannot find file: ") + arg);
+ return null;
+ }
+ }
+ BufferedReader br = new BufferedReader(new InputStreamReader(
+ url.openStream()));
+ String value = br.readLine();
+ br.close();
+ if (value == null) {
+ return new char[0];
+ } else {
+ return value.toCharArray();
+ }
+ } catch (IOException ioe) {
+ System.err.println(ioe);
+ return null;
+ }
+ } else {
+ System.err.println(rb.getString("Unknown password type: ") +
+ modifier);
+ return null;
+ }
+ }
}
// This class is exactly the same as com.sun.tools.javac.util.Pair,
@@ -3881,3 +3945,4 @@
return new Pair<A,B>(a,b);
}
}
+
--- a/jdk/src/share/classes/sun/security/util/Resources.java Fri Oct 02 18:49:05 2009 +0800
+++ b/jdk/src/share/classes/sun/security/util/Resources.java Fri Oct 02 18:49:46 2009 +0800
@@ -178,6 +178,10 @@
{"keytool error: ", "keytool error: "},
{"Illegal option: ", "Illegal option: "},
{"Illegal value: ", "Illegal value: "},
+ {"Unknown password type: ", "Unknown password type: "},
+ {"Cannot find environment variable: ",
+ "Cannot find environment variable: "},
+ {"Cannot find file: ", "Cannot find file: "},
{"Command option <flag> needs an argument.", "Command option {0} needs an argument."},
{"Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified <command> value.",
"Warning: Different store and key passwords not supported for PKCS12 KeyStores. Ignoring user-specified {0} value."},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/passtype.sh Fri Oct 02 18:49:46 2009 +0800
@@ -0,0 +1,72 @@
+#
+# Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 6868579
+# @summary RFE: jarsigner to support reading password from environment variable
+#
+
+if [ "${TESTJAVA}" = "" ] ; then
+ JAVAC_CMD=`which javac`
+ TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+ Windows_* )
+ FS="\\"
+ ;;
+ * )
+ FS="/"
+ ;;
+esac
+
+KS=pt.jks
+JFILE=pt.jar
+
+KT="$TESTJAVA${FS}bin${FS}keytool -keystore $KS -validity 300"
+JAR=$TESTJAVA${FS}bin${FS}jar
+JARSIGNER=$TESTJAVA${FS}bin${FS}jarsigner
+
+rm $KS $JFILE
+
+$KT -alias a -dname CN=a -keyalg rsa -genkey \
+ -storepass test12 -keypass test12 || exit 1
+PASSENV=test12 $KT -alias b -dname CN=b -keyalg rsa -genkey \
+ -storepass:env PASSENV -keypass:env PASSENV || exit 2
+echo test12 > passfile
+$KT -alias c -dname CN=c -keyalg rsa -genkey \
+ -storepass:file passfile -keypass:file passfile || exit 3
+
+echo A > A
+$JAR cvf $JFILE A
+
+$JARSIGNER -keystore $KS -storepass test12 $JFILE a || exit 4
+PASSENV=test12 $JARSIGNER -keystore $KS -storepass:env PASSENV $JFILE b || exit 5
+$JARSIGNER -keystore $KS -storepass:file passfile $JFILE b || exit 6
+
+$JARSIGNER -keystore $KS -verify -debug -strict $JFILE || exit 7
+
+exit 0
+