Revision e1eeda86
src/info/guardianproject/checkey/MainActivity.java | ||
---|---|---|
5 | 5 |
import android.app.Activity; |
6 | 6 |
import android.content.Context; |
7 | 7 |
import android.content.Intent; |
8 |
import android.content.pm.PackageInfo; |
|
9 |
import android.content.pm.PackageManager; |
|
10 |
import android.content.pm.PackageManager.NameNotFoundException; |
|
11 | 8 |
import android.net.Uri; |
12 | 9 |
import android.os.Bundle; |
13 | 10 |
import android.support.v4.app.ListFragment; |
... | ... | |
24 | 21 |
import android.widget.TextView; |
25 | 22 |
import android.widget.Toast; |
26 | 23 |
|
27 |
import java.io.ByteArrayInputStream; |
|
28 | 24 |
import java.io.FileNotFoundException; |
29 | 25 |
import java.io.FileOutputStream; |
30 | 26 |
import java.io.IOException; |
31 |
import java.io.InputStream; |
|
32 | 27 |
import java.io.StringBufferInputStream; |
33 | 28 |
import java.io.UnsupportedEncodingException; |
34 | 29 |
import java.security.NoSuchAlgorithmException; |
30 |
import java.security.PublicKey; |
|
35 | 31 |
import java.security.cert.CertificateException; |
36 |
import java.security.cert.CertificateFactory; |
|
37 | 32 |
import java.security.cert.X509Certificate; |
33 |
import java.security.interfaces.RSAPublicKey; |
|
38 | 34 |
import java.util.Arrays; |
39 | 35 |
import java.util.List; |
40 | 36 |
import java.util.Properties; |
... | ... | |
42 | 38 |
public class MainActivity extends ActionBarActivity { |
43 | 39 |
private final String TAG = "MainActivity"; |
44 | 40 |
|
45 |
private static PackageManager pm; |
|
46 |
private static CertificateFactory certificateFactory; |
|
47 | 41 |
private static int selectedItem = -1; |
48 | 42 |
private AppListFragment appListFragment = null; |
49 | 43 |
|
... | ... | |
102 | 96 |
return super.onOptionsItemSelected(item); |
103 | 97 |
} |
104 | 98 |
|
105 |
private static X509Certificate[] getX509Certificates(Context context, String packageName) { |
|
106 |
X509Certificate[] certs = null; |
|
107 |
if (pm == null) |
|
108 |
pm = context.getApplicationContext().getPackageManager(); |
|
109 |
try { |
|
110 |
PackageInfo pkgInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); |
|
111 |
if (certificateFactory == null) |
|
112 |
certificateFactory = CertificateFactory.getInstance("X509"); |
|
113 |
certs = new X509Certificate[pkgInfo.signatures.length]; |
|
114 |
for (int i = 0; i < certs.length; i++) { |
|
115 |
byte[] cert = pkgInfo.signatures[i].toByteArray(); |
|
116 |
InputStream inStream = new ByteArrayInputStream(cert); |
|
117 |
certs[i] = (X509Certificate) certificateFactory.generateCertificate(inStream); |
|
118 |
} |
|
119 |
} catch (NameNotFoundException e) { |
|
120 |
e.printStackTrace(); |
|
121 |
} catch (CertificateException e) { |
|
122 |
e.printStackTrace(); |
|
123 |
} |
|
124 |
return certs; |
|
125 |
} |
|
126 |
|
|
127 | 99 |
private static void showCertificateInfo(Activity activity, AppEntry appEntry) { |
128 | 100 |
String packageName = appEntry.getPackageName(); |
129 |
X509Certificate[] certs = getX509Certificates(activity, packageName); |
|
101 |
X509Certificate[] certs = Utils.getX509Certificates(activity, packageName);
|
|
130 | 102 |
if (certs == null || certs.length < 1) |
131 | 103 |
return; |
132 | 104 |
/* |
... | ... | |
172 | 144 |
private void saveCertificate(AppEntry appEntry, Intent intent) { |
173 | 145 |
String packageName = appEntry.getPackageName(); |
174 | 146 |
try { |
175 |
for (X509Certificate x509 : getX509Certificates(this, packageName)) { |
|
147 |
for (X509Certificate x509 : Utils.getX509Certificates(this, packageName)) {
|
|
176 | 148 |
String fileName = packageName + ".cer"; |
177 | 149 |
@SuppressWarnings("deprecation") |
178 | 150 |
final FileOutputStream os = openFileOutput(fileName, |
... | ... | |
206 | 178 |
private void generatePin(AppEntry appEntry, Intent intent) { |
207 | 179 |
String packageName = appEntry.getPackageName(); |
208 | 180 |
try { |
209 |
for (X509Certificate x509 : getX509Certificates(this, packageName)) { |
|
181 |
for (X509Certificate x509 : Utils.getX509Certificates(this, packageName)) {
|
|
210 | 182 |
Properties prop = new Properties(); |
211 | 183 |
prop.load(new StringBufferInputStream(x509.getSubjectDN().getName() |
212 | 184 |
.replaceAll(",", "\n"))); |
src/info/guardianproject/checkey/Utils.java | ||
---|---|---|
1 | 1 |
|
2 | 2 |
package info.guardianproject.checkey; |
3 | 3 |
|
4 |
import android.content.Context; |
|
5 |
import android.content.pm.PackageInfo; |
|
6 |
import android.content.pm.PackageManager; |
|
7 |
import android.content.pm.PackageManager.NameNotFoundException; |
|
4 | 8 |
import android.util.Log; |
5 | 9 |
|
6 | 10 |
import java.io.BufferedInputStream; |
11 |
import java.io.ByteArrayInputStream; |
|
7 | 12 |
import java.io.File; |
8 | 13 |
import java.io.FileInputStream; |
9 | 14 |
import java.io.IOException; |
... | ... | |
13 | 18 |
import java.security.NoSuchAlgorithmException; |
14 | 19 |
import java.security.cert.Certificate; |
15 | 20 |
import java.security.cert.CertificateEncodingException; |
21 |
import java.security.cert.CertificateException; |
|
22 |
import java.security.cert.CertificateFactory; |
|
23 |
import java.security.cert.X509Certificate; |
|
16 | 24 |
import java.util.jar.JarEntry; |
17 | 25 |
import java.util.jar.JarFile; |
18 | 26 |
|
19 | 27 |
public final class Utils { |
20 | 28 |
|
29 |
private static PackageManager pm; |
|
30 |
private static CertificateFactory certificateFactory; |
|
31 |
|
|
32 |
public static String getCertificateFingerprint(X509Certificate cert, String hashAlgorithm) { |
|
33 |
String hash = null; |
|
34 |
try { |
|
35 |
MessageDigest md = MessageDigest.getInstance(hashAlgorithm); |
|
36 |
byte[] rawCert = cert.getEncoded(); |
|
37 |
hash = toHexString(md.digest(rawCert)); |
|
38 |
md.reset(); |
|
39 |
} catch (CertificateEncodingException e) { |
|
40 |
hash = "CertificateEncodingException"; |
|
41 |
e.printStackTrace(); |
|
42 |
} catch (NoSuchAlgorithmException e) { |
|
43 |
hash = "NoSuchAlgorithm"; |
|
44 |
e.printStackTrace(); |
|
45 |
} |
|
46 |
return hash; |
|
47 |
} |
|
48 |
|
|
21 | 49 |
public static String getCertificateFingerprint(File apkFile, String hashAlgorithm) |
22 | 50 |
throws NoSuchAlgorithmException { |
23 |
byte[] rawCertBytes; |
|
51 |
MessageDigest md = MessageDigest.getInstance(hashAlgorithm); |
|
52 |
String hash = toHexString(md.digest(getCertificate(apkFile))); |
|
53 |
md.reset(); |
|
54 |
return hash; |
|
55 |
} |
|
56 |
|
|
57 |
public static X509Certificate[] getX509Certificates(Context context, String packageName) { |
|
58 |
X509Certificate[] certs = null; |
|
59 |
if (pm == null) |
|
60 |
pm = context.getApplicationContext().getPackageManager(); |
|
61 |
try { |
|
62 |
PackageInfo pkgInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); |
|
63 |
if (certificateFactory == null) |
|
64 |
certificateFactory = CertificateFactory.getInstance("X509"); |
|
65 |
certs = new X509Certificate[pkgInfo.signatures.length]; |
|
66 |
for (int i = 0; i < certs.length; i++) { |
|
67 |
byte[] cert = pkgInfo.signatures[i].toByteArray(); |
|
68 |
InputStream inStream = new ByteArrayInputStream(cert); |
|
69 |
certs[i] = (X509Certificate) certificateFactory.generateCertificate(inStream); |
|
70 |
} |
|
71 |
} catch (NameNotFoundException e) { |
|
72 |
e.printStackTrace(); |
|
73 |
} catch (CertificateException e) { |
|
74 |
e.printStackTrace(); |
|
75 |
} |
|
76 |
return certs; |
|
77 |
} |
|
78 |
|
|
79 |
public static byte[] getCertificate(File apkFile) |
|
80 |
throws NoSuchAlgorithmException { |
|
81 |
byte[] rawCertBytes = null; |
|
24 | 82 |
try { |
25 | 83 |
JarFile apkJar = new JarFile(apkFile); |
26 | 84 |
JarEntry aSignedEntry = (JarEntry) apkJar.getEntry("AndroidManifest.xml"); |
... | ... | |
50 | 108 |
Certificate signer = aSignedEntry.getCertificates()[0]; |
51 | 109 |
apkJar.close(); |
52 | 110 |
rawCertBytes = signer.getEncoded(); |
53 |
|
|
54 |
MessageDigest md = MessageDigest.getInstance(hashAlgorithm); |
|
55 |
String hash = toHexString(md.digest(rawCertBytes)); |
|
56 |
md.reset(); |
|
57 |
Log.i("SigningCertificate", "raw hash: " + hash); |
|
58 |
|
|
59 |
return hash; |
|
60 | 111 |
} catch (CertificateEncodingException e) { |
61 | 112 |
} catch (IOException e) { |
62 | 113 |
} |
63 |
return "BAD_CERTIFICATE";
|
|
114 |
return rawCertBytes;
|
|
64 | 115 |
} |
65 | 116 |
|
66 | 117 |
public static String getBinaryHash(File apk, String algo) { |
Also available in: Unified diff