void doCommands(PrintStream out) throws Exception {
if (storetype == null) {
storetype = KeyStore.getDefaultType();
}
storetype = KeyStoreUtil.niceStoreTypeName(storetype);
if (srcstoretype == null) {
srcstoretype = KeyStore.getDefaultType();
}
srcstoretype = KeyStoreUtil.niceStoreTypeName(srcstoretype);
if (P11KEYSTORE.equalsIgnoreCase(storetype) ||
KeyStoreUtil.isWindowsKeyStore(storetype)) {
token = true;
if (ksfname == null) {
ksfname = NONE;
}
}
if (NONE.equals(ksfname)) {
nullStream = true;
}
if (token && !nullStream) {
System.err.println(MessageFormat.format(rb.getString
("-keystore must be NONE if -storetype is {0}"), storetype));
System.err.println();
tinyHelp();
}
if (token &&
(command == KEYPASSWD || command == STOREPASSWD)) {
throw new UnsupportedOperationException(MessageFormat.format(rb.getString
("-storepasswd and -keypasswd commands not supported " +
"if -storetype is {0}"), storetype));
}
if (P12KEYSTORE.equalsIgnoreCase(storetype) && command == KEYPASSWD) {
throw new UnsupportedOperationException(rb.getString
("-keypasswd commands not supported " +
"if -storetype is PKCS12"));
}
if (token && (keyPass != null || newPass != null || destKeyPass != null)) {
throw new IllegalArgumentException(MessageFormat.format(rb.getString
("-keypass and -new " +
"can not be specified if -storetype is {0}"), storetype));
}
if (protectedPath) {
if (storePass != null || keyPass != null ||
newPass != null || destKeyPass != null) {
throw new IllegalArgumentException(rb.getString
("if -protected is specified, " +
"then -storepass, -keypass, and -new " +
"must not be specified"));
}
}
if (srcprotectedPath) {
if (srcstorePass != null || srckeyPass != null) {
throw new IllegalArgumentException(rb.getString
("if -srcprotected is specified, " +
"then -srcstorepass and -srckeypass " +
"must not be specified"));
}
}
if (KeyStoreUtil.isWindowsKeyStore(storetype)) {
if (storePass != null || keyPass != null ||
newPass != null || destKeyPass != null) {
throw new IllegalArgumentException(rb.getString
("if keystore is not password protected, " +
"then -storepass, -keypass, and -new " +
"must not be specified"));
}
}
if (KeyStoreUtil.isWindowsKeyStore(srcstoretype)) {
if (srcstorePass != null || srckeyPass != null) {
throw new IllegalArgumentException(rb.getString
("if source keystore is not password protected, " +
"then -srcstorepass and -srckeypass " +
"must not be specified"));
}
}
if (validity < = (long)0) {
throw new Exception
(rb.getString("Validity must be greater than zero"));
}
// Try to load and install specified provider
if (providers != null) {
ClassLoader cl = null;
if (pathlist != null) {
String path = null;
path = PathList.appendPath(
path, System.getProperty("java.class.path"));
path = PathList.appendPath(
path, System.getProperty("env.class.path"));
path = PathList.appendPath(path, pathlist);
URL[] urls = PathList.pathToURLs(path);
cl = new URLClassLoader(urls);
} else {
cl = ClassLoader.getSystemClassLoader();
}
for (Pair < String, String > provider: providers) {
String provName = provider.fst;
Class< ? > provClass;
if (cl != null) {
provClass = cl.loadClass(provName);
} else {
provClass = Class.forName(provName);
}
String provArg = provider.snd;
Object obj;
if (provArg == null) {
obj = provClass.newInstance();
} else {
Constructor< ? > c = provClass.getConstructor(PARAM_STRING);
obj = c.newInstance(provArg);
}
if (!(obj instanceof Provider)) {
MessageFormat form = new MessageFormat
(rb.getString("provName not a provider"));
Object[] source = {provName};
throw new Exception(form.format(source));
}
Security.addProvider((Provider)obj);
}
}
if (command == LIST && verbose && rfc) {
System.err.println(rb.getString
("Must not specify both -v and -rfc with 'list' command"));
tinyHelp();
}
// Make sure provided passwords are at least 6 characters long
if (command == GENKEYPAIR && keyPass!=null && keyPass.length < 6) {
throw new Exception(rb.getString
("Key password must be at least 6 characters"));
}
if (newPass != null && newPass.length < 6) {
throw new Exception(rb.getString
("New password must be at least 6 characters"));
}
if (destKeyPass != null && destKeyPass.length < 6) {
throw new Exception(rb.getString
("New password must be at least 6 characters"));
}
// Check if keystore exists.
// If no keystore has been specified at the command line, try to use
// the default, which is located in $HOME/.keystore.
// If the command is "genkey", "identitydb", "import", or "printcert",
// it is OK not to have a keystore.
if (command != PRINTCERT) {
if (ksfname == null) {
ksfname = System.getProperty("user.home") + File.separator
+ ".keystore";
}
if (!nullStream) {
try {
ksfile = new File(ksfname);
// Check if keystore file is empty
if (ksfile.exists() && ksfile.length() == 0) {
throw new Exception(rb.getString
("Keystore file exists, but is empty: ") + ksfname);
}
ksStream = new FileInputStream(ksfile);
} catch (FileNotFoundException e) {
if (command != GENKEYPAIR &&
command != GENSECKEY &&
command != IDENTITYDB &&
command != IMPORTCERT &&
command != IMPORTKEYSTORE) {
throw new Exception(rb.getString
("Keystore file does not exist: ") + ksfname);
}
}
}
}
if ((command == KEYCLONE || command == CHANGEALIAS)
&& dest == null) {
dest = getAlias("destination");
if ("".equals(dest)) {
throw new Exception(rb.getString
("Must specify destination alias"));
}
}
if (command == DELETE && alias == null) {
alias = getAlias(null);
if ("".equals(alias)) {
throw new Exception(rb.getString("Must specify alias"));
}
}
// Create new keystore
if (providerName == null) {
keyStore = KeyStore.getInstance(storetype);
} else {
keyStore = KeyStore.getInstance(storetype, providerName);
}
/*
* Load the keystore data.
*
* At this point, it's OK if no keystore password has been provided.
* We want to make sure that we can load the keystore data, i.e.,
* the keystore data has the right format. If we cannot load the
* keystore, why bother asking the user for his or her password?
* Only if we were able to load the keystore, and no keystore
* password has been provided, will we prompt the user for the
* keystore password to verify the keystore integrity.
* This means that the keystore is loaded twice: first load operation
* checks the keystore format, second load operation verifies the
* keystore integrity.
*
* If the keystore password has already been provided (at the
* command line), however, the keystore is loaded only once, and the
* keystore format and integrity are checked "at the same time".
*
* Null stream keystores are loaded later.
*/
if (!nullStream) {
keyStore.load(ksStream, storePass);
if (ksStream != null) {
ksStream.close();
}
}
// All commands that create or modify the keystore require a keystore
// password.
if (nullStream && storePass != null) {
keyStore.load(null, storePass);
} else if (!nullStream && storePass != null) {
// If we are creating a new non nullStream-based keystore,
// insist that the password be at least 6 characters
if (ksStream == null && storePass.length < 6) {
throw new Exception(rb.getString
("Keystore password must be at least 6 characters"));
}
} else if (storePass == null) {
// only prompt if (protectedPath == false)
if (!protectedPath && !KeyStoreUtil.isWindowsKeyStore(storetype) &&
(command == CERTREQ ||
command == DELETE ||
command == GENKEYPAIR ||
command == GENSECKEY ||
command == IMPORTCERT ||
command == IMPORTKEYSTORE ||
command == KEYCLONE ||
command == CHANGEALIAS ||
command == SELFCERT ||
command == STOREPASSWD ||
command == KEYPASSWD ||
command == IDENTITYDB)) {
int count = 0;
do {
if (command == IMPORTKEYSTORE) {
System.err.print
(rb.getString("Enter destination keystore password: "));
} else {
System.err.print
(rb.getString("Enter keystore password: "));
}
System.err.flush();
storePass = Password.readPassword(System.in);
passwords.add(storePass);
// If we are creating a new non nullStream-based keystore,
// insist that the password be at least 6 characters
if (!nullStream && (storePass == null || storePass.length < 6)) {
System.err.println(rb.getString
("Keystore password is too short - " +
"must be at least 6 characters"));
storePass = null;
}
// If the keystore file does not exist and needs to be
// created, the storepass should be prompted twice.
if (storePass != null && !nullStream && ksStream == null) {
System.err.print(rb.getString("Re-enter new password: "));
char[] storePassAgain = Password.readPassword(System.in);
passwords.add(storePassAgain);
if (!Arrays.equals(storePass, storePassAgain)) {
System.err.println
(rb.getString("They don't match. Try again"));
storePass = null;
}
}
count++;
} while ((storePass == null) && count < 3);
if (storePass == null) {
System.err.println
(rb.getString("Too many failures - try later"));
return;
}
} else if (!protectedPath
&& !KeyStoreUtil.isWindowsKeyStore(storetype)
&& !(command == PRINTCERT)) {
// here we have EXPORTCERT and LIST (info valid until STOREPASSWD)
System.err.print(rb.getString("Enter keystore password: "));
System.err.flush();
storePass = Password.readPassword(System.in);
passwords.add(storePass);
}
// Now load a nullStream-based keystore,
// or verify the integrity of an input stream-based keystore
if (nullStream) {
keyStore.load(null, storePass);
} else if (ksStream != null) {
ksStream = new FileInputStream(ksfile);
keyStore.load(ksStream, storePass);
ksStream.close();
}
}
if (storePass != null && P12KEYSTORE.equalsIgnoreCase(storetype)) {
MessageFormat form = new MessageFormat(rb.getString(
"Warning: Different store and key passwords not supported " +
"for PKCS12 KeyStores. Ignoring user-specified < command > value."));
if (keyPass != null && !Arrays.equals(storePass, keyPass)) {
Object[] source = {"-keypass"};
System.err.println(form.format(source));
keyPass = storePass;
}
if (newPass != null && !Arrays.equals(storePass, newPass)) {
Object[] source = {"-new"};
System.err.println(form.format(source));
newPass = storePass;
}
if (destKeyPass != null && !Arrays.equals(storePass, destKeyPass)) {
Object[] source = {"-destkeypass"};
System.err.println(form.format(source));
destKeyPass = storePass;
}
}
// Create a certificate factory
if (command == PRINTCERT || command == IMPORTCERT
|| command == IDENTITYDB) {
cf = CertificateFactory.getInstance("X509");
}
if (trustcacerts) {
caks = getCacertsKeyStore();
}
// Perform the specified command
if (command == CERTREQ) {
PrintStream ps = null;
if (filename != null) {
ps = new PrintStream(new FileOutputStream
(filename));
out = ps;
}
try {
doCertReq(alias, sigAlgName, out);
} finally {
if (ps != null) {
ps.close();
}
}
if (verbose && filename != null) {
MessageFormat form = new MessageFormat(rb.getString
("Certification request stored in file < filename >"));
Object[] source = {filename};
System.err.println(form.format(source));
System.err.println(rb.getString("Submit this to your CA"));
}
} else if (command == DELETE) {
doDeleteEntry(alias);
kssave = true;
} else if (command == EXPORTCERT) {
PrintStream ps = null;
if (filename != null) {
ps = new PrintStream(new FileOutputStream
(filename));
out = ps;
}
try {
doExportCert(alias, out);
} finally {
if (ps != null) {
ps.close();
}
}
if (filename != null) {
MessageFormat form = new MessageFormat(rb.getString
("Certificate stored in file < filename >"));
Object[] source = {filename};
System.err.println(form.format(source));
}
} else if (command == GENKEYPAIR) {
if (keyAlgName == null) {
keyAlgName = "DSA";
}
doGenKeyPair(alias, dname, keyAlgName, keysize, sigAlgName);
kssave = true;
} else if (command == GENSECKEY) {
if (keyAlgName == null) {
keyAlgName = "DES";
}
doGenSecretKey(alias, keyAlgName, keysize);
kssave = true;
} else if (command == IDENTITYDB) {
InputStream inStream = System.in;
if (filename != null) {
inStream = new FileInputStream(filename);
}
try {
doImportIdentityDatabase(inStream);
} finally {
if (inStream != System.in) {
inStream.close();
}
}
} else if (command == IMPORTCERT) {
InputStream inStream = System.in;
if (filename != null) {
inStream = new FileInputStream(filename);
}
try {
String importAlias = (alias!=null)?alias:keyAlias;
if (keyStore.entryInstanceOf(importAlias, KeyStore.PrivateKeyEntry.class)) {
kssave = installReply(importAlias, inStream);
if (kssave) {
System.err.println(rb.getString
("Certificate reply was installed in keystore"));
} else {
System.err.println(rb.getString
("Certificate reply was not installed in keystore"));
}
} else if (!keyStore.containsAlias(importAlias) ||
keyStore.entryInstanceOf(importAlias,
KeyStore.TrustedCertificateEntry.class)) {
kssave = addTrustedCert(importAlias, inStream);
if (kssave) {
System.err.println(rb.getString
("Certificate was added to keystore"));
} else {
System.err.println(rb.getString
("Certificate was not added to keystore"));
}
}
} finally {
if (inStream != System.in) {
inStream.close();
}
}
} else if (command == IMPORTKEYSTORE) {
doImportKeyStore();
kssave = true;
} else if (command == KEYCLONE) {
keyPassNew = newPass;
// added to make sure only key can go thru
if (alias == null) {
alias = keyAlias;
}
if (keyStore.containsAlias(alias) == false) {
MessageFormat form = new MessageFormat
(rb.getString("Alias < alias > does not exist"));
Object[] source = {alias};
throw new Exception(form.format(source));
}
if (!keyStore.entryInstanceOf(alias, KeyStore.PrivateKeyEntry.class)) {
MessageFormat form = new MessageFormat(rb.getString(
"Alias < alias > references an entry type that is not a private key entry. " +
"The -keyclone command only supports cloning of private key entries"));
Object[] source = {alias};
throw new Exception(form.format(source));
}
doCloneEntry(alias, dest, true); // Now everything can be cloned
kssave = true;
} else if (command == CHANGEALIAS) {
if (alias == null) {
alias = keyAlias;
}
doCloneEntry(alias, dest, false);
// in PKCS11, clone a PrivateKeyEntry will delete the old one
if (keyStore.containsAlias(alias)) {
doDeleteEntry(alias);
}
kssave = true;
} else if (command == KEYPASSWD) {
keyPassNew = newPass;
doChangeKeyPasswd(alias);
kssave = true;
} else if (command == LIST) {
if (alias != null) {
doPrintEntry(alias, out, true);
} else {
doPrintEntries(out);
}
} else if (command == PRINTCERT) {
InputStream inStream = System.in;
if (filename != null) {
inStream = new FileInputStream(filename);
}
try {
doPrintCert(inStream, out);
} finally {
if (inStream != System.in) {
inStream.close();
}
}
} else if (command == SELFCERT) {
doSelfCert(alias, dname, sigAlgName);
kssave = true;
} else if (command == STOREPASSWD) {
storePassNew = newPass;
if (storePassNew == null) {
storePassNew = getNewPasswd("keystore password", storePass);
}
kssave = true;
}
// If we need to save the keystore, do so.
if (kssave) {
if (verbose) {
MessageFormat form = new MessageFormat
(rb.getString("[Storing ksfname]"));
Object[] source = {nullStream ? "keystore" : ksfname};
System.err.println(form.format(source));
}
if (token) {
keyStore.store(null, null);
} else {
FileOutputStream fout = null;
try {
fout = (nullStream ?
(FileOutputStream)null :
new FileOutputStream(ksfname));
keyStore.store
(fout,
(storePassNew!=null) ? storePassNew : storePass);
} finally {
if (fout != null) {
fout.close();
}
}
}
}
}
|