Home | History | Annotate | Download | only in oem
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 package com.android.dialer.oem;
     17 
     18 import android.annotation.SuppressLint;
     19 import android.content.pm.PackageInfo;
     20 import android.content.pm.PackageManager;
     21 import android.content.pm.ProviderInfo;
     22 import android.content.pm.Signature;
     23 import android.support.annotation.Nullable;
     24 import com.android.dialer.common.LogUtil;
     25 import java.security.MessageDigest;
     26 import java.security.NoSuchAlgorithmException;
     27 import java.security.NoSuchProviderException;
     28 import java.util.ArrayList;
     29 import java.util.Arrays;
     30 import java.util.List;
     31 
     32 /** Utility class to verify Cequint package information. */
     33 final class CequintPackageUtils {
     34 
     35   private static final int SIGNED_1024 = 0;
     36   private static final int SIGNED_2048 = 1;
     37   private static final int SIGNED_VZW = 2;
     38   private static final int SIGNED_SPRINT = 3;
     39   // TODO(a bug): Add test for this signature.
     40   private static final int SIGNED_SPRINT_NEW = 4;
     41 
     42   // Known Caller Name ID fingerprints
     43   private static final List<byte[]> callerIdFingerprints = new ArrayList<>();
     44 
     45   static {
     46     // 1024 signed
     47     callerIdFingerprints.add(
     48         SIGNED_1024,
     49         new byte[] {
     50           0x1A,
     51           0x0C,
     52           (byte) 0xF8,
     53           (byte) 0x8D,
     54           0x5B,
     55           (byte) 0xE2,
     56           0x6A,
     57           (byte) 0xED,
     58           0x50,
     59           (byte) 0x85,
     60           (byte) 0xFE,
     61           (byte) 0x88,
     62           (byte) 0xA0,
     63           (byte) 0x9E,
     64           (byte) 0xEC,
     65           0x25,
     66           0x1E,
     67           (byte) 0xCA,
     68           0x16,
     69           (byte) 0x97,
     70           0x50,
     71           (byte) 0xDA,
     72           0x21,
     73           (byte) 0xCC,
     74           0x18,
     75           (byte) 0xC9,
     76           (byte) 0x98,
     77           (byte) 0xAF,
     78           0x26,
     79           (byte) 0xCD,
     80           0x06,
     81           0x71
     82         });
     83     // 2048 signed
     84     callerIdFingerprints.add(
     85         SIGNED_2048,
     86         new byte[] {
     87           (byte) 0xCA,
     88           0x2F,
     89           (byte) 0xAE,
     90           (byte) 0xF4,
     91           0x09,
     92           (byte) 0xEF,
     93           0x4C,
     94           0x79,
     95           (byte) 0xF8,
     96           0x4C,
     97           (byte) 0xD8,
     98           (byte) 0x97,
     99           (byte) 0xBF,
    100           0x1A,
    101           0x15,
    102           0x0F,
    103           (byte) 0xF0,
    104           0x5E,
    105           0x54,
    106           0x74,
    107           (byte) 0xB6,
    108           0x4A,
    109           (byte) 0xCA,
    110           (byte) 0xCD,
    111           0x05,
    112           0x7E,
    113           0x1E,
    114           (byte) 0x98,
    115           (byte) 0xC6,
    116           0x1F,
    117           0x5C,
    118           0x45
    119         });
    120     // VZW Package
    121     callerIdFingerprints.add(
    122         SIGNED_VZW,
    123         new byte[] {
    124           (byte) 0xE6,
    125           0x7A,
    126           0x0E,
    127           (byte) 0xB0,
    128           0x76,
    129           0x4E,
    130           (byte) 0xC3,
    131           0x28,
    132           (byte) 0xB7,
    133           (byte) 0xC1,
    134           0x1B,
    135           0x1B,
    136           (byte) 0xD0,
    137           (byte) 0x84,
    138           0x28,
    139           (byte) 0xA6,
    140           0x16,
    141           (byte) 0xD9,
    142           (byte) 0xF3,
    143           (byte) 0xEB,
    144           (byte) 0xB0,
    145           0x20,
    146           (byte) 0xA7,
    147           (byte) 0xD8,
    148           (byte) 0xDF,
    149           0x14,
    150           0x72,
    151           (byte) 0x81,
    152           0x4C,
    153           0x13,
    154           (byte) 0xF3,
    155           (byte) 0xC9
    156         });
    157 
    158     // Sprint Package
    159     callerIdFingerprints.add(
    160         SIGNED_SPRINT,
    161         new byte[] {
    162           0x1A,
    163           (byte) 0xBA,
    164           (byte) 0xA2,
    165           (byte) 0x84,
    166           0x0C,
    167           0x61,
    168           (byte) 0x96,
    169           0x09,
    170           (byte) 0x91,
    171           0x5E,
    172           (byte) 0x91,
    173           (byte) 0x95,
    174           0x3D,
    175           0x29,
    176           0x3C,
    177           (byte) 0x90,
    178           (byte) 0xEC,
    179           (byte) 0xB4,
    180           (byte) 0x89,
    181           0x1D,
    182           (byte) 0xC0,
    183           (byte) 0xB1,
    184           0x23,
    185           0x58,
    186           (byte) 0x98,
    187           (byte) 0xEB,
    188           (byte) 0xE6,
    189           (byte) 0xD4,
    190           0x09,
    191           (byte) 0xE5,
    192           (byte) 0x8E,
    193           (byte) 0x9D
    194         });
    195     callerIdFingerprints.add(
    196         SIGNED_SPRINT_NEW,
    197         new byte[] {
    198           0x27,
    199           (byte) 0xF9,
    200           0x6D,
    201           (byte) 0xBA,
    202           (byte) 0xB7,
    203           0x7B,
    204           0x31,
    205           (byte) 0xF6,
    206           (byte) 0x95,
    207           0x3E,
    208           0x4C,
    209           (byte) 0xD2,
    210           (byte) 0xC2,
    211           (byte) 0xDE,
    212           (byte) 0xFE,
    213           0x15,
    214           (byte) 0xF5,
    215           (byte) 0xD7,
    216           (byte) 0xC7,
    217           (byte) 0x8F,
    218           0x07,
    219           0x3D,
    220           (byte) 0xD7,
    221           0x16,
    222           0x20,
    223           0x18,
    224           (byte) 0xEF,
    225           0x47,
    226           0x6B,
    227           0x09,
    228           0x7C,
    229           0x34
    230         });
    231   }
    232 
    233   @SuppressLint("PackageManagerGetSignatures")
    234   static boolean isCallerIdInstalled(
    235       @Nullable PackageManager packageManager, @Nullable String authority) {
    236     if (packageManager == null) {
    237       LogUtil.i("CequintPackageUtils.isCallerIdInstalled", "failed to get PackageManager!");
    238       return false;
    239     }
    240 
    241     ProviderInfo providerInfo =
    242         packageManager.resolveContentProvider(authority, PackageManager.GET_META_DATA);
    243     if (providerInfo == null) {
    244       LogUtil.d(
    245           "CequintPackageUtils.isCallerIdInstalled",
    246           "no content provider with '%s' authority",
    247           authority);
    248       return false;
    249     }
    250 
    251     String packageName = providerInfo.packageName;
    252     if (packageName == null) {
    253       LogUtil.w("CequintPackageUtils.isCallerIdInstalled", "can't get valid package name.");
    254       return false;
    255     }
    256 
    257     LogUtil.i(
    258         "CequintPackageUtils.isCallerIdInstalled",
    259         "content provider package name : " + packageName);
    260 
    261     try {
    262       PackageInfo packageInfo =
    263           packageManager.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
    264 
    265       Signature[] signatures = packageInfo.signatures;
    266       if (signatures.length > 1) {
    267         LogUtil.w(
    268             "CequintPackageUtils.isCallerIdInstalled", "package has more than one signature.");
    269         return false;
    270       }
    271       byte[] sha256Bytes = getSHA256(signatures[0].toByteArray());
    272 
    273       for (int i = 0; i < callerIdFingerprints.size(); i++) {
    274         if (Arrays.equals(callerIdFingerprints.get(i), sha256Bytes)) {
    275           LogUtil.i(
    276               "CequintPackageUtils.isCallerIdInstalled",
    277               "this is %s Caller Name ID APK.",
    278               getApkTypeString(i));
    279           return true;
    280         }
    281       }
    282     } catch (PackageManager.NameNotFoundException e) {
    283       LogUtil.e(
    284           "CequintPackageUtils.isCallerIdInstalled",
    285           "couldn't find package info for the package: %s",
    286           packageName,
    287           e);
    288     }
    289     LogUtil.w(
    290         "CequintPackageUtils.isCallerIdInstalled",
    291         "signature check failed for package: %s",
    292         packageName);
    293     return false;
    294   }
    295 
    296   // Returns sha256 hash of the signature
    297   @Nullable
    298   private static byte[] getSHA256(byte[] sig) {
    299     MessageDigest digest;
    300     try {
    301       digest = MessageDigest.getInstance("SHA256", "BC");
    302     } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
    303       LogUtil.e("CequintPackageUtils.getSHA256", "", e);
    304       return null;
    305     }
    306 
    307     digest.update(sig);
    308     return digest.digest();
    309   }
    310 
    311   private static String getApkTypeString(int index) {
    312     switch (index) {
    313       case SIGNED_1024:
    314         return "1024-signed";
    315       case SIGNED_2048:
    316         return "2048-signed";
    317       case SIGNED_VZW:
    318         return "VZWPackage";
    319       case SIGNED_SPRINT:
    320       default:
    321         return "SprintPackage";
    322     }
    323   }
    324 }
    325