37 import java.security.Signature;
38 import java.security.Timestamp;
39 import java.security.UnrecoverableEntryException;
40 import java.security.UnrecoverableKeyException;
41 import java.security.Principal;
42 import java.security.Provider;
43 import java.security.cert.Certificate;
44 import java.security.cert.CertificateFactory;
45 import java.security.cert.CertStoreException;
46 import java.security.cert.CRL;
47 import java.security.cert.X509Certificate;
48 import java.security.cert.CertificateException;
49 import java.security.cert.URICertStoreParameters;
50
51
52 import java.text.Collator;
53 import java.text.MessageFormat;
54 import java.util.*;
55 import java.util.jar.JarEntry;
56 import java.util.jar.JarFile;
57 import java.lang.reflect.Constructor;
58 import java.math.BigInteger;
59 import java.net.URI;
60 import java.net.URL;
61 import java.net.URLClassLoader;
62 import java.security.cert.CertStore;
63
64 import java.security.cert.X509CRL;
65 import java.security.cert.X509CRLEntry;
66 import java.security.cert.X509CRLSelector;
67 import javax.security.auth.x500.X500Principal;
68 import java.util.Base64;
69
70 import sun.security.util.KeyUtil;
71 import sun.security.util.ObjectIdentifier;
72 import sun.security.pkcs10.PKCS10;
73 import sun.security.pkcs10.PKCS10Attribute;
74 import sun.security.provider.X509Factory;
75 import sun.security.provider.certpath.ssl.SSLServerCertStore;
76 import sun.security.util.Password;
77 import javax.crypto.KeyGenerator;
112 private String keyAlgName = null;
113 private boolean verbose = false;
114 private int keysize = -1;
115 private boolean rfc = false;
116 private long validity = (long)90;
117 private String alias = null;
118 private String dname = null;
119 private String dest = null;
120 private String filename = null;
121 private String infilename = null;
122 private String outfilename = null;
123 private String srcksfname = null;
124
125 // User-specified providers are added before any command is called.
126 // However, they are not removed before the end of the main() method.
127 // If you're calling KeyTool.main() directly in your own Java program,
128 // please programtically add any providers you need and do not specify
129 // them through the command line.
130
131 private Set<Pair <String, String>> providers = null;
132 private String storetype = null;
133 private boolean hasStoretypeOption = false;
134 private String srcProviderName = null;
135 private String providerName = null;
136 private String pathlist = null;
137 private char[] storePass = null;
138 private char[] storePassNew = null;
139 private char[] keyPass = null;
140 private char[] keyPassNew = null;
141 private char[] newPass = null;
142 private char[] destKeyPass = null;
143 private char[] srckeyPass = null;
144 private String ksfname = null;
145 private File ksfile = null;
146 private InputStream ksStream = null; // keystore stream
147 private String sslserver = null;
148 private String jarfile = null;
149 private KeyStore keyStore = null;
150 private boolean token = false;
151 private boolean nullStream = false;
152 private boolean kssave = false;
153 private boolean noprompt = false;
154 private boolean trustcacerts = false;
155 private boolean protectedPath = false;
156 private boolean srcprotectedPath = false;
157 private CertificateFactory cf = null;
158 private KeyStore caks = null; // "cacerts" keystore
159 private char[] srcstorePass = null;
160 private String srcstoretype = null;
161 private Set<char[]> passwords = new HashSet<>();
162 private String startDate = null;
163
164 private List<String> ids = new ArrayList<>(); // used in GENCRL
165 private List<String> v3ext = new ArrayList<>();
166
167 enum Command {
168 CERTREQ("Generates.a.certificate.request",
169 ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
170 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
171 PROVIDERARG, PROVIDERPATH, V, PROTECTED),
172 CHANGEALIAS("Changes.an.entry.s.alias",
173 ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
174 STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
175 PROVIDERPATH, V, PROTECTED),
176 DELETE("Deletes.an.entry",
177 ALIAS, KEYSTORE, STOREPASS, STORETYPE,
178 PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
179 PROVIDERPATH, V, PROTECTED),
180 EXPORTCERT("Exports.certificate",
181 RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
182 STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
183 PROVIDERPATH, V, PROTECTED),
184 GENKEYPAIR("Generates.a.key.pair",
185 ALIAS, KEYALG, KEYSIZE, SIGALG, DESTALIAS, DNAME,
186 STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
187 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
188 PROVIDERARG, PROVIDERPATH, V, PROTECTED),
189 GENSECKEY("Generates.a.secret.key",
190 ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
191 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
192 PROVIDERARG, PROVIDERPATH, V, PROTECTED),
193 GENCERT("Generates.certificate.from.a.certificate.request",
194 RFC, INFILE, OUTFILE, ALIAS, SIGALG, DNAME,
195 STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
196 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
197 PROVIDERARG, PROVIDERPATH, V, PROTECTED),
198 IMPORTCERT("Imports.a.certificate.or.a.certificate.chain",
199 NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
200 KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
201 PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
202 PROVIDERPATH, V),
203 IMPORTPASS("Imports.a.password",
204 ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
205 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
206 PROVIDERARG, PROVIDERPATH, V, PROTECTED),
207 IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
208 SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
209 DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
210 SRCPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
211 SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
212 NOPROMPT, PROVIDERCLASS, PROVIDERARG, PROVIDERPATH,
213 V),
214 KEYPASSWD("Changes.the.key.password.of.an.entry",
215 ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
216 STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
217 PROVIDERPATH, V),
218 LIST("Lists.entries.in.a.keystore",
219 RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE,
220 PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
221 PROVIDERPATH, V, PROTECTED),
222 PRINTCERT("Prints.the.content.of.a.certificate",
223 RFC, FILEIN, SSLSERVER, JARFILE, V),
224 PRINTCERTREQ("Prints.the.content.of.a.certificate.request",
225 FILEIN, V),
226 PRINTCRL("Prints.the.content.of.a.CRL.file",
227 FILEIN, V),
228 STOREPASSWD("Changes.the.store.password.of.a.keystore",
229 NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
230 PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
231
232 // Undocumented start here, KEYCLONE is used a marker in -help;
233
234 KEYCLONE("Clones.a.key.entry",
235 ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
236 KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDERCLASS,
237 PROVIDERARG, PROVIDERPATH, V),
238 SELFCERT("Generates.a.self.signed.certificate",
239 ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
240 STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
241 PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V),
242 GENCRL("Generates.CRL",
243 RFC, FILEOUT, ID,
244 ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
245 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
246 PROVIDERARG, PROVIDERPATH, V, PROTECTED),
247 IDENTITYDB("Imports.entries.from.a.JDK.1.1.x.style.identity.database",
248 FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
249 PROVIDERCLASS, PROVIDERARG, PROVIDERPATH, V);
250
251 final String description;
252 final Option[] options;
253 final String name;
254
255 String altName; // "genkey" is altName for "genkeypair"
256
257 Command(String d, Option... o) {
258 description = d;
259 options = o;
260 name = "-" + name().toLowerCase(Locale.ENGLISH);
261 }
262 @Override
263 public String toString() {
264 return name;
265 }
266 public String getAltName() {
267 return altName;
268 }
269 public void setAltName(String altName) {
273 for (Command c: Command.values()) {
274 if (collator.compare(cmd, c.name) == 0
275 || (c.altName != null
276 && collator.compare(cmd, c.altName) == 0)) {
277 return c;
278 }
279 }
280 return null;
281 }
282 };
283
284 static {
285 Command.GENKEYPAIR.setAltName("-genkey");
286 Command.IMPORTCERT.setAltName("-import");
287 Command.EXPORTCERT.setAltName("-export");
288 Command.IMPORTPASS.setAltName("-importpassword");
289 }
290
291 enum Option {
292 ALIAS("alias", "<alias>", "alias.name.of.the.entry.to.process"),
293 DESTALIAS("destalias", "<destalias>", "destination.alias"),
294 DESTKEYPASS("destkeypass", "<arg>", "destination.key.password"),
295 DESTKEYSTORE("destkeystore", "<destkeystore>", "destination.keystore.name"),
296 DESTPROTECTED("destprotected", null, "destination.keystore.password.protected"),
297 DESTPROVIDERNAME("destprovidername", "<destprovidername>", "destination.keystore.provider.name"),
298 DESTSTOREPASS("deststorepass", "<arg>", "destination.keystore.password"),
299 DESTSTORETYPE("deststoretype", "<deststoretype>", "destination.keystore.type"),
300 DNAME("dname", "<dname>", "distinguished.name"),
301 EXT("ext", "<value>", "X.509.extension"),
302 FILEOUT("file", "<filename>", "output.file.name"),
303 FILEIN("file", "<filename>", "input.file.name"),
304 ID("id", "<id:reason>", "Serial.ID.of.cert.to.revoke"),
305 INFILE("infile", "<filename>", "input.file.name"),
306 KEYALG("keyalg", "<keyalg>", "key.algorithm.name"),
307 KEYPASS("keypass", "<arg>", "key.password"),
308 KEYSIZE("keysize", "<keysize>", "key.bit.size"),
309 KEYSTORE("keystore", "<keystore>", "keystore.name"),
310 NEW("new", "<arg>", "new.password"),
311 NOPROMPT("noprompt", null, "do.not.prompt"),
312 OUTFILE("outfile", "<filename>", "output.file.name"),
313 PROTECTED("protected", null, "password.through.protected.mechanism"),
314 PROVIDERARG("providerarg", "<arg>", "provider.argument"),
315 PROVIDERCLASS("providerclass", "<providerclass>", "provider.class.name"),
316 PROVIDERNAME("providername", "<providername>", "provider.name"),
317 PROVIDERPATH("providerpath", "<pathlist>", "provider.classpath"),
318 RFC("rfc", null, "output.in.RFC.style"),
319 SIGALG("sigalg", "<sigalg>", "signature.algorithm.name"),
320 SRCALIAS("srcalias", "<srcalias>", "source.alias"),
321 SRCKEYPASS("srckeypass", "<arg>", "source.key.password"),
322 SRCKEYSTORE("srckeystore", "<srckeystore>", "source.keystore.name"),
323 SRCPROTECTED("srcprotected", null, "source.keystore.password.protected"),
324 SRCPROVIDERNAME("srcprovidername", "<srcprovidername>", "source.keystore.provider.name"),
325 SRCSTOREPASS("srcstorepass", "<arg>", "source.keystore.password"),
326 SRCSTORETYPE("srcstoretype", "<srcstoretype>", "source.keystore.type"),
327 SSLSERVER("sslserver", "<server[:port]>", "SSL.server.host.and.port"),
328 JARFILE("jarfile", "<filename>", "signed.jar.file"),
329 STARTDATE("startdate", "<startdate>", "certificate.validity.start.date.time"),
330 STOREPASS("storepass", "<arg>", "keystore.password"),
331 STORETYPE("storetype", "<storetype>", "keystore.type"),
332 TRUSTCACERTS("trustcacerts", null, "trust.certificates.from.cacerts"),
333 V("v", null, "verbose.output"),
334 VALIDITY("validity", "<valDays>", "validity.number.of.days");
335
336 final String name, arg, description;
337 Option(String name, String arg, String description) {
338 this.name = name;
339 this.arg = arg;
340 this.description = description;
341 }
342 @Override
343 public String toString() {
344 return "-" + name;
345 }
346 };
347
348 private static final Class<?>[] PARAM_STRING = { String.class };
349
350 private static final String NONE = "NONE";
351 private static final String P11KEYSTORE = "PKCS11";
352 private static final String P12KEYSTORE = "PKCS12";
353 private final String keyAlias = "mykey";
354
533 } else if (collator.compare(flags, "-startdate") == 0) {
534 startDate = args[++i];
535 } else if (collator.compare(flags, "-validity") == 0) {
536 validity = Long.parseLong(args[++i]);
537 } else if (collator.compare(flags, "-ext") == 0) {
538 v3ext.add(args[++i]);
539 } else if (collator.compare(flags, "-id") == 0) {
540 ids.add(args[++i]);
541 } else if (collator.compare(flags, "-file") == 0) {
542 filename = args[++i];
543 } else if (collator.compare(flags, "-infile") == 0) {
544 infilename = args[++i];
545 } else if (collator.compare(flags, "-outfile") == 0) {
546 outfilename = args[++i];
547 } else if (collator.compare(flags, "-sslserver") == 0) {
548 sslserver = args[++i];
549 } else if (collator.compare(flags, "-jarfile") == 0) {
550 jarfile = args[++i];
551 } else if (collator.compare(flags, "-srckeystore") == 0) {
552 srcksfname = args[++i];
553 } else if ((collator.compare(flags, "-provider") == 0) ||
554 (collator.compare(flags, "-providerclass") == 0)) {
555 if (providers == null) {
556 providers = new HashSet<Pair <String, String>> (3);
557 }
558 String providerClass = args[++i];
559 String providerArg = null;
560
561 if (args.length > (i+1)) {
562 flags = args[i+1];
563 if (collator.compare(flags, "-providerarg") == 0) {
564 if (args.length == (i+2)) errorNeedArgument(flags);
565 providerArg = args[i+2];
566 i += 2;
567 }
568 }
569 providers.add(
570 Pair.of(providerClass, providerArg));
571 }
572
573 /*
574 * options
575 */
576 else if (collator.compare(flags, "-v") == 0) {
577 verbose = true;
578 } else if (collator.compare(flags, "-debug") == 0) {
579 // Already processed
580 } else if (collator.compare(flags, "-rfc") == 0) {
581 rfc = true;
582 } else if (collator.compare(flags, "-noprompt") == 0) {
583 noprompt = true;
584 } else if (collator.compare(flags, "-trustcacerts") == 0) {
585 trustcacerts = true;
586 } else if (collator.compare(flags, "-protected") == 0 ||
587 collator.compare(flags, "-destprotected") == 0) {
588 protectedPath = true;
589 } else if (collator.compare(flags, "-srcprotected") == 0) {
601
602 if (command == null) {
603 if (help) {
604 usage();
605 } else {
606 System.err.println(rb.getString("Usage.error.no.command.provided"));
607 tinyHelp();
608 }
609 } else if (help) {
610 usage();
611 command = null;
612 }
613
614 return args;
615 }
616
617 boolean isKeyStoreRelated(Command cmd) {
618 return cmd != PRINTCERT && cmd != PRINTCERTREQ;
619 }
620
621
622 /**
623 * Execute the commands.
624 */
625 void doCommands(PrintStream out) throws Exception {
626 if (storetype == null) {
627 storetype = KeyStore.getDefaultType();
628 }
629 storetype = KeyStoreUtil.niceStoreTypeName(storetype);
630
631 if (srcstoretype == null) {
632 srcstoretype = KeyStore.getDefaultType();
633 }
634 srcstoretype = KeyStoreUtil.niceStoreTypeName(srcstoretype);
635
636 if (P11KEYSTORE.equalsIgnoreCase(storetype) ||
637 KeyStoreUtil.isWindowsKeyStore(storetype)) {
638 token = true;
639 if (ksfname == null) {
640 ksfname = NONE;
641 }
685 if (KeyStoreUtil.isWindowsKeyStore(storetype)) {
686 if (storePass != null || keyPass != null ||
687 newPass != null || destKeyPass != null) {
688 throw new IllegalArgumentException(rb.getString
689 ("if.keystore.is.not.password.protected.then.storepass.keypass.and.new.must.not.be.specified"));
690 }
691 }
692
693 if (KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
694 if (srcstorePass != null || srckeyPass != null) {
695 throw new IllegalArgumentException(rb.getString
696 ("if.source.keystore.is.not.password.protected.then.srcstorepass.and.srckeypass.must.not.be.specified"));
697 }
698 }
699
700 if (validity <= (long)0) {
701 throw new Exception
702 (rb.getString("Validity.must.be.greater.than.zero"));
703 }
704
705 // Try to load and install specified provider
706 if (providers != null) {
707 ClassLoader cl = null;
708 if (pathlist != null) {
709 String path = null;
710 path = PathList.appendPath(
711 path, System.getProperty("java.class.path"));
712 path = PathList.appendPath(
713 path, System.getProperty("env.class.path"));
714 path = PathList.appendPath(path, pathlist);
715
716 URL[] urls = PathList.pathToURLs(path);
717 cl = new URLClassLoader(urls);
718 } else {
719 cl = ClassLoader.getSystemClassLoader();
720 }
721
722 for (Pair <String, String> provider: providers) {
723 String provName = provider.fst;
724 Class<?> provClass;
725 if (cl != null) {
726 provClass = cl.loadClass(provName);
727 } else {
728 provClass = Class.forName(provName);
729 }
730
731 Object obj = provClass.newInstance();
732 if (!(obj instanceof Provider)) {
733 MessageFormat form = new MessageFormat
734 (rb.getString("provName.not.a.provider"));
735 Object[] source = {provName};
736 throw new Exception(form.format(source));
737 }
738 Provider p = (Provider) obj;
739 String provArg = provider.snd;
740 if (provArg != null) {
741 p = p.configure(provArg);
742 }
743 Security.addProvider(p);
744 }
745 }
746
747 if (command == LIST && verbose && rfc) {
748 System.err.println(rb.getString
749 ("Must.not.specify.both.v.and.rfc.with.list.command"));
750 tinyHelp();
751 }
752
753 // Make sure provided passwords are at least 6 characters long
754 if (command == GENKEYPAIR && keyPass!=null && keyPass.length < 6) {
755 throw new Exception(rb.getString
756 ("Key.password.must.be.at.least.6.characters"));
757 }
758 if (newPass != null && newPass.length < 6) {
759 throw new Exception(rb.getString
760 ("New.password.must.be.at.least.6.characters"));
761 }
762 if (destKeyPass != null && destKeyPass.length < 6) {
763 throw new Exception(rb.getString
764 ("New.password.must.be.at.least.6.characters"));
4115 }
4116 } catch(IOException e) {
4117 throw new RuntimeException(e);
4118 }
4119 return result;
4120 }
4121
4122 /**
4123 * Prints the usage of this tool.
4124 */
4125 private void usage() {
4126 if (command != null) {
4127 System.err.println("keytool " + command +
4128 rb.getString(".OPTION."));
4129 System.err.println();
4130 System.err.println(rb.getString(command.description));
4131 System.err.println();
4132 System.err.println(rb.getString("Options."));
4133 System.err.println();
4134
4135 // Left and right sides of the options list
4136 String[] left = new String[command.options.length];
4137 String[] right = new String[command.options.length];
4138
4139 // Check if there's an unknown option
4140 boolean found = false;
4141
4142 // Length of left side of options list
4143 int lenLeft = 0;
4144 for (int j=0; j<left.length; j++) {
4145 Option opt = command.options[j];
4146 left[j] = opt.toString();
4147 if (opt.arg != null) left[j] += " " + opt.arg;
4148 if (left[j].length() > lenLeft) {
4149 lenLeft = left[j].length();
4150 }
4151 right[j] = rb.getString(opt.description);
4152 }
4153 for (int j=0; j<left.length; j++) {
4154 System.err.printf(" %-" + lenLeft + "s %s\n",
4155 left[j], right[j]);
4156 }
4157 System.err.println();
4158 System.err.println(rb.getString(
4159 "Use.keytool.help.for.all.available.commands"));
4160 } else {
4161 System.err.println(rb.getString(
4162 "Key.and.Certificate.Management.Tool"));
4163 System.err.println();
4164 System.err.println(rb.getString("Commands."));
4165 System.err.println();
4166 for (Command c: Command.values()) {
4167 if (c == KEYCLONE) break;
4168 System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
4169 }
4170 System.err.println();
4171 System.err.println(rb.getString(
4172 "Use.keytool.command.name.help.for.usage.of.command.name"));
4173 }
4174 }
4175
|
37 import java.security.Signature;
38 import java.security.Timestamp;
39 import java.security.UnrecoverableEntryException;
40 import java.security.UnrecoverableKeyException;
41 import java.security.Principal;
42 import java.security.Provider;
43 import java.security.cert.Certificate;
44 import java.security.cert.CertificateFactory;
45 import java.security.cert.CertStoreException;
46 import java.security.cert.CRL;
47 import java.security.cert.X509Certificate;
48 import java.security.cert.CertificateException;
49 import java.security.cert.URICertStoreParameters;
50
51
52 import java.text.Collator;
53 import java.text.MessageFormat;
54 import java.util.*;
55 import java.util.jar.JarEntry;
56 import java.util.jar.JarFile;
57 import java.math.BigInteger;
58 import java.net.URI;
59 import java.net.URL;
60 import java.net.URLClassLoader;
61 import java.security.cert.CertStore;
62
63 import java.security.cert.X509CRL;
64 import java.security.cert.X509CRLEntry;
65 import java.security.cert.X509CRLSelector;
66 import javax.security.auth.x500.X500Principal;
67 import java.util.Base64;
68
69 import sun.security.util.KeyUtil;
70 import sun.security.util.ObjectIdentifier;
71 import sun.security.pkcs10.PKCS10;
72 import sun.security.pkcs10.PKCS10Attribute;
73 import sun.security.provider.X509Factory;
74 import sun.security.provider.certpath.ssl.SSLServerCertStore;
75 import sun.security.util.Password;
76 import javax.crypto.KeyGenerator;
111 private String keyAlgName = null;
112 private boolean verbose = false;
113 private int keysize = -1;
114 private boolean rfc = false;
115 private long validity = (long)90;
116 private String alias = null;
117 private String dname = null;
118 private String dest = null;
119 private String filename = null;
120 private String infilename = null;
121 private String outfilename = null;
122 private String srcksfname = null;
123
124 // User-specified providers are added before any command is called.
125 // However, they are not removed before the end of the main() method.
126 // If you're calling KeyTool.main() directly in your own Java program,
127 // please programtically add any providers you need and do not specify
128 // them through the command line.
129
130 private Set<Pair <String, String>> providers = null;
131 private Set<Pair <String, String>> providerClasses = null;
132 private String storetype = null;
133 private boolean hasStoretypeOption = false;
134 private String srcProviderName = null;
135 private String providerName = null;
136 private String pathlist = null;
137 private char[] storePass = null;
138 private char[] storePassNew = null;
139 private char[] keyPass = null;
140 private char[] keyPassNew = null;
141 private char[] newPass = null;
142 private char[] destKeyPass = null;
143 private char[] srckeyPass = null;
144 private String ksfname = null;
145 private File ksfile = null;
146 private InputStream ksStream = null; // keystore stream
147 private String sslserver = null;
148 private String jarfile = null;
149 private KeyStore keyStore = null;
150 private boolean token = false;
151 private boolean nullStream = false;
152 private boolean kssave = false;
153 private boolean noprompt = false;
154 private boolean trustcacerts = false;
155 private boolean protectedPath = false;
156 private boolean srcprotectedPath = false;
157 private CertificateFactory cf = null;
158 private KeyStore caks = null; // "cacerts" keystore
159 private char[] srcstorePass = null;
160 private String srcstoretype = null;
161 private Set<char[]> passwords = new HashSet<>();
162 private String startDate = null;
163
164 private List<String> ids = new ArrayList<>(); // used in GENCRL
165 private List<String> v3ext = new ArrayList<>();
166
167 enum Command {
168 CERTREQ("Generates.a.certificate.request",
169 ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
170 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER,
171 PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
172 CHANGEALIAS("Changes.an.entry.s.alias",
173 ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
174 STORETYPE, PROVIDERNAME, PROVIDER, PROVIDERCLASS,
175 PROVIDERPATH, V, PROTECTED),
176 DELETE("Deletes.an.entry",
177 ALIAS, KEYSTORE, STOREPASS, STORETYPE,
178 PROVIDERNAME, PROVIDER, PROVIDERCLASS,
179 PROVIDERPATH, V, PROTECTED),
180 EXPORTCERT("Exports.certificate",
181 RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
182 STORETYPE, PROVIDERNAME, PROVIDER, PROVIDERCLASS,
183 PROVIDERPATH, V, PROTECTED),
184 GENKEYPAIR("Generates.a.key.pair",
185 ALIAS, KEYALG, KEYSIZE, SIGALG, DESTALIAS, DNAME,
186 STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
187 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER,
188 PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
189 GENSECKEY("Generates.a.secret.key",
190 ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
191 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER,
192 PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
193 GENCERT("Generates.certificate.from.a.certificate.request",
194 RFC, INFILE, OUTFILE, ALIAS, SIGALG, DNAME,
195 STARTDATE, EXT, VALIDITY, KEYPASS, KEYSTORE,
196 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER,
197 PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
198 IMPORTCERT("Imports.a.certificate.or.a.certificate.chain",
199 NOPROMPT, TRUSTCACERTS, PROTECTED, ALIAS, FILEIN,
200 KEYPASS, KEYSTORE, STOREPASS, STORETYPE,
201 PROVIDERNAME, PROVIDER, PROVIDERCLASS,
202 PROVIDERPATH, V),
203 IMPORTPASS("Imports.a.password",
204 ALIAS, KEYPASS, KEYALG, KEYSIZE, KEYSTORE,
205 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER,
206 PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
207 IMPORTKEYSTORE("Imports.one.or.all.entries.from.another.keystore",
208 SRCKEYSTORE, DESTKEYSTORE, SRCSTORETYPE,
209 DESTSTORETYPE, SRCSTOREPASS, DESTSTOREPASS,
210 SRCPROTECTED, SRCPROVIDERNAME, DESTPROVIDERNAME,
211 SRCALIAS, DESTALIAS, SRCKEYPASS, DESTKEYPASS,
212 NOPROMPT, PROVIDER, PROVIDERCLASS, PROVIDERPATH,
213 V),
214 KEYPASSWD("Changes.the.key.password.of.an.entry",
215 ALIAS, KEYPASS, NEW, KEYSTORE, STOREPASS,
216 STORETYPE, PROVIDERNAME, PROVIDER, PROVIDERCLASS,
217 PROVIDERPATH, V),
218 LIST("Lists.entries.in.a.keystore",
219 RFC, ALIAS, KEYSTORE, STOREPASS, STORETYPE,
220 PROVIDERNAME, PROVIDER, PROVIDERCLASS,
221 PROVIDERPATH, V, PROTECTED),
222 PRINTCERT("Prints.the.content.of.a.certificate",
223 RFC, FILEIN, SSLSERVER, JARFILE, V),
224 PRINTCERTREQ("Prints.the.content.of.a.certificate.request",
225 FILEIN, V),
226 PRINTCRL("Prints.the.content.of.a.CRL.file",
227 FILEIN, V),
228 STOREPASSWD("Changes.the.store.password.of.a.keystore",
229 NEW, KEYSTORE, STOREPASS, STORETYPE, PROVIDERNAME,
230 PROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
231
232 // Undocumented start here, KEYCLONE is used a marker in -help;
233
234 KEYCLONE("Clones.a.key.entry",
235 ALIAS, DESTALIAS, KEYPASS, NEW, STORETYPE,
236 KEYSTORE, STOREPASS, PROVIDERNAME, PROVIDER,
237 PROVIDERCLASS, PROVIDERPATH, V),
238 SELFCERT("Generates.a.self.signed.certificate",
239 ALIAS, SIGALG, DNAME, STARTDATE, VALIDITY, KEYPASS,
240 STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
241 PROVIDER, PROVIDERCLASS, PROVIDERPATH, V),
242 GENCRL("Generates.CRL",
243 RFC, FILEOUT, ID,
244 ALIAS, SIGALG, EXT, KEYPASS, KEYSTORE,
245 STOREPASS, STORETYPE, PROVIDERNAME, PROVIDER,
246 PROVIDERCLASS, PROVIDERPATH, V, PROTECTED),
247 IDENTITYDB("Imports.entries.from.a.JDK.1.1.x.style.identity.database",
248 FILEIN, STORETYPE, KEYSTORE, STOREPASS, PROVIDERNAME,
249 PROVIDER, PROVIDERCLASS, PROVIDERPATH, V);
250
251 final String description;
252 final Option[] options;
253 final String name;
254
255 String altName; // "genkey" is altName for "genkeypair"
256
257 Command(String d, Option... o) {
258 description = d;
259 options = o;
260 name = "-" + name().toLowerCase(Locale.ENGLISH);
261 }
262 @Override
263 public String toString() {
264 return name;
265 }
266 public String getAltName() {
267 return altName;
268 }
269 public void setAltName(String altName) {
273 for (Command c: Command.values()) {
274 if (collator.compare(cmd, c.name) == 0
275 || (c.altName != null
276 && collator.compare(cmd, c.altName) == 0)) {
277 return c;
278 }
279 }
280 return null;
281 }
282 };
283
284 static {
285 Command.GENKEYPAIR.setAltName("-genkey");
286 Command.IMPORTCERT.setAltName("-import");
287 Command.EXPORTCERT.setAltName("-export");
288 Command.IMPORTPASS.setAltName("-importpassword");
289 }
290
291 enum Option {
292 ALIAS("alias", "<alias>", "alias.name.of.the.entry.to.process"),
293 DESTALIAS("destalias", "<alias>", "destination.alias"),
294 DESTKEYPASS("destkeypass", "<arg>", "destination.key.password"),
295 DESTKEYSTORE("destkeystore", "<keystore>", "destination.keystore.name"),
296 DESTPROTECTED("destprotected", null, "destination.keystore.password.protected"),
297 DESTPROVIDERNAME("destprovidername", "<name>", "destination.keystore.provider.name"),
298 DESTSTOREPASS("deststorepass", "<arg>", "destination.keystore.password"),
299 DESTSTORETYPE("deststoretype", "<type>", "destination.keystore.type"),
300 DNAME("dname", "<name>", "distinguished.name"),
301 EXT("ext", "<value>", "X.509.extension"),
302 FILEOUT("file", "<file>", "output.file.name"),
303 FILEIN("file", "<file>", "input.file.name"),
304 ID("id", "<id:reason>", "Serial.ID.of.cert.to.revoke"),
305 INFILE("infile", "<file>", "input.file.name"),
306 KEYALG("keyalg", "<alg>", "key.algorithm.name"),
307 KEYPASS("keypass", "<arg>", "key.password"),
308 KEYSIZE("keysize", "<size>", "key.bit.size"),
309 KEYSTORE("keystore", "<keystore>", "keystore.name"),
310 NEW("new", "<arg>", "new.password"),
311 NOPROMPT("noprompt", null, "do.not.prompt"),
312 OUTFILE("outfile", "<file>", "output.file.name"),
313 PROTECTED("protected", null, "password.through.protected.mechanism"),
314 PROVIDERCLASS("providerclass", "<class>\n[-providerarg <arg>]", "provider.class.option"),
315 PROVIDER("provider", "<name>\n[-providerarg <arg>]", "provider.option"),
316 PROVIDERNAME("providername", "<name>", "provider.name"),
317 PROVIDERPATH("providerpath", "<list>", "provider.classpath"),
318 RFC("rfc", null, "output.in.RFC.style"),
319 SIGALG("sigalg", "<alg>", "signature.algorithm.name"),
320 SRCALIAS("srcalias", "<alias>", "source.alias"),
321 SRCKEYPASS("srckeypass", "<arg>", "source.key.password"),
322 SRCKEYSTORE("srckeystore", "<keystore>", "source.keystore.name"),
323 SRCPROTECTED("srcprotected", null, "source.keystore.password.protected"),
324 SRCPROVIDERNAME("srcprovidername", "<name>", "source.keystore.provider.name"),
325 SRCSTOREPASS("srcstorepass", "<arg>", "source.keystore.password"),
326 SRCSTORETYPE("srcstoretype", "<type>", "source.keystore.type"),
327 SSLSERVER("sslserver", "<server[:port]>", "SSL.server.host.and.port"),
328 JARFILE("jarfile", "<file>", "signed.jar.file"),
329 STARTDATE("startdate", "<date>", "certificate.validity.start.date.time"),
330 STOREPASS("storepass", "<arg>", "keystore.password"),
331 STORETYPE("storetype", "<type>", "keystore.type"),
332 TRUSTCACERTS("trustcacerts", null, "trust.certificates.from.cacerts"),
333 V("v", null, "verbose.output"),
334 VALIDITY("validity", "<days>", "validity.number.of.days");
335
336 final String name, arg, description;
337 Option(String name, String arg, String description) {
338 this.name = name;
339 this.arg = arg;
340 this.description = description;
341 }
342 @Override
343 public String toString() {
344 return "-" + name;
345 }
346 };
347
348 private static final Class<?>[] PARAM_STRING = { String.class };
349
350 private static final String NONE = "NONE";
351 private static final String P11KEYSTORE = "PKCS11";
352 private static final String P12KEYSTORE = "PKCS12";
353 private final String keyAlias = "mykey";
354
533 } else if (collator.compare(flags, "-startdate") == 0) {
534 startDate = args[++i];
535 } else if (collator.compare(flags, "-validity") == 0) {
536 validity = Long.parseLong(args[++i]);
537 } else if (collator.compare(flags, "-ext") == 0) {
538 v3ext.add(args[++i]);
539 } else if (collator.compare(flags, "-id") == 0) {
540 ids.add(args[++i]);
541 } else if (collator.compare(flags, "-file") == 0) {
542 filename = args[++i];
543 } else if (collator.compare(flags, "-infile") == 0) {
544 infilename = args[++i];
545 } else if (collator.compare(flags, "-outfile") == 0) {
546 outfilename = args[++i];
547 } else if (collator.compare(flags, "-sslserver") == 0) {
548 sslserver = args[++i];
549 } else if (collator.compare(flags, "-jarfile") == 0) {
550 jarfile = args[++i];
551 } else if (collator.compare(flags, "-srckeystore") == 0) {
552 srcksfname = args[++i];
553 } else if (collator.compare(flags, "-provider") == 0) {
554 if (providers == null) {
555 providers = new HashSet<Pair <String, String>> (3);
556 }
557 String provider = args[++i];
558 String providerArg = null;
559
560 if (args.length > (i+1)) {
561 flags = args[i+1];
562 if (collator.compare(flags, "-providerarg") == 0) {
563 if (args.length == (i+2)) errorNeedArgument(flags);
564 providerArg = args[i+2];
565 i += 2;
566 }
567 }
568 providers.add(
569 Pair.of(provider, providerArg));
570 } else if (collator.compare(flags, "-providerclass") == 0) {
571 if (providerClasses == null) {
572 providerClasses = new HashSet<Pair <String, String>> (3);
573 }
574 String providerClass = args[++i];
575 String providerArg = null;
576
577 if (args.length > (i+1)) {
578 flags = args[i+1];
579 if (collator.compare(flags, "-providerarg") == 0) {
580 if (args.length == (i+2)) errorNeedArgument(flags);
581 providerArg = args[i+2];
582 i += 2;
583 }
584 }
585 providerClasses.add(
586 Pair.of(providerClass, providerArg));
587 }
588
589 /*
590 * options
591 */
592 else if (collator.compare(flags, "-v") == 0) {
593 verbose = true;
594 } else if (collator.compare(flags, "-debug") == 0) {
595 // Already processed
596 } else if (collator.compare(flags, "-rfc") == 0) {
597 rfc = true;
598 } else if (collator.compare(flags, "-noprompt") == 0) {
599 noprompt = true;
600 } else if (collator.compare(flags, "-trustcacerts") == 0) {
601 trustcacerts = true;
602 } else if (collator.compare(flags, "-protected") == 0 ||
603 collator.compare(flags, "-destprotected") == 0) {
604 protectedPath = true;
605 } else if (collator.compare(flags, "-srcprotected") == 0) {
617
618 if (command == null) {
619 if (help) {
620 usage();
621 } else {
622 System.err.println(rb.getString("Usage.error.no.command.provided"));
623 tinyHelp();
624 }
625 } else if (help) {
626 usage();
627 command = null;
628 }
629
630 return args;
631 }
632
633 boolean isKeyStoreRelated(Command cmd) {
634 return cmd != PRINTCERT && cmd != PRINTCERTREQ;
635 }
636
637 /**
638 * Execute the commands.
639 */
640 void doCommands(PrintStream out) throws Exception {
641 if (storetype == null) {
642 storetype = KeyStore.getDefaultType();
643 }
644 storetype = KeyStoreUtil.niceStoreTypeName(storetype);
645
646 if (srcstoretype == null) {
647 srcstoretype = KeyStore.getDefaultType();
648 }
649 srcstoretype = KeyStoreUtil.niceStoreTypeName(srcstoretype);
650
651 if (P11KEYSTORE.equalsIgnoreCase(storetype) ||
652 KeyStoreUtil.isWindowsKeyStore(storetype)) {
653 token = true;
654 if (ksfname == null) {
655 ksfname = NONE;
656 }
700 if (KeyStoreUtil.isWindowsKeyStore(storetype)) {
701 if (storePass != null || keyPass != null ||
702 newPass != null || destKeyPass != null) {
703 throw new IllegalArgumentException(rb.getString
704 ("if.keystore.is.not.password.protected.then.storepass.keypass.and.new.must.not.be.specified"));
705 }
706 }
707
708 if (KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
709 if (srcstorePass != null || srckeyPass != null) {
710 throw new IllegalArgumentException(rb.getString
711 ("if.source.keystore.is.not.password.protected.then.srcstorepass.and.srckeypass.must.not.be.specified"));
712 }
713 }
714
715 if (validity <= (long)0) {
716 throw new Exception
717 (rb.getString("Validity.must.be.greater.than.zero"));
718 }
719
720 try {
721 // Try to load and install specified provider
722 if (providers != null) {
723 for (Pair<String, String> provider : providers) {
724 KeyStoreUtil.loadProviderByName(
725 provider.fst, provider.snd, debug);
726 }
727 }
728 if (providerClasses != null) {
729 ClassLoader cl = null;
730 if (pathlist != null) {
731 String path = null;
732 path = PathList.appendPath(
733 path, System.getProperty("java.class.path"));
734 path = PathList.appendPath(
735 path, System.getProperty("env.class.path"));
736 path = PathList.appendPath(path, pathlist);
737
738 URL[] urls = PathList.pathToURLs(path);
739 cl = new URLClassLoader(urls);
740 } else {
741 cl = ClassLoader.getSystemClassLoader();
742 }
743 for (Pair<String, String> provider : providerClasses) {
744 KeyStoreUtil.loadProviderByClass(
745 provider.fst, provider.snd, cl, debug);
746 }
747 }
748 } catch (IllegalArgumentException e) {
749 MessageFormat form = new MessageFormat
750 (rb.getString("provName.not.a.provider"));
751 Object[] source = {e.getMessage()};
752 Exception ex = new Exception(form.format(source));
753 if (e.getCause() != null) {
754 ex.initCause(e.getCause());
755 }
756 throw ex;
757 }
758
759 if (command == LIST && verbose && rfc) {
760 System.err.println(rb.getString
761 ("Must.not.specify.both.v.and.rfc.with.list.command"));
762 tinyHelp();
763 }
764
765 // Make sure provided passwords are at least 6 characters long
766 if (command == GENKEYPAIR && keyPass!=null && keyPass.length < 6) {
767 throw new Exception(rb.getString
768 ("Key.password.must.be.at.least.6.characters"));
769 }
770 if (newPass != null && newPass.length < 6) {
771 throw new Exception(rb.getString
772 ("New.password.must.be.at.least.6.characters"));
773 }
774 if (destKeyPass != null && destKeyPass.length < 6) {
775 throw new Exception(rb.getString
776 ("New.password.must.be.at.least.6.characters"));
4127 }
4128 } catch(IOException e) {
4129 throw new RuntimeException(e);
4130 }
4131 return result;
4132 }
4133
4134 /**
4135 * Prints the usage of this tool.
4136 */
4137 private void usage() {
4138 if (command != null) {
4139 System.err.println("keytool " + command +
4140 rb.getString(".OPTION."));
4141 System.err.println();
4142 System.err.println(rb.getString(command.description));
4143 System.err.println();
4144 System.err.println(rb.getString("Options."));
4145 System.err.println();
4146
4147 // Left and right sides of the options list. Both might
4148 // contain "\n" and span multiple lines
4149 String[] left = new String[command.options.length];
4150 String[] right = new String[command.options.length];
4151
4152 // Length of left side of options list
4153 int lenLeft = 0;
4154
4155 for (int j=0; j<command.options.length; j++) {
4156 Option opt = command.options[j];
4157 left[j] = opt.toString();
4158 if (opt.arg != null) left[j] += " " + opt.arg;
4159 String[] lefts = left[j].split("\n");
4160 for (String s: lefts) {
4161 if (s.length() > lenLeft) {
4162 lenLeft = s.length();
4163 }
4164 }
4165 right[j] = rb.getString(opt.description);
4166 }
4167 for (int j=0; j<left.length; j++) {
4168 String[] lefts = left[j].split("\n");
4169 String[] rights = right[j].split("\n");
4170 for (int i=0; i<lefts.length && i<rights.length; i++) {
4171 String s1 = i < lefts.length? lefts[i]: "";
4172 String s2 = i < rights.length? rights[i]: "";
4173 if (i == 0) {
4174 System.err.printf(" %-" + lenLeft + "s %s\n", s1, s2);
4175 } else {
4176 System.err.printf(" %-" + lenLeft + "s %s\n", s1, s2);
4177 }
4178 }
4179 }
4180 System.err.println();
4181 System.err.println(rb.getString(
4182 "Use.keytool.help.for.all.available.commands"));
4183 } else {
4184 System.err.println(rb.getString(
4185 "Key.and.Certificate.Management.Tool"));
4186 System.err.println();
4187 System.err.println(rb.getString("Commands."));
4188 System.err.println();
4189 for (Command c: Command.values()) {
4190 if (c == KEYCLONE) break;
4191 System.err.printf(" %-20s%s\n", c, rb.getString(c.description));
4192 }
4193 System.err.println();
4194 System.err.println(rb.getString(
4195 "Use.keytool.command.name.help.for.usage.of.command.name"));
4196 }
4197 }
4198
|