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