< prev index next >

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

Print this page




  60 import java.util.jar.JarFile;
  61 import java.lang.reflect.Constructor;
  62 import java.math.BigInteger;
  63 import java.net.URI;
  64 import java.net.URL;
  65 import java.net.URLClassLoader;
  66 import java.security.cert.CertStore;
  67 
  68 import java.security.cert.X509CRL;
  69 import java.security.cert.X509CRLEntry;
  70 import java.security.cert.X509CRLSelector;
  71 import javax.security.auth.x500.X500Principal;
  72 import java.util.Base64;
  73 
  74 import sun.security.util.DisabledAlgorithmConstraints;
  75 import sun.security.util.KeyUtil;
  76 import sun.security.util.NamedCurve;
  77 import sun.security.util.ObjectIdentifier;
  78 import sun.security.pkcs10.PKCS10;
  79 import sun.security.pkcs10.PKCS10Attribute;

  80 import sun.security.provider.X509Factory;
  81 import sun.security.provider.certpath.CertStoreHelper;
  82 import sun.security.util.Password;

  83 import sun.security.util.SecurityProviderConstants;
  84 import sun.security.util.SignatureUtil;
  85 import javax.crypto.KeyGenerator;
  86 import javax.crypto.SecretKey;
  87 import javax.crypto.SecretKeyFactory;
  88 import javax.crypto.spec.PBEKeySpec;
  89 
  90 import sun.security.pkcs.PKCS9Attribute;
  91 import sun.security.tools.KeyStoreUtil;
  92 import sun.security.tools.PathList;
  93 import sun.security.util.DerValue;
  94 import sun.security.util.Pem;
  95 import sun.security.x509.*;
  96 
  97 import static java.security.KeyStore.*;
  98 import static sun.security.tools.keytool.Main.Command.*;
  99 import static sun.security.tools.keytool.Main.Option.*;
 100 
 101 /**
 102  * This tool manages keystores.


 173     private List<String> v3ext = new ArrayList<>();
 174 
 175     // In-place importkeystore is special.
 176     // A backup is needed, and no need to prompt for deststorepass.
 177     private boolean inplaceImport = false;
 178     private String inplaceBackupName = null;
 179 
 180     // Warnings on weak algorithms etc
 181     private List<String> weakWarnings = new ArrayList<>();
 182 
 183     private static final DisabledAlgorithmConstraints DISABLED_CHECK =
 184             new DisabledAlgorithmConstraints(
 185                     DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
 186 
 187     private static final DisabledAlgorithmConstraints LEGACY_CHECK =
 188             new DisabledAlgorithmConstraints(
 189                     DisabledAlgorithmConstraints.PROPERTY_SECURITY_LEGACY_ALGS);
 190 
 191     private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
 192             .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));

 193 
 194     enum Command {
 195         CERTREQ("Generates.a.certificate.request",
 196             ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
 197             STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
 198             PROVIDERARG, PROVIDERPATH, V, PROTECTED),
 199         CHANGEALIAS("Changes.an.entry.s.alias",
 200             ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
 201             STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
 202             PROVIDERPATH, V, PROTECTED),
 203         DELETE("Deletes.an.entry",
 204             ALIAS, KEYSTORE, STOREPASS, STORETYPE,
 205             PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
 206             PROVIDERPATH, V, PROTECTED),
 207         EXPORTCERT("Exports.certificate",
 208             RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
 209             STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
 210             PROVIDERPATH, V, PROTECTED),
 211         GENKEYPAIR("Generates.a.key.pair",
 212             ALIAS, KEYALG, KEYSIZE, SIGALG, DESTALIAS, DNAME,


 777                                 ("Keystore.file.does.not.exist.") + ksfname);
 778                     }
 779                 }
 780             }
 781 
 782         if ((command == KEYCLONE || command == CHANGEALIAS)
 783                 && dest == null) {
 784             dest = getAlias("destination");
 785             if ("".equals(dest)) {
 786                 throw new Exception(rb.getString
 787                         ("Must.specify.destination.alias"));
 788             }
 789         }
 790 
 791         if (command == DELETE && alias == null) {
 792             alias = getAlias(null);
 793             if ("".equals(alias)) {
 794                 throw new Exception(rb.getString("Must.specify.alias"));
 795             }
 796         }
 797 
 798         // Create new keystore
















 799         if (storetype == null) {
 800             storetype = KeyStore.getDefaultType();
 801         }
 802         if (providerName == null) {
 803             keyStore = KeyStore.getInstance(storetype);
 804         } else {
 805             keyStore = KeyStore.getInstance(storetype, providerName);
 806         }









 807 
 808         /*
 809          * Load the keystore data.
 810          *
 811          * At this point, it's OK if no keystore password has been provided.
 812          * We want to make sure that we can load the keystore data, i.e.,
 813          * the keystore data has the right format. If we cannot load the
 814          * keystore, why bother asking the user for his or her password?
 815          * Only if we were able to load the keystore, and no keystore
 816          * password has been provided, will we prompt the user for the
 817          * keystore password to verify the keystore integrity.
 818          * This means that the keystore is loaded twice: first load operation
 819          * checks the keystore format, second load operation verifies the
 820          * keystore integrity.
 821          *
 822          * If the keystore password has already been provided (at the
 823          * command line), however, the keystore is loaded only once, and the
 824          * keystore format and integrity are checked "at the same time".
 825          *
 826          * Null stream keystores are loaded later.
 827          */
 828         if (!nullStream) {
 829             if (inplaceImport) {
 830                 keyStore.load(null, storePass);
 831             } else {
 832             keyStore.load(ksStream, storePass);
 833             }
 834             if (ksStream != null) {
 835                 ksStream.close();
 836             }
 837         }
 838 
 839         if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) {
 840             throw new UnsupportedOperationException(rb.getString
 841                     (".keypasswd.commands.not.supported.if.storetype.is.PKCS12"));
 842         }
 843 
 844         // All commands that create or modify the keystore require a keystore
 845         // password.
 846 
 847         if (nullStream && storePass != null) {
 848             keyStore.load(null, storePass);
 849         } else if (!nullStream && storePass != null) {
 850             // If we are creating a new non nullStream-based keystore,
 851             // insist that the password be at least 6 characters
 852             if (ksStream == null && storePass.length < 6) {
 853                 throw new Exception(rb.getString
 854                         ("Keystore.password.must.be.at.least.6.characters"));
 855             }
 856         } else if (storePass == null) {
 857 
 858             // only prompt if (protectedPath == false)
 859 
 860             if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype) &&
 861                 (command == CERTREQ ||
 862                         command == DELETE ||
 863                         command == GENKEYPAIR ||
 864                         command == GENSECKEY ||
 865                         command == IMPORTCERT ||
 866                         command == IMPORTPASS ||
 867                         command == IMPORTKEYSTORE ||
 868                         command == KEYCLONE ||
 869                         command == CHANGEALIAS ||
 870                         command == SELFCERT ||
 871                         command == STOREPASSWD ||
 872                         command == KEYPASSWD ||
 873                         command == IDENTITYDB)) {
 874                 int count = 0;
 875                 do {
 876                     if (command == IMPORTKEYSTORE) {
 877                         System.err.print
 878                                 (rb.getString("Enter.destination.keystore.password."));
 879                     } else {
 880                         System.err.print
 881                                 (rb.getString("Enter.keystore.password."));
 882                     }
 883                     System.err.flush();
 884                     storePass = Password.readPassword(System.in);
 885                     passwords.add(storePass);
 886 
 887                     // If we are creating a new non nullStream-based keystore,
 888                     // insist that the password be at least 6 characters
 889                     if (!nullStream && (storePass == null || storePass.length < 6)) {
 890                         System.err.println(rb.getString
 891                                 ("Keystore.password.is.too.short.must.be.at.least.6.characters"));
 892                         storePass = null;
 893                     }


 897                     if (storePass != null && !nullStream && ksStream == null) {
 898                         System.err.print(rb.getString("Re.enter.new.password."));
 899                         char[] storePassAgain = Password.readPassword(System.in);
 900                         passwords.add(storePassAgain);
 901                         if (!Arrays.equals(storePass, storePassAgain)) {
 902                             System.err.println
 903                                 (rb.getString("They.don.t.match.Try.again"));
 904                             storePass = null;
 905                         }
 906                     }
 907 
 908                     count++;
 909                 } while ((storePass == null) && count < 3);
 910 
 911 
 912                 if (storePass == null) {
 913                     System.err.println
 914                         (rb.getString("Too.many.failures.try.later"));
 915                     return;
 916                 }
 917             } else if (!protectedPath
 918                     && !KeyStoreUtil.isWindowsKeyStore(storetype)
 919                     && isKeyStoreRelated(command)) {
 920                 // here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
 921                 if (command != PRINTCRL) {
 922                     System.err.print(rb.getString("Enter.keystore.password."));
 923                     System.err.flush();
 924                     storePass = Password.readPassword(System.in);
 925                     passwords.add(storePass);
 926                 }
 927             }

 928 
 929             // Now load a nullStream-based keystore,
 930             // or verify the integrity of an input stream-based keystore
 931             if (nullStream) {
 932                 keyStore.load(null, storePass);
 933             } else if (ksStream != null) {
 934                 ksStream = new FileInputStream(ksfile);
 935                 keyStore.load(ksStream, storePass);
 936                 ksStream.close();
 937             }
 938         }
 939 
 940         if (storePass != null && P12KEYSTORE.equalsIgnoreCase(storetype)) {
 941             MessageFormat form = new MessageFormat(rb.getString(
 942                 "Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value."));
 943             if (keyPass != null && !Arrays.equals(storePass, keyPass)) {
 944                 Object[] source = {"-keypass"};
 945                 System.err.println(form.format(source));
 946                 keyPass = storePass;
 947             }


1098             }
1099 
1100             doCloneEntry(alias, dest, true);  // Now everything can be cloned
1101             kssave = true;
1102         } else if (command == CHANGEALIAS) {
1103             if (alias == null) {
1104                 alias = keyAlias;
1105             }
1106             doCloneEntry(alias, dest, false);
1107             // in PKCS11, clone a PrivateKeyEntry will delete the old one
1108             if (keyStore.containsAlias(alias)) {
1109                 doDeleteEntry(alias);
1110             }
1111             kssave = true;
1112         } else if (command == KEYPASSWD) {
1113             keyPassNew = newPass;
1114             doChangeKeyPasswd(alias);
1115             kssave = true;
1116         } else if (command == LIST) {
1117             if (storePass == null
1118                     && !KeyStoreUtil.isWindowsKeyStore(storetype)) {

1119                 printNoIntegrityWarning();
1120             }
1121 
1122             if (alias != null) {
1123                 doPrintEntry(rb.getString("the.certificate"), alias, out);
1124             } else {
1125                 doPrintEntries(out);
1126             }
1127         } else if (command == PRINTCERT) {
1128             doPrintCert(out);
1129         } else if (command == SELFCERT) {
1130             doSelfCert(alias, dname, sigAlgName);
1131             kssave = true;
1132         } else if (command == STOREPASSWD) {
1133             storePassNew = newPass;
1134             if (storePassNew == null) {
1135                 storePassNew = getNewPasswd("keystore password", storePass);
1136             }
1137             kssave = true;
1138         } else if (command == GENCERT) {


1479     /**
1480      * Deletes an entry from the keystore.
1481      */
1482     private void doDeleteEntry(String alias) throws Exception {
1483         if (keyStore.containsAlias(alias) == false) {
1484             MessageFormat form = new MessageFormat
1485                 (rb.getString("Alias.alias.does.not.exist"));
1486             Object[] source = {alias};
1487             throw new Exception(form.format(source));
1488         }
1489         keyStore.deleteEntry(alias);
1490     }
1491 
1492     /**
1493      * Exports a certificate from the keystore.
1494      */
1495     private void doExportCert(String alias, PrintStream out)
1496         throws Exception
1497     {
1498         if (storePass == null
1499                 && !KeyStoreUtil.isWindowsKeyStore(storetype)) {

1500             printNoIntegrityWarning();
1501         }
1502         if (alias == null) {
1503             alias = keyAlias;
1504         }
1505         if (keyStore.containsAlias(alias) == false) {
1506             MessageFormat form = new MessageFormat
1507                 (rb.getString("Alias.alias.does.not.exist"));
1508             Object[] source = {alias};
1509             throw new Exception(form.format(source));
1510         }
1511 
1512         X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);
1513         if (cert == null) {
1514             MessageFormat form = new MessageFormat
1515                 (rb.getString("Alias.alias.has.no.certificate"));
1516             Object[] source = {alias};
1517             throw new Exception(form.format(source));
1518         }
1519         dumpCert(cert, out);
1520         checkWeak(rb.getString("the.certificate"), cert);
1521     }
1522 
1523     /**
1524      * Prompt the user for a keypass when generating a key entry.
1525      * @param alias the entry we will set password for
1526      * @param orig the original entry of doing a dup, null if generate new
1527      * @param origPass the password to copy from if user press ENTER
1528      */
1529     private char[] promptForKeyPass(String alias, String orig, char[] origPass) throws Exception{
1530         if (P12KEYSTORE.equalsIgnoreCase(storetype)) {
1531             return origPass;
1532         } else if (!token && !protectedPath) {
1533             // Prompt for key password
1534             int count;
1535             for (count = 0; count < 3; count++) {
1536                 MessageFormat form = new MessageFormat(rb.getString
1537                         ("Enter.key.password.for.alias."));
1538                 Object[] source = {alias};
1539                 System.err.println(form.format(source));


1540                 if (orig == null) {
1541                     System.err.print(rb.getString
1542                             (".RETURN.if.same.as.keystore.password."));
1543                 } else {
1544                     form = new MessageFormat(rb.getString
1545                             (".RETURN.if.same.as.for.otherAlias."));
1546                     Object[] src = {orig};
1547                     System.err.print(form.format(src));
1548                 }

1549                 System.err.flush();
1550                 char[] entered = Password.readPassword(System.in);
1551                 passwords.add(entered);
1552                 if (entered == null) {
1553                     return origPass;
1554                 } else if (entered.length >= 6) {
1555                     System.err.print(rb.getString("Re.enter.new.password."));
1556                     char[] passAgain = Password.readPassword(System.in);
1557                     passwords.add(passAgain);
1558                     if (!Arrays.equals(entered, passAgain)) {
1559                         System.err.println
1560                             (rb.getString("They.don.t.match.Try.again"));
1561                         continue;
1562                     }
1563                     return entered;
1564                 } else {
1565                     System.err.println(rb.getString
1566                         ("Key.password.is.too.short.must.be.at.least.6.characters"));
1567                 }
1568             }
1569             if (count == 3) {
1570                 if (command == KEYCLONE) {
1571                     throw new Exception(rb.getString
1572                         ("Too.many.failures.Key.entry.not.cloned"));
1573                 } else {
1574                     throw new Exception(rb.getString


1927                         MessageFormat form = new MessageFormat
1928                                 (rb.getString("Certificate.i.1."));
1929                         Object[] source = {new Integer((i + 1))};
1930                         out.println(form.format(source));
1931                         if (verbose && (chain[i] instanceof X509Certificate)) {
1932                             printX509Cert((X509Certificate)(chain[i]), out);
1933                         } else if (debug) {
1934                             out.println(chain[i].toString());
1935                         } else {
1936                             dumpCert(chain[i], out);
1937                         }
1938                         checkWeak(label, chain[i]);
1939                     }
1940                 } else {
1941                     // Print the digest of the user cert only
1942                     out.println
1943                         (rb.getString("Certificate.fingerprint.SHA.256.") +
1944                         getCertFingerPrint("SHA-256", chain[0]));
1945                     checkWeak(label, chain[0]);
1946                 }



1947             }
1948         } else if (keyStore.entryInstanceOf(alias,
1949                 KeyStore.TrustedCertificateEntry.class)) {
1950             // We have a trusted certificate entry
1951             Certificate cert = keyStore.getCertificate(alias);
1952             Object[] source = {"trustedCertEntry"};
1953             String mf = new MessageFormat(
1954                     rb.getString("Entry.type.type.")).format(source) + "\n";
1955             if (verbose && (cert instanceof X509Certificate)) {
1956                 out.println(mf);
1957                 printX509Cert((X509Certificate)cert, out);
1958             } else if (rfc) {
1959                 out.println(mf);
1960                 dumpCert(cert, out);
1961             } else if (debug) {
1962                 out.println(cert.toString());
1963             } else {
1964                 out.println("trustedCertEntry, ");
1965                 out.println(rb.getString("Certificate.fingerprint.SHA.256.")
1966                             + getCertFingerPrint("SHA-256", cert));


1991                 // Informational, especially if destkeystore is not
1992                 // provided, which default to ~/.keystore.
1993                 System.err.println(String.format(rb.getString(
1994                         "importing.keystore.status"), srcksfname, ksfname));
1995                 return false;
1996             }
1997         } else {
1998             throw new Exception(rb.getString
1999                     ("Please.specify.srckeystore"));
2000         }
2001     }
2002 
2003     /**
2004      * Load the srckeystore from a stream, used in -importkeystore
2005      * @returns the src KeyStore
2006      */
2007     KeyStore loadSourceKeyStore() throws Exception {
2008 
2009         InputStream is = null;
2010         File srcksfile = null;
2011 
2012         if (P11KEYSTORE.equalsIgnoreCase(srcstoretype) ||
2013                 KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
2014             if (!NONE.equals(srcksfname)) {
2015                 System.err.println(MessageFormat.format(rb.getString
2016                     (".keystore.must.be.NONE.if.storetype.is.{0}"), srcstoretype));
2017                 System.err.println();
2018                 tinyHelp();
2019             }
2020         } else {
2021             srcksfile = new File(srcksfname);
2022                 is = new FileInputStream(srcksfile);
2023         }
2024 
2025         KeyStore store;
2026         try {
2027             if (srcstoretype == null) {






2028                 srcstoretype = KeyStore.getDefaultType();
2029             }

2030             if (srcProviderName == null) {
2031                 store = KeyStore.getInstance(srcstoretype);
2032             } else {
2033                 store = KeyStore.getInstance(srcstoretype, srcProviderName);
2034             }
2035 
2036             if (srcstorePass == null
2037                     && !srcprotectedPath
2038                     && !KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {

2039                 System.err.print(rb.getString("Enter.source.keystore.password."));
2040                 System.err.flush();
2041                 srcstorePass = Password.readPassword(System.in);
2042                 passwords.add(srcstorePass);
2043             }
2044 
2045             // always let keypass be storepass when using pkcs12
2046             if (P12KEYSTORE.equalsIgnoreCase(srcstoretype)) {
2047                 if (srckeyPass != null && srcstorePass != null &&
2048                         !Arrays.equals(srcstorePass, srckeyPass)) {
2049                     MessageFormat form = new MessageFormat(rb.getString(
2050                         "Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value."));
2051                     Object[] source = {"-srckeypass"};
2052                     System.err.println(form.format(source));
2053                     srckeyPass = srcstorePass;
2054                 }
2055             }
2056 
2057             store.load(is, srcstorePass);   // "is" already null in PKCS11
2058         } finally {
2059             if (is != null) {
2060                 is.close();
2061             }
2062         }
2063 
2064         if (srcstorePass == null

2065                 && !KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
2066             // anti refactoring, copied from printNoIntegrityWarning(),
2067             // but change 2 lines
2068             System.err.println();
2069             System.err.println(rb.getString
2070                 (".WARNING.WARNING.WARNING."));
2071             System.err.println(rb.getString
2072                 (".The.integrity.of.the.information.stored.in.the.srckeystore."));
2073             System.err.println(rb.getString
2074                 (".WARNING.WARNING.WARNING."));
2075             System.err.println();
2076         }
2077 
2078         return store;
2079     }
2080 
2081     /**
2082      * import all keys and certs from importkeystore.
2083      * keep alias unchanged if no name conflict, otherwise, prompt.
2084      * keep keypass unchanged for keys


3359             key = keyStore.getKey(alias, null);
3360             return Pair.of(key, null);
3361         }
3362 
3363         if (keyStore.containsAlias(alias) == false) {
3364             MessageFormat form = new MessageFormat
3365                 (rb.getString("Alias.alias.does.not.exist"));
3366             Object[] source = {alias};
3367             throw new Exception(form.format(source));
3368         }
3369         if (!keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class) &&
3370                 !keyStore.entryInstanceOf(alias, KeyStore.SecretKeyEntry.class)) {
3371             MessageFormat form = new MessageFormat
3372                 (rb.getString("Alias.alias.has.no.key"));
3373             Object[] source = {alias};
3374             throw new Exception(form.format(source));
3375         }
3376 
3377         if (keyPass == null) {
3378             // Try to recover the key using the keystore password

3379             try {
3380                 key = keyStore.getKey(alias, storePass);
3381 
3382                 keyPass = storePass;
3383                 passwords.add(keyPass);
3384             } catch (UnrecoverableKeyException e) {
3385                 // Did not work out, so prompt user for key password
3386                 if (!token) {
3387                     keyPass = getKeyPasswd(alias, null, null);
3388                     key = keyStore.getKey(alias, keyPass);
3389                 } else {
3390                     throw e;
3391                 }
3392             }





3393         } else {
3394             key = keyStore.getKey(alias, keyPass);
3395         }
3396 
3397         return Pair.of(key, keyPass);
3398     }

3399 
3400     /**
3401      * Recovers entry associated with given alias.
3402      *
3403      * @return an array of objects, where the 1st element in the array is the
3404      * recovered entry, and the 2nd element is the password used to
3405      * recover it (null if no password).
3406      */
3407     private Pair<Entry,char[]> recoverEntry(KeyStore ks,
3408                             String alias,
3409                             char[] pstore,
3410                             char[] pkey) throws Exception {
3411 
3412         if (ks.containsAlias(alias) == false) {
3413             MessageFormat form = new MessageFormat
3414                 (rb.getString("Alias.alias.does.not.exist"));
3415             Object[] source = {alias};
3416             throw new Exception(form.format(source));
3417         }
3418 
3419         PasswordProtection pp = null;
3420         Entry entry;
3421 
3422         try {
3423             // First attempt to access entry without key password
3424             // (PKCS11 entry or trusted certificate entry, for example)
3425 
3426             entry = ks.getEntry(alias, pp);
3427             pkey = null;
3428         } catch (UnrecoverableEntryException une) {
3429 
3430             if(P11KEYSTORE.equalsIgnoreCase(ks.getType()) ||
3431                 KeyStoreUtil.isWindowsKeyStore(ks.getType())) {
3432                 // should not happen, but a possibility
3433                 throw une;
3434             }

3435 
3436             // entry is protected
3437 
3438             if (pkey != null) {




3439 
3440                 // try provided key password
3441 
3442                 pp = new PasswordProtection(pkey);
3443                 entry = ks.getEntry(alias, pp);
3444 
3445             } else {
3446 
3447                 // try store pass
3448 
3449                 try {
3450                     pp = new PasswordProtection(pstore);
3451                     entry = ks.getEntry(alias, pp);
3452                     pkey = pstore;
3453                 } catch (UnrecoverableEntryException une2) {
3454                     if (P12KEYSTORE.equalsIgnoreCase(ks.getType())) {
3455 
3456                         // P12 keystore currently does not support separate
3457                         // store and entry passwords
3458 
3459                         throw une2;
3460                     } else {
3461 
3462                         // prompt for entry password
3463 
3464                         pkey = getKeyPasswd(alias, null, null);
3465                         pp = new PasswordProtection(pkey);
3466                         entry = ks.getEntry(alias, pp);
3467                     }
3468                 }
3469             }
3470         }
3471 




3472         return Pair.of(entry, pkey);
3473     }

3474     /**
3475      * Gets the requested finger print of the certificate.
3476      */
3477     private String getCertFingerPrint(String mdAlg, Certificate cert)
3478         throws Exception
3479     {
3480         byte[] encCertInfo = cert.getEncoded();
3481         MessageDigest md = MessageDigest.getInstance(mdAlg);
3482         byte[] digest = md.digest(encCertInfo);
3483         return toHexString(digest);
3484     }
3485 
3486     /**
3487      * Prints warning about missing integrity check.
3488      */
3489     private void printNoIntegrityWarning() {
3490         System.err.println();
3491         System.err.println(rb.getString
3492             (".WARNING.WARNING.WARNING."));
3493         System.err.println(rb.getString




  60 import java.util.jar.JarFile;
  61 import java.lang.reflect.Constructor;
  62 import java.math.BigInteger;
  63 import java.net.URI;
  64 import java.net.URL;
  65 import java.net.URLClassLoader;
  66 import java.security.cert.CertStore;
  67 
  68 import java.security.cert.X509CRL;
  69 import java.security.cert.X509CRLEntry;
  70 import java.security.cert.X509CRLSelector;
  71 import javax.security.auth.x500.X500Principal;
  72 import java.util.Base64;
  73 
  74 import sun.security.util.DisabledAlgorithmConstraints;
  75 import sun.security.util.KeyUtil;
  76 import sun.security.util.NamedCurve;
  77 import sun.security.util.ObjectIdentifier;
  78 import sun.security.pkcs10.PKCS10;
  79 import sun.security.pkcs10.PKCS10Attribute;
  80 import sun.security.pkcs12.PKCS12KeyStore;
  81 import sun.security.provider.X509Factory;
  82 import sun.security.provider.certpath.CertStoreHelper;
  83 import sun.security.util.Password;
  84 import sun.security.util.SecurityProperties;
  85 import sun.security.util.SecurityProviderConstants;
  86 import sun.security.util.SignatureUtil;
  87 import javax.crypto.KeyGenerator;
  88 import javax.crypto.SecretKey;
  89 import javax.crypto.SecretKeyFactory;
  90 import javax.crypto.spec.PBEKeySpec;
  91 
  92 import sun.security.pkcs.PKCS9Attribute;
  93 import sun.security.tools.KeyStoreUtil;
  94 import sun.security.tools.PathList;
  95 import sun.security.util.DerValue;
  96 import sun.security.util.Pem;
  97 import sun.security.x509.*;
  98 
  99 import static java.security.KeyStore.*;
 100 import static sun.security.tools.keytool.Main.Command.*;
 101 import static sun.security.tools.keytool.Main.Option.*;
 102 
 103 /**
 104  * This tool manages keystores.


 175     private List<String> v3ext = new ArrayList<>();
 176 
 177     // In-place importkeystore is special.
 178     // A backup is needed, and no need to prompt for deststorepass.
 179     private boolean inplaceImport = false;
 180     private String inplaceBackupName = null;
 181 
 182     // Warnings on weak algorithms etc
 183     private List<String> weakWarnings = new ArrayList<>();
 184 
 185     private static final DisabledAlgorithmConstraints DISABLED_CHECK =
 186             new DisabledAlgorithmConstraints(
 187                     DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
 188 
 189     private static final DisabledAlgorithmConstraints LEGACY_CHECK =
 190             new DisabledAlgorithmConstraints(
 191                     DisabledAlgorithmConstraints.PROPERTY_SECURITY_LEGACY_ALGS);
 192 
 193     private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
 194             .unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
 195     private boolean isPasswordlessKeyStore = false;
 196 
 197     enum Command {
 198         CERTREQ("Generates.a.certificate.request",
 199             ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
 200             STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
 201             PROVIDERARG, PROVIDERPATH, V, PROTECTED),
 202         CHANGEALIAS("Changes.an.entry.s.alias",
 203             ALIAS, DESTALIAS, KEYPASS, KEYSTORE, STOREPASS,
 204             STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
 205             PROVIDERPATH, V, PROTECTED),
 206         DELETE("Deletes.an.entry",
 207             ALIAS, KEYSTORE, STOREPASS, STORETYPE,
 208             PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
 209             PROVIDERPATH, V, PROTECTED),
 210         EXPORTCERT("Exports.certificate",
 211             RFC, ALIAS, FILEOUT, KEYSTORE, STOREPASS,
 212             STORETYPE, PROVIDERNAME, PROVIDERCLASS, PROVIDERARG,
 213             PROVIDERPATH, V, PROTECTED),
 214         GENKEYPAIR("Generates.a.key.pair",
 215             ALIAS, KEYALG, KEYSIZE, SIGALG, DESTALIAS, DNAME,


 780                                 ("Keystore.file.does.not.exist.") + ksfname);
 781                     }
 782                 }
 783             }
 784 
 785         if ((command == KEYCLONE || command == CHANGEALIAS)
 786                 && dest == null) {
 787             dest = getAlias("destination");
 788             if ("".equals(dest)) {
 789                 throw new Exception(rb.getString
 790                         ("Must.specify.destination.alias"));
 791             }
 792         }
 793 
 794         if (command == DELETE && alias == null) {
 795             alias = getAlias(null);
 796             if ("".equals(alias)) {
 797                 throw new Exception(rb.getString("Must.specify.alias"));
 798             }
 799         }

 800     // Create new keystore
 801     // Probe for keystore type when filename is available
 802     if (ksfile != null && ksStream != null && providerName == null &&
 803             storetype == null && !inplaceImport) {
 804         String realType = keyStoreType(ksfile);
 805         // If the magic number does not conform to JKS
 806         // then it must be PKCS12
 807         if (!"JKS".equalsIgnoreCase(realType)) {
 808             storetype = P12KEYSTORE;
 809             isPasswordlessKeyStore = PKCS12KeyStore.isPasswordless(ksfile);
 810         } else {
 811             storetype = KeyStore.getDefaultType();;
 812         }
 813         keyStore = KeyStore.getInstance(storetype);
 814         keyStore.load(ksStream, storePass);
 815         ksStream.close();
 816     } else {
 817         if (storetype == null) {
 818             storetype = KeyStore.getDefaultType();
 819         }
 820         if (providerName == null) {
 821             keyStore = KeyStore.getInstance(storetype);
 822         } else {
 823             keyStore = KeyStore.getInstance(storetype, providerName);
 824         }
 825         // When creating a new pkcs12 file, Do not prompt for storepass
 826         // if certProtectionAlgorithm and macAlgorithm are both NONE.
 827         if (storetype.equalsIgnoreCase("pkcs12") && !isPasswordlessKeyStore) {
 828             isPasswordlessKeyStore =
 829                     "NONE".equals(SecurityProperties.privilegedGetOverridable(
 830                             "keystore.pkcs12.certProtectionAlgorithm"))
 831                             && "NONE".equals(SecurityProperties.privilegedGetOverridable(
 832                             "keystore.pkcs12.macAlgorithm"));
 833         }
 834 
 835         /*
 836          * Load the keystore data.
 837          *
 838          * At this point, it's OK if no keystore password has been provided.
 839          * We want to make sure that we can load the keystore data, i.e.,
 840          * the keystore data has the right format. If we cannot load the
 841          * keystore, why bother asking the user for his or her password?
 842          * Only if we were able to load the keystore, and no keystore
 843          * password has been provided, will we prompt the user for the
 844          * keystore password to verify the keystore integrity.
 845          * This means that the keystore is loaded twice: first load operation
 846          * checks the keystore format, second load operation verifies the
 847          * keystore integrity.
 848          *
 849          * If the keystore password has already been provided (at the
 850          * command line), however, the keystore is loaded only once, and the
 851          * keystore format and integrity are checked "at the same time".
 852          *
 853          * Null stream keystores are loaded later.
 854          */
 855         if (!nullStream) {
 856             if (inplaceImport) {
 857                 keyStore.load(null, storePass);
 858             } else {
 859                 keyStore.load(ksStream, storePass);
 860             }
 861             if (ksStream != null) {
 862                 ksStream.close();
 863             }
 864         }
 865     }
 866         if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) {
 867             throw new UnsupportedOperationException(rb.getString
 868                     (".keypasswd.commands.not.supported.if.storetype.is.PKCS12"));
 869         }
 870 
 871         // All commands that create or modify the keystore require a keystore
 872         // password.
 873 
 874         if (nullStream && storePass != null) {
 875             keyStore.load(null, storePass);
 876         } else if (!nullStream && storePass != null) {
 877             // If we are creating a new non nullStream-based keystore,
 878             // insist that the password be at least 6 characters
 879             if (ksStream == null && storePass.length < 6) {
 880                 throw new Exception(rb.getString
 881                         ("Keystore.password.must.be.at.least.6.characters"));
 882             }
 883         } else if (storePass == null) {
 884             if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype)
 885                     && isKeyStoreRelated(command)
 886                     && !isPasswordlessKeyStore) {
 887                 if (command == CERTREQ ||

 888                         command == DELETE ||
 889                         command == GENKEYPAIR ||
 890                         command == GENSECKEY ||
 891                         command == IMPORTCERT ||
 892                         command == IMPORTPASS ||
 893                         command == IMPORTKEYSTORE ||
 894                         command == KEYCLONE ||
 895                         command == CHANGEALIAS ||
 896                         command == SELFCERT ||
 897                         command == STOREPASSWD ||
 898                         command == KEYPASSWD ||
 899                         command == IDENTITYDB) {
 900                     int count = 0;
 901                     do {
 902                         if (command == IMPORTKEYSTORE) {
 903                             System.err.print
 904                                     (rb.getString("Enter.destination.keystore.password."));
 905                         } else {
 906                             System.err.print
 907                                     (rb.getString("Enter.keystore.password."));
 908                         }
 909                         System.err.flush();
 910                         storePass = Password.readPassword(System.in);
 911                         passwords.add(storePass);
 912 
 913                         // If we are creating a new non nullStream-based keystore,
 914                         // insist that the password be at least 6 characters
 915                         if (!nullStream && (storePass == null || storePass.length < 6)) {
 916                             System.err.println(rb.getString
 917                                     ("Keystore.password.is.too.short.must.be.at.least.6.characters"));
 918                             storePass = null;
 919                         }


 923                         if (storePass != null && !nullStream && ksStream == null) {
 924                             System.err.print(rb.getString("Re.enter.new.password."));
 925                             char[] storePassAgain = Password.readPassword(System.in);
 926                             passwords.add(storePassAgain);
 927                             if (!Arrays.equals(storePass, storePassAgain)) {
 928                                 System.err.println
 929                                         (rb.getString("They.don.t.match.Try.again"));
 930                                 storePass = null;
 931                             }
 932                         }
 933 
 934                         count++;
 935                     } while ((storePass == null) && count < 3);
 936 
 937 
 938                     if (storePass == null) {
 939                         System.err.println
 940                                 (rb.getString("Too.many.failures.try.later"));
 941                         return;
 942                     }
 943                 } else {


 944                     // here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
 945                     if (command != PRINTCRL) {
 946                         System.err.print(rb.getString("Enter.keystore.password."));
 947                         System.err.flush();
 948                         storePass = Password.readPassword(System.in);
 949                         passwords.add(storePass);
 950                     }
 951                 }
 952             }
 953 
 954             // Now load a nullStream-based keystore,
 955             // or verify the integrity of an input stream-based keystore
 956             if (nullStream) {
 957                 keyStore.load(null, storePass);
 958             } else if (ksStream != null) {
 959                 ksStream = new FileInputStream(ksfile);
 960                 keyStore.load(ksStream, storePass);
 961                 ksStream.close();
 962             }
 963         }
 964 
 965         if (storePass != null && P12KEYSTORE.equalsIgnoreCase(storetype)) {
 966             MessageFormat form = new MessageFormat(rb.getString(
 967                 "Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value."));
 968             if (keyPass != null && !Arrays.equals(storePass, keyPass)) {
 969                 Object[] source = {"-keypass"};
 970                 System.err.println(form.format(source));
 971                 keyPass = storePass;
 972             }


1123             }
1124 
1125             doCloneEntry(alias, dest, true);  // Now everything can be cloned
1126             kssave = true;
1127         } else if (command == CHANGEALIAS) {
1128             if (alias == null) {
1129                 alias = keyAlias;
1130             }
1131             doCloneEntry(alias, dest, false);
1132             // in PKCS11, clone a PrivateKeyEntry will delete the old one
1133             if (keyStore.containsAlias(alias)) {
1134                 doDeleteEntry(alias);
1135             }
1136             kssave = true;
1137         } else if (command == KEYPASSWD) {
1138             keyPassNew = newPass;
1139             doChangeKeyPasswd(alias);
1140             kssave = true;
1141         } else if (command == LIST) {
1142             if (storePass == null
1143                 && !KeyStoreUtil.isWindowsKeyStore(storetype)
1144                 && !isPasswordlessKeyStore) {
1145                 printNoIntegrityWarning();
1146             }
1147 
1148             if (alias != null) {
1149                 doPrintEntry(rb.getString("the.certificate"), alias, out);
1150             } else {
1151                 doPrintEntries(out);
1152             }
1153         } else if (command == PRINTCERT) {
1154             doPrintCert(out);
1155         } else if (command == SELFCERT) {
1156             doSelfCert(alias, dname, sigAlgName);
1157             kssave = true;
1158         } else if (command == STOREPASSWD) {
1159             storePassNew = newPass;
1160             if (storePassNew == null) {
1161                 storePassNew = getNewPasswd("keystore password", storePass);
1162             }
1163             kssave = true;
1164         } else if (command == GENCERT) {


1505     /**
1506      * Deletes an entry from the keystore.
1507      */
1508     private void doDeleteEntry(String alias) throws Exception {
1509         if (keyStore.containsAlias(alias) == false) {
1510             MessageFormat form = new MessageFormat
1511                 (rb.getString("Alias.alias.does.not.exist"));
1512             Object[] source = {alias};
1513             throw new Exception(form.format(source));
1514         }
1515         keyStore.deleteEntry(alias);
1516     }
1517 
1518     /**
1519      * Exports a certificate from the keystore.
1520      */
1521     private void doExportCert(String alias, PrintStream out)
1522         throws Exception
1523     {
1524         if (storePass == null
1525                 && !KeyStoreUtil.isWindowsKeyStore(storetype)
1526                 && !isPasswordlessKeyStore) {
1527             printNoIntegrityWarning();
1528         }
1529         if (alias == null) {
1530             alias = keyAlias;
1531         }
1532         if (keyStore.containsAlias(alias) == false) {
1533             MessageFormat form = new MessageFormat
1534                 (rb.getString("Alias.alias.does.not.exist"));
1535             Object[] source = {alias};
1536             throw new Exception(form.format(source));
1537         }
1538 
1539         X509Certificate cert = (X509Certificate)keyStore.getCertificate(alias);
1540         if (cert == null) {
1541             MessageFormat form = new MessageFormat
1542                 (rb.getString("Alias.alias.has.no.certificate"));
1543             Object[] source = {alias};
1544             throw new Exception(form.format(source));
1545         }
1546         dumpCert(cert, out);
1547         checkWeak(rb.getString("the.certificate"), cert);
1548     }
1549 
1550     /**
1551      * Prompt the user for a keypass when generating a key entry.
1552      * @param alias the entry we will set password for
1553      * @param orig the original entry of doing a dup, null if generate new
1554      * @param origPass the password to copy from if user press ENTER
1555      */
1556     private char[] promptForKeyPass(String alias, String orig, char[] origPass) throws Exception{
1557         if (origPass != null && P12KEYSTORE.equalsIgnoreCase(storetype)) {
1558             return origPass;
1559         } else if (!token && !protectedPath) {
1560             // Prompt for key password
1561             int count;
1562             for (count = 0; count < 3; count++) {
1563                 MessageFormat form = new MessageFormat(rb.getString
1564                         ("Enter.key.password.for.alias."));
1565                 Object[] source = {alias};
1566                 System.err.print(form.format(source));
1567                 if (origPass != null) {
1568                     System.err.println();
1569                     if (orig == null) {
1570                         System.err.print(rb.getString
1571                                 (".RETURN.if.same.as.keystore.password."));
1572                     } else {
1573                         form = new MessageFormat(rb.getString
1574                                 (".RETURN.if.same.as.for.otherAlias."));
1575                         Object[] src = {orig};
1576                         System.err.print(form.format(src));
1577                     }
1578                 }
1579                 System.err.flush();
1580                 char[] entered = Password.readPassword(System.in);
1581                 passwords.add(entered);
1582                 if (entered == null && origPass != null) {
1583                     return origPass;
1584                 } else if (entered != null && entered.length >= 6) {
1585                     System.err.print(rb.getString("Re.enter.new.password."));
1586                     char[] passAgain = Password.readPassword(System.in);
1587                     passwords.add(passAgain);
1588                     if (!Arrays.equals(entered, passAgain)) {
1589                         System.err.println
1590                             (rb.getString("They.don.t.match.Try.again"));
1591                         continue;
1592                     }
1593                     return entered;
1594                 } else {
1595                     System.err.println(rb.getString
1596                         ("Key.password.is.too.short.must.be.at.least.6.characters"));
1597                 }
1598             }
1599             if (count == 3) {
1600                 if (command == KEYCLONE) {
1601                     throw new Exception(rb.getString
1602                         ("Too.many.failures.Key.entry.not.cloned"));
1603                 } else {
1604                     throw new Exception(rb.getString


1957                         MessageFormat form = new MessageFormat
1958                                 (rb.getString("Certificate.i.1."));
1959                         Object[] source = {new Integer((i + 1))};
1960                         out.println(form.format(source));
1961                         if (verbose && (chain[i] instanceof X509Certificate)) {
1962                             printX509Cert((X509Certificate)(chain[i]), out);
1963                         } else if (debug) {
1964                             out.println(chain[i].toString());
1965                         } else {
1966                             dumpCert(chain[i], out);
1967                         }
1968                         checkWeak(label, chain[i]);
1969                     }
1970                 } else {
1971                     // Print the digest of the user cert only
1972                     out.println
1973                         (rb.getString("Certificate.fingerprint.SHA.256.") +
1974                         getCertFingerPrint("SHA-256", chain[0]));
1975                     checkWeak(label, chain[0]);
1976                 }
1977             } else {
1978                 out.println(rb.getString
1979                         ("Certificate.chain.length.") + 0);
1980             }
1981         } else if (keyStore.entryInstanceOf(alias,
1982                 KeyStore.TrustedCertificateEntry.class)) {
1983             // We have a trusted certificate entry
1984             Certificate cert = keyStore.getCertificate(alias);
1985             Object[] source = {"trustedCertEntry"};
1986             String mf = new MessageFormat(
1987                     rb.getString("Entry.type.type.")).format(source) + "\n";
1988             if (verbose && (cert instanceof X509Certificate)) {
1989                 out.println(mf);
1990                 printX509Cert((X509Certificate)cert, out);
1991             } else if (rfc) {
1992                 out.println(mf);
1993                 dumpCert(cert, out);
1994             } else if (debug) {
1995                 out.println(cert.toString());
1996             } else {
1997                 out.println("trustedCertEntry, ");
1998                 out.println(rb.getString("Certificate.fingerprint.SHA.256.")
1999                             + getCertFingerPrint("SHA-256", cert));


2024                 // Informational, especially if destkeystore is not
2025                 // provided, which default to ~/.keystore.
2026                 System.err.println(String.format(rb.getString(
2027                         "importing.keystore.status"), srcksfname, ksfname));
2028                 return false;
2029             }
2030         } else {
2031             throw new Exception(rb.getString
2032                     ("Please.specify.srckeystore"));
2033         }
2034     }
2035 
2036     /**
2037      * Load the srckeystore from a stream, used in -importkeystore
2038      * @returns the src KeyStore
2039      */
2040     KeyStore loadSourceKeyStore() throws Exception {
2041 
2042         InputStream is = null;
2043         File srcksfile = null;
2044         boolean srcIsPasswordless = false;
2045         if (P11KEYSTORE.equalsIgnoreCase(srcstoretype) ||
2046                 KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
2047             if (!NONE.equals(srcksfname)) {
2048                 System.err.println(MessageFormat.format(rb.getString
2049                     (".keystore.must.be.NONE.if.storetype.is.{0}"), srcstoretype));
2050                 System.err.println();
2051                 tinyHelp();
2052             }
2053         } else {
2054             srcksfile = new File(srcksfname);
2055                 is = new FileInputStream(srcksfile);
2056         }
2057 
2058         KeyStore store;
2059         try {
2060             if (srcstoretype == null) {
2061                 String realType = keyStoreType(srcksfile);
2062                 if (srcksfile != null && is != null && srcProviderName == null &&
2063                         !"JKS".equalsIgnoreCase(realType)) {
2064                     srcstoretype = P12KEYSTORE;
2065                     srcIsPasswordless = PKCS12KeyStore.isPasswordless(srcksfile);
2066                 } else {
2067                     srcstoretype = KeyStore.getDefaultType();
2068                 }
2069             }
2070             if (srcProviderName == null) {
2071                 store = KeyStore.getInstance(srcstoretype);
2072             } else {
2073                 store = KeyStore.getInstance(srcstoretype, srcProviderName);
2074             }
2075 
2076             if (srcstorePass == null
2077                     && !srcprotectedPath
2078                     && !KeyStoreUtil.isWindowsKeyStore(srcstoretype)
2079                     && !srcIsPasswordless) {
2080                 System.err.print(rb.getString("Enter.source.keystore.password."));
2081                 System.err.flush();
2082                 srcstorePass = Password.readPassword(System.in);
2083                 passwords.add(srcstorePass);
2084             }
2085 
2086             // always let keypass be storepass when using pkcs12
2087             if (P12KEYSTORE.equalsIgnoreCase(srcstoretype)) {
2088                 if (srckeyPass != null && srcstorePass != null &&
2089                         !Arrays.equals(srcstorePass, srckeyPass)) {
2090                     MessageFormat form = new MessageFormat(rb.getString(
2091                         "Warning.Different.store.and.key.passwords.not.supported.for.PKCS12.KeyStores.Ignoring.user.specified.command.value."));
2092                     Object[] source = {"-srckeypass"};
2093                     System.err.println(form.format(source));
2094                     srckeyPass = srcstorePass;
2095                 }
2096             }
2097 
2098             store.load(is, srcstorePass);   // "is" already null in PKCS11
2099         } finally {
2100             if (is != null) {
2101                 is.close();
2102             }
2103         }
2104 
2105         if (srcstorePass == null
2106                 && !srcIsPasswordless
2107                 && !KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
2108             // anti refactoring, copied from printNoIntegrityWarning(),
2109             // but change 2 lines
2110             System.err.println();
2111             System.err.println(rb.getString
2112                 (".WARNING.WARNING.WARNING."));
2113             System.err.println(rb.getString
2114                 (".The.integrity.of.the.information.stored.in.the.srckeystore."));
2115             System.err.println(rb.getString
2116                 (".WARNING.WARNING.WARNING."));
2117             System.err.println();
2118         }
2119 
2120         return store;
2121     }
2122 
2123     /**
2124      * import all keys and certs from importkeystore.
2125      * keep alias unchanged if no name conflict, otherwise, prompt.
2126      * keep keypass unchanged for keys


3401             key = keyStore.getKey(alias, null);
3402             return Pair.of(key, null);
3403         }
3404 
3405         if (keyStore.containsAlias(alias) == false) {
3406             MessageFormat form = new MessageFormat
3407                 (rb.getString("Alias.alias.does.not.exist"));
3408             Object[] source = {alias};
3409             throw new Exception(form.format(source));
3410         }
3411         if (!keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class) &&
3412                 !keyStore.entryInstanceOf(alias, KeyStore.SecretKeyEntry.class)) {
3413             MessageFormat form = new MessageFormat
3414                 (rb.getString("Alias.alias.has.no.key"));
3415             Object[] source = {alias};
3416             throw new Exception(form.format(source));
3417         }
3418 
3419         if (keyPass == null) {
3420             // Try to recover the key using the keystore password
3421             if (storePass != null) {
3422                 try {
3423                     key = keyStore.getKey(alias, storePass);
3424                     passwords.add(storePass);
3425                     return Pair.of(key, storePass);

3426                 } catch (UnrecoverableKeyException e) {
3427                     if (token) {




3428                         throw e;
3429                     }
3430                 }
3431             }
3432             // prompt user for key password
3433             keyPass = getKeyPasswd(alias, null, null);
3434             key = keyStore.getKey(alias, keyPass);
3435             return Pair.of(key, keyPass);
3436         } else {
3437             key = keyStore.getKey(alias, keyPass);


3438             return Pair.of(key, keyPass);
3439         }
3440     }
3441 
3442     /**
3443      * Recovers entry associated with given alias.
3444      *
3445      * @return an array of objects, where the 1st element in the array is the
3446      * recovered entry, and the 2nd element is the password used to
3447      * recover it (null if no password).
3448      */
3449     private Pair<Entry,char[]> recoverEntry(KeyStore ks,
3450                             String alias,
3451                             char[] pstore,
3452                             char[] pkey) throws Exception {
3453         if (!ks.containsAlias(alias)) {
3454             MessageFormat form = new MessageFormat(
3455                     rb.getString("Alias.alias.does.not.exist"));

3456             Object[] source = {alias};
3457             throw new Exception(form.format(source));
3458         }
3459 
3460         // Step 1: First attempt to access entry without key password
3461         // (PKCS11 entry or trusted certificate entry, for example).
3462         // If fail, go next.
3463         try {
3464             Entry entry = ks.getEntry(alias, null);
3465             return Pair.of(entry, null);



3466         } catch (UnrecoverableEntryException une) {

3467             if(P11KEYSTORE.equalsIgnoreCase(ks.getType()) ||
3468                     KeyStoreUtil.isWindowsKeyStore(ks.getType())) {
3469                 // should not happen, but a possibility
3470                 throw une;
3471             }
3472         }
3473 
3474         // entry is protected
3475         // Step 2: try pkey if not null. If fail, fail.
3476         if (pkey != null) {
3477             PasswordProtection pp = new PasswordProtection(pkey);
3478             Entry entry = ks.getEntry(alias, pp);
3479             return Pair.of(entry, pkey);
3480         }
3481 
3482         // Step 3: try pstore if not null. If fail, go next.
3483         if (pstore != null) {







3484             try {
3485                 PasswordProtection pp = new PasswordProtection(pstore);
3486                 Entry entry = ks.getEntry(alias, pp);
3487                 return Pair.of(entry, pstore);
3488             } catch (UnrecoverableEntryException une) {
3489                 if (P12KEYSTORE.equalsIgnoreCase(ks.getType())) {

3490                     // P12 keystore currently does not support separate
3491                     // store and entry passwords. We will not prompt for
3492                     // entry password.
3493                     throw une;








3494                 }
3495             }
3496         }
3497 
3498         // Step 4: prompt for entry password
3499         pkey = getKeyPasswd(alias, null, null);
3500         PasswordProtection pp = new PasswordProtection(pkey);
3501         Entry entry = ks.getEntry(alias, pp);
3502         return Pair.of(entry, pkey);
3503     }
3504 
3505     /**
3506      * Gets the requested finger print of the certificate.
3507      */
3508     private String getCertFingerPrint(String mdAlg, Certificate cert)
3509         throws Exception
3510     {
3511         byte[] encCertInfo = cert.getEncoded();
3512         MessageDigest md = MessageDigest.getInstance(mdAlg);
3513         byte[] digest = md.digest(encCertInfo);
3514         return toHexString(digest);
3515     }
3516 
3517     /**
3518      * Prints warning about missing integrity check.
3519      */
3520     private void printNoIntegrityWarning() {
3521         System.err.println();
3522         System.err.println(rb.getString
3523             (".WARNING.WARNING.WARNING."));
3524         System.err.println(rb.getString


< prev index next >