From 772004756e570452f080c611da33ef54d8ded823 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Tue, 28 Jan 2014 17:45:34 -0500 Subject: [PATCH] handle new signed repo with only fingerprint, no pubkey yet A new repo can be added with only the fingerprint of the signing key, while the regular tests are based on the entire public key (repo.pubkey). This checks for the case when a repo only has the fingerprint and no pubkey yet. In that case, it the pubkey presented by the index.jar file against the stored fingerprint. If they match, then the whole pubkey in the index.jar is stored. --- src/org/fdroid/fdroid/DB.java | 27 ++++++++++++++----- .../fdroid/fdroid/updater/RepoUpdater.java | 6 ++--- .../fdroid/updater/SignedRepoUpdater.java | 6 +++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java index 56c0e070d..e94374bab 100644 --- a/src/org/fdroid/fdroid/DB.java +++ b/src/org/fdroid/fdroid/DB.java @@ -21,9 +21,8 @@ package org.fdroid.fdroid; import java.io.File; import java.security.MessageDigest; -import java.net.MalformedURLException; -import java.net.URL; -import java.text.ParseException; +import java.security.cert.Certificate; +import java.security.cert.CertificateEncodingException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; @@ -48,6 +47,7 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.preference.PreferenceManager; +import android.text.TextUtils; import android.text.TextUtils.SimpleStringSplitter; import android.util.DisplayMetrics; import android.util.Log; @@ -419,14 +419,27 @@ public class DB { } } - public static String calcFingerprint(String pubkey) { - String ret = null; - if (pubkey == null) + public static String calcFingerprint(String keyHexString) { + if (TextUtils.isEmpty(keyHexString)) return null; + else + return calcFingerprint(Hasher.unhex(keyHexString)); + } + + public static String calcFingerprint(Certificate cert) { + try { + return calcFingerprint(cert.getEncoded()); + } catch (CertificateEncodingException e) { + return null; + } + } + + public static String calcFingerprint(byte[] key) { + String ret = null; try { // keytool -list -v gives you the SHA-256 fingerprint MessageDigest digest = MessageDigest.getInstance("SHA-256"); - digest.update(Hasher.unhex(pubkey)); + digest.update(key); byte[] fingerprint = digest.digest(); Formatter formatter = new Formatter(new StringBuilder()); for (int i = 1; i < fingerprint.length; i++) { diff --git a/src/org/fdroid/fdroid/updater/RepoUpdater.java b/src/org/fdroid/fdroid/updater/RepoUpdater.java index f77bbccbc..0ab99ba3d 100644 --- a/src/org/fdroid/fdroid/updater/RepoUpdater.java +++ b/src/org/fdroid/fdroid/updater/RepoUpdater.java @@ -31,10 +31,10 @@ abstract public class RepoUpdater { public static final String PROGRESS_DATA_REPO = "repo"; public static RepoUpdater createUpdaterFor(Context ctx, Repo repo) { - if (repo.pubkey != null) { - return new SignedRepoUpdater(ctx, repo); - } else { + if (repo.fingerprint == null && repo.pubkey == null) { return new UnsignedRepoUpdater(ctx, repo); + } else { + return new SignedRepoUpdater(ctx, repo); } } diff --git a/src/org/fdroid/fdroid/updater/SignedRepoUpdater.java b/src/org/fdroid/fdroid/updater/SignedRepoUpdater.java index 8f3f75aaa..d8925c304 100644 --- a/src/org/fdroid/fdroid/updater/SignedRepoUpdater.java +++ b/src/org/fdroid/fdroid/updater/SignedRepoUpdater.java @@ -7,7 +7,6 @@ import org.fdroid.fdroid.Hasher; import org.fdroid.fdroid.R; import org.fdroid.fdroid.Utils; import org.fdroid.fdroid.data.Repo; -import org.fdroid.fdroid.net.Downloader; import java.io.*; import java.security.cert.Certificate; @@ -31,7 +30,10 @@ public class SignedRepoUpdater extends RepoUpdater { boolean match = false; for (Certificate cert : certs) { String certdata = Hasher.hex(cert); - if (repo.pubkey.equals(certdata)) { + if (repo.pubkey == null && repo.fingerprint.equals(DB.calcFingerprint(cert))) { + repo.pubkey = certdata; + } + if (repo.pubkey != null && repo.pubkey.equals(certdata)) { match = true; break; }