Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1011)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java

Issue 2167573003: Verify intent signatures. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: refine code for review Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
index 99c2a0418e6c33bcb9d4d677230334e3549929bd..864650352bb039debbef5d7e1fb8a7751d3649e1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/externalnav/ExternalNavigationHandler.java
@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.externalnav;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.SystemClock;
@@ -28,8 +29,10 @@ import org.chromium.chrome.browser.util.UrlUtilities;
import org.chromium.ui.base.PageTransition;
import java.net.URI;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
@@ -112,6 +115,10 @@ public class ExternalNavigationHandler {
browserFallbackUrl = null;
}
+ if (!intentPackageSignatureMatches(intent)) {
+ return OverrideUrlLoadingResult.NO_OVERRIDE;
+ }
+
long time = SystemClock.elapsedRealtime();
OverrideUrlLoadingResult result = shouldOverrideUrlLoadingInternal(
params, intent, hasBrowserFallbackUrl, browserFallbackUrl);
@@ -127,6 +134,71 @@ public class ExternalNavigationHandler {
return result;
}
+ /**
+ * When a custom scheme intent trying to launch another application, verify the signature
+ * fingerprint of intent, if the fingerprint matches fingerprints of target application, the
+ * intent should be override, or it shouldn't.
+ *
+ * @param intent intent from url
+ * @return boolean, true if the feature is not supported or url should override,
+ * false if the the intent should not override.
+ */
+ private boolean intentPackageSignatureMatches(Intent intent) {
+ try {
+ //This new feature is based on custom scheme, string "scheme" used to check whether
please use gerrit instead 2016/07/29 16:59:52 1) "//" should always be followed by " " before th
+ //the intent url has extra custom scheme, if not, the new feature won't work.
+ String scheme = intent.getData().getScheme();
+ String fragment = intent.getData().getFragment();
+ if (!TextUtils.isEmpty(scheme) && fragment != null && fragment.contains(";")) {
+ String[] parts = fragment.split(";");
+ Set<Set<String>> allFingerPrint256 = new HashSet<>();
+ //Consider that apks could have same package name, different keystores.
+ //1. An apk's signature may update and differ from old, so you might need config and
+ //support new and old signatures, but this is optional. (e.g. (1)only config new
+ //fingerprint. (2)only config old fingerprint.(3)config new and old fingerprint)
+ //2. An apk itself may contain more than one keystore to sign.
+ //example: suppose apk's new signature is sha256_1,sha256_2,and old signature
+ //is sha256_3. You can config the intent like "...;sha256=sha256_1,sha256_2;..."
+ //or "...;sha256=sha256_1,sha256_2|sha256_3;..."
+ String pkgName = "";
+ String fingerPrint256 = "";
+ String[] fingerPrint256DifGroups;
+ for (int i = 0; i < parts.length; ++i) {
+ String[] part = parts[i].split("=");
+ if (part[0].equals("sha256")) {
+ fingerPrint256 = part[1];
+ }
+ if (part[0].equals("package")) {
+ pkgName = part[1];
+ }
+ }
+ if (!TextUtils.isEmpty(pkgName) && !TextUtils.isEmpty(fingerPrint256)) {
+ fingerPrint256DifGroups = fingerPrint256.split("\\|");
+ for (int i = 0; i < fingerPrint256DifGroups.length; ++i) {
+ Set<String> fingerPrint256GroupSignKeySet = new HashSet<>();
+ Collections.addAll(fingerPrint256GroupSignKeySet, fingerPrint256DifGroups[i]
+ .split(","));
+ allFingerPrint256.add(fingerPrint256GroupSignKeySet);
+ }
+ Set<String> fingerPrint256Set = mDelegate.getPackageSHA256Fingerprints(pkgName);
+ if (!allFingerPrint256.contains(fingerPrint256Set)) {
+ return false;
+ }
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
please use gerrit instead 2016/07/29 16:59:52 Modify getPackageSHA256FingerPrints() to return nu
+ return false;
+ } catch (Throwable ignore) {
please use gerrit instead 2016/07/29 16:59:52 Don't surround large blocks of code with try-catch
+ //1. In method getPackageSHA256Fingerprints() , if no SHA-256 implementation found,
+ //we consider this new feature won't work, so it should reset to the original way
+ //to handle the intent , we should ignore ths throwable.
+ //2. In the process above, any other exception or error happens except
+ //"NameNotFoundException", we can consider the feature fail ,and catch the throwable
+ // and continue next work.
+ }
+ return true;
+ }
+
private boolean resolversSubsetOf(List<ResolveInfo> infos, List<ResolveInfo> container) {
HashSet<ComponentName> containerSet = new HashSet<>();
for (ResolveInfo info : container) {

Powered by Google App Engine
This is Rietveld 408576698