SignApk - use existing password mechanism when using keystore

Summary:
In my last diff, I've added mechanism to load private key from keystore.
However, that mechanism will reveal password as part of the java param.
This diff tries to use existing ANDROID_PW_FILE mechanism to support
password for keystore private keys (through stdin)

This diff also fix a null pointer bug in the existing password handling

Test: This diff has been tested locally, and could sign correctly with our
  keystore with or without password

Tags:
Change-Id: Ie291ea8702a3b4d270b0f8689b023c3f290980a7
This commit is contained in:
Lingfeng Guan
2021-11-11 21:31:42 -08:00
parent 8e7cdf65d1
commit 65672df61f

View File

@@ -204,13 +204,14 @@ class SignApk {
* If a console doesn't exist, reads the password from stdin * If a console doesn't exist, reads the password from stdin
* If a console exists, reads the password from console and returns it as a string. * If a console exists, reads the password from console and returns it as a string.
* *
* @param keyFile The file containing the private key. Used to prompt the user. * @param keyFileName Name of the file containing the private key. Used to prompt the user.
*/ */
private static String readPassword(File keyFile) { private static String readPassword(String keyFileName) {
Console console; Console console;
char[] pwd; char[] pwd;
if ((console = System.console()) == null) { if ((console = System.console()) == null) {
System.out.print("Enter password for " + keyFile + " (password will not be hidden): "); System.out.print(
"Enter password for " + keyFileName + " (password will not be hidden): ");
System.out.flush(); System.out.flush();
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
try { try {
@@ -219,7 +220,7 @@ class SignApk {
return null; return null;
} }
} else { } else {
if ((pwd = console.readPassword("[%s]", "Enter password for " + keyFile)) != null) { if ((pwd = console.readPassword("[%s]", "Enter password for " + keyFileName)) != null) {
return String.valueOf(pwd); return String.valueOf(pwd);
} else { } else {
return null; return null;
@@ -246,11 +247,11 @@ class SignApk {
return null; return null;
} }
char[] password = readPassword(keyFile).toCharArray(); final String password = readPassword(keyFile.getPath());
SecretKeyFactory skFactory = SecretKeyFactory.getInstance(epkInfo.getAlgName()); SecretKeyFactory skFactory = SecretKeyFactory.getInstance(epkInfo.getAlgName());
Key key = skFactory.generateSecret(new PBEKeySpec(password)); Key key = skFactory.generateSecret(
new PBEKeySpec(password != null ? password.toCharArray() : null));
Cipher cipher = Cipher.getInstance(epkInfo.getAlgName()); Cipher cipher = Cipher.getInstance(epkInfo.getAlgName());
cipher.init(Cipher.DECRYPT_MODE, key, epkInfo.getAlgParameters()); cipher.init(Cipher.DECRYPT_MODE, key, epkInfo.getAlgParameters());
@@ -305,10 +306,11 @@ class SignApk {
/** Get a PKCS#11 private key from keyStore */ /** Get a PKCS#11 private key from keyStore */
private static PrivateKey loadPrivateKeyFromKeyStore( private static PrivateKey loadPrivateKeyFromKeyStore(
final KeyStore keyStore, final String keyName, final String password) final KeyStore keyStore, final String keyName)
throws CertificateException, KeyStoreException, NoSuchAlgorithmException, throws CertificateException, KeyStoreException, NoSuchAlgorithmException,
UnrecoverableKeyException, UnrecoverableEntryException { UnrecoverableKeyException, UnrecoverableEntryException {
final Key key = keyStore.getKey(keyName, password == null ? null : password.toCharArray()); final String password = readPassword(keyName);
final Key key = keyStore.getKey(keyName, password != null ? password.toCharArray() : null);
final PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry(keyName, null); final PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry(keyName, null);
if (privateKeyEntry == null) { if (privateKeyEntry == null) {
throw new Error( throw new Error(
@@ -1201,10 +1203,8 @@ class SignApk {
if (keyStore == null) { if (keyStore == null) {
privateKey[i] = readPrivateKey(new File(args[argNum])); privateKey[i] = readPrivateKey(new File(args[argNum]));
} else { } else {
String[] splits = args[argNum].split(":", 2); final String keyAlias = args[argNum];
final String keyAlias = splits[0]; privateKey[i] = loadPrivateKeyFromKeyStore(keyStore, keyAlias);
final String password = splits.length > 1 ? splits[1] : null;
privateKey[i] = loadPrivateKeyFromKeyStore(keyStore, keyAlias, password);
} }
} }
inputJar = new JarFile(new File(inputFilename), false); // Don't verify. inputJar = new JarFile(new File(inputFilename), false); // Don't verify.