void doCommands()

in src/java.base/share/classes/sun/security/tools/keytool/Main.java [736:1440]


    void doCommands(PrintStream out) throws Exception {

        if (cacerts) {
            if (ksfname != null || storetype != null) {
                throw new IllegalArgumentException(rb.getString
                        ("the.keystore.or.storetype.option.cannot.be.used.with.the.cacerts.option"));
            }
            ksfname = KeyStoreUtil.getCacerts();
        }

        if (P11KEYSTORE.equalsIgnoreCase(storetype) ||
                KeyStoreUtil.isWindowsKeyStore(storetype)) {
            token = true;
            if (ksfname == null) {
                ksfname = NONE;
            }
        }
        if (NONE.equals(ksfname)) {
            nullStream = true;
        }

        if (token && !nullStream) {
            System.err.println(MessageFormat.format(rb.getString
                (".keystore.must.be.NONE.if.storetype.is.{0}"), storetype));
            System.err.println();
            tinyHelp();
        }

        if (token &&
            (command == KEYPASSWD || command == STOREPASSWD)) {
            throw new UnsupportedOperationException(MessageFormat.format(rb.getString
                        (".storepasswd.and.keypasswd.commands.not.supported.if.storetype.is.{0}"), storetype));
        }

        if (token && (keyPass != null || newPass != null || destKeyPass != null)) {
            throw new IllegalArgumentException(MessageFormat.format(rb.getString
                (".keypass.and.new.can.not.be.specified.if.storetype.is.{0}"), storetype));
        }

        if (protectedPath) {
            if (storePass != null || keyPass != null ||
                    newPass != null || destKeyPass != null) {
                throw new IllegalArgumentException(rb.getString
                        ("if.protected.is.specified.then.storepass.keypass.and.new.must.not.be.specified"));
            }
        }

        if (srcprotectedPath) {
            if (srcstorePass != null || srckeyPass != null) {
                throw new IllegalArgumentException(rb.getString
                        ("if.srcprotected.is.specified.then.srcstorepass.and.srckeypass.must.not.be.specified"));
            }
        }

        if (KeyStoreUtil.isWindowsKeyStore(storetype)) {
            if (storePass != null || keyPass != null ||
                    newPass != null || destKeyPass != null) {
                throw new IllegalArgumentException(rb.getString
                        ("if.keystore.is.not.password.protected.then.storepass.keypass.and.new.must.not.be.specified"));
            }
        }

        if (KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
            if (srcstorePass != null || srckeyPass != null) {
                throw new IllegalArgumentException(rb.getString
                        ("if.source.keystore.is.not.password.protected.then.srcstorepass.and.srckeypass.must.not.be.specified"));
            }
        }

        if (validity <= (long)0) {
            throw new Exception
                (rb.getString("Validity.must.be.greater.than.zero"));
        }

        // Try to load and install specified provider
        if (providers != null) {
            for (Pair<String, String> provider : providers) {
                try {
                    KeyStoreUtil.loadProviderByName(
                            provider.fst, provider.snd);
                    if (debug) {
                        System.out.println("loadProviderByName: " + provider.fst);
                    }
                } catch (IllegalArgumentException e) {
                    throw new Exception(String.format(rb.getString(
                            "provider.name.not.found"), provider.fst));
                }
            }
        }
        if (providerClasses != null) {
            ClassLoader cl;
            if (pathlist != null) {
                String path = System.getProperty("java.class.path");
                path = PathList.appendPath(
                        path, System.getProperty("env.class.path"));
                path = PathList.appendPath(path, pathlist);

                URL[] urls = PathList.pathToURLs(path);
                cl = new URLClassLoader(urls);
            } else {
                cl = ClassLoader.getSystemClassLoader();
            }
            for (Pair<String, String> provider : providerClasses) {
                try {
                    KeyStoreUtil.loadProviderByClass(
                            provider.fst, provider.snd, cl);
                    if (debug) {
                        System.out.println("loadProviderByClass: " + provider.fst);
                    }
                } catch (ClassCastException cce) {
                    throw new Exception(String.format(rb.getString(
                            "provclass.not.a.provider"), provider.fst));
                } catch (IllegalArgumentException e) {
                    throw new Exception(String.format(rb.getString(
                            "provider.class.not.found"), provider.fst), e.getCause());
                }
            }
        }

        if (command == LIST && verbose && rfc) {
            System.err.println(rb.getString
                ("Must.not.specify.both.v.and.rfc.with.list.command"));
            tinyHelp();
        }

        // Make sure provided passwords are at least 6 characters long
        if (command == GENKEYPAIR && keyPass!=null && keyPass.length < 6) {
            throw new Exception(rb.getString
                ("Key.password.must.be.at.least.6.characters"));
        }
        if (newPass != null && newPass.length < 6) {
            throw new Exception(rb.getString
                ("New.password.must.be.at.least.6.characters"));
        }
        if (destKeyPass != null && destKeyPass.length < 6) {
            throw new Exception(rb.getString
                ("New.password.must.be.at.least.6.characters"));
        }

        // Set this before inplaceImport check so we can compare name.
        if (ksfname == null) {
            ksfname = System.getProperty("user.home") + File.separator
                    + ".keystore";
        }

        KeyStore srcKeyStore = null;
        if (command == IMPORTKEYSTORE) {
            inplaceImport = inplaceImportCheck();
            if (inplaceImport) {
                // We load srckeystore first so we have srcstorePass that
                // can be assigned to storePass
                srcKeyStore = loadSourceKeyStore();
                if (storePass == null) {
                    storePass = srcstorePass;
                }
            }
        }

        // Check if keystore exists.
        // If no keystore has been specified at the command line, try to use
        // the default, which is located in $HOME/.keystore.
        // No need to check if isKeyStoreRelated(command) is false.

        // DO NOT open the existing keystore if this is an in-place import.
        // The keystore should be created as brand new.
        if (isKeyStoreRelated(command) && !nullStream && !inplaceImport) {
            try {
                ksfile = new File(ksfname);
                // Check if keystore file is empty
                if (ksfile.exists() && ksfile.length() == 0) {
                    throw new Exception(rb.getString
                            ("Keystore.file.exists.but.is.empty.") + ksfname);
                }
                ksStream = new FileInputStream(ksfile);
            } catch (FileNotFoundException e) {
                // These commands do not need the keystore to be existing.
                // Either it will create a new one or the keystore is
                // optional (i.e. PRINTCRL and PRINTCERT).
                if (command != GENKEYPAIR &&
                        command != GENSECKEY &&
                        command != IDENTITYDB &&
                        command != IMPORTCERT &&
                        command != IMPORTPASS &&
                        command != IMPORTKEYSTORE &&
                        command != PRINTCRL &&
                        command != PRINTCERT) {
                    throw new Exception(rb.getString
                            ("Keystore.file.does.not.exist.") + ksfname);
                }
            }
        }

        if ((command == KEYCLONE || command == CHANGEALIAS)
                && dest == null) {
            dest = getAlias("destination");
            if ("".equals(dest)) {
                throw new Exception(rb.getString
                        ("Must.specify.destination.alias"));
            }
        }

        if (command == DELETE && alias == null) {
            alias = getAlias(null);
            if ("".equals(alias)) {
                throw new Exception(rb.getString("Must.specify.alias"));
            }
        }

        if (ksfile != null && ksStream != null && providerName == null &&
                !inplaceImport) {
            // existing keystore
            if (storetype == null) {
                // Probe for keystore type when filename is available
                keyStore = KeyStore.getInstance(ksfile, storePass);
                storetype = keyStore.getType();
            } else {
                keyStore = KeyStore.getInstance(storetype);
                // storePass might be null here, will probably prompt later
                keyStore.load(ksStream, storePass);
            }
            if (storetype.equalsIgnoreCase("pkcs12")) {
                try {
                    isPasswordlessKeyStore = PKCS12KeyStore.isPasswordless(ksfile);
                } catch (IOException ioe) {
                    // This must be a JKS keystore that's opened as a PKCS12
                }
            }
        } else {
            // Create new keystore
            if (storetype == null) {
                storetype = KeyStore.getDefaultType();
            }
            if (providerName == null) {
                keyStore = KeyStore.getInstance(storetype);
            } else {
                keyStore = KeyStore.getInstance(storetype, providerName);
            }
            // When creating a new pkcs12 file, Do not prompt for storepass
            // if certProtectionAlgorithm and macAlgorithm are both NONE.
            if (storetype.equalsIgnoreCase("pkcs12")) {
                isPasswordlessKeyStore =
                        "NONE".equals(SecurityProperties.getOverridableProperty(
                                "keystore.pkcs12.certProtectionAlgorithm"))
                        && "NONE".equals(SecurityProperties.getOverridableProperty(
                                "keystore.pkcs12.macAlgorithm"));
            }

            /*
             * Load the keystore data.
             *
             * At this point, it's OK if no keystore password has been provided.
             * We want to make sure that we can load the keystore data, i.e.,
             * the keystore data has the right format. If we cannot load the
             * keystore, why bother asking the user for his or her password?
             * Only if we were able to load the keystore, and no keystore
             * password has been provided, will we prompt the user for the
             * keystore password to verify the keystore integrity.
             * This means that the keystore is loaded twice: first load operation
             * checks the keystore format, second load operation verifies the
             * keystore integrity.
             *
             * If the keystore password has already been provided (at the
             * command line), however, the keystore is loaded only once, and the
             * keystore format and integrity are checked "at the same time".
             *
             * Null stream keystores are loaded later.
             */
            if (!nullStream) {
                if (inplaceImport) {
                    keyStore.load(null, storePass);
                } else {
                    // both ksStream and storePass could be null
                    keyStore.load(ksStream, storePass);
                }
            }
        }

        if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) {
            throw new UnsupportedOperationException(rb.getString
                    (".keypasswd.commands.not.supported.if.storetype.is.PKCS12"));
        }

        // All commands that create or modify the keystore require a keystore
        // password.

        if (nullStream && storePass != null) {
            keyStore.load(null, storePass);
        } else if (!nullStream && storePass != null) {
            // If we are creating a new non nullStream-based keystore,
            // insist that the password be at least 6 characters
            if (ksStream == null && storePass.length < 6) {
                throw new Exception(rb.getString
                        ("Keystore.password.must.be.at.least.6.characters"));
            }
        } else {
            if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype)
                    && isKeyStoreRelated(command)
                    && !isPasswordlessKeyStore) {
                if (command == CERTREQ ||
                        command == DELETE ||
                        command == GENKEYPAIR ||
                        command == GENSECKEY ||
                        command == IMPORTCERT ||
                        command == IMPORTPASS ||
                        command == IMPORTKEYSTORE ||
                        command == KEYCLONE ||
                        command == CHANGEALIAS ||
                        command == SELFCERT ||
                        command == STOREPASSWD ||
                        command == KEYPASSWD ||
                        command == IDENTITYDB) {
                    int count = 0;
                    do {
                        if (command == IMPORTKEYSTORE) {
                            System.err.print
                                    (rb.getString("Enter.destination.keystore.password."));
                        } else {
                            System.err.print
                                    (rb.getString("Enter.keystore.password."));
                        }
                        System.err.flush();
                        storePass = Password.readPassword(System.in);
                        passwords.add(storePass);

                        // If we are creating a new non nullStream-based keystore,
                        // insist that the password be at least 6 characters
                        if (!nullStream && (storePass == null || storePass.length < 6)) {
                            System.err.println(rb.getString
                                    ("Keystore.password.is.too.short.must.be.at.least.6.characters"));
                            storePass = null;
                        }

                        // If the keystore file does not exist and needs to be
                        // created, the storepass should be prompted twice.
                        if (storePass != null && !nullStream && ksStream == null) {
                            System.err.print(rb.getString("Re.enter.new.password."));
                            char[] storePassAgain = Password.readPassword(System.in);
                            passwords.add(storePassAgain);
                            if (!Arrays.equals(storePass, storePassAgain)) {
                                System.err.println
                                        (rb.getString("They.don.t.match.Try.again"));
                                storePass = null;
                            }
                        }

                        count++;
                    } while ((storePass == null) && count < 3);


                    if (storePass == null) {
                        System.err.println
                                (rb.getString("Too.many.failures.try.later"));
                        return;
                    }
                } else {
                    // here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
                    if (command != PRINTCRL && command != PRINTCERT) {
                        System.err.print(rb.getString("Enter.keystore.password."));
                        System.err.flush();
                        storePass = Password.readPassword(System.in);
                        passwords.add(storePass);
                    }
                }
            }

            // Now load a nullStream-based keystore,
            // or verify the integrity of an input stream-based keystore
            if (nullStream) {
                keyStore.load(null, storePass);
            } else if (ksStream != null) {
                // Reload with user-provided password
                try (FileInputStream fis = new FileInputStream(ksfile)) {
                    keyStore.load(fis, storePass);
                }
            }
        }

        if (storePass != null && P12KEYSTORE.equalsIgnoreCase(storetype)) {
            MessageFormat form = new MessageFormat(rb.getString(
                "Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value."));
            if (keyPass != null && !Arrays.equals(storePass, keyPass)) {
                Object[] source = {"-keypass"};
                System.err.println(form.format(source));
                keyPass = storePass;
            }
            if (destKeyPass != null && !Arrays.equals(storePass, destKeyPass)) {
                Object[] source = {"-destkeypass"};
                System.err.println(form.format(source));
                destKeyPass = storePass;
            }
        }

        // -trustcacerts can be specified on -importcert, -printcert or -printcrl.
        // Reset it so that warnings on CA cert will remain for other command.
        if (command != IMPORTCERT && command != PRINTCERT
                && command != PRINTCRL) {
            trustcacerts = false;
        }

        if (trustcacerts) {
            KeyStore cakstore = buildTrustedCerts();
            if (cakstore != null) {
                caks = cakstore;
            } else {
                // try to load cacerts again, and let exception propagate
                // if it cannot be loaded
                caks = KeyStoreUtil.getCacertsKeyStore();
            }
        }

        // Perform the specified command
        if (command == CERTREQ) {
            if (filename != null) {
                try (PrintStream ps = new PrintStream(new FileOutputStream
                                                      (filename))) {
                    doCertReq(alias, sigAlgName, ps);
                }
            } else {
                doCertReq(alias, sigAlgName, out);
            }
            if (verbose && filename != null) {
                MessageFormat form = new MessageFormat(rb.getString
                        ("Certification.request.stored.in.file.filename."));
                Object[] source = {filename};
                System.err.println(form.format(source));
                System.err.println(rb.getString("Submit.this.to.your.CA"));
            }
        } else if (command == DELETE) {
            doDeleteEntry(alias);
            kssave = true;
        } else if (command == EXPORTCERT) {
            if (filename != null) {
                try (PrintStream ps = new PrintStream(new FileOutputStream
                                                   (filename))) {
                    doExportCert(alias, ps);
                }
            } else {
                doExportCert(alias, out);
            }
            if (filename != null) {
                MessageFormat form = new MessageFormat(rb.getString
                        ("Certificate.stored.in.file.filename."));
                Object[] source = {filename};
                System.err.println(form.format(source));
            }
        } else if (command == GENKEYPAIR) {
            if (keyAlgName == null) {
                throw new Exception(rb.getString(
                        "keyalg.option.missing.error"));
            }
            doGenKeyPair(alias, dname, keyAlgName, keysize, groupName, sigAlgName,
                    signerAlias);
            kssave = true;
        } else if (command == GENSECKEY) {
            if (keyAlgName == null) {
                throw new Exception(rb.getString(
                        "keyalg.option.missing.error"));
            }
            doGenSecretKey(alias, keyAlgName, keysize);
            kssave = true;
        } else if (command == IMPORTPASS) {
            if (keyAlgName == null) {
                keyAlgName = "PBE";
            }
            // password is stored as a secret key
            doGenSecretKey(alias, keyAlgName, keysize);
            kssave = true;
        } else if (command == IDENTITYDB) {
            if (filename != null) {
                try (InputStream inStream = new FileInputStream(filename)) {
                    doImportIdentityDatabase(inStream);
                }
            } else {
                doImportIdentityDatabase(System.in);
            }
        } else if (command == IMPORTCERT) {
            InputStream inStream = System.in;
            if (filename != null) {
                inStream = new FileInputStream(filename);
            }
            String importAlias = (alias!=null)?alias:keyAlias;
            try {
                if (keyStore.entryInstanceOf(
                        importAlias, KeyStore.PrivateKeyEntry.class)) {
                    kssave = installReply(importAlias, inStream);
                    if (kssave) {
                        System.err.println(rb.getString
                            ("Certificate.reply.was.installed.in.keystore"));
                    } else {
                        System.err.println(rb.getString
                            ("Certificate.reply.was.not.installed.in.keystore"));
                    }
                } else if (!keyStore.containsAlias(importAlias) ||
                        keyStore.entryInstanceOf(importAlias,
                            KeyStore.TrustedCertificateEntry.class)) {
                    kssave = addTrustedCert(importAlias, inStream);
                    if (kssave) {
                        System.err.println(rb.getString
                            ("Certificate.was.added.to.keystore"));
                    } else {
                        System.err.println(rb.getString
                            ("Certificate.was.not.added.to.keystore"));
                    }
                }
            } finally {
                if (inStream != System.in) {
                    inStream.close();
                }
            }
        } else if (command == IMPORTKEYSTORE) {
            // When not in-place import, srcKeyStore is not loaded yet.
            if (srcKeyStore == null) {
                srcKeyStore = loadSourceKeyStore();
            }
            doImportKeyStore(srcKeyStore);
            kssave = true;
        } else if (command == KEYCLONE) {
            keyPassNew = newPass;

            // added to make sure only key can go through
            if (alias == null) {
                alias = keyAlias;
            }
            if (!keyStore.containsAlias(alias)) {
                MessageFormat form = new MessageFormat
                    (rb.getString("Alias.alias.does.not.exist"));
                Object[] source = {alias};
                throw new Exception(form.format(source));
            }
            if (!keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
                MessageFormat form = new MessageFormat(rb.getString(
                        "Alias.alias.references.an.entry.type.that.is.not.a.private.key.entry.The.keyclone.command.only.supports.cloning.of.private.key"));
                Object[] source = {alias};
                throw new Exception(form.format(source));
            }

            doCloneEntry(alias, dest, true);  // Now everything can be cloned
            kssave = true;
        } else if (command == CHANGEALIAS) {
            if (alias == null) {
                alias = keyAlias;
            }
            doCloneEntry(alias, dest, false);
            // in PKCS11, clone a PrivateKeyEntry will delete the old one
            if (keyStore.containsAlias(alias)) {
                doDeleteEntry(alias);
            }
            kssave = true;
        } else if (command == KEYPASSWD) {
            keyPassNew = newPass;
            doChangeKeyPasswd(alias);
            kssave = true;
        } else if (command == LIST) {
            if (storePass == null
                    && !protectedPath
                    && !KeyStoreUtil.isWindowsKeyStore(storetype)
                    && !isPasswordlessKeyStore) {
                printNoIntegrityWarning();
            }

            if (alias != null) {
                doPrintEntry(alias, out);
            } else {
                doPrintEntries(out);
            }
        } else if (command == PRINTCERT) {
            doPrintCert(out);
        } else if (command == SELFCERT) {
            doSelfCert(alias, dname, sigAlgName);
            kssave = true;
        } else if (command == STOREPASSWD) {
            doChangeStorePasswd();
            kssave = true;
        } else if (command == GENCERT) {
            if (alias == null) {
                alias = keyAlias;
            }
            InputStream inStream = System.in;
            if (infilename != null) {
                inStream = new FileInputStream(infilename);
            }
            PrintStream ps = null;
            if (outfilename != null) {
                ps = new PrintStream(new FileOutputStream(outfilename));
                out = ps;
            }
            try {
                doGenCert(alias, sigAlgName, inStream, out);
            } finally {
                if (inStream != System.in) {
                    inStream.close();
                }
                if (ps != null) {
                    ps.close();
                }
            }
        } else if (command == GENCRL) {
            if (alias == null) {
                alias = keyAlias;
            }
            if (filename != null) {
                try (PrintStream ps =
                         new PrintStream(new FileOutputStream(filename))) {
                    doGenCRL(ps);
                }
            } else {
                doGenCRL(out);
            }
        } else if (command == PRINTCERTREQ) {
            if (filename != null) {
                try (InputStream inStream = new FileInputStream(filename)) {
                    doPrintCertReq(inStream, out);
                }
            } else {
                doPrintCertReq(System.in, out);
            }
        } else if (command == PRINTCRL) {
            doPrintCRL(filename, out);
        } else if (command == SHOWINFO) {
            doShowInfo();
        } else if (command == VERSION) {
            doPrintVersion();
        }

        // If we need to save the keystore, do so.
        if (kssave) {
            if (verbose) {
                MessageFormat form = new MessageFormat
                        (rb.getString(".Storing.ksfname."));
                Object[] source = {nullStream ? "keystore" : ksfname};
                System.err.println(form.format(source));
            }

            if (token) {
                keyStore.store(null, null);
            } else {
                char[] pass = (storePassNew!=null) ? storePassNew : storePass;
                if (nullStream) {
                    keyStore.store(null, pass);
                } else {
                    ByteArrayOutputStream bout = new ByteArrayOutputStream();
                    keyStore.store(bout, pass);
                    try (FileOutputStream fout = new FileOutputStream(ksfname)) {
                        fout.write(bout.toByteArray());
                    }
                }
            }
        }

        if (isKeyStoreRelated(command)
                && !token && !nullStream && ksfname != null) {

            // JKS storetype warning on the final result keystore
            File f = new File(ksfname);
            char[] pass = (storePassNew!=null) ? storePassNew : storePass;
            if (f.exists()) {
                // Probe for real type. A JKS can be loaded as PKCS12 because
                // DualFormat support, vice versa.
                String realType = storetype;
                try {
                    keyStore = KeyStore.getInstance(f, pass);
                    realType = keyStore.getType();
                    if (realType.equalsIgnoreCase("JKS")
                            || realType.equalsIgnoreCase("JCEKS")) {
                        boolean allCerts = true;
                        for (String a : Collections.list(keyStore.aliases())) {
                            if (!keyStore.entryInstanceOf(
                                    a, TrustedCertificateEntry.class)) {
                                allCerts = false;
                                break;
                            }
                        }
                        // Don't warn for "cacerts" style keystore.
                        if (!allCerts) {
                            weakWarnings.add(String.format(
                                    rb.getString("jks.storetype.warning"),
                                    realType, ksfname));
                        }
                    }
                } catch (KeyStoreException e) {
                    // Probing not supported, therefore cannot be JKS or JCEKS.
                    // Skip the legacy type warning at all.
                }
                if (inplaceImport) {
                    String realSourceStoreType = srcstoretype;
                    try {
                        realSourceStoreType = KeyStore.getInstance(
                                new File(inplaceBackupName), srcstorePass).getType();
                    } catch (KeyStoreException e) {
                        // Probing not supported. Assuming srcstoretype.
                    }
                    String format =
                            realType.equalsIgnoreCase(realSourceStoreType) ?
                            rb.getString("backup.keystore.warning") :
                            rb.getString("migrate.keystore.warning");
                    weakWarnings.add(
                            String.format(format,
                                    srcksfname,
                                    realSourceStoreType,
                                    inplaceBackupName,
                                    realType));
                }
            }
        }
    }