From 9ca1c0b33cc3fc28c21a915730797ec01e71a152 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Wed, 17 Dec 2008 18:04:04 -0800 Subject: Code drop from //branches/cupcake/...@124589 --- .../src/com/android/jarutils/DebugKeyProvider.java | 202 +----------------- .../com/android/jarutils/JavaResourceFilter.java | 3 +- .../src/com/android/jarutils/KeystoreHelper.java | 228 +++++++++++++++++++++ 3 files changed, 241 insertions(+), 192 deletions(-) create mode 100644 jarutils/src/com/android/jarutils/KeystoreHelper.java (limited to 'jarutils') diff --git a/jarutils/src/com/android/jarutils/DebugKeyProvider.java b/jarutils/src/com/android/jarutils/DebugKeyProvider.java index 966f0b4..6dc32ba 100644 --- a/jarutils/src/com/android/jarutils/DebugKeyProvider.java +++ b/jarutils/src/com/android/jarutils/DebugKeyProvider.java @@ -19,12 +19,9 @@ package com.android.jarutils; import com.android.prefs.AndroidLocation; import com.android.prefs.AndroidLocation.AndroidLocationException; -import java.io.BufferedReader; -import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStreamReader; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; @@ -33,7 +30,6 @@ import java.security.UnrecoverableEntryException; import java.security.UnrecoverableKeyException; import java.security.cert.Certificate; import java.security.cert.CertificateException; -import java.util.ArrayList; /** * A provider of a dummy key to sign Android application for debugging purpose. @@ -88,46 +84,29 @@ public class DebugKeyProvider { *

The keystore, and a new random android debug key are created if they do not yet exist. *

Password for the store/key is android, and the key alias is * AndroidDebugKey. - * @param osKeyStorePath the OS path to the keystore. + * @param osKeyStorePath the OS path to the keystore, or null if the default one + * is to be used. * @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 KeytoolException If the creation of the debug key failed. + * @throws AndroidLocationException */ public DebugKeyProvider(String osKeyStorePath, String storeType, IKeyGenOutput output) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, - UnrecoverableEntryException, IOException, KeytoolException { + UnrecoverableEntryException, IOException, KeytoolException, AndroidLocationException { - if (loadKeyEntry(osKeyStorePath, storeType) == false) { - // create the store with they key - createNewStore(osKeyStorePath, storeType, output); + if (osKeyStorePath == null) { + osKeyStorePath = getDefaultKeyStoreOsPath(); } - } - - /** - * Creates a provider using the default keystore location. - *

The keystore, and a new random android debug key are created if they do not yet exist. - *

Password for the store/key is android, and the key alias is - * AndroidDebugKey. - * @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 KeytoolException If the creation of the debug key failed. - * @throws AndroidLocationException If getting the location to store android files failed. - */ - public DebugKeyProvider(String storeType, IKeyGenOutput output) throws KeyStoreException, - NoSuchAlgorithmException, CertificateException, UnrecoverableEntryException, - IOException, KeytoolException, AndroidLocationException { - - String osKeyStorePath = getDefaultKeyStoreOsPath(); + if (loadKeyEntry(osKeyStorePath, storeType) == false) { // create the store with the key createNewStore(osKeyStorePath, storeType, output); } } - + /** * Returns the OS path to the default debug keystore. * @@ -215,168 +194,9 @@ public class DebugKeyProvider { throws KeyStoreException, NoSuchAlgorithmException, CertificateException, UnrecoverableEntryException, IOException, 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 commandList = new ArrayList(); - commandList.add(keytoolCommand); - commandList.add("-genkey"); - commandList.add("-alias"); - commandList.add(DEBUG_ALIAS); - commandList.add("-keyalg"); - commandList.add("RSA"); - commandList.add("-dname"); - commandList.add(CERTIFICATE_DESC); - commandList.add("-validity"); - commandList.add("365"); - commandList.add("-keypass"); - commandList.add(PASSWORD_STRING); - commandList.add("-keystore"); - commandList.add(osKeyStorePath); - commandList.add("-storepass"); - commandList.add(PASSWORD_STRING); - 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 debug key: " + e.getMessage(), - javaHome, builder.toString()); - } - - if (result != 0) { - return; - } - loadKeyEntry(osKeyStorePath, storeType); - } - - /** - * 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 - */ - private int grabProcessOutput(final Process process, final IKeyGenOutput output) { - // 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; + if (KeystoreHelper.createNewStore(osKeyStorePath, storeType, PASSWORD_STRING, DEBUG_ALIAS, + PASSWORD_STRING, CERTIFICATE_DESC, 1 /* validity*/, output)) { + loadKeyEntry(osKeyStorePath, storeType); } } } diff --git a/jarutils/src/com/android/jarutils/JavaResourceFilter.java b/jarutils/src/com/android/jarutils/JavaResourceFilter.java index ca3dcc7..d9f8da6 100644 --- a/jarutils/src/com/android/jarutils/JavaResourceFilter.java +++ b/jarutils/src/com/android/jarutils/JavaResourceFilter.java @@ -90,6 +90,7 @@ public class JavaResourceFilter implements IZipEntryFilter { "package.html".equalsIgnoreCase(fileName) == false && "overview.html".equalsIgnoreCase(fileName) == false && ".cvsignore".equalsIgnoreCase(fileName) == false && - ".DS_Store".equals(fileName) == false; + ".DS_Store".equals(fileName) == false && + fileName.charAt(fileName.length()-1) != '~'; } } diff --git a/jarutils/src/com/android/jarutils/KeystoreHelper.java b/jarutils/src/com/android/jarutils/KeystoreHelper.java new file mode 100644 index 0000000..c694684 --- /dev/null +++ b/jarutils/src/com/android/jarutils/KeystoreHelper.java @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.jarutils; + +import com.android.jarutils.DebugKeyProvider.IKeyGenOutput; +import com.android.jarutils.DebugKeyProvider.KeytoolException; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableEntryException; +import java.security.cert.CertificateException; +import java.util.ArrayList; + +/** + * A Helper to create new keystore/key. + */ +public final class KeystoreHelper { + + /** + * 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 + */ + public static boolean createNewStore( + String osKeyStorePath, + String storeType, + String storePassword, + String alias, + String keyPassword, + String description, + int validityYears, + IKeyGenOutput output) + throws KeyStoreException, NoSuchAlgorithmException, CertificateException, + UnrecoverableEntryException, IOException, 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 commandList = new ArrayList(); + 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; + } + + /** + * 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 + */ + private static int grabProcessOutput(final Process process, final IKeyGenOutput output) { + // 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; + } + } +} -- cgit v1.1