Revision cba1dc86

View differences:

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="&lt;version&gt;.*&lt;/version&gt;"
90
                   replace="&lt;version&gt;${git.describe}&lt;/version&gt;"
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="&lt;version&gt;.*&lt;/version&gt;"
90
                   replace="&lt;version&gt;${git.describe}&lt;/version&gt;"
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 {
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff