Created
September 16, 2014 06:40
-
-
Save strazzere/5511cab3be4b4ad73906 to your computer and use it in GitHub Desktop.
Leaked Bangle Signer Source
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.bangcle.signer; | |
public class LocalStore | |
{ | |
public static String APK_PATH = ""; | |
public static String KEYSTORE_PATH = ""; | |
public static String KEYSTORE_PWD = ""; | |
public static String KEY_ALIAS = ""; | |
public static String KEY_PWD = ""; | |
public static String DESTINATION = ""; | |
public static void setApkPath(String value) | |
{ | |
APK_PATH = value; | |
System.out.println(APK_PATH); | |
} | |
public static void setKeystorePath(String value) | |
{ | |
KEYSTORE_PATH = value; | |
System.out.println(KEYSTORE_PATH); | |
} | |
public static void setKeystorePassword(String value) | |
{ | |
KEYSTORE_PWD = value; | |
System.out.println(KEYSTORE_PWD); | |
} | |
public static void setKeyAlias(String value) | |
{ | |
KEY_ALIAS = value; | |
System.out.println(KEY_ALIAS); | |
} | |
public static void setKeyPassword(String value) | |
{ | |
KEY_PWD = value; | |
System.out.println(KEY_PWD); | |
} | |
public static void setDestinationName(String value) | |
{ | |
DESTINATION = value; | |
System.out.println(DESTINATION); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.bangcle.signer; | |
import java.io.BufferedReader; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileNotFoundException; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.InputStreamReader; | |
import java.security.KeyStore; | |
import java.security.KeyStoreException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.cert.CertificateException; | |
import java.util.Enumeration; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.events.ModifyEvent; | |
import org.eclipse.swt.events.ModifyListener; | |
import org.eclipse.swt.events.SelectionAdapter; | |
import org.eclipse.swt.events.SelectionEvent; | |
import org.eclipse.swt.layout.GridData; | |
import org.eclipse.swt.layout.GridLayout; | |
import org.eclipse.swt.widgets.Button; | |
import org.eclipse.swt.widgets.Combo; | |
import org.eclipse.swt.widgets.Composite; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.swt.widgets.FileDialog; | |
import org.eclipse.swt.widgets.Label; | |
import org.eclipse.swt.widgets.MessageBox; | |
import org.eclipse.swt.widgets.Shell; | |
import org.eclipse.swt.widgets.Text; | |
public class main { | |
protected Shell shell; | |
private Composite mTopComposite; | |
private Text mProjectText; | |
private Composite mErrorComposite; | |
private Label mUseExistingKeystore; | |
private Text mKeystore; | |
private Text mKeystorePassword; | |
private Label mKeyAliasesLabel; | |
private Combo mKeyAliases; | |
private Label mKeyPasswordLabel; | |
private Text mKeyPassword; | |
private Text mDestination; | |
private Label mDestinationMsg; | |
/** | |
* Launch the application. | |
* @param args | |
*/ | |
public static void main(String[] args) { | |
try { | |
main window = new main(); | |
window.open(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
/** | |
* Open the window. | |
*/ | |
public void open() { | |
Display display = Display.getDefault(); | |
createContents(); | |
shell.open(); | |
shell.layout(); | |
while (!shell.isDisposed()) { | |
if (!display.readAndDispatch()) { | |
display.sleep(); | |
} | |
} | |
} | |
/** | |
* Create contents of the window. | |
*/ | |
protected void createContents() { | |
shell = new Shell(); | |
shell.setSize(600, 400); | |
shell.setText("Bangcle Signer"); | |
shell.setLayout(new GridLayout()); | |
GridLayout gl = null; | |
GridData gd = null; | |
mTopComposite = new Composite(shell, SWT.NONE); | |
mTopComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); | |
mTopComposite.setLayout(new GridLayout(1, false)); | |
// composite for the project selection. | |
Composite projectComposite = new Composite(mTopComposite, SWT.NONE); | |
projectComposite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
projectComposite.setLayout(gl = new GridLayout(3, false)); | |
gl.marginHeight = gl.marginWidth = 0; | |
Label label = new Label(projectComposite, SWT.NONE); | |
label.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); | |
gd.horizontalSpan = 3; | |
label.setText("Select the APK to sign:"); | |
new Label(projectComposite, SWT.NONE).setText("APK:"); | |
mProjectText = new Text(projectComposite, SWT.BORDER); | |
mProjectText.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL)); | |
mProjectText.addModifyListener(new ModifyListener() { | |
public void modifyText(ModifyEvent e) { | |
LocalStore.setApkPath(mProjectText.getText().trim()); | |
} | |
}); | |
final Button browseButton = new Button(projectComposite, SWT.PUSH); | |
browseButton.setText("Browse..."); | |
browseButton.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
FileDialog fileDialog; | |
fileDialog = new FileDialog(browseButton.getShell(),SWT.OPEN); | |
fileDialog.setText("Load Keystore"); | |
String fileName = fileDialog.open(); | |
if (fileName != null) { | |
mProjectText.setText(fileName); | |
} | |
} | |
}); | |
Composite composite = new Composite(shell, SWT.NULL); | |
composite.setLayoutData(new GridData(GridData.FILL_BOTH)); | |
GridLayout gl2 = new GridLayout(3, false); | |
composite.setLayout(gl2); | |
GridData gd2; | |
mUseExistingKeystore = new Label(composite, SWT.NULL); | |
mUseExistingKeystore.setText("Use existing keystore"); | |
mUseExistingKeystore.setLayoutData(gd2 = new GridData(GridData.FILL_HORIZONTAL)); | |
gd2.horizontalSpan = 3; | |
new Label(composite, SWT.NONE).setText("Location:"); | |
mKeystore = new Text(composite, SWT.BORDER); | |
mKeystore.setLayoutData(gd2 = new GridData(GridData.FILL_HORIZONTAL)); | |
final Button browseButton2 = new Button(composite, SWT.PUSH); | |
browseButton2.setText("Browse..."); | |
browseButton2.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
FileDialog fileDialog; | |
fileDialog = new FileDialog(browseButton2.getShell(),SWT.OPEN); | |
fileDialog.setText("Load Keystore"); | |
String fileName = fileDialog.open(); | |
if (fileName != null) { | |
mKeystore.setText(fileName); | |
} | |
} | |
}); | |
new Label(composite, SWT.NONE).setText("Password:"); | |
mKeystorePassword = new Text(composite, SWT.BORDER | SWT.PASSWORD); | |
mKeystorePassword.setLayoutData(gd2 = new GridData(GridData.FILL_HORIZONTAL)); | |
new Composite(composite, SWT.NONE).setLayoutData(gd2 = new GridData()); | |
gd2.heightHint = gd2.widthHint = 0; | |
mKeyAliasesLabel = new Label(composite, SWT.NONE); | |
mKeyAliasesLabel.setText("Alias:"); | |
mKeyAliases = new Combo(composite, SWT.READ_ONLY); | |
mKeyAliases.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
mKeyAliasesLabel.setEnabled(false); | |
mKeyAliases.setEnabled(false); | |
new Composite(composite, SWT.NONE).setLayoutData(gd = new GridData()); | |
gd.heightHint = 0; | |
gd.widthHint = 50; | |
mKeyPasswordLabel = new Label(composite, SWT.NONE); | |
mKeyPasswordLabel.setText("Password:"); | |
mKeyPassword = new Text(composite, SWT.BORDER | SWT.PASSWORD); | |
mKeyPassword.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); | |
mKeyPassword.setEnabled(false); | |
mKeyPasswordLabel.setEnabled(false); | |
mKeystore.addModifyListener(new ModifyListener() { | |
public void modifyText(ModifyEvent e) { | |
LocalStore.setKeystorePath(mKeystore.getText().trim()); | |
onChange(); | |
} | |
}); | |
mKeystorePassword.addModifyListener(new ModifyListener() { | |
public void modifyText(ModifyEvent e) { | |
LocalStore.setKeystorePassword(mKeystorePassword.getText()); | |
onChange(); | |
} | |
}); | |
mKeyAliases.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
LocalStore.setKeyAlias(mKeyAliases.getItem(mKeyAliases.getSelectionIndex())); | |
// reset the password | |
mKeyPassword.setText(""); | |
} | |
}); | |
mKeyPassword.addModifyListener(new ModifyListener() { | |
public void modifyText(ModifyEvent e) { | |
LocalStore.setKeyPassword(mKeyPassword.getText()); | |
} | |
}); | |
Composite composite3 = new Composite(shell, SWT.NULL); | |
composite3.setLayoutData(new GridData(GridData.FILL_BOTH)); | |
GridLayout gl3 = new GridLayout(3, false); | |
composite3.setLayout(gl3); | |
GridData gd3; | |
mDestinationMsg = new Label(composite3, SWT.NULL); | |
mDestinationMsg.setText("Enter destination for the APK file."); | |
mDestinationMsg.setLayoutData(gd3 = new GridData(GridData.FILL_HORIZONTAL)); | |
gd3.horizontalSpan = 3; | |
new Label(composite3, SWT.NONE).setText("Destination APK file:"); | |
mDestination = new Text(composite3, SWT.BORDER); | |
mDestination.setLayoutData(gd3 = new GridData(GridData.FILL_HORIZONTAL)); | |
mDestination.addModifyListener(new ModifyListener() { | |
public void modifyText(ModifyEvent e) { | |
onDestinationChange(); | |
} | |
}); | |
final Button browseButton3 = new Button(composite3, SWT.PUSH); | |
browseButton3.setText("Browse..."); | |
new Label(composite3, SWT.NONE); | |
new Label(composite3, SWT.NONE); | |
browseButton3.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(SelectionEvent e) { | |
FileDialog fileDialog = new FileDialog(browseButton3.getShell(), SWT.SAVE); | |
fileDialog.setText("Destination file name"); | |
String saveLocation = fileDialog.open(); | |
if (saveLocation != null) { | |
mDestination.setText(saveLocation); | |
} | |
} | |
}); | |
GridData gd4; | |
final Button OkButton = new Button(shell, SWT.CENTER); | |
OkButton.setText("Sign Now"); | |
OkButton.setLayoutData(gd4 = new GridData(GridData.HORIZONTAL_ALIGN_CENTER)); | |
OkButton.addSelectionListener(new SelectionAdapter() { | |
@Override | |
public void widgetSelected(final SelectionEvent e) | |
{ | |
System.out.println("Thread1 = "+Thread.currentThread().getName()); | |
if(LocalStore.APK_PATH.equals("") | |
|| LocalStore.KEYSTORE_PATH.equals("") | |
|| LocalStore.KEYSTORE_PWD.equals("") | |
|| LocalStore.KEY_ALIAS.equals("") | |
|| LocalStore.DESTINATION.equals("")) | |
{ | |
Display.getDefault().asyncExec(new Runnable() { | |
public void run() { | |
int style = SWT.APPLICATION_MODAL | SWT.YES; | |
MessageBox messageBox = new MessageBox(shell, style); | |
messageBox.setText("Error"); | |
messageBox.setMessage("You should fill in all the blanks before signing!"); | |
e.doit = messageBox.open() == SWT.YES; | |
} | |
}); | |
return; | |
} | |
Thread t = new Thread() | |
{ | |
@Override | |
public void run() | |
{ | |
System.out.println("Thread2 = "+Thread.currentThread().getName()); | |
Runtime rn = Runtime.getRuntime(); | |
Process proc = null; | |
String exeFile = "cmd /c .\\java1.6.0\\bin\\jarsigner.exe -verbose -keystore "+LocalStore.KEYSTORE_PATH | |
+" -storepass "+LocalStore.KEYSTORE_PWD | |
+" -signedjar "+LocalStore.DESTINATION+" "+LocalStore.APK_PATH+" "+LocalStore.KEY_ALIAS; | |
System.out.println("Sign cmd = "+exeFile); | |
try { | |
proc = rn.exec(exeFile); | |
InputStream stdin = proc.getInputStream(); | |
InputStreamReader isr = new InputStreamReader(stdin); | |
BufferedReader br = new BufferedReader(isr); | |
String line = null; | |
System.out.println("<OUTPUT>"); | |
while ( (line = br.readLine()) != null) | |
System.out.println(line); | |
System.out.println("</OUTPUT>"); | |
final int exitVal = proc.waitFor(); | |
System.out.println("Process exitValue: " + exitVal); | |
Display.getDefault().asyncExec(new Runnable() { | |
public void run() { | |
int style = SWT.APPLICATION_MODAL | SWT.YES; | |
MessageBox messageBox = new MessageBox(shell, style); | |
messageBox.setText("Sign status"); | |
if(exitVal == 0) | |
messageBox.setMessage("Sign success!"); | |
else | |
messageBox.setMessage("Sign fail!"); | |
e.doit = messageBox.open() == SWT.YES; | |
} | |
}); | |
} catch (Exception e1) { | |
e1.printStackTrace(); | |
System.out.println("error = "+e1.getMessage()); | |
} | |
} | |
}; | |
t.start(); | |
} | |
}); | |
} | |
private void onChange() | |
{ | |
if(mKeystore.getText().trim().length()>0 && mKeystorePassword.getText().length()>0) | |
{ | |
try { | |
// remove the content of the alias combo always and first, in case the | |
// keystore password is wrong | |
mKeyAliases.removeAll(); | |
// get the alias list (also used as a keystore password test) | |
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); | |
FileInputStream fis = new FileInputStream(LocalStore.KEYSTORE_PATH); | |
keyStore.load(fis, LocalStore.KEYSTORE_PWD.toCharArray()); | |
fis.close(); | |
Enumeration<String> aliases = keyStore.aliases(); | |
int count = 0; | |
while (aliases.hasMoreElements()) { | |
String alias = aliases.nextElement(); | |
mKeyAliases.add(alias); | |
count++; | |
} | |
if(count != 0) | |
{ | |
mKeyAliasesLabel.setEnabled(true); | |
mKeyAliases.setEnabled(true); | |
mKeyPassword.setEnabled(true); | |
mKeyPasswordLabel.setEnabled(true); | |
mKeyAliases.select(0); | |
LocalStore.setKeyAlias(mKeyAliases.getItem(0)); | |
} | |
else | |
{ | |
mKeyAliasesLabel.setEnabled(false); | |
mKeyAliases.setEnabled(false); | |
mKeyPassword.setEnabled(false); | |
mKeyPasswordLabel.setEnabled(false); | |
} | |
// reset the password | |
mKeyPassword.setText(""); | |
} catch (KeyStoreException e) { | |
System.out.println(e.getMessage()); | |
} catch (FileNotFoundException e) { | |
System.out.println(e.getMessage()); | |
} catch (NoSuchAlgorithmException e) { | |
System.out.println(e.getMessage()); | |
} catch (CertificateException e) { | |
System.out.println(e.getMessage()); | |
} catch (IOException e) { | |
System.out.println(e.getMessage()); | |
} | |
} | |
else | |
{ | |
mKeyAliasesLabel.setEnabled(false); | |
mKeyAliases.setEnabled(false); | |
mKeyPassword.setEnabled(false); | |
mKeyPasswordLabel.setEnabled(false); | |
} | |
} | |
private void onDestinationChange() | |
{ | |
setMessage(""); | |
String path = mDestination.getText().trim(); | |
if (path.length() == 0) { | |
setMessage("Enter destination for the APK file."); | |
// reset canFinish in the wizard. | |
LocalStore.DESTINATION = ""; | |
return; | |
} | |
File file = new File(path); | |
if (file.isDirectory()) { | |
setMessage("ERROR: Destination is a directory."); | |
// reset canFinish in the wizard. | |
LocalStore.DESTINATION = ""; | |
return; | |
} | |
File parentFolder = file.getParentFile(); | |
if (parentFolder == null || parentFolder.isDirectory() == false) { | |
setMessage("ERROR: Not a valid directory."); | |
// reset canFinish in the wizard. | |
LocalStore.DESTINATION = ""; | |
return; | |
} | |
boolean fileExists = false; | |
if (file.isFile()) | |
fileExists = true; | |
else | |
{ | |
setMessage(path); | |
} | |
// no error, set the destination in the wizard. | |
LocalStore.setDestinationName(mDestination.getText()); | |
// However, we should also test if the file already exists. | |
if (fileExists) { | |
setMessage("WARNING: A destination file already exists."); | |
} | |
} | |
private void setMessage(String msg) | |
{ | |
mDestinationMsg.setText(msg); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment