From f05905c85559a9fee3fa05df5e2f7118e1e48713 Mon Sep 17 00:00:00 2001 From: Ciaran Gultnieks Date: Sun, 16 Jan 2011 16:07:42 +0000 Subject: [PATCH] Can now detect attempt to install an apk with a different signature and tell the user to uninstall first --- res/values/strings.xml | 1 + src/org/fdroid/fdroid/AppDetails.java | 43 +++++++++++++++-------- src/org/fdroid/fdroid/DB.java | 14 ++++++-- src/org/fdroid/fdroid/RepoXMLHandler.java | 2 ++ 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 4afc6faec..bced43756 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,5 +1,6 @@ + The new version is signed with a different key to the old one. To install the new version, the old one must be uninstalled first. Please do this and try again. (Note that uninstalling will erase any internal data stored by the application) Version %d versions available %d version available diff --git a/src/org/fdroid/fdroid/AppDetails.java b/src/org/fdroid/fdroid/AppDetails.java index bd31e7681..7bd42ea28 100644 --- a/src/org/fdroid/fdroid/AppDetails.java +++ b/src/org/fdroid/fdroid/AppDetails.java @@ -171,6 +171,7 @@ public class AppDetails extends ListActivity { // The signature of the installed version. private Signature mInstalledSignature; + private String mInstalledSigID; @Override protected void onStart() { @@ -221,8 +222,21 @@ public class AppDetails extends ListActivity { PackageInfo pi = pm.getPackageInfo(appid, PackageManager.GET_SIGNATURES); mInstalledSignature = pi.signatures[0]; + MessageDigest md; + md = MessageDigest.getInstance("MD5"); + byte[] md5sum = new byte[32]; + md.update(mInstalledSignature.toCharsString().getBytes()); + md5sum = md.digest(); + BigInteger bigInt = new BigInteger(1, md5sum); + String md5hash = bigInt.toString(16); + while (md5hash.length() < 32) + md5hash = "0" + md5hash; + mInstalledSigID = md5hash; } catch (NameNotFoundException e) { Log.d("FDroid", "Failed to get installed signature"); + } catch (NoSuchAlgorithmException e) { + Log.d("FDroid", "Failed to calculate signature MD5 sum"); + mInstalledSignature = null; } } @@ -252,20 +266,8 @@ public class AppDetails extends ListActivity { tv = (TextView) findViewById(R.id.description); tv.setText(app.description); if (pref_expert && mInstalledSignature != null) { - try { - tv = (TextView) findViewById(R.id.signature); - MessageDigest md; - md = MessageDigest.getInstance("MD5"); - byte[] md5sum = new byte[32]; - md.update(mInstalledSignature.toCharsString().getBytes()); - md5sum = md.digest(); - BigInteger bigInt = new BigInteger(1, md5sum); - String md5hash = bigInt.toString(16); - while (md5hash.length() < 32) - md5hash = "0" + md5hash; - tv.setText("Signed: " + md5hash); - } catch (NoSuchAlgorithmException e) { - } + tv = (TextView) findViewById(R.id.signature); + tv.setText("Signed: " + mInstalledSigID); } // Set up the list... @@ -410,6 +412,19 @@ public class AppDetails extends ListActivity { // Install the version of this app denoted by 'curapk'. private void install() { + if (mInstalledSigID != null && !curapk.sig.equals(mInstalledSigID)) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setMessage(R.string.SignatureMismatch).setPositiveButton( + "Ok", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }); + AlertDialog alert = builder.create(); + alert.show(); + return; + } + pd = new ProgressDialog(this); pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); pd.setMessage(getString(R.string.download_server)); diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java index f9db98971..11eefa112 100644 --- a/src/org/fdroid/fdroid/DB.java +++ b/src/org/fdroid/fdroid/DB.java @@ -149,6 +149,11 @@ public class DB { public int size; // Size in bytes - 0 means we don't know! public String server; public String hash; + + // ID (md5 sum of public key) of signature. Might be null, in the + // transition to this field existing. + public String sig; + public String apkName; // If null, the apk comes from the same server as the repo index. @@ -194,7 +199,7 @@ public class DB { // private static final String[][] DB_UPGRADES = { - // Version 2... + // Version 2... { "alter table " + TABLE_APP + " add marketVersion text", "alter table " + TABLE_APP + " add marketVercode integer" }, @@ -205,7 +210,10 @@ public class DB { { "alter table " + TABLE_APP + " add installedVerCode integer" }, // Version 5... - { "alter table " + TABLE_APP + " add antiFeatures string" } + { "alter table " + TABLE_APP + " add antiFeatures string" }, + + // Version 6... + { "alter table " + TABLE_APK + " add sig string" } }; @@ -334,6 +342,7 @@ public class DB { apk.vercode = c2.getInt(c2.getColumnIndex("vercode")); apk.server = c2.getString(c2.getColumnIndex("server")); apk.hash = c2.getString(c2.getColumnIndex("hash")); + apk.sig = c2.getString(c2.getColumnIndex("sig")); apk.size = c2.getInt(c2.getColumnIndex("size")); apk.apkName = c2.getString(c2.getColumnIndex("apkName")); apk.apkSource = c2 @@ -555,6 +564,7 @@ public class DB { values.put("vercode", upapk.vercode); values.put("server", upapk.server); values.put("hash", upapk.hash); + values.put("sig", upapk.sig); values.put("size", upapk.size); values.put("apkName", upapk.apkName); values.put("apkSource", upapk.apkSource); diff --git a/src/org/fdroid/fdroid/RepoXMLHandler.java b/src/org/fdroid/fdroid/RepoXMLHandler.java index 7a34a5af3..01888a7a9 100644 --- a/src/org/fdroid/fdroid/RepoXMLHandler.java +++ b/src/org/fdroid/fdroid/RepoXMLHandler.java @@ -102,6 +102,8 @@ public class RepoXMLHandler extends DefaultHandler { } } else if (curel == "hash") { curapk.hash = str; + } else if (curel == "sig") { + curapk.sig = str; } else if (curel == "apkname") { curapk.apkName = str; } else if (curel == "apksource") {