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
|