blob: f51c3a60ed03f2a3aa8021179d01c634dd1daa16 [file]
/*
* Copyright (C) 2022 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.managedprovisioning.task;
import static java.util.Objects.requireNonNull;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.managedprovisioning.analytics.MetricsWriterFactory;
import com.android.managedprovisioning.analytics.ProvisioningAnalyticsTracker;
import com.android.managedprovisioning.common.ManagedProvisioningSharedPreferences;
import com.android.managedprovisioning.common.ProvisionLogger;
import com.android.managedprovisioning.common.SettingsFacade;
import com.android.managedprovisioning.common.Utils;
import com.android.managedprovisioning.model.PackageDownloadInfo;
import com.android.managedprovisioning.model.ProvisioningParams;
import java.io.File;
/**
* Verifies the management app apk downloaded previously in {@link DownloadPackageTask}.
*
* <p>The first check verifies that a {@link android.app.admin.DeviceAdminReceiver} is present in
* the apk and that it corresponds to the one provided via
* {@link ProvisioningParams#deviceAdminComponentName}.</p>
*
* <p>The second check verifies that the package or signature checksum matches the ones given via
* {@link PackageDownloadInfo#packageChecksum} or {@link PackageDownloadInfo#signatureChecksum}
* respectively. The package checksum takes priority in case both are present.</p>
*/
public class VerifyRoleHolderPackageTask extends AbstractProvisioningTask {
public static final int ERROR_HASH_MISMATCH = 0;
private final PackageLocationProvider mDownloadLocationProvider;
private final PackageManager mPackageManager;
private final PackageDownloadInfo mPackageDownloadInfo;
private final ChecksumUtils mChecksumUtils;
public VerifyRoleHolderPackageTask(
PackageLocationProvider downloadLocationProvider,
Context context,
ProvisioningParams params,
PackageDownloadInfo packageDownloadInfo,
Callback callback) {
this(downloadLocationProvider, context, params, packageDownloadInfo, callback,
new ProvisioningAnalyticsTracker(
MetricsWriterFactory.getMetricsWriter(context, new SettingsFacade()),
new ManagedProvisioningSharedPreferences(context)),
new ChecksumUtils(new Utils()));
}
@VisibleForTesting
VerifyRoleHolderPackageTask(
PackageLocationProvider downloadLocationProvider,
Context context,
ProvisioningParams params,
PackageDownloadInfo packageDownloadInfo,
Callback callback,
ProvisioningAnalyticsTracker provisioningAnalyticsTracker,
ChecksumUtils checksumUtils) {
super(context, params, callback, provisioningAnalyticsTracker);
mDownloadLocationProvider = requireNonNull(downloadLocationProvider);
mPackageManager = mContext.getPackageManager();
mPackageDownloadInfo = requireNonNull(packageDownloadInfo);
mChecksumUtils = requireNonNull(checksumUtils);
}
@Override
public void run(int userId) {
final File packageLocation = mDownloadLocationProvider.getPackageLocation();
if (packageLocation == null) {
ProvisionLogger.logw("VerifyPackageTask invoked, but package is null");
success();
return;
}
ProvisionLogger.logi("Verifying package from location " + packageLocation.getAbsolutePath()
+ " for user " + userId);
PackageInfo packageInfo = mPackageManager.getPackageArchiveInfo(
packageLocation.getAbsolutePath(),
PackageManager.GET_SIGNATURES | PackageManager.GET_RECEIVERS);
if (mPackageDownloadInfo.packageChecksum.length > 0) {
if (!mChecksumUtils.doesPackageHashMatch(
packageLocation.getAbsolutePath(), mPackageDownloadInfo.packageChecksum)) {
error(ERROR_HASH_MISMATCH);
return;
}
} else {
if (!mChecksumUtils.doesASignatureHashMatch(
packageInfo, mPackageDownloadInfo.signatureChecksum)) {
error(ERROR_HASH_MISMATCH);
return;
}
}
success();
}
}