Revision cba1dc86
AndroidManifest.xml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
|
3 |
package="info.guardianproject.trustedintents" |
|
4 |
android:versionCode="0" |
|
5 |
android:versionName="0.0" > |
|
6 |
|
|
7 |
<uses-sdk android:minSdkVersion="7" /> |
|
8 |
|
|
9 |
</manifest> |
app/build.gradle | ||
---|---|---|
11 | 11 |
versionCode 1 |
12 | 12 |
versionName "1.0" |
13 | 13 |
} |
14 |
buildTypes { |
|
15 |
release { |
|
16 |
minifyEnabled false |
|
17 |
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' |
|
18 |
} |
|
19 |
} |
|
20 | 14 |
} |
21 | 15 |
|
22 | 16 |
dependencies { |
23 | 17 |
compile fileTree(dir: 'libs', include: ['*.jar']) |
18 |
compile project (':trustedintents') |
|
24 | 19 |
testCompile 'junit:junit:4.12' |
25 | 20 |
compile 'com.android.support:appcompat-v7:23.1.1' |
26 | 21 |
compile 'com.android.support:design:23.1.1' |
app/src/androidTest/java/info/guardianproject/trustedintents/ApplicationTest.java | ||
---|---|---|
1 |
package info.guardianproject.trustedintents; |
|
2 |
|
|
3 |
import android.app.Application; |
|
4 |
import android.test.ApplicationTestCase; |
|
5 |
|
|
6 |
/** |
|
7 |
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> |
|
8 |
*/ |
|
9 |
public class ApplicationTest extends ApplicationTestCase<Application> { |
|
10 |
public ApplicationTest() { |
|
11 |
super(Application.class); |
|
12 |
} |
|
13 |
} |
app/src/androidTest/java/info/guardianproject/trustedintents/example/ApplicationTest.java | ||
---|---|---|
1 |
package info.guardianproject.trustedintents.example; |
|
2 |
|
|
3 |
import android.app.Application; |
|
4 |
import android.test.ApplicationTestCase; |
|
5 |
|
|
6 |
/** |
|
7 |
* <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a> |
|
8 |
*/ |
|
9 |
public class ApplicationTest extends ApplicationTestCase<Application> { |
|
10 |
public ApplicationTest() { |
|
11 |
super(Application.class); |
|
12 |
} |
|
13 |
} |
app/src/main/AndroidManifest.xml | ||
---|---|---|
1 | 1 |
<?xml version="1.0" encoding="utf-8"?> |
2 | 2 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
3 |
package="info.guardianproject.trustedintents" > |
|
3 |
package="info.guardianproject.trustedintents.example" >
|
|
4 | 4 |
|
5 | 5 |
<application |
6 | 6 |
android:allowBackup="true" |
app/src/main/java/info/guardianproject/trustedintents/MainActivity.java | ||
---|---|---|
1 |
package info.guardianproject.trustedintents; |
|
2 |
|
|
3 |
import android.app.Activity; |
|
4 |
import android.content.ActivityNotFoundException; |
|
5 |
import android.content.Intent; |
|
6 |
import android.os.Bundle; |
|
7 |
import android.support.design.widget.FloatingActionButton; |
|
8 |
import android.support.design.widget.Snackbar; |
|
9 |
import android.support.v7.app.AppCompatActivity; |
|
10 |
import android.support.v7.widget.Toolbar; |
|
11 |
import android.view.Menu; |
|
12 |
import android.view.MenuItem; |
|
13 |
import android.view.View; |
|
14 |
import android.widget.Toast; |
|
15 |
|
|
16 |
import org.torproject.TorProjectRSA1024; |
|
17 |
|
|
18 |
import java.security.cert.CertificateException; |
|
19 |
|
|
20 |
import info.guardianproject.GuardianProjectRSA1024; |
|
21 |
|
|
22 |
public class MainActivity extends AppCompatActivity { |
|
23 |
|
|
24 |
private static TrustedIntents trustedIntents; |
|
25 |
|
|
26 |
@Override |
|
27 |
protected void onCreate(Bundle savedInstanceState) { |
|
28 |
super.onCreate(savedInstanceState); |
|
29 |
|
|
30 |
trustedIntents = TrustedIntents.get(this); |
|
31 |
trustedIntents.addTrustedSigner(GuardianProjectRSA1024.class); |
|
32 |
|
|
33 |
setContentView(R.layout.activity_main); |
|
34 |
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); |
|
35 |
setSupportActionBar(toolbar); |
|
36 |
|
|
37 |
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); |
|
38 |
fab.setOnClickListener(new View.OnClickListener() { |
|
39 |
@Override |
|
40 |
public void onClick(View view) { |
|
41 |
final Activity activity = MainActivity.this; |
|
42 |
try { |
|
43 |
Intent intent = new Intent(Intent.ACTION_VIEW); |
|
44 |
intent.setClassName("info.guardianproject.gpg", |
|
45 |
"info.guardianproject.gpg.MainActivity"); |
|
46 |
trustedIntents.startActivity(activity, intent); |
|
47 |
} catch (ActivityNotFoundException e) { |
|
48 |
e.printStackTrace(); |
|
49 |
Toast.makeText(activity, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); |
|
50 |
} catch (CertificateException e) { |
|
51 |
e.printStackTrace(); |
|
52 |
Toast.makeText(activity, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); |
|
53 |
} |
|
54 |
} |
|
55 |
}); |
|
56 |
} |
|
57 |
|
|
58 |
@Override |
|
59 |
public boolean onCreateOptionsMenu(Menu menu) { |
|
60 |
// Inflate the menu; this adds items to the action bar if it is present. |
|
61 |
getMenuInflater().inflate(R.menu.menu_main, menu); |
|
62 |
return true; |
|
63 |
} |
|
64 |
|
|
65 |
@Override |
|
66 |
public boolean onOptionsItemSelected(MenuItem item) { |
|
67 |
// Handle action bar item clicks here. The action bar will |
|
68 |
// automatically handle clicks on the Home/Up button, so long |
|
69 |
// as you specify a parent activity in AndroidManifest.xml. |
|
70 |
int id = item.getItemId(); |
|
71 |
|
|
72 |
//noinspection SimplifiableIfStatement |
|
73 |
if (id == R.id.action_settings) { |
|
74 |
return true; |
|
75 |
} |
|
76 |
|
|
77 |
return super.onOptionsItemSelected(item); |
|
78 |
} |
|
79 |
} |
app/src/main/java/info/guardianproject/trustedintents/example/MainActivity.java | ||
---|---|---|
1 |
package info.guardianproject.trustedintents.example; |
|
2 |
|
|
3 |
import android.app.Activity; |
|
4 |
import android.content.ActivityNotFoundException; |
|
5 |
import android.content.Intent; |
|
6 |
import android.os.Bundle; |
|
7 |
import android.support.design.widget.FloatingActionButton; |
|
8 |
import android.support.v7.app.AppCompatActivity; |
|
9 |
import android.support.v7.widget.Toolbar; |
|
10 |
import android.view.Menu; |
|
11 |
import android.view.MenuItem; |
|
12 |
import android.view.View; |
|
13 |
import android.widget.Toast; |
|
14 |
|
|
15 |
import java.security.cert.CertificateException; |
|
16 |
|
|
17 |
import info.guardianproject.GuardianProjectRSA1024; |
|
18 |
import info.guardianproject.trustedintents.TrustedIntents; |
|
19 |
|
|
20 |
public class MainActivity extends AppCompatActivity { |
|
21 |
|
|
22 |
private static TrustedIntents trustedIntents; |
|
23 |
|
|
24 |
@Override |
|
25 |
protected void onCreate(Bundle savedInstanceState) { |
|
26 |
super.onCreate(savedInstanceState); |
|
27 |
|
|
28 |
trustedIntents = TrustedIntents.get(this); |
|
29 |
trustedIntents.addTrustedSigner(GuardianProjectRSA1024.class); |
|
30 |
|
|
31 |
setContentView(R.layout.activity_main); |
|
32 |
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); |
|
33 |
setSupportActionBar(toolbar); |
|
34 |
|
|
35 |
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); |
|
36 |
fab.setOnClickListener(new View.OnClickListener() { |
|
37 |
@Override |
|
38 |
public void onClick(View view) { |
|
39 |
final Activity activity = MainActivity.this; |
|
40 |
try { |
|
41 |
Intent intent = new Intent(Intent.ACTION_VIEW); |
|
42 |
intent.setClassName("info.guardianproject.gpg", |
|
43 |
"info.guardianproject.gpg.MainActivity"); |
|
44 |
trustedIntents.startActivity(activity, intent); |
|
45 |
} catch (ActivityNotFoundException e) { |
|
46 |
e.printStackTrace(); |
|
47 |
Toast.makeText(activity, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); |
|
48 |
} catch (CertificateException e) { |
|
49 |
e.printStackTrace(); |
|
50 |
Toast.makeText(activity, e.getLocalizedMessage(), Toast.LENGTH_LONG).show(); |
|
51 |
} |
|
52 |
} |
|
53 |
}); |
|
54 |
} |
|
55 |
|
|
56 |
@Override |
|
57 |
public boolean onCreateOptionsMenu(Menu menu) { |
|
58 |
// Inflate the menu; this adds items to the action bar if it is present. |
|
59 |
getMenuInflater().inflate(R.menu.menu_main, menu); |
|
60 |
return true; |
|
61 |
} |
|
62 |
|
|
63 |
@Override |
|
64 |
public boolean onOptionsItemSelected(MenuItem item) { |
|
65 |
// Handle action bar item clicks here. The action bar will |
|
66 |
// automatically handle clicks on the Home/Up button, so long |
|
67 |
// as you specify a parent activity in AndroidManifest.xml. |
|
68 |
int id = item.getItemId(); |
|
69 |
|
|
70 |
//noinspection SimplifiableIfStatement |
|
71 |
if (id == R.id.action_settings) { |
|
72 |
return true; |
|
73 |
} |
|
74 |
|
|
75 |
return super.onOptionsItemSelected(item); |
|
76 |
} |
|
77 |
} |
app/src/test/java/info/guardianproject/trustedintents/ExampleUnitTest.java | ||
---|---|---|
1 |
package info.guardianproject.trustedintents; |
|
2 |
|
|
3 |
import org.junit.Test; |
|
4 |
|
|
5 |
import static org.junit.Assert.*; |
|
6 |
|
|
7 |
/** |
|
8 |
* To work on unit tests, switch the Test Artifact in the Build Variants view. |
|
9 |
*/ |
|
10 |
public class ExampleUnitTest { |
|
11 |
@Test |
|
12 |
public void addition_isCorrect() throws Exception { |
|
13 |
assertEquals(4, 2 + 2); |
|
14 |
} |
|
15 |
} |
app/src/test/java/info/guardianproject/trustedintents/example/ExampleUnitTest.java | ||
---|---|---|
1 |
package info.guardianproject.trustedintents.example; |
|
2 |
|
|
3 |
import org.junit.Test; |
|
4 |
|
|
5 |
import static org.junit.Assert.*; |
|
6 |
|
|
7 |
/** |
|
8 |
* To work on unit tests, switch the Test Artifact in the Build Variants view. |
|
9 |
*/ |
|
10 |
public class ExampleUnitTest { |
|
11 |
@Test |
|
12 |
public void addition_isCorrect() throws Exception { |
|
13 |
assertEquals(4, 2 + 2); |
|
14 |
} |
|
15 |
} |
custom_rules.xml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<project name="custom_rules"> |
|
3 |
|
|
4 |
<property name="name" value="trustedintents" /> |
|
5 |
|
|
6 |
<target name="-getgitdetails" > |
|
7 |
<exec executable="git" outputproperty="git.describe"> |
|
8 |
<arg value="describe"/> |
|
9 |
</exec> |
|
10 |
<exec executable="git" outputproperty="git.revision"> |
|
11 |
<arg value="rev-parse"/> |
|
12 |
<arg value="HEAD"/> |
|
13 |
</exec> |
|
14 |
<property name="jar.name" value="${name}-${git.describe}" /> |
|
15 |
<property name="javadoc.jar" value="${jar.name}-javadoc.jar" /> |
|
16 |
<property name="source.jar" value="${jar.name}-source.jar" /> |
|
17 |
<property name="pom" value="${jar.name}-source.jar" /> |
|
18 |
</target> |
|
19 |
|
|
20 |
<target name="-pre-clean" depends="-getgitdetails"> |
|
21 |
<property name="delete.pattern" value="${jar.name}*.jar*" /> |
|
22 |
<echo message="deleting ${delete.pattern}" /> |
|
23 |
<delete failonerror="false"> |
|
24 |
<fileset dir="." includes="${delete.pattern}" /> |
|
25 |
</delete> |
|
26 |
</target> |
|
27 |
|
|
28 |
<target name="-create-manifest"> |
|
29 |
<echo message="Creating custom MANIFEST.MF" /> |
|
30 |
<manifest file="MANIFEST.MF"> |
|
31 |
<attribute name="Extension-Name" value="info.guardianproject.${name}"/> |
|
32 |
<attribute name="Implementation-Vendor" value="Guardian Project"/> |
|
33 |
<attribute name="Implementation-Title" value="TrustedIntents"/> |
|
34 |
<attribute name="Implementation-URL" value="https://dev.guardianproject.info/projects/${name}"/> |
|
35 |
<attribute name="Implementation-Git-URL" value="https://github.com/guardianproject/${name}"/> |
|
36 |
</manifest> |
|
37 |
<replaceregexp file="MANIFEST.MF" |
|
38 |
match="\nCreated-By:.*?\n" |
|
39 |
replace="" |
|
40 |
flags="m"/> |
|
41 |
</target> |
|
42 |
|
|
43 |
<target name="-pre-build" depends="-getgitdetails,-create-manifest"> |
|
44 |
<echo message="running" /> |
|
45 |
</target> |
|
46 |
|
|
47 |
<target name="javadoc" description="Generate Javadocs" depends="-pre-build"> |
|
48 |
<property name="javadoc.dir" value="${out.dir}/javadoc" /> |
|
49 |
<javadoc sourcepath="${source.dir}" |
|
50 |
classpath="${toString:project.all.jars.path}:${toString:project.target.class.path}" |
|
51 |
destdir="${javadoc.dir}" |
|
52 |
packagenames="info.guardianproject.*" |
|
53 |
additionalparam="-notimestamp" |
|
54 |
windowtitle="${ant.project.name}" |
|
55 |
linkoffline="https://developer.android.com/reference ${sdk.dir}/docs/reference" |
|
56 |
linksource="true" |
|
57 |
doctitle="${ant.project.name}" /> |
|
58 |
<jar destfile="${javadoc.jar}" |
|
59 |
manifest="MANIFEST.MF" |
|
60 |
basedir="${javadoc.dir}"> |
|
61 |
</jar> |
|
62 |
<delete file="${javadoc.jar}.asc"/> |
|
63 |
<exec executable="gpg" failonerror="false"> |
|
64 |
<arg value="--armor" /> |
|
65 |
<arg value="--detach-sign" /> |
|
66 |
<arg value="${javadoc.jar}" /> |
|
67 |
</exec> |
|
68 |
</target> |
|
69 |
|
|
70 |
<target name="source" description="Generate Javadocs" depends="-build-setup,-getgitdetails"> |
|
71 |
|
|
72 |
<jar destfile="${source.jar}" |
|
73 |
manifest="MANIFEST.MF" |
|
74 |
includes="info/**" |
|
75 |
basedir="${source.dir}"> |
|
76 |
</jar> |
|
77 |
<delete file="${source.jar}.asc"/> |
|
78 |
<exec executable="gpg" failonerror="false"> |
|
79 |
<arg value="--armor" /> |
|
80 |
<arg value="--detach-sign" /> |
|
81 |
<arg value="${source.jar}" /> |
|
82 |
</exec> |
|
83 |
</target> |
|
84 |
|
|
85 |
<target name="pom" description="Generate maven .pom" depends="-build-setup,-getgitdetails"> |
|
86 |
<property name="pom.file" value="${jar.name}.pom" /> |
|
87 |
<copy file="${name}.pom" tofile="${pom.file}" /> |
|
88 |
<replaceregexp file="${pom.file}" |
|
89 |
match="<version>.*</version>" |
|
90 |
replace="<version>${git.describe}</version>" |
|
91 |
byline="true" /> |
|
92 |
|
|
93 |
<delete file="${pom.file}.asc" /> |
|
94 |
<exec executable="gpg" failonerror="false"> |
|
95 |
<arg value="--armor" /> |
|
96 |
<arg value="--detach-sign" /> |
|
97 |
<arg value="${pom.file}" /> |
|
98 |
</exec> |
|
99 |
</target> |
|
100 |
|
|
101 |
<target name="-post-build" depends="-getgitdetails"> |
|
102 |
<condition property="build.is.debug" value="true" else="false"> |
|
103 |
<equals arg1="${build.target}" arg2="debug" /> |
|
104 |
</condition> |
|
105 |
<if condition="${build.is.debug}"> |
|
106 |
<then> |
|
107 |
<property name="release.jar" value="${jar.name}-debug.jar" /> |
|
108 |
</then> |
|
109 |
<else> |
|
110 |
<property name="release.jar" value="${jar.name}.jar" /> |
|
111 |
</else> |
|
112 |
</if> |
|
113 |
<property file="${sdk.dir}/tools/source.properties" /> |
|
114 |
<delete file="${release.jar}"/> |
|
115 |
<jar destfile="${release.jar}" |
|
116 |
manifest="MANIFEST.MF" |
|
117 |
includes="**" |
|
118 |
excludes="info/guardianproject/trustedintents/BuildConfig.*" |
|
119 |
basedir="${out.classes.absolute.dir}"> |
|
120 |
</jar> |
|
121 |
<if condition="${build.is.debug}"> |
|
122 |
<else> |
|
123 |
<delete file="${release.jar}.asc"/> |
|
124 |
<exec executable="gpg" failonerror="false"> |
|
125 |
<arg value="--armor" /> |
|
126 |
<arg value="--detach-sign" /> |
|
127 |
<arg value="${release.jar}" /> |
|
128 |
</exec> |
|
129 |
</else> |
|
130 |
</if> |
|
131 |
</target> |
|
132 |
|
|
133 |
<target name="release-all" depends="clean,release,javadoc,source,pom" /> |
|
134 |
|
|
135 |
</project> |
jenkins-build | ||
---|---|---|
14 | 14 |
|
15 | 15 |
export PATH=$PATH:$ANDROID_HOME/tools |
16 | 16 |
|
17 |
cd trustedintents |
|
17 | 18 |
./setup-ant |
make-release-build | ||
---|---|---|
14 | 14 |
git reset --hard |
15 | 15 |
git clean -fdx |
16 | 16 |
|
17 |
cd trustedintents |
|
17 | 18 |
./setup-ant |
18 | 19 |
|
19 | 20 |
faketime -f "$TIMESTAMP" ant release-all |
project.properties | ||
---|---|---|
1 |
target=android-19 |
|
2 |
android.library=true |
settings.gradle | ||
---|---|---|
1 |
include ':app' |
|
1 |
include ':app', ':trustedintents' |
setup-ant | ||
---|---|---|
1 |
#!/bin/sh |
|
2 |
|
|
3 |
set -e |
|
4 |
set -x |
|
5 |
|
|
6 |
if ! which android > /dev/null; then |
|
7 |
if [ -z $ANDROID_HOME ]; then |
|
8 |
if [ -e ~/.android/bashrc ]; then |
|
9 |
. ~/.android/bashrc |
|
10 |
else |
|
11 |
echo "'android' not found, ANDROID_HOME must be set!" |
|
12 |
exit |
|
13 |
fi |
|
14 |
else |
|
15 |
export PATH="${ANDROID_HOME}/tools:$PATH" |
|
16 |
fi |
|
17 |
fi |
|
18 |
|
|
19 |
# fetch target from project.properties |
|
20 |
eval `grep '^target=' project.properties` |
|
21 |
|
|
22 |
CURDIR=`pwd` |
|
23 |
|
|
24 |
android update lib-project --path ${CURDIR} --target $target |
|
25 |
android update test-project --path ${CURDIR}/test --main ${CURDIR} |
src/info/guardianproject/GuardianProjectRSA1024.java | ||
---|---|---|
1 |
|
|
2 |
package info.guardianproject; |
|
3 |
|
|
4 |
import info.guardianproject.trustedintents.ApkSignaturePin; |
|
5 |
|
|
6 |
/** |
|
7 |
* This is the original Guardian Project APK signing key. No new apps will be |
|
8 |
* signed by this key, it is considered deprecated since RSA 1024-bit keys are |
|
9 |
* deprecated. It is used to sign these apps: |
|
10 |
* <ul> |
|
11 |
* <li>CACertMan</li> |
|
12 |
* <li>ChatSecure</li> |
|
13 |
* <li>Gnu Privacy Guard</li> |
|
14 |
* <li>Lil' Debi</li> |
|
15 |
* <li>NoteCipher</li> |
|
16 |
* <li>ObscuraCam</li> |
|
17 |
* <li>Orweb</li> |
|
18 |
* <li>PixelKnot</li> |
|
19 |
* <li>StoryMaker</li> |
|
20 |
* </ul> |
|
21 |
* |
|
22 |
* @author hans |
|
23 |
*/ |
|
24 |
public final class GuardianProjectRSA1024 extends ApkSignaturePin { |
|
25 |
|
|
26 |
public GuardianProjectRSA1024() { |
|
27 |
fingerprints = new String[] { |
|
28 |
"d71620711b04dfa13216116fbc8a9f3e3409846b16ff2bacf43e1c5ef5a3ed6b", |
|
29 |
}; |
|
30 |
certificates = new byte[][] { |
|
31 |
{ |
|
32 |
48, -126, 2, -111, 48, -126, 1, -6, -96, 3, 2, 1, 2, 2, 4, 75, -107, -101, |
|
33 |
-63, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 5, 5, 0, 48, -127, |
|
34 |
-116, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 85, 83, 49, 17, 48, 15, 6, 3, |
|
35 |
85, 4, 8, 19, 8, 78, 101, 119, 32, 89, 111, 114, 107, 49, 17, 48, 15, 6, 3, |
|
36 |
85, 4, 7, 19, 8, 78, 101, 119, 32, 89, 111, 114, 107, 49, 29, 48, 27, 6, 3, |
|
37 |
85, 4, 10, 19, 20, 103, 117, 97, 114, 100, 105, 97, 110, 112, 114, 111, |
|
38 |
106, 101, 99, 116, 46, 105, 110, 102, 111, 49, 29, 48, 27, 6, 3, 85, 4, 11, |
|
39 |
19, 20, 103, 117, 97, 114, 100, 105, 97, 110, 112, 114, 111, 106, 101, 99, |
|
40 |
116, 46, 105, 110, 102, 111, 49, 25, 48, 23, 6, 3, 85, 4, 3, 19, 16, 71, |
|
41 |
117, 97, 114, 100, 105, 97, 110, 32, 80, 114, 111, 106, 101, 99, 116, 48, |
|
42 |
30, 23, 13, 49, 48, 48, 51, 48, 57, 48, 48, 53, 50, 49, 55, 90, 23, 13, 51, |
|
43 |
55, 48, 55, 50, 53, 48, 48, 53, 50, 49, 55, 90, 48, -127, -116, 49, 11, 48, |
|
44 |
9, 6, 3, 85, 4, 6, 19, 2, 85, 83, 49, 17, 48, 15, 6, 3, 85, 4, 8, 19, 8, |
|
45 |
78, 101, 119, 32, 89, 111, 114, 107, 49, 17, 48, 15, 6, 3, 85, 4, 7, 19, 8, |
|
46 |
78, 101, 119, 32, 89, 111, 114, 107, 49, 29, 48, 27, 6, 3, 85, 4, 10, 19, |
|
47 |
20, 103, 117, 97, 114, 100, 105, 97, 110, 112, 114, 111, 106, 101, 99, 116, |
|
48 |
46, 105, 110, 102, 111, 49, 29, 48, 27, 6, 3, 85, 4, 11, 19, 20, 103, 117, |
|
49 |
97, 114, 100, 105, 97, 110, 112, 114, 111, 106, 101, 99, 116, 46, 105, 110, |
|
50 |
102, 111, 49, 25, 48, 23, 6, 3, 85, 4, 3, 19, 16, 71, 117, 97, 114, 100, |
|
51 |
105, 97, 110, 32, 80, 114, 111, 106, 101, 99, 116, 48, -127, -97, 48, 13, |
|
52 |
6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -127, -115, 0, 48, |
|
53 |
-127, -119, 2, -127, -127, 0, -101, -15, 20, 57, 18, -13, 105, 60, 19, 105, |
|
54 |
110, 96, 27, 109, 64, 54, -18, -115, 109, -1, 48, 20, 86, 116, -29, 29, |
|
55 |
-120, 37, 1, -111, -52, -83, 3, -81, -83, -91, -55, -51, 4, -80, 14, 1, 92, |
|
56 |
-66, -93, 57, -9, 6, -72, -110, -109, -68, 124, 18, -92, 30, -83, -76, 65, |
|
57 |
121, 0, -92, 82, -11, 98, 4, -73, -81, -50, 114, 82, -35, 17, 107, -19, -4, |
|
58 |
16, -53, -62, -57, -121, -69, 85, -91, 51, 43, 17, -110, -65, -105, -54, |
|
59 |
-64, -110, -38, 108, 16, -50, 119, -114, 49, -20, 19, -32, 34, -76, -45, |
|
60 |
-76, 81, 70, 98, -22, -128, 84, 116, 92, 20, -106, -73, -5, 94, -12, 15, |
|
61 |
-86, -74, 47, 98, 121, -33, 2, 3, 1, 0, 1, 48, 13, 6, 9, 42, -122, 72, |
|
62 |
-122, -9, 13, 1, 1, 5, 5, 0, 3, -127, -127, 0, 38, 10, 32, 65, -93, 9, 34, |
|
63 |
116, 16, -74, 100, -99, 44, -54, 65, -107, -54, 23, 118, 54, 33, 61, -124, |
|
64 |
-105, -27, 95, 18, -70, -61, -82, -20, 117, -28, -121, 71, -75, -118, -9, |
|
65 |
-53, 6, -127, 7, 75, -3, -48, 121, -37, 75, 97, 62, 86, -113, -83, -33, |
|
66 |
-98, -61, -6, -22, -11, 81, 48, -33, -83, -116, -12, -18, -128, 48, 29, 40, |
|
67 |
-17, -91, 119, 98, 40, -41, 48, -117, 31, -41, -33, -47, -18, 126, -26, |
|
68 |
-75, -75, 8, 22, 45, -27, -14, -58, 3, 23, -73, -100, 26, -58, 88, -122, |
|
69 |
-60, 35, -125, 33, 87, 7, 21, -54, 55, -123, 54, 91, 0, -89, -46, -9, 68, |
|
70 |
121, 15, 69, 103, 22, -26, 126, 83, -22, -57 |
|
71 |
}, |
|
72 |
}; |
|
73 |
} |
|
74 |
} |
src/info/guardianproject/GuardianProjectRSA4096.java | ||
---|---|---|
1 |
|
|
2 |
package info.guardianproject; |
|
3 |
|
|
4 |
import info.guardianproject.trustedintents.ApkSignaturePin; |
|
5 |
|
|
6 |
/** |
|
7 |
* This is the second Guardian Project APK signing key. It was generated since |
|
8 |
* RSA 1024-bit keys are deprecated. So any new Guardian Project app will be |
|
9 |
* signed by this key. It is used to sign these apps: |
|
10 |
* <ul> |
|
11 |
* <li>Checkey</li> |
|
12 |
* <li>Courier</li> |
|
13 |
* </ul> |
|
14 |
* |
|
15 |
* @author hans |
|
16 |
*/ |
|
17 |
public final class GuardianProjectRSA4096 extends ApkSignaturePin { |
|
18 |
|
|
19 |
public GuardianProjectRSA4096() { |
|
20 |
fingerprints = new String[] { |
|
21 |
"f006a20481c71a690de02e385ab0c9fa4ac1245240f68102682703ba0656867a", |
|
22 |
}; |
|
23 |
certificates = new byte[][] { |
|
24 |
{ |
|
25 |
48, -126, 5, -84, 48, -126, 3, -108, 2, 9, 0, -126, -20, 93, -43, 112, 34, |
|
26 |
-87, 29, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 5, 5, 0, 48, -127, |
|
27 |
-105, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 85, 83, 49, 17, 48, 15, 6, 3, |
|
28 |
85, 4, 8, 12, 8, 78, 101, 119, 32, 89, 111, 114, 107, 49, 17, 48, 15, 6, 3, |
|
29 |
85, 4, 7, 12, 8, 78, 101, 119, 32, 89, 111, 114, 107, 49, 25, 48, 23, 6, 3, |
|
30 |
85, 4, 10, 12, 16, 71, 117, 97, 114, 100, 105, 97, 110, 32, 80, 114, 111, |
|
31 |
106, 101, 99, 116, 49, 29, 48, 27, 6, 3, 85, 4, 3, 12, 20, 103, 117, 97, |
|
32 |
114, 100, 105, 97, 110, 112, 114, 111, 106, 101, 99, 116, 46, 105, 110, |
|
33 |
102, 111, 49, 40, 48, 38, 6, 9, 42, -122, 72, -122, -9, 13, 1, 9, 1, 22, |
|
34 |
25, 114, 111, 111, 116, 64, 103, 117, 97, 114, 100, 105, 97, 110, 112, 114, |
|
35 |
111, 106, 101, 99, 116, 46, 105, 110, 102, 111, 48, 30, 23, 13, 49, 52, 48, |
|
36 |
53, 49, 52, 49, 55, 53, 55, 50, 57, 90, 23, 13, 52, 49, 48, 57, 50, 56, 49, |
|
37 |
55, 53, 55, 50, 57, 90, 48, -127, -105, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, |
|
38 |
2, 85, 83, 49, 17, 48, 15, 6, 3, 85, 4, 8, 12, 8, 78, 101, 119, 32, 89, |
|
39 |
111, 114, 107, 49, 17, 48, 15, 6, 3, 85, 4, 7, 12, 8, 78, 101, 119, 32, 89, |
|
40 |
111, 114, 107, 49, 25, 48, 23, 6, 3, 85, 4, 10, 12, 16, 71, 117, 97, 114, |
|
41 |
100, 105, 97, 110, 32, 80, 114, 111, 106, 101, 99, 116, 49, 29, 48, 27, 6, |
|
42 |
3, 85, 4, 3, 12, 20, 103, 117, 97, 114, 100, 105, 97, 110, 112, 114, 111, |
|
43 |
106, 101, 99, 116, 46, 105, 110, 102, 111, 49, 40, 48, 38, 6, 9, 42, -122, |
|
44 |
72, -122, -9, 13, 1, 9, 1, 22, 25, 114, 111, 111, 116, 64, 103, 117, 97, |
|
45 |
114, 100, 105, 97, 110, 112, 114, 111, 106, 101, 99, 116, 46, 105, 110, |
|
46 |
102, 111, 48, -126, 2, 34, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, |
|
47 |
1, 5, 0, 3, -126, 2, 15, 0, 48, -126, 2, 10, 2, -126, 2, 1, 0, -51, 108, |
|
48 |
83, -44, 61, 81, 46, 61, 2, -61, 46, 60, 2, -30, 44, 38, -70, -63, -93, |
|
49 |
-66, -57, 1, 2, -32, -80, -82, 98, -26, -70, -34, 60, -65, -55, -43, 16, |
|
50 |
-63, -89, -104, 50, 108, -26, -2, -3, -55, -77, 47, 75, 89, 99, 12, -32, |
|
51 |
32, 120, -26, -81, 54, 95, -57, -114, -100, -39, -110, -4, 120, 90, 90, |
|
52 |
-40, -89, -53, 63, -122, -45, -80, 32, -6, -12, -29, -107, 45, 10, -23, 76, |
|
53 |
5, 112, -15, -63, 48, 35, -61, 0, -107, -110, 44, -46, -126, -30, -30, -33, |
|
54 |
86, 22, 30, 8, -72, 29, 75, 121, 31, -120, 119, 59, -57, 19, -64, 31, 84, |
|
55 |
-94, -38, 91, 82, 92, -95, 66, 2, 120, -37, -113, 126, 54, -83, 83, -125, |
|
56 |
122, 110, -106, 80, 59, -127, -72, -23, 64, 105, 20, 25, -41, -3, -61, -44, |
|
57 |
51, -28, 17, 36, -90, -18, -25, 96, 37, -93, -48, 98, 47, 27, 49, 40, -31, |
|
58 |
-62, -102, -49, 28, -55, 50, -38, -70, -83, 101, 97, 96, -122, -114, 18, |
|
59 |
47, 119, 117, -7, -55, -64, -1, 96, -120, 61, -89, -70, -7, -89, 113, -41, |
|
60 |
88, 27, 26, 95, -52, 53, 59, 7, 11, 79, 86, 31, -109, -21, 120, -15, 38, |
|
61 |
106, 33, -121, 82, 18, 45, 32, 49, 93, -26, -74, -104, 4, -122, 96, 39, |
|
62 |
126, -24, 16, 119, -45, -119, 110, -31, 55, -109, 53, 53, -11, -58, -124, |
|
63 |
-84, 41, -42, 64, 17, -5, -78, -57, -100, 118, -105, -38, -94, 84, -16, |
|
64 |
-53, -106, -11, 76, 81, 70, -83, -56, 73, -96, -100, -18, 55, -3, -3, 34, |
|
65 |
-97, -62, 59, -17, -79, 91, -9, 122, 95, -108, -121, -76, -62, -72, 61, |
|
66 |
-82, 105, -99, -59, 10, 51, 52, 77, -105, -127, 37, 79, 88, -127, 27, 39, |
|
67 |
44, 15, 123, -59, -118, -96, 61, -28, 23, -54, 124, 100, 57, 37, 123, -83, |
|
68 |
-124, 11, 123, 73, -53, 18, 119, -39, -13, 46, 123, -55, 4, -91, 114, 93, |
|
69 |
-116, -98, 21, 95, -30, -82, -108, 87, -65, -8, 30, 67, 14, 22, 79, -64, |
|
70 |
86, -128, -83, 74, 69, -42, 9, -18, -120, -52, 7, 62, 78, 88, -53, -125, |
|
71 |
41, -122, -91, -34, -110, 111, -118, -25, 25, -83, 90, -95, 84, -121, 95, |
|
72 |
72, -53, -14, -14, -48, 65, 4, 23, 99, 56, 23, -20, 9, 46, 63, 83, -26, |
|
73 |
-86, 54, -104, 79, 9, 94, -91, -69, 10, -125, -17, -28, -32, -79, 5, -11, |
|
74 |
37, 103, -46, -75, 71, -119, 39, 48, -53, -51, 118, 43, 28, 68, 14, -33, |
|
75 |
-82, -76, -98, 1, 41, 94, -128, -86, 51, -89, 17, -31, 38, -70, -2, -27, |
|
76 |
-105, -87, 103, 93, 19, 73, -106, -82, -76, 110, -48, -124, -51, 92, -91, |
|
77 |
-51, 22, 1, -48, 52, -127, -24, 26, -77, 4, 22, 33, 24, -128, -1, 9, -42, |
|
78 |
23, -53, 78, 10, -39, -115, -95, 17, 100, 90, 16, -23, -127, -38, 10, -62, |
|
79 |
-64, 113, -115, -114, 78, -11, -124, 113, 113, -42, -66, 114, -98, -40, |
|
80 |
-41, 2, 3, 1, 0, 1, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 5, 5, |
|
81 |
0, 3, -126, 2, 1, 0, -54, 125, -113, -9, -45, 82, 2, -79, -87, 31, -17, |
|
82 |
-10, 117, 16, 1, 67, -63, 57, -49, -81, -90, 48, 7, -58, 89, -29, 120, 84, |
|
83 |
116, 51, 54, -94, 74, -111, -11, 53, -13, 53, -125, -76, -64, 46, -35, 19, |
|
84 |
-19, 25, 36, -82, 66, 113, -14, -6, -63, 83, 15, 8, -77, -74, -94, -53, |
|
85 |
-35, -61, -75, 52, 13, -128, 9, 96, 66, 46, 46, -57, 24, -28, -39, -46, 96, |
|
86 |
-115, -63, 92, -70, 51, 49, -94, 96, 77, 16, 108, -59, -28, 112, -2, -3, |
|
87 |
-87, 27, 56, 118, 29, -95, -76, -70, 34, -105, -24, -104, 70, 24, -88, -29, |
|
88 |
-28, -101, -98, 24, -48, -32, -111, 97, 61, -70, -21, -111, 70, -55, 68, |
|
89 |
-76, 125, -61, 56, -122, 48, -118, 74, 61, -101, -46, -43, -12, -114, -116, |
|
90 |
-57, -108, 91, -109, -62, -117, -76, -48, 109, 81, -22, -113, -73, 64, -61, |
|
91 |
102, 92, -117, -9, -100, 62, -90, 99, 102, -50, -41, -75, 31, 5, -76, -31, |
|
92 |
-85, 118, -57, -21, 102, 71, 41, -34, -45, -92, 88, 82, -95, 65, -100, -31, |
|
93 |
-28, -85, -37, 94, -52, 72, 39, 55, -42, 18, 29, 115, 23, -106, -2, -54, |
|
94 |
-45, 61, 53, 62, 107, 109, -65, 69, 4, -123, 124, -30, -54, -44, 38, 119, |
|
95 |
49, -123, -27, -50, 77, -9, -40, -114, -50, -70, -123, 86, -115, 127, 45, |
|
96 |
42, 23, -25, -83, -81, -38, -84, -3, 99, -36, 12, -67, -39, -110, 21, -40, |
|
97 |
-128, 6, -96, -24, -116, -62, 63, 127, 39, 57, -83, -63, 0, 127, -12, 73, |
|
98 |
85, -41, -101, -70, -48, -94, -94, -73, -38, -115, -62, -34, 62, -92, 96, |
|
99 |
16, 6, -19, -84, 38, -93, -117, -52, 32, 92, -21, 123, -117, 81, 50, -71, |
|
100 |
103, 121, 127, 4, -3, -40, 62, 100, 22, -123, -68, -69, -54, -127, -67, 50, |
|
101 |
-114, 77, -30, 26, -102, 29, 106, 48, 83, 99, 73, 96, 124, -77, 51, 8, 15, |
|
102 |
40, 72, -108, 105, 62, 119, -113, -90, 57, -62, 127, -57, -21, -40, -109, |
|
103 |
96, 101, 71, -40, -101, 127, 69, 110, 43, 59, -102, -8, -42, -70, -24, 51, |
|
104 |
-51, 54, 42, -110, -119, 41, -101, 45, -101, -124, 56, -75, -26, 86, -65, |
|
105 |
54, 21, -88, -30, 79, -26, -127, 121, -102, -48, -25, -62, 99, 76, -90, |
|
106 |
-48, -37, 123, 9, 67, 51, -41, -116, 29, 69, 88, 93, -42, 23, 73, -112, 24, |
|
107 |
-85, 60, 1, 3, -95, 12, -49, -55, 95, 109, -37, 10, -124, 119, -52, -31, |
|
108 |
91, 55, -67, 99, 87, -55, 97, 25, -9, -119, -41, -98, 100, -14, 70, -44, |
|
109 |
-63, 60, -127, -99, 15, 49, 22, -118, -49, 66, -106, 36, -34, -5, 6, -48, |
|
110 |
123, -79, 115, 57, 30, -3, -34, -67, 91, 34, 3, -52, -106, 79, -63, 125, |
|
111 |
123, -16, -120, -53, -98, 34, 86, -60, 94, 78, -91, -34, 0, -8, 73, -119, |
|
112 |
-87, 12, -101, -112, -10, -79, 10, 105, -82, 120, -106, -9, 99, 57, -63, |
|
113 |
-26, 125, -80, 102, -106, -11, -91, -1, 37, 33 |
|
114 |
}, |
|
115 |
}; |
|
116 |
} |
|
117 |
} |
src/info/guardianproject/trustedintents/ApkSignaturePin.java | ||
---|---|---|
1 |
|
|
2 |
package info.guardianproject.trustedintents; |
|
3 |
|
|
4 |
import android.content.pm.Signature; |
|
5 |
|
|
6 |
import java.math.BigInteger; |
|
7 |
import java.security.MessageDigest; |
|
8 |
import java.security.NoSuchAlgorithmException; |
|
9 |
import java.util.Arrays; |
|
10 |
|
|
11 |
public abstract class ApkSignaturePin { |
|
12 |
|
|
13 |
protected String[] fingerprints; // hex-encoded SHA-256 hashes of the certs |
|
14 |
protected byte[][] certificates; // array of DER-encoded X.509 certificates |
|
15 |
private Signature[] signatures; |
|
16 |
|
|
17 |
public Signature[] getSignatures() { |
|
18 |
if (signatures == null) { |
|
19 |
signatures = new Signature[certificates.length]; |
|
20 |
for (int i = 0; i < certificates.length; i++) |
|
21 |
signatures[i] = new Signature(certificates[i]); |
|
22 |
} |
|
23 |
return signatures; |
|
24 |
} |
|
25 |
|
|
26 |
/** |
|
27 |
* Gets the fingerprint of the first certificate in the signature. |
|
28 |
* |
|
29 |
* @param algorithm - Which hash to use (e.g. MD5, SHA1, SHA-256) |
|
30 |
* @return the fingerprint as hex String |
|
31 |
*/ |
|
32 |
public String getFingerprint(String algorithm) { |
|
33 |
try { |
|
34 |
MessageDigest md = MessageDigest.getInstance(algorithm); |
|
35 |
byte[] hashBytes = md.digest(certificates[0]); |
|
36 |
BigInteger bi = new BigInteger(1, hashBytes); |
|
37 |
md.reset(); |
|
38 |
return String.format("%0" + (hashBytes.length << 1) + "x", bi); |
|
39 |
} catch (NoSuchAlgorithmException e) { |
|
40 |
e.printStackTrace(); |
|
41 |
} |
|
42 |
return null; |
|
43 |
} |
|
44 |
|
|
45 |
/** |
|
46 |
* Gets the MD5 fingerprint of the first certificate in the signature. |
|
47 |
* |
|
48 |
* @return the MD5 sum as hex String |
|
49 |
*/ |
|
50 |
public String getMD5Fingerprint() { |
|
51 |
return getFingerprint("MD5"); |
|
52 |
} |
|
53 |
|
|
54 |
/** |
|
55 |
* Gets the SHA1 fingerprint of the first certificate in the signature. |
|
56 |
* |
|
57 |
* @return the SHA1 sum as hex String |
|
58 |
*/ |
|
59 |
public String getSHA1Fingerprint() { |
|
60 |
return getFingerprint("SHA1"); |
|
61 |
} |
|
62 |
|
|
63 |
/** |
|
64 |
* Gets the SHA-256 fingerprint of the first certificate in the signature. |
|
65 |
* |
|
66 |
* @return the SHA-256 sum as hex String |
|
67 |
*/ |
|
68 |
public String getSHA256Fingerprint() { |
|
69 |
return getFingerprint("SHA-256"); |
|
70 |
} |
|
71 |
|
|
72 |
/** |
|
73 |
* Compares the calculated SHA-256 cert fingerprint to the stored one. |
|
74 |
* |
|
75 |
* @return the result of the comparison |
|
76 |
*/ |
|
77 |
public boolean doFingerprintsMatchCertificates() { |
|
78 |
if (fingerprints == null || certificates == null) |
|
79 |
return false; |
|
80 |
String[] calcedFingerprints = new String[certificates.length]; |
|
81 |
for (int i = 0; i < calcedFingerprints.length; i++) |
|
82 |
calcedFingerprints[i] = getSHA256Fingerprint(); |
|
83 |
if (fingerprints.length == 0 || calcedFingerprints.length == 0) |
|
84 |
return false; |
|
85 |
return Arrays.equals(fingerprints, calcedFingerprints); |
|
86 |
} |
|
87 |
} |
src/info/guardianproject/trustedintents/TrustedIntents.java | ||
---|---|---|
1 |
|
|
2 |
package info.guardianproject.trustedintents; |
|
3 |
|
|
4 |
import android.app.Activity; |
|
5 |
import android.content.ActivityNotFoundException; |
|
6 |
import android.content.ComponentName; |
|
7 |
import android.content.Context; |
|
8 |
import android.content.Intent; |
|
9 |
import android.content.pm.ActivityInfo; |
|
10 |
import android.content.pm.PackageInfo; |
|
11 |
import android.content.pm.PackageManager; |
|
12 |
import android.content.pm.PackageManager.NameNotFoundException; |
|
13 |
import android.content.pm.ResolveInfo; |
|
14 |
import android.content.pm.Signature; |
|
15 |
import android.text.TextUtils; |
|
16 |
|
|
17 |
import java.lang.reflect.Constructor; |
|
18 |
import java.security.cert.CertificateException; |
|
19 |
import java.util.LinkedHashSet; |
|
20 |
|
|
21 |
public class TrustedIntents { |
|
22 |
|
|
23 |
private static TrustedIntents instance; |
|
24 |
|
|
25 |
private static PackageManager pm; |
|
26 |
|
|
27 |
private final LinkedHashSet<ApkSignaturePin> pinList; |
|
28 |
|
|
29 |
private TrustedIntents(Context context) { |
|
30 |
pm = context.getPackageManager(); |
|
31 |
this.pinList = new LinkedHashSet<ApkSignaturePin>(); |
|
32 |
} |
|
33 |
|
|
34 |
public static TrustedIntents get(Context context) { |
|
35 |
if (instance == null) |
|
36 |
instance = new TrustedIntents(context); |
|
37 |
return instance; |
|
38 |
} |
|
39 |
|
|
40 |
/** |
|
41 |
* Check whether a resolved {@link Activity} is trusted. |
|
42 |
* |
|
43 |
* @param resolveInfo the one to check |
|
44 |
* @return whether the {@code Intent}'s receiver is trusted |
|
45 |
*/ |
|
46 |
public boolean isReceiverTrusted(ResolveInfo resolveInfo) { |
|
47 |
return isPackageNameTrusted(resolveInfo.activityInfo.packageName); |
|
48 |
} |
|
49 |
|
|
50 |
/** |
|
51 |
* Check whether a resolved {@link Activity} is trusted. |
|
52 |
* |
|
53 |
* @param activityInfo the one to check |
|
54 |
* @return whether the {@code Intent}'s receiver is trusted |
|
55 |
*/ |
|
56 |
public boolean isReceiverTrusted(ActivityInfo activityInfo) { |
|
57 |
return isPackageNameTrusted(activityInfo.packageName); |
|
58 |
} |
|
59 |
|
|
60 |
/** |
|
61 |
* Check an {@link Intent} is trusted based on the {@code packageName} set |
|
62 |
* by {@link Intent#setPackage(String)} |
|
63 |
* |
|
64 |
* @param intent the one to check |
|
65 |
* @return whether the {@code Intent}'s receiver is trusted |
|
66 |
*/ |
|
67 |
public boolean isReceiverTrusted(Intent intent) { |
|
68 |
if (!isIntentSane(intent)) |
|
69 |
return false; |
|
70 |
String packageName = intent.getPackage(); |
|
71 |
if (TextUtils.isEmpty(packageName)) { |
|
72 |
packageName = intent.getComponent().getPackageName(); |
|
73 |
} |
|
74 |
return isPackageNameTrusted(packageName); |
|
75 |
} |
|
76 |
|
|
77 |
/** |
|
78 |
* Check whether a {@code packageName} is trusted. |
|
79 |
* |
|
80 |
* @param packageName the one to check |
|
81 |
* @return whether the {@code packageName} is trusted |
|
82 |
*/ |
|
83 |
public boolean isPackageNameTrusted(String packageName) { |
|
84 |
try { |
|
85 |
checkTrustedSigner(packageName); |
|
86 |
} catch (NameNotFoundException e) { |
|
87 |
e.printStackTrace(); |
|
88 |
return false; |
|
89 |
} catch (CertificateException e) { |
|
90 |
return false; |
|
91 |
} |
|
92 |
return true; |
|
93 |
} |
|
94 |
|
|
95 |
public Intent getIntentFromTrustedSender(Activity activity) |
|
96 |
throws NameNotFoundException, CertificateException { |
|
97 |
Intent intent = activity.getIntent(); |
|
98 |
if (!isIntentSane(intent)) |
|
99 |
throw new NameNotFoundException( |
|
100 |
"Intent incomplete or was sent using startActivity() instead of startActivityWithResult()"); |
|
101 |
String packageName = intent.getPackage(); |
|
102 |
if (TextUtils.isEmpty(packageName)) { |
|
103 |
packageName = intent.getComponent().getPackageName(); |
|
104 |
} |
|
105 |
if (TextUtils.isEmpty(packageName)) |
|
106 |
throw new NameNotFoundException(packageName); |
|
107 |
checkTrustedSigner(packageName); |
|
108 |
return intent; |
|
109 |
} |
|
110 |
|
|
111 |
private boolean isIntentSane(Intent intent) { |
|
112 |
if (intent == null) |
|
113 |
return false; |
|
114 |
if (TextUtils.isEmpty(intent.getPackage())) { |
|
115 |
ComponentName componentName = intent.getComponent(); |
|
116 |
if (componentName == null || TextUtils.isEmpty(componentName.getPackageName())) { |
|
117 |
return false; |
|
118 |
} |
|
119 |
} |
|
120 |
return true; |
|
121 |
} |
|
122 |
|
|
123 |
/** |
|
124 |
* Add an APK signature that is always trusted for any packageName. |
|
125 |
* |
|
126 |
* @param cls {@link Class} of the {@link ApkSignaturePin} to trust |
|
127 |
* @return boolean |
|
128 |
* @throws {@link IllegalArgumentException} the class cannot be instantiated |
|
129 |
*/ |
|
130 |
public boolean addTrustedSigner(Class<? extends ApkSignaturePin> cls) { |
|
131 |
try { |
|
132 |
Constructor<? extends ApkSignaturePin> constructor = cls.getConstructor(); |
|
133 |
return pinList.add((ApkSignaturePin) constructor.newInstance((Object[]) null)); |
|
134 |
} catch (Exception e) { |
|
135 |
e.printStackTrace(); |
|
136 |
throw new IllegalArgumentException(e); |
|
137 |
} |
|
138 |
} |
|
139 |
|
|
140 |
/** |
|
141 |
* Remove an APK signature from the trusted set. |
|
142 |
* |
|
143 |
* @param cls {@link Class} of the {@link ApkSignaturePin} to remove |
|
144 |
*/ |
|
145 |
public boolean removeTrustedSigner(Class<? extends ApkSignaturePin> cls) { |
|
146 |
for (ApkSignaturePin pin : pinList) { |
|
147 |
if (pin.getClass().equals(cls)) { |
|
148 |
return pinList.remove(pin); |
|
149 |
} |
|
150 |
} |
|
151 |
return false; |
|
152 |
} |
|
153 |
|
|
154 |
/** |
|
155 |
* Remove all {@link ApkSignaturePin}s from the trusted set. |
|
156 |
*/ |
|
157 |
public boolean removeAllTrustedSigners() { |
|
158 |
pinList.clear(); |
|
159 |
return pinList.isEmpty(); |
|
160 |
} |
|
161 |
|
|
162 |
/** |
|
163 |
* Check if a {@link ApkSignaturePin} is trusted. |
|
164 |
* |
|
165 |
* @param cls {@link Class} of the {@link ApkSignaturePin} to check |
|
166 |
*/ |
|
167 |
public boolean isTrustedSigner(Class<? extends ApkSignaturePin> cls) { |
|
168 |
for (ApkSignaturePin pin : pinList) { |
|
169 |
if (pin.getClass().equals(cls)) { |
|
170 |
return true; |
|
171 |
} |
|
172 |
} |
|
173 |
return false; |
|
174 |
} |
|
175 |
|
|
176 |
public void checkTrustedSigner(String packageName) |
|
177 |
throws NameNotFoundException, CertificateException { |
|
178 |
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); |
|
179 |
checkTrustedSigner(packageInfo.signatures); |
|
180 |
} |
|
181 |
|
|
182 |
public void checkTrustedSigner(PackageInfo packageInfo) |
|
183 |
throws NameNotFoundException, CertificateException { |
|
184 |
checkTrustedSigner(packageInfo.signatures); |
|
185 |
} |
|
186 |
|
|
187 |
public void checkTrustedSigner(Signature[] signatures) |
|
188 |
throws NameNotFoundException, CertificateException { |
|
189 |
if (signatures == null || signatures.length == 0) |
|
190 |
throw new CertificateException("signatures cannot be null or empty!"); |
|
191 |
for (int i = 0; i < signatures.length; i++) |
|
192 |
if (signatures[i] == null || signatures[i].toByteArray().length == 0) |
|
193 |
throw new CertificateException("Certificates cannot be null or empty!"); |
|
194 |
|
|
195 |
// check whether the APK signer is trusted for all apps |
|
196 |
for (ApkSignaturePin pin : pinList) |
|
197 |
if (areSignaturesEqual(signatures, pin.getSignatures())) |
|
198 |
return; // found a matching trusted APK signer |
|
199 |
|
|
200 |
throw new CertificateException("APK signatures did not match!"); |
|
201 |
} |
|
202 |
|
|
203 |
public boolean areSignaturesEqual(Signature[] sigs0, Signature[] sigs1) { |
|
204 |
// TODO where is Android's implementation of this that I can just call? |
|
205 |
if (sigs0 == null || sigs1 == null) |
|
206 |
return false; |
|
207 |
if (sigs0.length == 0 || sigs1.length == 0) |
|
208 |
return false; |
|
209 |
if (sigs0.length != sigs1.length) |
|
210 |
return false; |
|
211 |
for (int i = 0; i < sigs0.length; i++) |
|
212 |
if (!sigs0[i].equals(sigs1[i])) |
|
213 |
return false; |
|
214 |
return true; |
|
215 |
} |
|
216 |
|
|
217 |
public void startActivity(Context context, Intent intent) throws CertificateException { |
|
218 |
if (!isIntentSane(intent)) |
|
219 |
throw new ActivityNotFoundException("The intent was null or empty!"); |
|
220 |
String packageName = intent.getPackage(); |
|
221 |
if (TextUtils.isEmpty(packageName)) { |
|
222 |
packageName = intent.getComponent().getPackageName(); |
|
223 |
intent.setPackage(packageName); |
|
224 |
} |
|
225 |
try { |
|
226 |
checkTrustedSigner(packageName); |
|
227 |
} catch (NameNotFoundException e) { |
|
228 |
e.printStackTrace(); |
|
229 |
throw new ActivityNotFoundException(e.getLocalizedMessage()); |
|
230 |
} |
|
231 |
context.startActivity(intent); |
|
232 |
} |
|
233 |
} |
src/org/iilab/IilabEngineeringRSA2048Pin.java | ||
---|---|---|
1 |
|
|
2 |
package org.iilab; |
|
3 |
|
|
4 |
import info.guardianproject.trustedintents.ApkSignaturePin; |
|
5 |
|
|
6 |
public final class IilabEngineeringRSA2048Pin extends ApkSignaturePin { |
|
7 |
|
|
8 |
public IilabEngineeringRSA2048Pin() { |
|
9 |
fingerprints = new String[] { |
|
10 |
"0cac98293ad7814abe161c47dc674c83618e63bae08bd4191bf4927d83fd1ae2", |
|
11 |
}; |
|
12 |
certificates = new byte[][] { |
|
13 |
{ |
|
14 |
48, -126, 3, 105, 48, -126, 2, 81, -96, 3, 2, 1, 2, 2, 4, 58, 60, 86, 4, |
|
15 |
48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 11, 5, 0, 48, 101, 49, 11, |
|
16 |
48, 9, 6, 3, 85, 4, 6, 19, 2, 68, 69, 49, 15, 48, 13, 6, 3, 85, 4, 8, 19, |
|
17 |
6, 66, 101, 114, 108, 105, 110, 49, 15, 48, 13, 6, 3, 85, 4, 7, 19, 6, 66, |
|
18 |
101, 114, 108, 105, 110, 49, 14, 48, 12, 6, 3, 85, 4, 10, 19, 5, 105, 105, |
|
19 |
108, 97, 98, 49, 20, 48, 18, 6, 3, 85, 4, 11, 19, 11, 69, 110, 103, 105, |
|
20 |
110, 101, 101, 114, 105, 110, 103, 49, 14, 48, 12, 6, 3, 85, 4, 3, 19, 5, |
|
21 |
105, 105, 108, 97, 98, 48, 30, 23, 13, 49, 52, 48, 54, 49, 49, 48, 57, 49, |
|
22 |
53, 49, 51, 90, 23, 13, 52, 49, 49, 48, 50, 55, 48, 57, 49, 53, 49, 51, |
|
23 |
90, 48, 101, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 68, 69, 49, 15, 48, 13, |
|
24 |
6, 3, 85, 4, 8, 19, 6, 66, 101, 114, 108, 105, 110, 49, 15, 48, 13, 6, 3, |
|
25 |
85, 4, 7, 19, 6, 66, 101, 114, 108, 105, 110, 49, 14, 48, 12, 6, 3, 85, 4, |
|
26 |
10, 19, 5, 105, 105, 108, 97, 98, 49, 20, 48, 18, 6, 3, 85, 4, 11, 19, 11, |
|
27 |
69, 110, 103, 105, 110, 101, 101, 114, 105, 110, 103, 49, 14, 48, 12, 6, |
|
28 |
3, 85, 4, 3, 19, 5, 105, 105, 108, 97, 98, 48, -126, 1, 34, 48, 13, 6, 9, |
|
29 |
42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -126, 1, 15, 0, 48, -126, 1, |
|
30 |
10, 2, -126, 1, 1, 0, -83, -104, -37, 113, -104, 93, -125, -22, 99, -89, |
|
31 |
97, 119, -113, -112, 112, -127, 63, 8, 77, -70, -58, 124, -33, -71, -82, |
|
32 |
-45, -72, 97, -18, -85, -122, 111, 22, -24, 95, -97, -42, 24, 121, -116, |
|
33 |
23, -19, 115, 91, -67, 96, -117, 18, 48, -7, -92, -5, 97, -75, -64, 6, -71, |
|
34 |
81, 7, -80, -51, 26, -47, 46, -19, 119, -51, 35, -120, -14, -1, -125, 2, |
|
35 |
-117, 66, 109, 19, -18, 61, 28, -65, 42, -116, 63, -81, 2, 56, -22, -91, |
|
36 |
104, 45, -47, -20, 120, 64, -127, 10, -104, 46, -41, -43, 68, 27, -10, |
|
37 |
-110, -48, -3, 101, -66, -67, -58, 49, -27, 75, -69, 74, -32, 38, -4, -98, |
|
38 |
58, 79, 94, -57, -121, -64, 53, -53, 22, -25, 97, 41, 105, 94, -119, 12, 1, |
|
39 |
100, -94, -81, 103, 68, 42, -127, 117, 86, 52, -21, 58, -54, 93, 65, -18, |
|
40 |
-47, 30, -121, 109, -17, 2, 117, -106, 116, -98, -32, 39, 26, -96, 56, -16, |
|
41 |
-124, 6, 75, -101, -122, 126, -17, -21, 42, -53, 70, 57, 84, -111, 3, -34, |
|
42 |
110, -99, -60, 31, 79, 67, -58, -89, -102, -7, -40, 62, 56, 102, 98, 112, |
|
43 |
107, -1, 82, -127, 32, -125, 43, -78, -44, 4, 111, -112, -46, 67, -2, 106, |
|
44 |
-32, 118, 19, -93, -68, 50, -103, 111, -128, -1, 96, 30, 49, -97, -94, 88, |
|
45 |
73, 117, -78, -89, 110, -90, 52, 69, 86, -1, 74, -57, 44, -78, 115, -34, |
|
46 |
-60, 86, -24, -114, 41, -118, 101, 2, 3, 1, 0, 1, -93, 33, 48, 31, 48, 29, |
|
47 |
6, 3, 85, 29, 14, 4, 22, 4, 20, -23, 8, 8, -50, -119, 109, -22, -102, -122, |
|
48 |
-41, 65, -37, -126, 103, -85, 113, 113, 75, 28, -12, 48, 13, 6, 9, 42, -122, |
|
49 |
72, -122, -9, 13, 1, 1, 11, 5, 0, 3, -126, 1, 1, 0, 94, -121, -98, 98, 99, |
|
50 |
-40, -99, -81, 63, -76, -74, 67, 4, 8, 69, -114, 113, -22, -44, 9, 44, 103, |
|
51 |
79, 50, 36, -81, 26, -83, 90, -103, 16, 21, -93, 103, -37, -93, -72, -112, |
|
52 |
85, 80, -39, -12, -75, 45, -102, 29, 63, 97, 108, -15, 13, -65, -127, 124, |
|
53 |
89, -84, 84, -119, 119, -76, 126, 39, -4, 26, 41, 87, -32, -119, -94, -107, |
|
54 |
-25, 113, 106, -115, -80, 75, 71, -9, 28, 113, 21, 76, 17, -119, -103, -24, |
|
55 |
18, 53, 78, -6, -72, -84, -103, 35, 24, -112, -19, -31, -4, -95, 76, -97, |
|
56 |
55, -52, -93, 42, 77, -23, 99, 10, -70, 106, 72, -112, -93, 94, -44, 13, |
|
57 |
-117, 104, 99, 51, -92, 31, -117, -106, 109, 119, -39, 111, 105, -126, -9, |
|
58 |
-113, 88, 87, -37, -78, 7, -10, -110, -39, -43, 10, -108, 52, -109, 82, 34, |
|
59 |
-45, -28, 70, -29, -119, -28, -5, -121, 98, 124, -71, 65, 24, 33, -30, -111, |
|
60 |
-9, -68, -10, -18, 118, 80, -94, -104, -5, -88, 50, -97, 118, -54, 107, 125, |
|
61 |
-67, 95, -114, -11, -126, 98, -44, 21, 77, -43, 24, 109, -118, 64, 28, 6, |
|
62 |
64, 39, -109, -28, -45, -86, 113, -49, 115, 23, -46, 4, 91, -58, 118, 75, |
|
63 |
105, 47, 76, -70, -56, -111, 54, -121, 34, 29, 35, 86, -104, -31, 16, -20, |
|
64 |
-30, -99, -4, -84, 123, 98, 1, -48, 24, 91, -63, -47, -40, 5, 10, -67, 2, |
|
65 |
126, -9, -126, -80, 77, -59, -103, 6, -43, 32 |
|
66 |
}, |
|
67 |
}; |
|
68 |
} |
|
69 |
} |
src/org/torproject/TorProjectRSA1024.java | ||
---|---|---|
1 |
|
|
2 |
package org.torproject; |
|
3 |
|
|
4 |
import info.guardianproject.trustedintents.ApkSignaturePin; |
|
5 |
|
|
6 |
/** |
|
7 |
* This is the Tor Project APK signing key. It is used to sign these apps: |
|
8 |
* <ul> |
|
9 |
* <li>Orbot</li> |
|
10 |
* </ul> |
|
11 |
* |
|
12 |
* @author hans |
|
13 |
*/ |
|
14 |
public final class TorProjectRSA1024 extends ApkSignaturePin { |
|
15 |
|
|
16 |
public TorProjectRSA1024() { |
|
17 |
fingerprints = new String[] { |
|
18 |
"a454b87a1847a89ed7f5e70fba6bba96f3ef29c26e0981204fe347bf231dfd5b", |
|
19 |
}; |
|
20 |
certificates = new byte[][] { |
|
21 |
{ |
|
22 |
48, -126, 2, 97, 48, -126, 1, -54, -96, 3, 2, 1, 2, 2, 4, 75, -125, 84, 0, |
|
23 |
48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 5, 5, 0, 48, 117, 49, 11, |
|
24 |
48, 9, 6, 3, 85, 4, 6, 19, 2, 85, 83, 49, 11, 48, 9, 6, 3, 85, 4, 8, 19, 2, |
|
25 |
78, 89, 49, 17, 48, 15, 6, 3, 85, 4, 7, 19, 8, 78, 101, 119, 32, 89, 111, |
|
26 |
114, 107, 49, 23, 48, 21, 6, 3, 85, 4, 10, 19, 14, 84, 111, 114, 80, 114, |
|
27 |
111, 106, 101, 99, 116, 46, 111, 114, 103, 49, 23, 48, 21, 6, 3, 85, 4, 11, |
|
28 |
19, 14, 84, 111, 114, 80, 114, 111, 106, 101, 99, 116, 46, 111, 114, 103, |
|
29 |
49, 20, 48, 18, 6, 3, 85, 4, 3, 19, 11, 84, 111, 114, 32, 80, 114, 111, |
|
30 |
106, 101, 99, 116, 48, 30, 23, 13, 49, 48, 48, 50, 50, 51, 48, 52, 48, 53, |
|
31 |
50, 48, 90, 23, 13, 51, 55, 48, 55, 49, 49, 48, 52, 48, 53, 50, 48, 90, 48, |
|
32 |
117, 49, 11, 48, 9, 6, 3, 85, 4, 6, 19, 2, 85, 83, 49, 11, 48, 9, 6, 3, 85, |
|
33 |
4, 8, 19, 2, 78, 89, 49, 17, 48, 15, 6, 3, 85, 4, 7, 19, 8, 78, 101, 119, |
|
34 |
32, 89, 111, 114, 107, 49, 23, 48, 21, 6, 3, 85, 4, 10, 19, 14, 84, 111, |
|
35 |
114, 80, 114, 111, 106, 101, 99, 116, 46, 111, 114, 103, 49, 23, 48, 21, 6, |
|
36 |
3, 85, 4, 11, 19, 14, 84, 111, 114, 80, 114, 111, 106, 101, 99, 116, 46, |
|
37 |
111, 114, 103, 49, 20, 48, 18, 6, 3, 85, 4, 3, 19, 11, 84, 111, 114, 32, |
|
38 |
80, 114, 111, 106, 101, 99, 116, 48, -127, -97, 48, 13, 6, 9, 42, -122, 72, |
|
39 |
-122, -9, 13, 1, 1, 1, 5, 0, 3, -127, -115, 0, 48, -127, -119, 2, -127, |
|
40 |
-127, 0, -72, 51, -28, 71, -108, 15, -74, 108, -72, 2, 69, -127, -86, -38, |
|
41 |
89, 110, -68, -105, 74, 3, 127, 13, -55, 60, -115, 104, 120, 31, -111, 44, |
|
42 |
34, -46, -32, 21, 62, 40, -127, 51, -128, -57, 110, 89, 121, -100, 122, 96, |
|
43 |
-8, -35, -2, -128, 85, -79, 124, 74, -26, 121, -51, -14, 60, 61, 23, -102, |
|
44 |
119, 25, 112, -109, 97, 51, 15, -67, -62, 108, -77, 42, 6, 12, -75, -66, |
|
45 |
76, 99, 80, 27, 78, 17, -86, 31, 11, 126, -102, -113, -46, 95, -85, -91, |
|
46 |
-111, -118, -42, 83, -15, -62, 5, 97, 7, -102, 12, -34, 50, 28, 40, 93, 57, |
|
47 |
111, 16, -39, -33, 14, 115, -78, 81, -13, 111, -33, -86, 127, 124, -60, |
|
48 |
-20, -31, 2, 3, 1, 0, 1, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 5, |
|
49 |
5, 0, 3, -127, -127, 0, 11, -111, 99, 127, -23, -63, -88, -96, -91, -3, 5, |
|
50 |
-94, 100, 61, 1, -56, -98, -44, -121, -31, -45, 13, 110, 107, 126, -71, 58, |
|
51 |
109, 122, 38, -75, 84, -37, 49, 5, 121, -99, 10, -12, -120, -111, 37, -49, |
|
52 |
67, -74, 90, 100, 63, 125, -94, 21, 83, 70, 57, -14, -116, -69, 46, -27, |
|
53 |
89, 49, 79, 6, 115, 76, -112, -4, 15, 61, 55, -102, 41, -78, -116, 13, 59, |
|
54 |
93, -120, -119, -72, -45, -55, -66, -59, 52, 25, -68, 120, 36, 117, -111, |
|
55 |
98, -55, -106, 37, 121, 123, 77, 28, 36, -111, 45, -94, -26, 121, -127, |
|
56 |
-26, 70, 67, 112, 116, 106, 0, -32, -27, 112, 90, 97, 42, -83, 27, -102, |
|
57 |
-118, 70, 58, -112, 22, -47 |
|
58 |
}, |
|
59 |
}; |
|
60 |
} |
|
61 |
} |
test/ant.properties | ||
---|---|---|
15 | 15 |
# 'key.alias' for the name of the key to use. |
16 | 16 |
# The password will be asked during the build when you use the 'release' target. |
17 | 17 |
|
18 |
tested.project.dir=.. |
|
18 |
tested.project.dir=../trustedintents
|
|
19 | 19 |
test.runner=com.zutubi.android.junitreport.JUnitReportTestRunner |
trustedintents.pom | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" |
|
3 |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> |
|
4 |
<modelVersion>4.0.0</modelVersion> |
|
5 |
<groupId>info.guardianproject.trustedintents</groupId> |
|
6 |
<artifactId>trustedintents</artifactId> |
|
7 |
<version>0.0</version> |
|
8 |
<name>TrustedIntents</name> |
|
9 |
<url>https://guardianproject.info/code/trustedintents</url> |
|
10 |
<description>TrustedIntents is a library for flexible trusted interactions between Android apps. It is modeled after Android's `signature` protection level for permissions. The key difference is that the framework allows the trusted signature to be set, rather than requiring to match the current app's signature.</description> |
|
11 |
<licenses> |
|
12 |
<license> |
|
13 |
<name>LGPLv2.1</name> |
|
14 |
<url>https://github.com/guardianproject/TrustedIntents/blob/master/LICENSE.txt</url> |
|
15 |
</license> |
|
16 |
</licenses> |
|
17 |
<developers> |
|
18 |
<developer> |
|
19 |
<id>guardianproject</id> |
|
20 |
<name>Guardian Project</name> |
|
21 |
<email>support@guardianproject.info</email> |
|
22 |
</developer> |
|
23 |
</developers> |
|
24 |
<issueManagement> |
|
25 |
<url>https://dev.guardianproject.info/projects/trustedintents/issues</url> |
|
26 |
<system>Redmine</system> |
|
27 |
</issueManagement> |
|
28 |
<scm> |
|
29 |
<connection>scm:https://github.com/guardianproject/TrustedIntents.git</connection> |
|
30 |
<developerConnection>scm:git@github.com:guardianproject/TrustedIntents.git</developerConnection> |
|
31 |
<url>scm:https://github.com/guardianproject/TrustedIntents</url> |
|
32 |
</scm> |
|
33 |
</project> |
trustedintents/AndroidManifest.xml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8"?> |
|
2 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" |
|
3 |
package="info.guardianproject.trustedintents" |
|
4 |
android:versionCode="0" |
|
5 |
android:versionName="0.0" > |
|
6 |
|
|
7 |
<uses-sdk android:minSdkVersion="7" /> |
|
8 |
|
|
9 |
</manifest> |
trustedintents/build.gradle | ||
---|---|---|
1 |
apply plugin: 'com.android.library' |
|
2 |
|
|
3 |
android { |
|
4 |
compileSdkVersion 21 |
|
5 |
buildToolsVersion "21.1.2" |
|
6 |
|
|
7 |
sourceSets.main { |
|
8 |
manifest.srcFile 'AndroidManifest.xml' |
|
9 |
java.srcDirs = ['src'] |
|
10 |
resources.srcDirs = ['src'] |
|
11 |
aidl.srcDirs = ['src'] |
|
12 |
renderscript.srcDirs = ['src'] |
|
13 |
res.srcDirs = ['res'] |
|
14 |
assets.srcDirs = ['assets'] |
|
15 |
} |
|
16 |
} |
|
17 |
|
|
18 |
dependencies { |
|
19 |
compile fileTree(dir: 'libs', include: ['*.jar']) |
|
20 |
} |
|
21 |
|
|
22 |
task jar(type: Jar) { |
|
23 |
from android.sourceSets.main.java.srcDirs |
|
24 |
} |
trustedintents/custom_rules.xml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="UTF-8"?> |
|
2 |
<project name="custom_rules"> |
|
3 |
|
|
4 |
<property name="name" value="trustedintents" /> |
|
5 |
|
|
6 |
<target name="-getgitdetails" > |
|
7 |
<exec executable="git" outputproperty="git.describe"> |
|
8 |
<arg value="describe"/> |
|
9 |
</exec> |
|
10 |
<exec executable="git" outputproperty="git.revision"> |
|
11 |
<arg value="rev-parse"/> |
|
12 |
<arg value="HEAD"/> |
|
13 |
</exec> |
|
14 |
<property name="jar.name" value="${name}-${git.describe}" /> |
|
15 |
<property name="javadoc.jar" value="${jar.name}-javadoc.jar" /> |
|
16 |
<property name="source.jar" value="${jar.name}-source.jar" /> |
|
17 |
<property name="pom" value="${jar.name}-source.jar" /> |
|
18 |
</target> |
|
19 |
|
|
20 |
<target name="-pre-clean" depends="-getgitdetails"> |
|
21 |
<property name="delete.pattern" value="${jar.name}*.jar*" /> |
|
22 |
<echo message="deleting ${delete.pattern}" /> |
|
23 |
<delete failonerror="false"> |
|
24 |
<fileset dir="." includes="${delete.pattern}" /> |
|
25 |
</delete> |
|
26 |
</target> |
|
27 |
|
|
28 |
<target name="-create-manifest"> |
|
29 |
<echo message="Creating custom MANIFEST.MF" /> |
|
30 |
<manifest file="MANIFEST.MF"> |
|
31 |
<attribute name="Extension-Name" value="info.guardianproject.${name}"/> |
|
32 |
<attribute name="Implementation-Vendor" value="Guardian Project"/> |
|
33 |
<attribute name="Implementation-Title" value="TrustedIntents"/> |
|
34 |
<attribute name="Implementation-URL" value="https://dev.guardianproject.info/projects/${name}"/> |
|
35 |
<attribute name="Implementation-Git-URL" value="https://github.com/guardianproject/${name}"/> |
|
36 |
</manifest> |
|
37 |
<replaceregexp file="MANIFEST.MF" |
|
38 |
match="\nCreated-By:.*?\n" |
|
39 |
replace="" |
|
40 |
flags="m"/> |
|
41 |
</target> |
|
42 |
|
|
43 |
<target name="-pre-build" depends="-getgitdetails,-create-manifest"> |
|
44 |
<echo message="running" /> |
|
45 |
</target> |
|
46 |
|
|
47 |
<target name="javadoc" description="Generate Javadocs" depends="-pre-build"> |
|
48 |
<property name="javadoc.dir" value="${out.dir}/javadoc" /> |
|
49 |
<javadoc sourcepath="${source.dir}" |
|
50 |
classpath="${toString:project.all.jars.path}:${toString:project.target.class.path}" |
|
51 |
destdir="${javadoc.dir}" |
|
52 |
packagenames="info.guardianproject.*" |
|
53 |
additionalparam="-notimestamp" |
|
54 |
windowtitle="${ant.project.name}" |
|
55 |
linkoffline="https://developer.android.com/reference ${sdk.dir}/docs/reference" |
|
56 |
linksource="true" |
|
57 |
doctitle="${ant.project.name}" /> |
|
58 |
<jar destfile="${javadoc.jar}" |
|
59 |
manifest="MANIFEST.MF" |
|
60 |
basedir="${javadoc.dir}"> |
|
61 |
</jar> |
|
62 |
<delete file="${javadoc.jar}.asc"/> |
|
63 |
<exec executable="gpg" failonerror="false"> |
|
64 |
<arg value="--armor" /> |
|
65 |
<arg value="--detach-sign" /> |
|
66 |
<arg value="${javadoc.jar}" /> |
|
67 |
</exec> |
|
68 |
</target> |
|
69 |
|
|
70 |
<target name="source" description="Generate Javadocs" depends="-build-setup,-getgitdetails"> |
|
71 |
|
|
72 |
<jar destfile="${source.jar}" |
|
73 |
manifest="MANIFEST.MF" |
|
74 |
includes="info/**" |
|
75 |
basedir="${source.dir}"> |
|
76 |
</jar> |
|
77 |
<delete file="${source.jar}.asc"/> |
|
78 |
<exec executable="gpg" failonerror="false"> |
|
79 |
<arg value="--armor" /> |
|
80 |
<arg value="--detach-sign" /> |
|
81 |
<arg value="${source.jar}" /> |
|
82 |
</exec> |
|
83 |
</target> |
|
84 |
|
|
85 |
<target name="pom" description="Generate maven .pom" depends="-build-setup,-getgitdetails"> |
|
86 |
<property name="pom.file" value="${jar.name}.pom" /> |
|
87 |
<copy file="${name}.pom" tofile="${pom.file}" /> |
|
88 |
<replaceregexp file="${pom.file}" |
|
89 |
match="<version>.*</version>" |
|
90 |
replace="<version>${git.describe}</version>" |
|
91 |
byline="true" /> |
|
92 |
|
|
93 |
<delete file="${pom.file}.asc" /> |
|
94 |
<exec executable="gpg" failonerror="false"> |
|
95 |
<arg value="--armor" /> |
|
96 |
<arg value="--detach-sign" /> |
|
97 |
<arg value="${pom.file}" /> |
|
98 |
</exec> |
|
99 |
</target> |
|
100 |
|
|
101 |
<target name="-post-build" depends="-getgitdetails"> |
|
102 |
<condition property="build.is.debug" value="true" else="false"> |
|
103 |
<equals arg1="${build.target}" arg2="debug" /> |
|
104 |
</condition> |
|
105 |
<if condition="${build.is.debug}"> |
|
106 |
<then> |
|
107 |
<property name="release.jar" value="${jar.name}-debug.jar" /> |
|
108 |
</then> |
|
109 |
<else> |
|
110 |
<property name="release.jar" value="${jar.name}.jar" /> |
|
111 |
</else> |
|
112 |
</if> |
|
113 |
<property file="${sdk.dir}/tools/source.properties" /> |
|
114 |
<delete file="${release.jar}"/> |
|
115 |
<jar destfile="${release.jar}" |
|
116 |
manifest="MANIFEST.MF" |
|
117 |
includes="**" |
|
118 |
excludes="info/guardianproject/trustedintents/BuildConfig.*" |
|
119 |
basedir="${out.classes.absolute.dir}"> |
|
120 |
</jar> |
|
121 |
<if condition="${build.is.debug}"> |
|
122 |
<else> |
|
123 |
<delete file="${release.jar}.asc"/> |
|
124 |
<exec executable="gpg" failonerror="false"> |
|
125 |
<arg value="--armor" /> |
|
126 |
<arg value="--detach-sign" /> |
|
127 |
<arg value="${release.jar}" /> |
|
128 |
</exec> |
|
129 |
</else> |
|
130 |
</if> |
|
131 |
</target> |
|
132 |
|
|
133 |
<target name="release-all" depends="clean,release,javadoc,source,pom" /> |
|
134 |
|
|
135 |
</project> |
trustedintents/project.properties | ||
---|---|---|
1 |
target=android-19 |
|
2 |
android.library=true |
trustedintents/setup-ant | ||
---|---|---|
1 |
#!/bin/sh |
|
2 |
|
|
3 |
set -e |
|
4 |
set -x |
|
5 |
|
|
6 |
if ! which android > /dev/null; then |
|
7 |
if [ -z $ANDROID_HOME ]; then |
|
8 |
if [ -e ~/.android/bashrc ]; then |
|
9 |
. ~/.android/bashrc |
|
10 |
else |
|
11 |
echo "'android' not found, ANDROID_HOME must be set!" |
|
12 |
exit |
|
13 |
fi |
|
14 |
else |
|
15 |
export PATH="${ANDROID_HOME}/tools:$PATH" |
|
16 |
fi |
|
17 |
fi |
|
18 |
|
|
19 |
# fetch target from project.properties |
|
20 |
eval `grep '^target=' project.properties` |
|
21 |
|
|
22 |
CURDIR=`pwd` |
|
23 |
|
|
24 |
android update lib-project --path ${CURDIR} --target $target |
|
25 |
android update test-project --path ${CURDIR}/../test --main ${CURDIR} |
trustedintents/src/info/guardianproject/GuardianProjectRSA1024.java | ||
---|---|---|
1 |
|
|
2 |
package info.guardianproject; |
|
3 |
|
|
4 |
import info.guardianproject.trustedintents.ApkSignaturePin; |
|
5 |
|
|
6 |
/** |
|
7 |
* This is the original Guardian Project APK signing key. No new apps will be |
|
8 |
* signed by this key, it is considered deprecated since RSA 1024-bit keys are |
|
9 |
* deprecated. It is used to sign these apps: |
|
10 |
* <ul> |
|
11 |
* <li>CACertMan</li> |
|
12 |
* <li>ChatSecure</li> |
|
13 |
* <li>Gnu Privacy Guard</li> |
|
14 |
* <li>Lil' Debi</li> |
|
15 |
* <li>NoteCipher</li> |
|
16 |
* <li>ObscuraCam</li> |
|
17 |
* <li>Orweb</li> |
|
18 |
* <li>PixelKnot</li> |
|
19 |
* <li>StoryMaker</li> |
|
20 |
* </ul> |
|
21 |
* |
|
22 |
* @author hans |
|
23 |
*/ |
|
24 |
public final class GuardianProjectRSA1024 extends ApkSignaturePin { |
Also available in: Unified diff