< prev index next >
src/share/classes/sun/security/tools/keytool/Main.java
Print this page
@@ -75,13 +75,15 @@
import sun.security.util.KeyUtil;
import sun.security.util.NamedCurve;
import sun.security.util.ObjectIdentifier;
import sun.security.pkcs10.PKCS10;
import sun.security.pkcs10.PKCS10Attribute;
+import sun.security.pkcs12.PKCS12KeyStore;
import sun.security.provider.X509Factory;
import sun.security.provider.certpath.CertStoreHelper;
import sun.security.util.Password;
+import sun.security.util.SecurityProperties;
import sun.security.util.SecurityProviderConstants;
import sun.security.util.SignatureUtil;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@@ -188,10 +190,11 @@
new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_SECURITY_LEGACY_ALGS);
private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET = Collections
.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+ private boolean isPasswordlessKeyStore = false;
enum Command {
CERTREQ("Generates.a.certificate.request",
ALIAS, SIGALG, FILEOUT, KEYPASS, KEYSTORE, DNAME,
STOREPASS, STORETYPE, PROVIDERNAME, PROVIDERCLASS,
@@ -792,20 +795,44 @@
alias = getAlias(null);
if ("".equals(alias)) {
throw new Exception(rb.getString("Must.specify.alias"));
}
}
-
// Create new keystore
+ // Probe for keystore type when filename is available
+ if (ksfile != null && ksStream != null && providerName == null &&
+ storetype == null && !inplaceImport) {
+ String realType = keyStoreType(ksfile);
+ // If the magic number does not conform to JKS
+ // then it must be PKCS12
+ if (!"JKS".equalsIgnoreCase(realType)) {
+ storetype = P12KEYSTORE;
+ isPasswordlessKeyStore = PKCS12KeyStore.isPasswordless(ksfile);
+ } else {
+ storetype = KeyStore.getDefaultType();;
+ }
+ keyStore = KeyStore.getInstance(storetype);
+ keyStore.load(ksStream, storePass);
+ ksStream.close();
+ } else {
if (storetype == null) {
storetype = KeyStore.getDefaultType();
}
if (providerName == null) {
keyStore = KeyStore.getInstance(storetype);
} else {
keyStore = KeyStore.getInstance(storetype, providerName);
}
+ // When creating a new pkcs12 file, Do not prompt for storepass
+ // if certProtectionAlgorithm and macAlgorithm are both NONE.
+ if (storetype.equalsIgnoreCase("pkcs12") && !isPasswordlessKeyStore) {
+ isPasswordlessKeyStore =
+ "NONE".equals(SecurityProperties.privilegedGetOverridable(
+ "keystore.pkcs12.certProtectionAlgorithm"))
+ && "NONE".equals(SecurityProperties.privilegedGetOverridable(
+ "keystore.pkcs12.macAlgorithm"));
+ }
/*
* Load the keystore data.
*
* At this point, it's OK if no keystore password has been provided.
@@ -833,11 +860,11 @@
}
if (ksStream != null) {
ksStream.close();
}
}
-
+ }
if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) {
throw new UnsupportedOperationException(rb.getString
(".keypasswd.commands.not.supported.if.storetype.is.PKCS12"));
}
@@ -852,15 +879,14 @@
if (ksStream == null && storePass.length < 6) {
throw new Exception(rb.getString
("Keystore.password.must.be.at.least.6.characters"));
}
} else if (storePass == null) {
-
- // only prompt if (protectedPath == false)
-
- if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype) &&
- (command == CERTREQ ||
+ if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype)
+ && isKeyStoreRelated(command)
+ && !isPasswordlessKeyStore) {
+ if (command == CERTREQ ||
command == DELETE ||
command == GENKEYPAIR ||
command == GENSECKEY ||
command == IMPORTCERT ||
command == IMPORTPASS ||
@@ -868,11 +894,11 @@
command == KEYCLONE ||
command == CHANGEALIAS ||
command == SELFCERT ||
command == STOREPASSWD ||
command == KEYPASSWD ||
- command == IDENTITYDB)) {
+ command == IDENTITYDB) {
int count = 0;
do {
if (command == IMPORTKEYSTORE) {
System.err.print
(rb.getString("Enter.destination.keystore.password."));
@@ -912,21 +938,20 @@
if (storePass == null) {
System.err.println
(rb.getString("Too.many.failures.try.later"));
return;
}
- } else if (!protectedPath
- && !KeyStoreUtil.isWindowsKeyStore(storetype)
- && isKeyStoreRelated(command)) {
+ } else {
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
if (command != PRINTCRL) {
System.err.print(rb.getString("Enter.keystore.password."));
System.err.flush();
storePass = Password.readPassword(System.in);
passwords.add(storePass);
}
}
+ }
// Now load a nullStream-based keystore,
// or verify the integrity of an input stream-based keystore
if (nullStream) {
keyStore.load(null, storePass);
@@ -1113,11 +1138,12 @@
keyPassNew = newPass;
doChangeKeyPasswd(alias);
kssave = true;
} else if (command == LIST) {
if (storePass == null
- && !KeyStoreUtil.isWindowsKeyStore(storetype)) {
+ && !KeyStoreUtil.isWindowsKeyStore(storetype)
+ && !isPasswordlessKeyStore) {
printNoIntegrityWarning();
}
if (alias != null) {
doPrintEntry(rb.getString("the.certificate"), alias, out);
@@ -1494,11 +1520,12 @@
*/
private void doExportCert(String alias, PrintStream out)
throws Exception
{
if (storePass == null
- && !KeyStoreUtil.isWindowsKeyStore(storetype)) {
+ && !KeyStoreUtil.isWindowsKeyStore(storetype)
+ && !isPasswordlessKeyStore) {
printNoIntegrityWarning();
}
if (alias == null) {
alias = keyAlias;
}
@@ -1525,35 +1552,38 @@
* @param alias the entry we will set password for
* @param orig the original entry of doing a dup, null if generate new
* @param origPass the password to copy from if user press ENTER
*/
private char[] promptForKeyPass(String alias, String orig, char[] origPass) throws Exception{
- if (P12KEYSTORE.equalsIgnoreCase(storetype)) {
+ if (origPass != null && P12KEYSTORE.equalsIgnoreCase(storetype)) {
return origPass;
} else if (!token && !protectedPath) {
// Prompt for key password
int count;
for (count = 0; count < 3; count++) {
MessageFormat form = new MessageFormat(rb.getString
("Enter.key.password.for.alias."));
Object[] source = {alias};
- System.err.println(form.format(source));
+ System.err.print(form.format(source));
+ if (origPass != null) {
+ System.err.println();
if (orig == null) {
System.err.print(rb.getString
(".RETURN.if.same.as.keystore.password."));
} else {
form = new MessageFormat(rb.getString
(".RETURN.if.same.as.for.otherAlias."));
Object[] src = {orig};
System.err.print(form.format(src));
}
+ }
System.err.flush();
char[] entered = Password.readPassword(System.in);
passwords.add(entered);
- if (entered == null) {
+ if (entered == null && origPass != null) {
return origPass;
- } else if (entered.length >= 6) {
+ } else if (entered != null && entered.length >= 6) {
System.err.print(rb.getString("Re.enter.new.password."));
char[] passAgain = Password.readPassword(System.in);
passwords.add(passAgain);
if (!Arrays.equals(entered, passAgain)) {
System.err.println
@@ -1942,10 +1972,13 @@
out.println
(rb.getString("Certificate.fingerprint.SHA.256.") +
getCertFingerPrint("SHA-256", chain[0]));
checkWeak(label, chain[0]);
}
+ } else {
+ out.println(rb.getString
+ ("Certificate.chain.length.") + 0);
}
} else if (keyStore.entryInstanceOf(alias,
KeyStore.TrustedCertificateEntry.class)) {
// We have a trusted certificate entry
Certificate cert = keyStore.getCertificate(alias);
@@ -2006,11 +2039,11 @@
*/
KeyStore loadSourceKeyStore() throws Exception {
InputStream is = null;
File srcksfile = null;
-
+ boolean srcIsPasswordless = false;
if (P11KEYSTORE.equalsIgnoreCase(srcstoretype) ||
KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
if (!NONE.equals(srcksfname)) {
System.err.println(MessageFormat.format(rb.getString
(".keystore.must.be.NONE.if.storetype.is.{0}"), srcstoretype));
@@ -2023,21 +2056,29 @@
}
KeyStore store;
try {
if (srcstoretype == null) {
+ String realType = keyStoreType(srcksfile);
+ if (srcksfile != null && is != null && srcProviderName == null &&
+ !"JKS".equalsIgnoreCase(realType)) {
+ srcstoretype = P12KEYSTORE;
+ srcIsPasswordless = PKCS12KeyStore.isPasswordless(srcksfile);
+ } else {
srcstoretype = KeyStore.getDefaultType();
}
+ }
if (srcProviderName == null) {
store = KeyStore.getInstance(srcstoretype);
} else {
store = KeyStore.getInstance(srcstoretype, srcProviderName);
}
if (srcstorePass == null
&& !srcprotectedPath
- && !KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
+ && !KeyStoreUtil.isWindowsKeyStore(srcstoretype)
+ && !srcIsPasswordless) {
System.err.print(rb.getString("Enter.source.keystore.password."));
System.err.flush();
srcstorePass = Password.readPassword(System.in);
passwords.add(srcstorePass);
}
@@ -2060,10 +2101,11 @@
is.close();
}
}
if (srcstorePass == null
+ && !srcIsPasswordless
&& !KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
// anti refactoring, copied from printNoIntegrityWarning(),
// but change 2 lines
System.err.println();
System.err.println(rb.getString
@@ -3374,30 +3416,30 @@
throw new Exception(form.format(source));
}
if (keyPass == null) {
// Try to recover the key using the keystore password
+ if (storePass != null) {
try {
key = keyStore.getKey(alias, storePass);
-
- keyPass = storePass;
- passwords.add(keyPass);
+ passwords.add(storePass);
+ return Pair.of(key, storePass);
} catch (UnrecoverableKeyException e) {
- // Did not work out, so prompt user for key password
- if (!token) {
- keyPass = getKeyPasswd(alias, null, null);
- key = keyStore.getKey(alias, keyPass);
- } else {
+ if (token) {
throw e;
}
}
+ }
+ // prompt user for key password
+ keyPass = getKeyPasswd(alias, null, null);
+ key = keyStore.getKey(alias, keyPass);
+ return Pair.of(key, keyPass);
} else {
key = keyStore.getKey(alias, keyPass);
- }
-
return Pair.of(key, keyPass);
}
+ }
/**
* Recovers entry associated with given alias.
*
* @return an array of objects, where the 1st element in the array is the
@@ -3406,73 +3448,62 @@
*/
private Pair<Entry,char[]> recoverEntry(KeyStore ks,
String alias,
char[] pstore,
char[] pkey) throws Exception {
-
- if (ks.containsAlias(alias) == false) {
- MessageFormat form = new MessageFormat
- (rb.getString("Alias.alias.does.not.exist"));
+ if (!ks.containsAlias(alias)) {
+ MessageFormat form = new MessageFormat(
+ rb.getString("Alias.alias.does.not.exist"));
Object[] source = {alias};
throw new Exception(form.format(source));
}
- PasswordProtection pp = null;
- Entry entry;
-
+ // Step 1: First attempt to access entry without key password
+ // (PKCS11 entry or trusted certificate entry, for example).
+ // If fail, go next.
try {
- // First attempt to access entry without key password
- // (PKCS11 entry or trusted certificate entry, for example)
-
- entry = ks.getEntry(alias, pp);
- pkey = null;
+ Entry entry = ks.getEntry(alias, null);
+ return Pair.of(entry, null);
} catch (UnrecoverableEntryException une) {
-
if(P11KEYSTORE.equalsIgnoreCase(ks.getType()) ||
KeyStoreUtil.isWindowsKeyStore(ks.getType())) {
// should not happen, but a possibility
throw une;
}
+ }
// entry is protected
-
+ // Step 2: try pkey if not null. If fail, fail.
if (pkey != null) {
+ PasswordProtection pp = new PasswordProtection(pkey);
+ Entry entry = ks.getEntry(alias, pp);
+ return Pair.of(entry, pkey);
+ }
- // try provided key password
-
- pp = new PasswordProtection(pkey);
- entry = ks.getEntry(alias, pp);
-
- } else {
-
- // try store pass
-
+ // Step 3: try pstore if not null. If fail, go next.
+ if (pstore != null) {
try {
- pp = new PasswordProtection(pstore);
- entry = ks.getEntry(alias, pp);
- pkey = pstore;
- } catch (UnrecoverableEntryException une2) {
+ PasswordProtection pp = new PasswordProtection(pstore);
+ Entry entry = ks.getEntry(alias, pp);
+ return Pair.of(entry, pstore);
+ } catch (UnrecoverableEntryException une) {
if (P12KEYSTORE.equalsIgnoreCase(ks.getType())) {
-
// P12 keystore currently does not support separate
- // store and entry passwords
-
- throw une2;
- } else {
-
- // prompt for entry password
-
- pkey = getKeyPasswd(alias, null, null);
- pp = new PasswordProtection(pkey);
- entry = ks.getEntry(alias, pp);
- }
+ // store and entry passwords. We will not prompt for
+ // entry password.
+ throw une;
}
}
}
+ // Step 4: prompt for entry password
+ pkey = getKeyPasswd(alias, null, null);
+ PasswordProtection pp = new PasswordProtection(pkey);
+ Entry entry = ks.getEntry(alias, pp);
return Pair.of(entry, pkey);
}
+
/**
* Gets the requested finger print of the certificate.
*/
private String getCertFingerPrint(String mdAlg, Certificate cert)
throws Exception
< prev index next >