--- old/src/java.base/share/classes/sun/security/tools/keytool/Main.java 2016-02-19 21:04:35.000000000 +0800 +++ new/src/java.base/share/classes/sun/security/tools/keytool/Main.java 2016-02-19 21:04:35.000000000 +0800 @@ -54,7 +54,6 @@ import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; -import java.lang.reflect.Constructor; import java.math.BigInteger; import java.net.URI; import java.net.URL; @@ -129,6 +128,7 @@ // them through the command line. private Set> providers = null; + private Set> providerClasses = null; private String storetype = null; private boolean hasStoretypeOption = false; private String srcProviderName = null; @@ -167,57 +167,57 @@ enum Command { CERTREQ("Generates.a.certificate.request", ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME, - STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, - PROVIDERARG, PROVIDERPATH, V, PROTECTED), + STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER, + PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), CHANGEALIAS("Changes.an.entry.s.alias", ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS, - STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, + STORETYPE, PROVIDERNAME, PROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), DELETE("Deletes.an.entry", ALIAS, KEYSTORE, STOREPASS, STORETYPE, - PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, + PROVIDERNAME, PROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), EXPORTCERT("Exports.certificate", RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS, - STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, + STORETYPE, PROVIDERNAME, PROVIDER, 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, PROVIDER, + 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, PROVIDER, + 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, PROVIDER, + 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, PROVIDER, PROVIDERCLASS, PROVIDERPATH, V), IMPORTPASS("Imports.a.password", ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE, - STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS, - PROVIDERARG, PROVIDERPATH, V, PROTECTED), + STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER, + PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore", SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE, DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS, SRCPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME, SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS, - NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, + NOPROMPT, PROVIDER, PROVIDERCLASS, PROVIDERPATH, V), KEYPASSWD("Changes.the.key.password.of.an.entry", ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS, - STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, + STORETYPE, PROVIDERNAME, PROVIDER, PROVIDERCLASS, PROVIDERPATH, V), LIST("Lists.entries.in.a.keystore", RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE, - PROVIDERNAME, PROVIDERCLASS, PROVIDERARG, + PROVIDERNAME, PROVIDER, PROVIDERCLASS, PROVIDERPATH, V, PROTECTED), PRINTCERT("Prints.the.content.of.a.certificate", RFC, FILEIN, SSLSERVER, JARFILE, V), @@ -227,26 +227,26 @@ FILEIN, V), STOREPASSWD("Changes.the.store.password.of.a.keystore", NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME, - PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), + PROVIDER, 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, PROVIDER, + PROVIDERCLASS, PROVIDERPATH, V), SELFCERT("Generates.a.self.signed.certificate", ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME, - PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V), + PROVIDER, 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, PROVIDER, + 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); + PROVIDER, PROVIDERCLASS, PROVIDERPATH, V); final String description; final Option[] options; @@ -290,48 +290,48 @@ enum Option { ALIAS("alias", "", "alias.name.of.the.entry.to.process"), - DESTALIAS("destalias", "", "destination.alias"), + DESTALIAS("destalias", "", "destination.alias"), DESTKEYPASS("destkeypass", "", "destination.key.password"), - DESTKEYSTORE("destkeystore", "", "destination.keystore.name"), + DESTKEYSTORE("destkeystore", "", "destination.keystore.name"), DESTPROTECTED("destprotected", null, "destination.keystore.password.protected"), - DESTPROVIDERNAME("destprovidername", "", "destination.keystore.provider.name"), + DESTPROVIDERNAME("destprovidername", "", "destination.keystore.provider.name"), DESTSTOREPASS("deststorepass", "", "destination.keystore.password"), - DESTSTORETYPE("deststoretype", "", "destination.keystore.type"), - DNAME("dname", "", "distinguished.name"), + DESTSTORETYPE("deststoretype", "", "destination.keystore.type"), + DNAME("dname", "", "distinguished.name"), EXT("ext", "", "X.509.extension"), - FILEOUT("file", "", "output.file.name"), - FILEIN("file", "", "input.file.name"), + FILEOUT("file", "", "output.file.name"), + FILEIN("file", "", "input.file.name"), ID("id", "", "Serial.ID.of.cert.to.revoke"), - INFILE("infile", "", "input.file.name"), - KEYALG("keyalg", "", "key.algorithm.name"), + INFILE("infile", "", "input.file.name"), + KEYALG("keyalg", "", "key.algorithm.name"), KEYPASS("keypass", "", "key.password"), - KEYSIZE("keysize", "", "key.bit.size"), + KEYSIZE("keysize", "", "key.bit.size"), KEYSTORE("keystore", "", "keystore.name"), NEW("new", "", "new.password"), NOPROMPT("noprompt", null, "do.not.prompt"), - OUTFILE("outfile", "", "output.file.name"), + OUTFILE("outfile", "", "output.file.name"), PROTECTED("protected", null, "password.through.protected.mechanism"), - PROVIDERARG("providerarg", "", "provider.argument"), - PROVIDERCLASS("providerclass", "", "provider.class.name"), - PROVIDERNAME("providername", "", "provider.name"), - PROVIDERPATH("providerpath", "", "provider.classpath"), + PROVIDERCLASS("providerclass", "\n[-providerarg ]", "provider.class.option"), + PROVIDER("provider", "\n[-providerarg ]", "provider.option"), + PROVIDERNAME("providername", "", "provider.name"), + PROVIDERPATH("providerpath", "", "provider.classpath"), RFC("rfc", null, "output.in.RFC.style"), - SIGALG("sigalg", "", "signature.algorithm.name"), - SRCALIAS("srcalias", "", "source.alias"), + SIGALG("sigalg", "", "signature.algorithm.name"), + SRCALIAS("srcalias", "", "source.alias"), SRCKEYPASS("srckeypass", "", "source.key.password"), - SRCKEYSTORE("srckeystore", "", "source.keystore.name"), + SRCKEYSTORE("srckeystore", "", "source.keystore.name"), SRCPROTECTED("srcprotected", null, "source.keystore.password.protected"), - SRCPROVIDERNAME("srcprovidername", "", "source.keystore.provider.name"), + SRCPROVIDERNAME("srcprovidername", "", "source.keystore.provider.name"), SRCSTOREPASS("srcstorepass", "", "source.keystore.password"), - SRCSTORETYPE("srcstoretype", "", "source.keystore.type"), + SRCSTORETYPE("srcstoretype", "", "source.keystore.type"), SSLSERVER("sslserver", "", "SSL.server.host.and.port"), - JARFILE("jarfile", "", "signed.jar.file"), - STARTDATE("startdate", "", "certificate.validity.start.date.time"), + JARFILE("jarfile", "", "signed.jar.file"), + STARTDATE("startdate", "", "certificate.validity.start.date.time"), STOREPASS("storepass", "", "keystore.password"), - STORETYPE("storetype", "", "keystore.type"), + STORETYPE("storetype", "", "keystore.type"), TRUSTCACERTS("trustcacerts", null, "trust.certificates.from.cacerts"), V("v", null, "verbose.output"), - VALIDITY("validity", "", "validity.number.of.days"); + VALIDITY("validity", "", "validity.number.of.days"); final String name, arg, description; Option(String name, String arg, String description) { @@ -550,12 +550,11 @@ 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)) { + } else if (collator.compare(flags, "-provider") == 0) { if (providers == null) { providers = new HashSet> (3); } - String providerClass = args[++i]; + String provider = args[++i]; String providerArg = null; if (args.length > (i+1)) { @@ -567,6 +566,23 @@ } } providers.add( + Pair.of(provider, providerArg)); + } else if (collator.compare(flags, "-providerclass") == 0) { + if (providerClasses == null) { + providerClasses = new HashSet> (3); + } + String providerClass = 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; + } + } + providerClasses.add( Pair.of(providerClass, providerArg)); } @@ -618,7 +634,6 @@ return cmd != PRINTCERT && cmd != PRINTCERTREQ; } - /** * Execute the commands. */ @@ -702,46 +717,43 @@ (rb.getString("Validity.must.be.greater.than.zero")); } - // Try to load and install specified provider - if (providers != null) { - ClassLoader cl = null; - if (pathlist != null) { - String path = null; - path = PathList.appendPath( - path, System.getProperty("java.class.path")); - path = PathList.appendPath( - path, System.getProperty("env.class.path")); - path = PathList.appendPath(path, pathlist); - - URL[] urls = PathList.pathToURLs(path); - cl = new URLClassLoader(urls); - } else { - cl = ClassLoader.getSystemClassLoader(); - } + try { + // Try to load and install specified provider + if (providers != null) { + for (Pair provider : providers) { + KeyStoreUtil.loadProviderByName( + provider.fst, provider.snd, debug); + } + } + if (providerClasses != null) { + ClassLoader cl = null; + if (pathlist != null) { + String path = null; + path = PathList.appendPath( + path, System.getProperty("java.class.path")); + path = PathList.appendPath( + path, System.getProperty("env.class.path")); + path = PathList.appendPath(path, pathlist); - for (Pair provider: providers) { - String provName = provider.fst; - Class provClass; - if (cl != null) { - provClass = cl.loadClass(provName); + URL[] urls = PathList.pathToURLs(path); + cl = new URLClassLoader(urls); } else { - provClass = Class.forName(provName); + cl = ClassLoader.getSystemClassLoader(); } - - 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); + for (Pair provider : providerClasses) { + KeyStoreUtil.loadProviderByClass( + provider.fst, provider.snd, cl, debug); } - Security.addProvider(p); } + } catch (IllegalArgumentException e) { + MessageFormat form = new MessageFormat + (rb.getString("provName.not.a.provider")); + Object[] source = {e.getMessage()}; + Exception ex = new Exception(form.format(source)); + if (e.getCause() != null) { + ex.initCause(e.getCause()); + } + throw ex; } if (command == LIST && verbose && rfc) { @@ -4132,27 +4144,38 @@ 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 lenLeft) { - lenLeft = left[j].length(); + 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