diff -r f774415f91ad -r 9dc7586be5f0 jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java --- a/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Mon Jul 11 17:18:59 2016 -0700 +++ b/jdk/src/java.base/share/classes/sun/security/tools/keytool/Main.java Tue Jul 12 09:41:49 2016 +0800 @@ -33,13 +33,11 @@ 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 @@ // 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; @@ -166,57 +165,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, 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 @@ 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 @@ 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"), + ADDPROVIDER("addprovider", "\n[-providerarg ]", "addprovider.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) { @@ -344,8 +343,6 @@ } }; - 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 @@ 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> (3); + } else if (collator.compare(flags, "-provider") == 0 || + collator.compare(flags, "-providerclass") == 0) { + if (providerClasses == null) { + providerClasses = new HashSet> (3); } String providerClass = args[++i]; String providerArg = null; @@ -565,8 +562,25 @@ i += 2; } } + providerClasses.add( + Pair.of(providerClass, providerArg)); + } else if (collator.compare(flags, "-addprovider") == 0) { + if (providers == null) { + providers = new HashSet> (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(providerClass, providerArg)); + Pair.of(provider, providerArg)); } /* @@ -617,7 +631,6 @@ return cmd != PRINTCERT && cmd != PRINTCERTREQ; } - /** * Execute the commands. */ @@ -703,6 +716,20 @@ // Try to load and install specified provider if (providers != null) { + for (Pair 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 @@ } else { cl = ClassLoader.getSystemClassLoader(); } - - for (Pair provider: providers) { - String provName = provider.fst; - Class provClass; - if (cl != null) { - provClass = cl.loadClass(provName); - } else { - provClass = Class.forName(provName); + for (Pair 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 @@ 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(); + 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