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 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 })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 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 })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 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 })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 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 })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 }); callerIdFingerprints.add( SIGNED_SPRINT_NEW, new byte[] { 0x27, (byte) 0xF9, 0x6D, (byte) 0xBA, (byte) 0xB7, 0x7B, 0x31, (byte) 0xF6, (byte) 0x95, 0x3E, 0x4C, (byte) 0xD2, (byte) 0xC2, (byte) 0xDE, (byte) 0xFE, 0x15, (byte) 0xF5, (byte) 0xD7, (byte) 0xC7, (byte) 0x8F, 0x07, 0x3D, (byte) 0xD7, 0x16, 0x20, 0x18, (byte) 0xEF, 0x47, 0x6B, 0x09, 0x7C, 0x34 })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") isCallerIdInstalled( @ullable PackageManager packageManager, @Nullable String authority)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 getSHA256(byte[] sig)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 getApkTypeString(int index)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