2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.jarutils;
19 import com.android.jarutils.DebugKeyProvider.IKeyGenOutput;
20 import com.android.jarutils.DebugKeyProvider.KeytoolException;
22 import java.io.BufferedReader;
24 import java.io.IOException;
25 import java.io.InputStreamReader;
26 import java.security.KeyStoreException;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.UnrecoverableEntryException;
29 import java.security.cert.CertificateException;
30 import java.util.ArrayList;
33 * A Helper to create new keystore/key.
35 public final class KeystoreHelper {
39 * @param osKeyStorePath the location of the store
40 * @param storeType an optional keystore type, or <code>null</code> if the default is to
42 * @param output an optional {@link IKeyGenOutput} object to get the stdout and stderr
43 * of the keytool process call.
44 * @throws KeyStoreException
45 * @throws NoSuchAlgorithmException
46 * @throws CertificateException
47 * @throws UnrecoverableEntryException
49 * @throws KeytoolException
51 public static boolean createNewStore(
52 String osKeyStorePath,
60 throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
61 UnrecoverableEntryException, IOException, KeytoolException {
63 // get the executable name of keytool depending on the platform.
64 String os = System.getProperty("os.name");
66 String keytoolCommand;
67 if (os.startsWith("Windows")) {
68 keytoolCommand = "keytool.exe";
70 keytoolCommand = "keytool";
73 String javaHome = System.getProperty("java.home");
75 if (javaHome != null && javaHome.length() > 0) {
76 keytoolCommand = javaHome + File.separator + "bin" + File.separator + keytoolCommand;
79 // create the command line to call key tool to build the key with no user input.
80 ArrayList<String> commandList = new ArrayList<String>();
81 commandList.add(keytoolCommand);
82 commandList.add("-genkey");
83 commandList.add("-alias");
84 commandList.add(alias);
85 commandList.add("-keyalg");
86 commandList.add("RSA");
87 commandList.add("-dname");
88 commandList.add(description);
89 commandList.add("-validity");
90 commandList.add(Integer.toString(validityYears * 365));
91 commandList.add("-keypass");
92 commandList.add(keyPassword);
93 commandList.add("-keystore");
94 commandList.add(osKeyStorePath);
95 commandList.add("-storepass");
96 commandList.add(storePassword);
97 if (storeType != null) {
98 commandList.add("-storetype");
99 commandList.add(storeType);
102 String[] commandArray = commandList.toArray(new String[commandList.size()]);
104 // launch the command line process
107 result = grabProcessOutput(Runtime.getRuntime().exec(commandArray), output);
108 } catch (Exception e) {
109 // create the command line as one string
110 StringBuilder builder = new StringBuilder();
111 boolean firstArg = true;
112 for (String arg : commandArray) {
113 boolean hasSpace = arg.indexOf(' ') != -1;
115 if (firstArg == true) {
132 throw new KeytoolException("Failed to create key: " + e.getMessage(),
133 javaHome, builder.toString());
144 * Get the stderr/stdout outputs of a process and return when the process is done.
145 * Both <b>must</b> be read or the process will block on windows.
146 * @param process The process to get the ouput from
147 * @return the process return code.
148 * @throws InterruptedException
150 private static int grabProcessOutput(final Process process, final IKeyGenOutput output) {
151 // read the lines as they come. if null is returned, it's
152 // because the process finished
153 Thread t1 = new Thread("") {
156 // create a buffer to read the stderr output
157 InputStreamReader is = new InputStreamReader(process.getErrorStream());
158 BufferedReader errReader = new BufferedReader(is);
162 String line = errReader.readLine();
164 if (output != null) {
167 System.err.println(line);
173 } catch (IOException e) {
179 Thread t2 = new Thread("") {
182 InputStreamReader is = new InputStreamReader(process.getInputStream());
183 BufferedReader outReader = new BufferedReader(is);
187 String line = outReader.readLine();
189 if (output != null) {
192 System.out.println(line);
198 } catch (IOException e) {
207 // it looks like on windows process#waitFor() can return
208 // before the thread have filled the arrays, so we wait for both threads and the
212 } catch (InterruptedException e) {
216 } catch (InterruptedException e) {
219 // get the return code from the process
221 return process.waitFor();
222 } catch (InterruptedException e) {
223 // since we're waiting for the output thread above, we should never actually wait
224 // on the process to end, since it'll be done by the time we call waitFor()