summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwangqi <wangqi@google.com>2017-11-20 11:09:02 -0800
committerCopybara-Service <copybara-piper@google.com>2017-11-20 11:11:44 -0800
commitf75954b1425038e13dabbf342613510930b48836 (patch)
tree0109c9bda4395c5384ceb330b078a9e6cf846c46
parent241be987e90cae4f83215bcdfe0594c8cba23be4 (diff)
Add more Cequint provider and signature check.
This change expands Cequint Caller ID to more provider name and adds signature check to avoid fake provider fraud. Bug: 69061848,69310040 Test: CequintPackageUtilsTest PiperOrigin-RevId: 176386836 Change-Id: Ie8759ae5acb18fe8fe61f365065ae020428a7880
-rw-r--r--java/com/android/dialer/oem/CequintCallerIdManager.java39
-rw-r--r--java/com/android/dialer/oem/CequintPackageUtils.java286
-rw-r--r--java/com/android/dialer/oem/res/values/motorola_config.xml6
3 files changed, 314 insertions, 17 deletions
diff --git a/java/com/android/dialer/oem/CequintCallerIdManager.java b/java/com/android/dialer/oem/CequintCallerIdManager.java
index df624e06a..48a5985ce 100644
--- a/java/com/android/dialer/oem/CequintCallerIdManager.java
+++ b/java/com/android/dialer/oem/CequintCallerIdManager.java
@@ -46,17 +46,10 @@ public class CequintCallerIdManager {
private static final String CONFIG_CALLER_ID_ENABLED = "config_caller_id_enabled";
- private static final String PROVIDER_NAME = "com.cequint.ecid";
-
- private static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/lookup");
-
private static final int CALLER_ID_LOOKUP_USER_PROVIDED_CID = 0x0001;
private static final int CALLER_ID_LOOKUP_SYSTEM_PROVIDED_CID = 0x0002;
private static final int CALLER_ID_LOOKUP_INCOMING_CALL = 0x0020;
- private static final Uri CONTENT_URI_FOR_INCALL =
- Uri.parse("content://" + PROVIDER_NAME + "/incalllookup");
-
private static final String[] EMPTY_PROJECTION = new String[] {};
// Column names in Cequint provider.
@@ -72,7 +65,7 @@ public class CequintCallerIdManager {
private static final String DISPLAY_NAME = "cid_pDisplayName";
private static boolean hasAlreadyCheckedCequintCallerIdPackage;
- private static boolean isCequintCallerIdEnabled;
+ private static String cequintProviderAuthority;
// TODO(wangqi): Revisit it and maybe remove it if it's not necessary.
private final ConcurrentHashMap<String, CequintCallerIdContact> callLogCache;
@@ -98,16 +91,20 @@ public class CequintCallerIdManager {
}
if (!hasAlreadyCheckedCequintCallerIdPackage) {
hasAlreadyCheckedCequintCallerIdPackage = true;
- isCequintCallerIdEnabled = false;
- try {
- context.getPackageManager().getPackageInfo(PROVIDER_NAME, 0);
- isCequintCallerIdEnabled = true;
- } catch (PackageManager.NameNotFoundException e) {
- isCequintCallerIdEnabled = false;
+ String[] providerNames = context.getResources().getStringArray(R.array.cequint_providers);
+ PackageManager packageManager = context.getPackageManager();
+ for (String provider : providerNames) {
+ if (CequintPackageUtils.isCallerIdInstalled(packageManager, provider)) {
+ cequintProviderAuthority = provider;
+ LogUtil.i(
+ "CequintCallerIdManager.isCequintCallerIdEnabled", "found provider: %s", provider);
+ return true;
+ }
}
+ LogUtil.d("CequintCallerIdManager.isCequintCallerIdEnabled", "no provider found");
}
- return isCequintCallerIdEnabled;
+ return cequintProviderAuthority != null;
}
public static CequintCallerIdManager createInstanceForCallLog() {
@@ -133,7 +130,7 @@ public class CequintCallerIdManager {
flag |= CALLER_ID_LOOKUP_USER_PROVIDED_CID;
}
String[] flags = {cnapName, String.valueOf(flag)};
- return lookup(context, CONTENT_URI_FOR_INCALL, number, flags);
+ return lookup(context, getIncallLookupUri(), number, flags);
}
@WorkerThread
@@ -150,7 +147,7 @@ public class CequintCallerIdManager {
CequintCallerIdContact cequintCallerIdContact =
lookup(
context,
- CONTENT_URI,
+ getLookupUri(),
PhoneNumberUtils.stripSeparators(number),
new String[] {"system"});
if (cequintCallerIdContact != null) {
@@ -267,6 +264,14 @@ public class CequintCallerIdManager {
return geoDescription;
}
+ private static Uri getLookupUri() {
+ return Uri.parse("content://" + cequintProviderAuthority + "/lookup");
+ }
+
+ private static Uri getIncallLookupUri() {
+ return Uri.parse("content://" + cequintProviderAuthority + "/incalllookup");
+ }
+
private CequintCallerIdManager() {
callLogCache = new ConcurrentHashMap<>();
}
diff --git a/java/com/android/dialer/oem/CequintPackageUtils.java b/java/com/android/dialer/oem/CequintPackageUtils.java
new file mode 100644
index 000000000..66c900e8b
--- /dev/null
+++ b/java/com/android/dialer/oem/CequintPackageUtils.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.dialer.oem;
+
+import android.annotation.SuppressLint;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ProviderInfo;
+import android.content.pm.Signature;
+import android.support.annotation.Nullable;
+import com.android.dialer.common.LogUtil;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/** Utility class to verify Cequint package information. */
+final class CequintPackageUtils {
+
+ private static final int SIGNED_1024 = 0;
+ private static final int SIGNED_2048 = 1;
+ private static final int SIGNED_VZW = 2;
+ private static final int SIGNED_SPRINT = 3;
+
+ // Known Caller Name ID fingerprints
+ private static final List<byte[]> callerIdFingerprints = new ArrayList<>();
+
+ static {
+ // 1024 signed
+ callerIdFingerprints.add(
+ SIGNED_1024,
+ new byte[] {
+ 0x1A,
+ 0x0C,
+ (byte) 0xF8,
+ (byte) 0x8D,
+ 0x5B,
+ (byte) 0xE2,
+ 0x6A,
+ (byte) 0xED,
+ 0x50,
+ (byte) 0x85,
+ (byte) 0xFE,
+ (byte) 0x88,
+ (byte) 0xA0,
+ (byte) 0x9E,
+ (byte) 0xEC,
+ 0x25,
+ 0x1E,
+ (byte) 0xCA,
+ 0x16,
+ (byte) 0x97,
+ 0x50,
+ (byte) 0xDA,
+ 0x21,
+ (byte) 0xCC,
+ 0x18,
+ (byte) 0xC9,
+ (byte) 0x98,
+ (byte) 0xAF,
+ 0x26,
+ (byte) 0xCD,
+ 0x06,
+ 0x71
+ });
+ // 2048 signed
+ callerIdFingerprints.add(
+ SIGNED_2048,
+ new byte[] {
+ (byte) 0xCA,
+ 0x2F,
+ (byte) 0xAE,
+ (byte) 0xF4,
+ 0x09,
+ (byte) 0xEF,
+ 0x4C,
+ 0x79,
+ (byte) 0xF8,
+ 0x4C,
+ (byte) 0xD8,
+ (byte) 0x97,
+ (byte) 0xBF,
+ 0x1A,
+ 0x15,
+ 0x0F,
+ (byte) 0xF0,
+ 0x5E,
+ 0x54,
+ 0x74,
+ (byte) 0xB6,
+ 0x4A,
+ (byte) 0xCA,
+ (byte) 0xCD,
+ 0x05,
+ 0x7E,
+ 0x1E,
+ (byte) 0x98,
+ (byte) 0xC6,
+ 0x1F,
+ 0x5C,
+ 0x45
+ });
+ // VZW Package
+ callerIdFingerprints.add(
+ SIGNED_VZW,
+ new byte[] {
+ (byte) 0xE6,
+ 0x7A,
+ 0x0E,
+ (byte) 0xB0,
+ 0x76,
+ 0x4E,
+ (byte) 0xC3,
+ 0x28,
+ (byte) 0xB7,
+ (byte) 0xC1,
+ 0x1B,
+ 0x1B,
+ (byte) 0xD0,
+ (byte) 0x84,
+ 0x28,
+ (byte) 0xA6,
+ 0x16,
+ (byte) 0xD9,
+ (byte) 0xF3,
+ (byte) 0xEB,
+ (byte) 0xB0,
+ 0x20,
+ (byte) 0xA7,
+ (byte) 0xD8,
+ (byte) 0xDF,
+ 0x14,
+ 0x72,
+ (byte) 0x81,
+ 0x4C,
+ 0x13,
+ (byte) 0xF3,
+ (byte) 0xC9
+ });
+
+ // Sprint Package
+ callerIdFingerprints.add(
+ SIGNED_SPRINT,
+ new byte[] {
+ 0x1A,
+ (byte) 0xBA,
+ (byte) 0xA2,
+ (byte) 0x84,
+ 0x0C,
+ 0x61,
+ (byte) 0x96,
+ 0x09,
+ (byte) 0x91,
+ 0x5E,
+ (byte) 0x91,
+ (byte) 0x95,
+ 0x3D,
+ 0x29,
+ 0x3C,
+ (byte) 0x90,
+ (byte) 0xEC,
+ (byte) 0xB4,
+ (byte) 0x89,
+ 0x1D,
+ (byte) 0xC0,
+ (byte) 0xB1,
+ 0x23,
+ 0x58,
+ (byte) 0x98,
+ (byte) 0xEB,
+ (byte) 0xE6,
+ (byte) 0xD4,
+ 0x09,
+ (byte) 0xE5,
+ (byte) 0x8E,
+ (byte) 0x9D
+ });
+ }
+
+ @SuppressLint("PackageManagerGetSignatures")
+ static boolean isCallerIdInstalled(
+ @Nullable PackageManager packageManager, @Nullable String authority) {
+ if (packageManager == null) {
+ LogUtil.i("CequintPackageUtils.isCallerIdInstalled", "failed to get PackageManager!");
+ return false;
+ }
+
+ ProviderInfo providerInfo =
+ packageManager.resolveContentProvider(authority, PackageManager.GET_META_DATA);
+ if (providerInfo == null) {
+ LogUtil.d(
+ "CequintPackageUtils.isCallerIdInstalled",
+ "no content provider with '%s' authority",
+ authority);
+ return false;
+ }
+
+ String packageName = providerInfo.packageName;
+ if (packageName == null) {
+ LogUtil.w("CequintPackageUtils.isCallerIdInstalled", "can't get valid package name.");
+ return false;
+ }
+
+ LogUtil.i(
+ "CequintPackageUtils.isCallerIdInstalled",
+ "content provider package name : " + packageName);
+
+ try {
+ PackageInfo packageInfo =
+ packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
+
+ Signature[] signatures = packageInfo.signatures;
+ if (signatures.length > 1) {
+ LogUtil.w(
+ "CequintPackageUtils.isCallerIdInstalled", "package has more than one signature.");
+ return false;
+ }
+ byte[] sha256Bytes = getSHA256(signatures[0].toByteArray());
+
+ for (int i = 0; i < callerIdFingerprints.size(); i++) {
+ if (Arrays.equals(callerIdFingerprints.get(i), sha256Bytes)) {
+ LogUtil.i(
+ "CequintPackageUtils.isCallerIdInstalled",
+ "this is %s Caller Name ID APK.",
+ getApkTypeString(i));
+ return true;
+ }
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ LogUtil.e(
+ "CequintPackageUtils.isCallerIdInstalled",
+ "couldn't find package info for the package: %s",
+ packageName,
+ e);
+ }
+ LogUtil.w(
+ "CequintPackageUtils.isCallerIdInstalled",
+ "signature check failed for package: %s",
+ packageName);
+ return false;
+ }
+
+ // Returns sha256 hash of the signature
+ @Nullable
+ private static byte[] getSHA256(byte[] sig) {
+ MessageDigest digest;
+ try {
+ digest = MessageDigest.getInstance("SHA256", "BC");
+ } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+ LogUtil.e("CequintPackageUtils.getSHA256", "", e);
+ return null;
+ }
+
+ digest.update(sig);
+ return digest.digest();
+ }
+
+ private static String getApkTypeString(int index) {
+ switch (index) {
+ case SIGNED_1024:
+ return "1024-signed";
+ case SIGNED_2048:
+ return "2048-signed";
+ case SIGNED_VZW:
+ return "VZWPackage";
+ case SIGNED_SPRINT:
+ default:
+ return "SprintPackage";
+ }
+ }
+}
diff --git a/java/com/android/dialer/oem/res/values/motorola_config.xml b/java/com/android/dialer/oem/res/values/motorola_config.xml
index 46e7a16b6..ba451e715 100644
--- a/java/com/android/dialer/oem/res/values/motorola_config.xml
+++ b/java/com/android/dialer/oem/res/values/motorola_config.xml
@@ -74,4 +74,10 @@
<string-array name="motorola_hidden_menu_key_pattern_intents">
<item>@string/motorola_hidden_menu_intent</item>
</string-array>
+
+ <!-- This defines the provider names for cequint callerid applications
+ used for different carriers-->
+ <string-array name="cequint_providers">
+ <item>com.cequint.ecid</item>
+ </string-array>
</resources> \ No newline at end of file