1 /* 2 * Copyright (C) 2022 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 17 18 package com.android.managedprovisioning.task; 19 20 import static java.util.Objects.requireNonNull; 21 22 import android.content.Context; 23 import android.content.pm.PackageInfo; 24 import android.content.pm.PackageManager; 25 26 import com.android.internal.annotations.VisibleForTesting; 27 import com.android.managedprovisioning.analytics.MetricsWriterFactory; 28 import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker; 29 import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences; 30 import com.android.managedprovisioning.common.ProvisionLogger; 31 import com.android.managedprovisioning.common.SettingsFacade; 32 import com.android.managedprovisioning.common.Utils; 33 import com.android.managedprovisioning.model.PackageDownloadInfo; 34 import com.android.managedprovisioning.model.ProvisioningParams; 35 36 import java.io.File; 37 38 /** 39 * Verifies the management app apk downloaded previously in {@link DownloadPackageTask}. 40 * 41 * <p>The first check verifies that a {@link android.app.admin.DeviceAdminReceiver} is present in 42 * the apk and that it corresponds to the one provided via 43 * {@link ProvisioningParams#deviceAdminComponentName}.</p> 44 * 45 * <p>The second check verifies that the package or signature checksum matches the ones given via 46 * {@link PackageDownloadInfo#packageChecksum} or {@link PackageDownloadInfo#signatureChecksum} 47 * respectively. The package checksum takes priority in case both are present.</p> 48 */ 49 public class VerifyRoleHolderPackageTask extends AbstractProvisioningTask { 50 public static final int ERROR_HASH_MISMATCH = 0; 51 52 private final PackageLocationProvider mDownloadLocationProvider; 53 private final PackageManager mPackageManager; 54 private final PackageDownloadInfo mPackageDownloadInfo; 55 private final ChecksumUtils mChecksumUtils; 56 VerifyRoleHolderPackageTask( PackageLocationProvider downloadLocationProvider, Context context, ProvisioningParams params, PackageDownloadInfo packageDownloadInfo, Callback callback)57 public VerifyRoleHolderPackageTask( 58 PackageLocationProvider downloadLocationProvider, 59 Context context, 60 ProvisioningParams params, 61 PackageDownloadInfo packageDownloadInfo, 62 Callback callback) { 63 this(downloadLocationProvider, context, params, packageDownloadInfo, callback, 64 new ProvisioningAnalyticsTracker( 65 MetricsWriterFactory.getMetricsWriter(context, new SettingsFacade()), 66 new ManagedProvisioningSharedPreferences(context)), 67 new ChecksumUtils(new Utils())); 68 } 69 70 @VisibleForTesting VerifyRoleHolderPackageTask( PackageLocationProvider downloadLocationProvider, Context context, ProvisioningParams params, PackageDownloadInfo packageDownloadInfo, Callback callback, ProvisioningAnalyticsTracker provisioningAnalyticsTracker, ChecksumUtils checksumUtils)71 VerifyRoleHolderPackageTask( 72 PackageLocationProvider downloadLocationProvider, 73 Context context, 74 ProvisioningParams params, 75 PackageDownloadInfo packageDownloadInfo, 76 Callback callback, 77 ProvisioningAnalyticsTracker provisioningAnalyticsTracker, 78 ChecksumUtils checksumUtils) { 79 super(context, params, callback, provisioningAnalyticsTracker); 80 81 mDownloadLocationProvider = requireNonNull(downloadLocationProvider); 82 mPackageManager = mContext.getPackageManager(); 83 mPackageDownloadInfo = requireNonNull(packageDownloadInfo); 84 mChecksumUtils = requireNonNull(checksumUtils); 85 } 86 87 @Override run(int userId)88 public void run(int userId) { 89 final File packageLocation = mDownloadLocationProvider.getPackageLocation(); 90 if (packageLocation == null) { 91 ProvisionLogger.logw("VerifyPackageTask invoked, but package is null"); 92 success(); 93 return; 94 } 95 ProvisionLogger.logi("Verifying package from location " + packageLocation.getAbsolutePath() 96 + " for user " + userId); 97 98 PackageInfo packageInfo = mPackageManager.getPackageArchiveInfo( 99 packageLocation.getAbsolutePath(), 100 PackageManager.GET_SIGNATURES | PackageManager.GET_RECEIVERS); 101 102 if (mPackageDownloadInfo.packageChecksum.length > 0) { 103 if (!mChecksumUtils.doesPackageHashMatch( 104 packageLocation.getAbsolutePath(), mPackageDownloadInfo.packageChecksum)) { 105 error(ERROR_HASH_MISMATCH); 106 return; 107 } 108 } else { 109 if (!mChecksumUtils.doesASignatureHashMatch( 110 packageInfo, mPackageDownloadInfo.signatureChecksum)) { 111 error(ERROR_HASH_MISMATCH); 112 return; 113 } 114 } 115 116 success(); 117 } 118 } 119