• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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