Skip to content

Commit 8709eaa

Browse files
committed
Finish KeyStore manager GUI and signing logic
1 parent 70d971f commit 8709eaa

File tree

4 files changed

+169
-100
lines changed

4 files changed

+169
-100
lines changed

src/processing/mode/android/AndroidBuild.java

Lines changed: 7 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import processing.core.PApplet;
3535
import processing.mode.java.JavaBuild;
3636
import sun.security.tools.JarSigner;
37-
import sun.security.tools.KeyTool;
3837

3938
import java.io.*;
4039

@@ -275,37 +274,33 @@ public File exportProject() throws IOException, SketchException {
275274
return null;
276275
}
277276

278-
public File exportPackage() throws Exception {
277+
public File exportPackage(String keyStorePassword) throws Exception {
279278
File projectFolder = build("release");
280279
if(projectFolder == null) return null;
281280

282-
File signedPackage = signPackage(projectFolder);
281+
File signedPackage = signPackage(projectFolder, keyStorePassword);
283282
if(signedPackage == null) return null;
284283

285284
File exportFolder = createExportFolder();
286285
Base.copyDir(projectFolder, exportFolder);
287286
return new File(exportFolder, "/bin/");
288287
}
289288

290-
private File signPackage(File projectFolder) throws Exception {
291-
File keyStore = getKeyStore();
289+
private File signPackage(File projectFolder, String keyStorePassword) throws Exception {
290+
File keyStore = AndroidKeyStore.getKeyStore();
292291
if(keyStore == null) return null;
293292

294293
File unsignedPackage = new File(projectFolder, "bin/" + sketch.getName() + "-release-unsigned.apk");
295294
if(!unsignedPackage.exists()) return null;
296295

297-
// NOT sure that works: java.home returns JRE path here, need to walk back to ../../bin to find jarsigner
298-
// TODO receive generated password here
299-
String password = "generatedpasswordhere";
300-
301296
String[] args = {
302297
"-sigalg", "SHA1withRSA",
303298
"-digestalg", "SHA1",
304-
"-keypass", password,
305-
"-storepass", password,
299+
"-keypass", keyStorePassword,
300+
"-storepass", keyStorePassword,
306301
"-keystore", keyStore.getCanonicalPath(),
307302
unsignedPackage.getCanonicalPath(),
308-
sketch.getName()
303+
AndroidKeyStore.ALIAS_STRING
309304
};
310305

311306
// TODO remove hardcoded tools.jar path from build.xml
@@ -363,51 +358,6 @@ private boolean verifySignedPackage(File signedPackage) throws IOException, Inte
363358
return false;
364359
}
365360

366-
private File getKeyStore() throws Exception {
367-
File keyStoreFolder = new File(sketch.getFolder(), "keystore");
368-
if(!keyStoreFolder.exists()) {
369-
boolean result = keyStoreFolder.mkdirs();
370-
371-
if(!result) {
372-
Base.showWarning("Folders, folders, folders",
373-
"Could not create the necessary folders to build.\n" +
374-
"Perhaps you have some file permissions to sort out?", null);
375-
return null;
376-
}
377-
}
378-
379-
File keyStore = new File(keyStoreFolder, sketch.getName() + "-release-key.keystore");
380-
if(!keyStore.exists()) {
381-
String dname = "CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, S=Unknown, C=Unknown";
382-
// TODO Generate password and store it with alias in some accessible place
383-
String password = "generatedpasswordhere";
384-
385-
String[] args = {
386-
"-genkey",
387-
"-keystore", keyStore.getCanonicalPath(),
388-
"-alias", sketch.getName(),
389-
"-keyalg", "RSA",
390-
"-keysize", "2048",
391-
"-validity", "10000",
392-
"-keypass", password,
393-
"-storepass", password,
394-
"-dname", dname
395-
};
396-
397-
KeyTool.main(args);
398-
399-
// any better ways to check if it is created now?
400-
keyStore = new File(keyStore.getCanonicalPath());
401-
if(!keyStore.exists()) {
402-
Base.showWarning("Failed to create key store",
403-
"There was an error while creating the key store");
404-
return null;
405-
}
406-
}
407-
408-
return keyStore;
409-
}
410-
411361
/*
412362
// SDK tools 17 have a problem where 'dex' won't pick up the libs folder
413363
// (which contains our friend processing-core.jar) unless your current

src/processing/mode/android/AndroidEditor.java

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -373,36 +373,37 @@ public void run() {
373373
public void handleExportPackage() {
374374
// Need to implement an entire signing setup first
375375
// http://dev.processing.org/bugs/show_bug.cgi?id=1430
376-
deactivateExport();
377-
new KeyStoreManager(sketch);
378-
/*
379-
380376
if(handleExportCheckModified()) {
381-
new Thread() {
382-
public void run() {
383-
startIndeterminate();
384-
statusNotice("Exporting signed package...");
385-
AndroidBuild build = new AndroidBuild(sketch, androidMode);
386-
try {
387-
File projectFolder = build.exportPackage();
388-
if(projectFolder != null) {
389-
statusNotice("Done with export.");
390-
Base.openFolder(projectFolder);
391-
} else {
392-
statusError("Error with export");
393-
}
394-
} catch (IOException e) {
395-
statusError(e);
396-
} catch (SketchException e) {
397-
statusError(e);
398-
} catch (InterruptedException e) {
399-
e.printStackTrace();
400-
} catch (Exception e) {
401-
e.printStackTrace();
377+
deactivateExport();
378+
new KeyStoreManager(this);
379+
}
380+
}
381+
382+
public void startExportPackage(final String keyStorePassword) {
383+
new Thread() {
384+
public void run() {
385+
startIndeterminate();
386+
statusNotice("Exporting signed package...");
387+
AndroidBuild build = new AndroidBuild(sketch, androidMode);
388+
try {
389+
File projectFolder = build.exportPackage(keyStorePassword);
390+
if(projectFolder != null) {
391+
statusNotice("Done with export.");
392+
Base.openFolder(projectFolder);
393+
} else {
394+
statusError("Error with export");
402395
}
403-
stopIndeterminate();
396+
} catch (IOException e) {
397+
statusError(e);
398+
} catch (SketchException e) {
399+
statusError(e);
400+
} catch (InterruptedException e) {
401+
e.printStackTrace();
402+
} catch (Exception e) {
403+
e.printStackTrace();
404404
}
405-
}.start();
406-
} */
405+
stopIndeterminate();
406+
}
407+
}.start();
407408
}
408409
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package processing.mode.android;
2+
3+
import processing.app.Base;
4+
import sun.security.tools.KeyTool;
5+
6+
import java.io.File;
7+
8+
/**
9+
* Created with IntelliJ IDEA.
10+
* User: imilka
11+
* Date: 27.05.14
12+
* Time: 14:38
13+
*/
14+
public class AndroidKeyStore {
15+
16+
public static final String ALIAS_STRING = "processing-keystore";
17+
public static final String KEYSTORE_FILE_NAME = "android-release-key.keystore";
18+
19+
public static File getKeyStore() {
20+
File keyStore = getKeyStoreLocation();
21+
if(!keyStore.exists()) return null;
22+
return keyStore;
23+
}
24+
25+
public static File getKeyStoreLocation() {
26+
File sketchbookFolder = processing.app.Base.getSketchbookFolder();
27+
File keyStoreFolder = new File(sketchbookFolder, "keystore");
28+
if(!keyStoreFolder.exists()) {
29+
boolean result = keyStoreFolder.mkdirs();
30+
31+
if(!result) {
32+
Base.showWarning("Folders, folders, folders",
33+
"Could not create the necessary folders to build.\n" +
34+
"Perhaps you have some file permissions to sort out?", null);
35+
return null;
36+
}
37+
}
38+
39+
File keyStore = new File(keyStoreFolder, KEYSTORE_FILE_NAME);
40+
return keyStore;
41+
}
42+
43+
public static void generateKeyStore(String password,
44+
String commonName, String organizationalUnit,
45+
String organizationName, String locality,
46+
String state, String country) throws Exception {
47+
String dnamePlaceholder = "CN=%s, OU=%s, O=%s, L=%s, S=%s, C=%s";
48+
String dname = String.format(dnamePlaceholder,
49+
parseDnameField(commonName), parseDnameField(organizationalUnit), parseDnameField(organizationName),
50+
parseDnameField(locality), parseDnameField(state), parseDnameField(country));
51+
52+
String[] args = {
53+
"-genkey",
54+
"-keystore", getKeyStoreLocation().getAbsolutePath(),
55+
"-alias", ALIAS_STRING,
56+
"-keyalg", "RSA",
57+
"-keysize", "2048",
58+
"-validity", "10000",
59+
"-keypass", password,
60+
"-storepass", password,
61+
"-dname", dname
62+
};
63+
64+
KeyTool.main(args);
65+
66+
if(getKeyStore() == null) throw new Exception();
67+
}
68+
69+
private static String parseDnameField(String content) {
70+
if(content == null || content.length() == 0) return "Unknown";
71+
else return content;
72+
}
73+
}

0 commit comments

Comments
 (0)