8130302: jarsigner and keytool -providerClass needs be re-examined for modules

Reviewed-by: valeriep, mchung, mullan
This commit is contained in:
Weijun Wang 2016-07-12 09:41:49 +08:00
parent fadef405a9
commit 1931ac4196
14 changed files with 490 additions and 284 deletions

View File

@ -38,6 +38,8 @@ import java.net.URL;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.text.Collator;
@ -46,6 +48,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.ServiceLoader;
import sun.security.util.PropertyExpander;
@ -209,6 +212,7 @@ public class KeyStoreUtil {
/**
* Prepends matched options from a pre-configured options file.
*
* @param tool the name of the tool, can be "keytool" or "jarsigner"
* @param file the pre-configured options file
* @param c1 the name of the command, with the "-" prefix,
@ -259,4 +263,68 @@ public class KeyStoreUtil {
return result.toArray(new String[result.size()]);
}
}
/**
* Loads a security provider as a service.
*
* @param provName the name
* @param arg optional arg
* @throws IllegalArgumentException if no provider matches the name
*/
public static void loadProviderByName(String provName, String arg) {
Provider loaded = Security.getProvider(provName);
if (loaded != null) {
if (arg != null) {
loaded = loaded.configure(arg);
Security.addProvider(loaded);
}
return;
}
for (Provider p : ServiceLoader.load(Provider.class,
ClassLoader.getSystemClassLoader())) {
if (p.getName().equals(provName)) {
if (arg != null) {
p = p.configure(arg);
}
Security.addProvider(p);
return;
}
}
throw new IllegalArgumentException("No provider found");
}
/**
* Loads a security provider by a fully-qualified class name.
*
* @param provClass the class name
* @param arg optional arg
* @param cl optional class loader
* @throws IllegalArgumentException if no provider matches the class name
* @throws ClassCastException if the class has not extended Provider
*/
public static void loadProviderByClass(
String provClass, String arg, ClassLoader cl) {
// For compatibility, SunPKCS11 and OracleUcrypto can still be
// loadable with -providerClass.
if (provClass.equals("sun.security.pkcs11.SunPKCS11")) {
loadProviderByName("SunPKCS11", arg);
return;
} else if (provClass.equals("com.oracle.security.crypto.UcryptoProvider")) {
loadProviderByName("OracleUcrypto", arg);
return;
}
Provider prov;
try {
Class<?> clazz = Class.forName(provClass, false, cl);
prov = (Provider) clazz.getConstructor().newInstance();
} catch (ReflectiveOperationException e) {
throw new IllegalArgumentException(e);
}
if (arg != null) {
prov = prov.configure(arg);
}
Security.addProvider(prov);
}
}

View File

@ -33,13 +33,11 @@ import java.security.MessageDigest;
import java.security.Key;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.Security;
import java.security.Signature;
import java.security.Timestamp;
import java.security.UnrecoverableEntryException;
import java.security.UnrecoverableKeyException;
import java.security.Principal;
import java.security.Provider;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.CertStoreException;
@ -128,6 +126,7 @@ public final class Main {
// them through the command line.
private Set<Pair <String, String>> providers = null;
private Set<Pair <String, String>> providerClasses = null;
private String storetype = null;
private boolean hasStoretypeOption = false;
private String srcProviderName = null;
@ -166,57 +165,57 @@ public final class Main {
enum Command {
CERTREQ("Generates.a.certificate.request",
ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
CHANGEALIAS("Changes.an.entry.s.alias",
ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
DELETE("Deletes.an.entry",
ALIAS, KEYSTORE, STOREPASS, STORETYPE,
PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
EXPORTCERT("Exports.certificate",
RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
GENKEYPAIR("Generates.a.key.pair",
ALIAS, KEYALG, KEYSIZE, SIGALG, DESTALIAS, DNAME,
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
GENSECKEY("Generates.a.secret.key",
ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
GENCERT("Generates.certificate.from.a.certificate.request",
RFC, INFILE, OUTFILE, ALIAS, SIGALG, DNAME,
STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
IMPORTCERT("Imports.a.certificate.or.a.certificate.chain",
NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V),
IMPORTPASS("Imports.a.password",
ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
SRCPROTECTED, DESTPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
NOPROMPT, ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH,
V),
KEYPASSWD("Changes.the.key.password.of.an.entry",
ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
STORETYPE, PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V),
LIST("Lists.entries.in.a.keystore",
RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE,
PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
PROVIDERNAME, ADDPROVIDER, PROVIDERCLASS,
PROVIDERPATH, V, PROTECTED),
PRINTCERT("Prints.the.content.of.a.certificate",
RFC, FILEIN, SSLSERVER, JARFILE, V),
@ -226,26 +225,26 @@ public final class Main {
FILEIN, V),
STOREPASSWD("Changes.the.store.password.of.a.keystore",
NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
// Undocumented start here, KEYCLONE is used a marker in -help;
KEYCLONE("Clones.a.key.entry",
ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V),
KEYSTORE, STOREPASS, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V),
SELFCERT("Generates.a.self.signed.certificate",
ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
GENCRL("Generates.CRL",
RFC, FILEOUT, ID,
ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
PROVIDERARG, PROVIDERPATH, V, PROTECTED),
STOREPASS, STORETYPE, PROVIDERNAME, ADDPROVIDER,
PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
IDENTITYDB("Imports.entries.from.a.JDK.1.1.x.style.identity.database",
FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
ADDPROVIDER, PROVIDERCLASS, PROVIDERPATH, V);
final String description;
final Option[] options;
@ -289,48 +288,48 @@ public final class Main {
enum Option {
ALIAS("alias", "<alias>", "alias.name.of.the.entry.to.process"),
DESTALIAS("destalias", "<destalias>", "destination.alias"),
DESTALIAS("destalias", "<alias>", "destination.alias"),
DESTKEYPASS("destkeypass", "<arg>", "destination.key.password"),
DESTKEYSTORE("destkeystore", "<destkeystore>", "destination.keystore.name"),
DESTKEYSTORE("destkeystore", "<keystore>", "destination.keystore.name"),
DESTPROTECTED("destprotected", null, "destination.keystore.password.protected"),
DESTPROVIDERNAME("destprovidername", "<destprovidername>", "destination.keystore.provider.name"),
DESTPROVIDERNAME("destprovidername", "<name>", "destination.keystore.provider.name"),
DESTSTOREPASS("deststorepass", "<arg>", "destination.keystore.password"),
DESTSTORETYPE("deststoretype", "<deststoretype>", "destination.keystore.type"),
DNAME("dname", "<dname>", "distinguished.name"),
DESTSTORETYPE("deststoretype", "<type>", "destination.keystore.type"),
DNAME("dname", "<name>", "distinguished.name"),
EXT("ext", "<value>", "X.509.extension"),
FILEOUT("file", "<filename>", "output.file.name"),
FILEIN("file", "<filename>", "input.file.name"),
FILEOUT("file", "<file>", "output.file.name"),
FILEIN("file", "<file>", "input.file.name"),
ID("id", "<id:reason>", "Serial.ID.of.cert.to.revoke"),
INFILE("infile", "<filename>", "input.file.name"),
KEYALG("keyalg", "<keyalg>", "key.algorithm.name"),
INFILE("infile", "<file>", "input.file.name"),
KEYALG("keyalg", "<alg>", "key.algorithm.name"),
KEYPASS("keypass", "<arg>", "key.password"),
KEYSIZE("keysize", "<keysize>", "key.bit.size"),
KEYSIZE("keysize", "<size>", "key.bit.size"),
KEYSTORE("keystore", "<keystore>", "keystore.name"),
NEW("new", "<arg>", "new.password"),
NOPROMPT("noprompt", null, "do.not.prompt"),
OUTFILE("outfile", "<filename>", "output.file.name"),
OUTFILE("outfile", "<file>", "output.file.name"),
PROTECTED("protected", null, "password.through.protected.mechanism"),
PROVIDERARG("providerarg", "<arg>", "provider.argument"),
PROVIDERCLASS("providerclass", "<providerclass>", "provider.class.name"),
PROVIDERNAME("providername", "<providername>", "provider.name"),
PROVIDERPATH("providerpath", "<pathlist>", "provider.classpath"),
PROVIDERCLASS("providerclass", "<class>\n[-providerarg <arg>]", "provider.class.option"),
ADDPROVIDER("addprovider", "<name>\n[-providerarg <arg>]", "addprovider.option"),
PROVIDERNAME("providername", "<name>", "provider.name"),
PROVIDERPATH("providerpath", "<list>", "provider.classpath"),
RFC("rfc", null, "output.in.RFC.style"),
SIGALG("sigalg", "<sigalg>", "signature.algorithm.name"),
SRCALIAS("srcalias", "<srcalias>", "source.alias"),
SIGALG("sigalg", "<alg>", "signature.algorithm.name"),
SRCALIAS("srcalias", "<alias>", "source.alias"),
SRCKEYPASS("srckeypass", "<arg>", "source.key.password"),
SRCKEYSTORE("srckeystore", "<srckeystore>", "source.keystore.name"),
SRCKEYSTORE("srckeystore", "<keystore>", "source.keystore.name"),
SRCPROTECTED("srcprotected", null, "source.keystore.password.protected"),
SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source.keystore.provider.name"),
SRCPROVIDERNAME("srcprovidername", "<name>", "source.keystore.provider.name"),
SRCSTOREPASS("srcstorepass", "<arg>", "source.keystore.password"),
SRCSTORETYPE("srcstoretype", "<srcstoretype>", "source.keystore.type"),
SRCSTORETYPE("srcstoretype", "<type>", "source.keystore.type"),
SSLSERVER("sslserver", "<server[:port]>", "SSL.server.host.and.port"),
JARFILE("jarfile", "<filename>", "signed.jar.file"),
STARTDATE("startdate", "<startdate>", "certificate.validity.start.date.time"),
JARFILE("jarfile", "<file>", "signed.jar.file"),
STARTDATE("startdate", "<date>", "certificate.validity.start.date.time"),
STOREPASS("storepass", "<arg>", "keystore.password"),
STORETYPE("storetype", "<storetype>", "keystore.type"),
STORETYPE("storetype", "<type>", "keystore.type"),
TRUSTCACERTS("trustcacerts", null, "trust.certificates.from.cacerts"),
V("v", null, "verbose.output"),
VALIDITY("validity", "<valDays>", "validity.number.of.days");
VALIDITY("validity", "<days>", "validity.number.of.days");
final String name, arg, description;
Option(String name, String arg, String description) {
@ -344,8 +343,6 @@ public final class Main {
}
};
private static final Class<?>[] PARAM_STRING = { String.class };
private static final String NONE = "NONE";
private static final String P11KEYSTORE = "PKCS11";
private static final String P12KEYSTORE = "PKCS12";
@ -549,10 +546,10 @@ public final class Main {
jarfile = args[++i];
} else if (collator.compare(flags, "-srckeystore") == 0) {
srcksfname = args[++i];
} else if ((collator.compare(flags, "-provider") == 0) ||
(collator.compare(flags, "-providerclass") == 0)) {
if (providers == null) {
providers = new HashSet<Pair <String, String>> (3);
} else if (collator.compare(flags, "-provider") == 0 ||
collator.compare(flags, "-providerclass") == 0) {
if (providerClasses == null) {
providerClasses = new HashSet<Pair <String, String>> (3);
}
String providerClass = args[++i];
String providerArg = null;
@ -565,8 +562,25 @@ public final class Main {
i += 2;
}
}
providers.add(
providerClasses.add(
Pair.of(providerClass, providerArg));
} else if (collator.compare(flags, "-addprovider") == 0) {
if (providers == null) {
providers = new HashSet<Pair <String, String>> (3);
}
String provider = args[++i];
String providerArg = null;
if (args.length > (i+1)) {
flags = args[i+1];
if (collator.compare(flags, "-providerarg") == 0) {
if (args.length == (i+2)) errorNeedArgument(flags);
providerArg = args[i+2];
i += 2;
}
}
providers.add(
Pair.of(provider, providerArg));
}
/*
@ -617,7 +631,6 @@ public final class Main {
return cmd != PRINTCERT && cmd != PRINTCERTREQ;
}
/**
* Execute the commands.
*/
@ -703,6 +716,20 @@ public final class Main {
// Try to load and install specified provider
if (providers != null) {
for (Pair<String, String> provider : providers) {
try {
KeyStoreUtil.loadProviderByName(
provider.fst, provider.snd);
if (debug) {
System.out.println("loadProviderByName: " + provider.fst);
}
} catch (IllegalArgumentException e) {
throw new Exception(String.format(rb.getString(
"provider.name.not.found"), provider.fst));
}
}
}
if (providerClasses != null) {
ClassLoader cl = null;
if (pathlist != null) {
String path = null;
@ -717,30 +744,20 @@ public final class Main {
} else {
cl = ClassLoader.getSystemClassLoader();
}
for (Pair <String, String> provider: providers) {
String provName = provider.fst;
Class<?> provClass;
if (cl != null) {
provClass = cl.loadClass(provName);
} else {
provClass = Class.forName(provName);
for (Pair<String, String> provider : providerClasses) {
try {
KeyStoreUtil.loadProviderByClass(
provider.fst, provider.snd, cl);
if (debug) {
System.out.println("loadProviderByClass: " + provider.fst);
}
} catch (ClassCastException cce) {
throw new Exception(String.format(rb.getString(
"provclass.not.a.provider"), provider.fst));
} catch (IllegalArgumentException e) {
throw new Exception(String.format(rb.getString(
"provider.class.not.found"), provider.fst), e.getCause());
}
@SuppressWarnings("deprecation")
Object obj = provClass.newInstance();
if (!(obj instanceof Provider)) {
MessageFormat form = new MessageFormat
(rb.getString("provName.not.a.provider"));
Object[] source = {provName};
throw new Exception(form.format(source));
}
Provider p = (Provider) obj;
String provArg = provider.snd;
if (provArg != null) {
p = p.configure(provArg);
}
Security.addProvider(p);
}
}
@ -4132,27 +4149,40 @@ public final class Main {
System.err.println(rb.getString("Options."));
System.err.println();
// Left and right sides of the options list
// Left and right sides of the options list. Both might
// contain "\n" and span multiple lines
String[] left = new String[command.options.length];
String[] right = new String[command.options.length];
// Check if there's an unknown option
boolean found = false;
// Length of left side of options list
int lenLeft = 0;
for (int j=0; j<left.length; j++) {
for (int j = 0; j < command.options.length; j++) {
Option opt = command.options[j];
left[j] = opt.toString();
if (opt.arg != null) left[j] += " " + opt.arg;
if (left[j].length() > lenLeft) {
lenLeft = left[j].length();
if (opt.arg != null) {
left[j] += " " + opt.arg;
}
String[] lefts = left[j].split("\n");
for (String s : lefts) {
if (s.length() > lenLeft) {
lenLeft = s.length();
}
}
right[j] = rb.getString(opt.description);
}
for (int j=0; j<left.length; j++) {
System.err.printf(" %-" + lenLeft + "s %s\n",
left[j], right[j]);
for (int j = 0; j < left.length; j++) {
String[] lefts = left[j].split("\n");
String[] rights = right[j].split("\n");
for (int i = 0; i < lefts.length && i < rights.length; i++) {
String s1 = i < lefts.length ? lefts[i] : "";
String s2 = i < rights.length ? rights[i] : "";
if (i == 0) {
System.err.printf(" %-" + lenLeft + "s %s\n", s1, s2);
} else {
System.err.printf(" %-" + lenLeft + "s %s\n", s1, s2);
}
}
}
System.err.println();
System.err.println(rb.getString(

View File

@ -133,10 +133,16 @@ public class Resources extends java.util.ListResourceBundle {
"do not prompt"}, //-noprompt
{"password.through.protected.mechanism",
"password through protected mechanism"}, //-protected
{"provider.argument",
"provider argument"}, //-providerarg
{"provider.class.name",
"provider class name"}, //-providerclass
// The following 2 values should span 2 lines, the first for the
// option itself, the second for its -providerArg value.
{"addprovider.option",
"add security provider by name (e.g. SunPKCS11)\n" +
"configure argument for -addprovider"}, //-addprovider
{"provider.class.option",
"add security provider by fully-qualified class name\n" +
"configure argument for -providerclass"}, //-providerclass
{"provider.name",
"provider name"}, //-providername
{"provider.classpath",
@ -209,7 +215,9 @@ public class Resources extends java.util.ListResourceBundle {
{"Illegal.startdate.value", "Illegal startdate value"},
{"Validity.must.be.greater.than.zero",
"Validity must be greater than zero"},
{"provName.not.a.provider", "{0} not a provider"},
{"provclass.not.a.provider", "%s not a provider"},
{"provider.name.not.found", "Provider named \"%s\" not found"},
{"provider.class.not.found", "Provider \"%s\" not found"},
{"Usage.error.no.command.provided", "Usage error: no command provided"},
{"Source.keystore.file.exists.but.is.empty.", "Source keystore file exists, but is empty: "},
{"Please.specify.srckeystore", "Please specify -srckeystore"},

View File

@ -30,7 +30,8 @@ grant codeBase "jrt:/jdk.crypto.ucrypto" {
permission java.security.SecurityPermission "putProviderProperty.OracleUcrypto";
permission java.security.SecurityPermission "clearProviderProperties.OracleUcrypto";
permission java.security.SecurityPermission "removeProviderProperty.OracleUcrypto";
permission java.io.FilePermission "${java.home}/conf/security/ucrypto-solaris.cfg", "read";
// Needed for reading Ucrypto config file
permission java.io.FilePermission "<<ALL FILES>>", "read";
};
grant codeBase "jrt:/java.sql" {

View File

@ -235,13 +235,14 @@ public final class UcryptoProvider extends Provider {
@Override
public Provider configure(String configArg) throws InvalidParameterException {
// default policy entry only grants read access to default config
if (!defConfigName.equals(configArg)) {
throw new InvalidParameterException("Ucrypto provider can only be " +
"configured with default configuration file");
try {
init(configArg);
} catch (UcryptoException ue) {
InvalidParameterException ipe =
new InvalidParameterException("Error using " + configArg);
ipe.initCause(ue.getCause());
throw ipe;
}
// re-read the config
init(defConfigName);
return this;
}

View File

@ -118,7 +118,8 @@ public class Main {
boolean protectedPath; // protected authentication path
String storetype; // keystore type
String providerName; // provider name
Vector<String> providers = null; // list of providers
List<String> providers = null; // list of provider names
List<String> providerClasses = null; // list of provider classes
// arguments for provider constructors
HashMap<String,String> providerArgs = new HashMap<>();
char[] keypass; // private key password
@ -174,30 +175,36 @@ public class Main {
// Try to load and install the specified providers
if (providers != null) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
Enumeration<String> e = providers.elements();
while (e.hasMoreElements()) {
String provName = e.nextElement();
Class<?> provClass;
if (cl != null) {
provClass = cl.loadClass(provName);
} else {
provClass = Class.forName(provName);
for (String provName: providers) {
try {
KeyStoreUtil.loadProviderByName(provName,
providerArgs.get(provName));
if (debug) {
System.out.println("loadProviderByName: " + provName);
}
} catch (IllegalArgumentException e) {
throw new Exception(String.format(rb.getString(
"provider.name.not.found"), provName));
}
}
}
Object obj = provClass.newInstance();
if (!(obj instanceof Provider)) {
MessageFormat form = new MessageFormat(rb.getString
("provName.not.a.provider"));
Object[] source = {provName};
throw new Exception(form.format(source));
if (providerClasses != null) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
for (String provClass: providerClasses) {
try {
KeyStoreUtil.loadProviderByClass(provClass,
providerArgs.get(provClass), cl);
if (debug) {
System.out.println("loadProviderByClass: " + provClass);
}
} catch (ClassCastException cce) {
throw new Exception(String.format(rb.getString(
"provclass.not.a.provider"), provClass));
} catch (IllegalArgumentException e) {
throw new Exception(String.format(rb.getString(
"provider.class.not.found"), provClass), e.getCause());
}
Provider p = (Provider) obj;
String provArg = providerArgs.get(provName);
if (provArg != null) {
p = p.configure(provArg);
}
Security.addProvider(p);
}
}
@ -335,11 +342,26 @@ public class Main {
} else if (collator.compare(flags, "-providerName") ==0) {
if (++n == args.length) usageNoArg();
providerName = args[n];
} else if ((collator.compare(flags, "-provider") == 0) ||
(collator.compare(flags, "-providerClass") == 0)) {
} else if (collator.compare(flags, "-provider") == 0 ||
collator.compare(flags, "-providerClass") == 0) {
if (++n == args.length) usageNoArg();
if (providerClasses == null) {
providerClasses = new ArrayList<>(3);
}
providerClasses.add(args[n]);
if (args.length > (n+1)) {
flags = args[n+1];
if (collator.compare(flags, "-providerArg") == 0) {
if (args.length == (n+2)) usageNoArg();
providerArgs.put(args[n], args[n+2]);
n += 2;
}
}
} else if (collator.compare(flags, "-addprovider") == 0) {
if (++n == args.length) usageNoArg();
if (providers == null) {
providers = new Vector<String>(3);
providers = new ArrayList<>(3);
}
providers.add(args[n]);
@ -584,9 +606,14 @@ public class Main {
(".providerName.name.provider.name"));
System.out.println();
System.out.println(rb.getString
(".providerClass.class.name.of.cryptographic.service.provider.s"));
(".add.provider.option"));
System.out.println(rb.getString
(".providerArg.arg.master.class.file.and.constructor.argument"));
(".providerArg.option.1"));
System.out.println();
System.out.println(rb.getString
(".providerClass.option"));
System.out.println(rb.getString
(".providerArg.option.2"));
System.out.println();
System.out.println(rb.getString
(".strict.treat.warnings.as.errors"));

View File

@ -40,8 +40,9 @@ public class Resources extends java.util.ListResourceBundle {
{"6SPACE", " "},
{"COMMA", ", "},
{"provName.not.a.provider", "{0} not a provider"},
{"signerClass.is.not.a.signing.mechanism", "{0} is not a signing mechanism"},
{"provclass.not.a.provider", "%s not a provider"},
{"provider.name.not.found", "Provider named \"%s\" not found"},
{"provider.class.not.found", "Provider \"%s\" not found"},
{"jarsigner.error.", "jarsigner error: "},
{"Illegal.option.", "Illegal option: "},
{"This.option.is.deprecated", "This option is deprecated: "},
@ -105,10 +106,14 @@ public class Resources extends java.util.ListResourceBundle {
"[-protected] keystore has protected authentication path"},
{".providerName.name.provider.name",
"[-providerName <name>] provider name"},
{".providerClass.class.name.of.cryptographic.service.provider.s",
"[-providerClass <class> name of cryptographic service provider's"},
{".providerArg.arg.master.class.file.and.constructor.argument",
" [-providerArg <arg>]] ... master class file and constructor argument"},
{".add.provider.option",
"[-addprovider <name> add security provider by name (e.g. SunPKCS11)"},
{".providerArg.option.1",
" [-providerArg <arg>]] ... configure argument for -addprovider"},
{".providerClass.option",
"[-providerClass <class> add security provider by fully-qualified class name"},
{".providerArg.option.2",
" [-providerArg <arg>]] ... configure argument for -providerClass"},
{".strict.treat.warnings.as.errors",
"[-strict] treat warnings as errors"},
{".conf.url.specify.a.pre.configured.options.file",

View File

@ -37,7 +37,7 @@ setenv LD_LIBRARY_PATH $WS/test/sun/security/pkcs11/nss/lib/solaris-sparc
modutil -create -dbdir .
modutil -changepw "NSS Internal PKCS #11 Module" -dbdir .
$JHOME/bin/keytool -list -storetype PKCS11 -providerclass sun.security.pkcs11.SunPKCS11 -providerarg "--name=NSS\nnssSecmodDirectory=." -v -storepass test12
$JHOME/bin/keytool -list -storetype PKCS11 -addprovider SunPKCS11 -providerarg "--name=NSS\nnssSecmodDirectory=." -v -storepass test12
modutil -fips true -dbdir .

View File

@ -0,0 +1,161 @@
/*
* Copyright (c) 2016, 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 4906940 8130302
* @summary -providerPath, -providerClass, -addprovider, and -providerArg
* @library /lib/testlibrary /test/lib/share/classes
* @modules java.base/jdk.internal.misc
*/
import jdk.test.lib.JDKToolLauncher;
import jdk.test.lib.process.OutputAnalyzer;
import jdk.test.lib.process.ProcessTools;
import jdk.testlibrary.JarUtils;
import java.nio.file.*;
public class AltProvider {
private static final String TEST_SRC =
Paths.get(System.getProperty("test.src")).toString();
private static final Path MOD_SRC_DIR = Paths.get(TEST_SRC, "alt");
private static final Path MOD_DEST_DIR = Paths.get("mods");
private static final String ktCommand = "-keystore x.jks " +
"-storepass changeit -storetype dummyks -list -debug";
private static final String jsCommand = "-keystore x.jks " +
"-storepass changeit -storetype dummyks -debug x.jar x";
public static void main(String[] args) throws Throwable {
// Compile the provider
CompilerUtils.compile(
MOD_SRC_DIR, MOD_DEST_DIR,
"-modulesourcepath",
MOD_SRC_DIR.toString());
// Create a keystore
tool("keytool", "-keystore x.jks -storetype jks -genkeypair" +
" -storepass changeit -keypass changeit -alias x -dname CN=X")
.shouldHaveExitValue(0);
// Create a jar file
JarUtils.createJar("x.jar", "x.jks");
// Test starts here
// Without new provider
testBoth("", 1, "DUMMYKS not found");
// legacy use (-providerPath only supported by keytool)
testKeytool("-providerPath mods/test.dummy " +
"-providerClass org.test.dummy.DummyProvider -providerArg full",
0, "loadProviderByClass: org.test.dummy.DummyProvider");
// legacy, on classpath
testBoth("-J-cp -Jmods/test.dummy " +
"-providerClass org.test.dummy.DummyProvider -providerArg full",
0, "loadProviderByClass: org.test.dummy.DummyProvider");
// Wrong name
testBoth("-J-cp -Jmods/test.dummy " +
"-providerClass org.test.dummy.Dummy -providerArg full",
1, "Provider \"org.test.dummy.Dummy\" not found");
// Not a provider name
testBoth("-J-cp -Jmods/test.dummy " +
"-providerClass java.lang.Object -providerArg full",
1, "java.lang.Object not a provider");
// without arg
testBoth("-J-cp -Jmods/test.dummy " +
"-providerClass org.test.dummy.DummyProvider",
1, "DUMMYKS not found");
// old -provider still works
testBoth("-J-cp -Jmods/test.dummy " +
"-provider org.test.dummy.DummyProvider -providerArg full",
0, "loadProviderByClass: org.test.dummy.DummyProvider");
// name in a module
testBoth("-J-mp -Jmods " +
"-addprovider Dummy -providerArg full",
0, "loadProviderByName: Dummy");
// -providerClass does not work
testBoth("-J-mp -Jmods " +
"-providerClass org.test.dummy.DummyProvider -providerArg full",
1, "Provider \"org.test.dummy.DummyProvider\" not found");
// -addprovider with class does not work
testBoth("-J-mp -Jmods " +
"-addprovider org.test.dummy.DummyProvider -providerArg full",
1, "Provider named \"org.test.dummy.DummyProvider\" not found");
// -addprovider without arg does not work
testBoth("-J-mp -Jmods " +
"-addprovider Dummy",
1, "DUMMYKS not found");
}
// Test both tools with the same extra options
private static void testBoth(String args, int exitValue, String contains)
throws Throwable {
testKeytool(args, exitValue, contains);
testJarsigner(args, exitValue, contains);
}
// Test keytool with extra options and check exitValue and output
private static void testKeytool(String args, int exitValue, String contains)
throws Throwable {
tool("keytool", ktCommand + " " + args)
.shouldHaveExitValue(exitValue)
.shouldContain(contains);
}
// Test jarsigner with extra options and check exitValue and output
private static void testJarsigner(String args, int exitValue, String contains)
throws Throwable {
tool("jarsigner", jsCommand + " " + args)
.shouldHaveExitValue(exitValue)
.shouldContain(contains);
}
// Launch a tool with args (space separated string)
private static OutputAnalyzer tool(String tool, String args)
throws Throwable {
JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK(tool);
for (String a: args.split("\\s+")) {
if (a.startsWith("-J")) {
l.addVMArg(a.substring(2));
} else {
l.addToolArg(a);
}
}
return ProcessTools.executeCommand(l.getCommand());
}
}

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2016, 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.
*/
module test.dummy {
provides java.security.Provider with org.test.dummy.DummyProvider;
}

View File

@ -21,22 +21,22 @@
* questions.
*/
/*
*
*
* @bug 4906490
* @summary Dummy security service provider.
* It is cited by the AltProviderPath.sh script.
*/
package org.test.dummy;
import java.util.*;
import java.security.*;
public class DummyProvider extends Provider {
public DummyProvider() {
super("Dummy", 0.1, "Dummy Provider");
super("Dummy", 0.1, "Dummy Provider with nothing");
}
@Override
public Provider configure(String configArg) {
return new DummyProvider(configArg);
}
private DummyProvider(String arg) {
super("Dummy", 0.2, "Dummy Provider with " + arg);
//
// KeyStore
//

View File

@ -1,122 +0,0 @@
#
# Copyright (c) 2004, 2013, 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 4906940
# @summary Add -providerPath option for keytool allowing one to specify
# an additional classpath to search for providers.
# @author Andrew Fan
#
# @run build DummyProvider
# @run shell AltProviderPath.sh
# set a few environment variables so that the shell-script can run stand-alone
# in the source directory
if [ "${TESTSRC}" = "" ] ; then
TESTSRC="."
fi
if [ "${TESTCLASSES}" = "" ] ; then
TESTCLASSES="."
fi
if [ "${TESTJAVA}" = "" ] ; then
echo "TESTJAVA not set. Test cannot execute."
echo "FAILED!!!"
exit 1
fi
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
SunOS | Linux | Darwin | AIX )
NULL=/dev/null
PS=":"
FS="/"
;;
CYGWIN* )
NULL=/dev/null
PS=";"
FS="/"
;;
Windows_* )
NULL=NUL
PS=";"
FS="\\"
;;
* )
echo "Unrecognized operating system!"
exit 1;
;;
esac
# the test code
#genkey
${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -genkey -v -alias dummyTestCA \
-keyalg "RSA" -keysize 1024 -sigalg "ShA1WithRSA" \
-dname "cn=Dummy Test CA, ou=JSN, o=JavaSoft, c=US" -validity 3650 \
-keypass storepass -keystore keystoreCA.dks -storepass storepass \
-storetype "dummyks" -provider "org.test.dummy.DummyProvider" \
-providerPath ${TESTCLASSES}
if [ $? -ne 0 ]; then
exit 1
fi
#Change keystore password
${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -storepasswd -new storepass2 \
-keystore keystoreCA.dks -storetype "dummyks" -storepass storepass \
-provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES}
if [ $? -ne 0 ]; then
exit 1
fi
#Change keystore key password
${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -keypasswd -alias "dummyTestCA" \
-keypass storepass -new keypass -keystore keystoreCA.dks \
-storetype "dummyks" -storepass storepass2 \
-provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES}
if [ $? -ne 0 ]; then
exit 1
fi
#Export certificate
${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -v -export -rfc -alias "dummyTestCA" \
-file "dummyTestCA.der" -keystore keystoreCA.dks -storetype "dummyks" \
-storepass storepass2 -provider "org.test.dummy.DummyProvider" \
-providerPath ${TESTCLASSES}
if [ $? -ne 0 ]; then
exit 1
fi
#list keystore
${TESTJAVA}${FS}bin${FS}keytool ${TESTTOOLVMOPTS} -v -list -keystore keystoreCA.dks \
-storetype "dummyks" -storepass storepass2 \
-provider "org.test.dummy.DummyProvider" -providerPath ${TESTCLASSES}
if [ $? -ne 0 ]; then
exit 1
fi
exit 0

View File

@ -82,8 +82,9 @@ public class KeyToolTest {
static final String NSS_P11_ARG =
"-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nss " +
"-providerClass sun.security.pkcs11.SunPKCS11 " +
"-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 " +
@ -91,12 +92,12 @@ public class KeyToolTest {
"-providerArg p11-nss.txt ";
static final String NZZ_P11_ARG =
"-keystore NONE -storetype PKCS11 -providerName SunPKCS11-nzz " +
"-providerClass sun.security.pkcs11.SunPKCS11 " +
"-addprovider SunPKCS11 " +
"-providerArg p11-nzz.txt ";
static final String NZZ_SRC_P11_ARG =
"-srckeystore NONE -srcstoretype PKCS11 " +
"-srcproviderName SunPKCS11-nzz " +
"-providerClass sun.security.pkcs11.SunPKCS11 " +
"-addprovider SunPKCS11 " +
"-providerArg p11-nzz.txt ";
static final String SUN_P11_ARG = "-keystore NONE -storetype PKCS11 ";
static final String SUN_SRC_P11_ARG =
@ -1715,9 +1716,9 @@ public class KeyToolTest {
// 14. keytool -printcert -file cert
testOK("", "-printcert -file cert -keystore x.jks -storetype JKS");
remove("cert");
// 15. keytool -list -storepass password -provider sun.security.provider.Sun
// 15. keytool -list -storepass password -addprovider SUN
testOK("", "-list -storepass password" +
" -provider sun.security.provider.Sun" +
" -addprovider SUN" +
" -keystore x.jks -storetype JKS");
//Error tests

View File

@ -50,7 +50,7 @@ from keytool is correct (you can read everything in english fine).
<li> keytool -import -v -file /tmp/cert -storepass password
Check error (Certificate reply and cert are the same)
<li> keytool -printcert -file /tmp/cert
<li> keytool -list -storepass password -provider sun.security.provider.Sun
<li> keytool -list -storepass password -addprovider SUN
</ol>
Error tests
@ -93,19 +93,19 @@ PKCS#11 tests
<ol>
<li> sccs edit cert8.db key3.db
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -genkey -alias genkey -dname cn=genkey -keysize 512 -keyalg rsa
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -list
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -list -alias genkey
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -certreq -alias genkey -file genkey.certreq
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -export -alias genkey -file genkey.cert
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -genkey -alias genkey -dname cn=genkey -keysize 512 -keyalg rsa
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -list
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -list -alias genkey
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -certreq -alias genkey -file genkey.certreq
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -export -alias genkey -file genkey.cert
<li> keytool -printcert -file genkey.cert
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -selfcert -alias genkey -dname cn=selfCert
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -selfcert -alias genkey -dname cn=selfCert
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -list -alias genkey -v
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -list -alias genkey -v
(check that cert subject DN is [cn=selfCert])
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -delete -alias genkey
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -providerClass sun.security.pkcs11.SunPKCS11 -providerArg p11-nss.txt -list
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -delete -alias genkey
<li> keytool -keystore NONE -storepass test12 -storetype PKCS11 -providerName SunPKCS11-nss -addprovider SunPKCS11 -providerArg p11-nss.txt -list
(check for empty database listing)
<li> sccs unedit cert8.db key3.db