FileDocCategorySizeDatePackage
KeystoreHelper.javaAPI DocAndroid 1.5 API7972Wed May 06 22:41:10 BST 2009com.android.jarutils

KeystoreHelper

public final class KeystoreHelper extends Object
A Helper to create new keystore/key.

Fields Summary
Constructors Summary
Methods Summary
public static booleancreateNewStore(java.lang.String osKeyStorePath, java.lang.String storeType, java.lang.String storePassword, java.lang.String alias, java.lang.String keyPassword, java.lang.String description, int validityYears, com.android.jarutils.DebugKeyProvider.IKeyGenOutput output)
Creates a new store

param
osKeyStorePath the location of the store
param
storeType an optional keystore type, or null if the default is to be used.
param
output an optional {@link IKeyGenOutput} object to get the stdout and stderr of the keytool process call.
throws
KeyStoreException
throws
NoSuchAlgorithmException
throws
CertificateException
throws
UnrecoverableEntryException
throws
IOException
throws
KeytoolException

        
        // get the executable name of keytool depending on the platform.
        String os = System.getProperty("os.name");

        String keytoolCommand;
        if (os.startsWith("Windows")) {
            keytoolCommand = "keytool.exe";
        } else {
            keytoolCommand = "keytool";
        }

        String javaHome = System.getProperty("java.home");

        if (javaHome != null && javaHome.length() > 0) {
            keytoolCommand = javaHome + File.separator + "bin" + File.separator + keytoolCommand; 
        }
        
        // create the command line to call key tool to build the key with no user input.
        ArrayList<String> commandList = new ArrayList<String>();
        commandList.add(keytoolCommand);
        commandList.add("-genkey");
        commandList.add("-alias");
        commandList.add(alias);
        commandList.add("-keyalg");
        commandList.add("RSA");
        commandList.add("-dname");
        commandList.add(description);
        commandList.add("-validity");
        commandList.add(Integer.toString(validityYears * 365));
        commandList.add("-keypass");
        commandList.add(keyPassword);
        commandList.add("-keystore");
        commandList.add(osKeyStorePath);
        commandList.add("-storepass");
        commandList.add(storePassword);
        if (storeType != null) {
            commandList.add("-storetype");
            commandList.add(storeType);
        }

        String[] commandArray = commandList.toArray(new String[commandList.size()]);

        // launch the command line process
        int result = 0;
        try {
            result = grabProcessOutput(Runtime.getRuntime().exec(commandArray), output);
        } catch (Exception e) {
            // create the command line as one string
            StringBuilder builder = new StringBuilder();
            boolean firstArg = true;
            for (String arg : commandArray) {
                boolean hasSpace = arg.indexOf(' ") != -1;
                
                if (firstArg == true) {
                    firstArg = false;
                } else {
                    builder.append(' ");
                }
                
                if (hasSpace) {
                    builder.append('"");
                }
                
                builder.append(arg);

                if (hasSpace) {
                    builder.append('"");
                }
            }
            
            throw new KeytoolException("Failed to create key: " + e.getMessage(),
                    javaHome, builder.toString());
        }
        
        if (result != 0) {
            return false;
        }
        
        return true;
    
private static intgrabProcessOutput(java.lang.Process process, com.android.jarutils.DebugKeyProvider.IKeyGenOutput output)
Get the stderr/stdout outputs of a process and return when the process is done. Both must be read or the process will block on windows.

param
process The process to get the ouput from
return
the process return code.
throws
InterruptedException

        // read the lines as they come. if null is returned, it's
        // because the process finished
        Thread t1 = new Thread("") {
            @Override
            public void run() {
                // create a buffer to read the stderr output
                InputStreamReader is = new InputStreamReader(process.getErrorStream());
                BufferedReader errReader = new BufferedReader(is);

                try {
                    while (true) {
                        String line = errReader.readLine();
                        if (line != null) {
                            if (output != null) {
                                output.err(line);
                            } else {
                                System.err.println(line);
                            }
                        } else {
                            break;
                        }
                    }
                } catch (IOException e) {
                    // do nothing.
                }
            }
        };

        Thread t2 = new Thread("") {
            @Override
            public void run() {
                InputStreamReader is = new InputStreamReader(process.getInputStream());
                BufferedReader outReader = new BufferedReader(is);

                try {
                    while (true) {
                        String line = outReader.readLine();
                        if (line != null) {
                            if (output != null) {
                                output.out(line);
                            } else {
                                System.out.println(line);
                            }
                        } else {
                            break;
                        }
                    }
                } catch (IOException e) {
                    // do nothing.
                }
            }
        };

        t1.start();
        t2.start();

        // it looks like on windows process#waitFor() can return
        // before the thread have filled the arrays, so we wait for both threads and the
        // process itself.
        try {
            t1.join();
        } catch (InterruptedException e) {
        }
        try {
            t2.join();
        } catch (InterruptedException e) {
        }

        // get the return code from the process
        try {
            return process.waitFor();
        } catch (InterruptedException e) {
            // since we're waiting for the output thread above, we should never actually wait
            // on the process to end, since it'll be done by the time we call waitFor()
            return 0;
        }