< prev index next >

src/java.base/share/classes/sun/security/tools/keytool/Main.java

Print this page
rev 15253 : 8130302: jarsigner and keytool -providerClass needs be re-examined for modules


  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 


< prev index next >