1945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz/*
2945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * Copyright 2016, The Android Open Source Project
3945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz *
4945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * Licensed under the Apache License, Version 2.0 (the "License");
5945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * you may not use this file except in compliance with the License.
6945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * You may obtain a copy of the License at
7945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz *
8945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz *     http://www.apache.org/licenses/LICENSE-2.0
9945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz *
10945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * Unless required by applicable law or agreed to in writing, software
11945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * distributed under the License is distributed on an "AS IS" BASIS,
12945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * See the License for the specific language governing permissions and
14945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * limitations under the License.
15945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz */
16945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
17945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzpackage com.android.managedprovisioning.task;
18945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
19945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport static com.android.internal.util.Preconditions.checkNotNull;
20945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
21945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport android.content.Context;
22945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport android.content.pm.PackageInfo;
23945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport android.content.pm.PackageManager;
24945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport android.content.pm.Signature;
25945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport android.text.TextUtils;
26945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
27945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport com.android.internal.annotations.VisibleForTesting;
28f7a9eea8fe577f2f5edbbe6e73891a54351286c6Benjamin Franzimport com.android.managedprovisioning.common.ProvisionLogger;
29945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport com.android.managedprovisioning.R;
30945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport com.android.managedprovisioning.common.StoreUtils;
31945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport com.android.managedprovisioning.common.Utils;
32945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport com.android.managedprovisioning.model.PackageDownloadInfo;
33945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport com.android.managedprovisioning.model.ProvisioningParams;
34945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
35945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport java.util.Arrays;
36945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport java.util.LinkedList;
37945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzimport java.util.List;
38945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
39945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz/**
40945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * Verifies the management app apk downloaded previously in {@link DownloadPackageTask}.
41945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz *
42945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * <p>The first check verifies that a {@link android.app.admin.DeviceAdminReceiver} is present in
43945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * the apk and that it corresponds to the one provided via
44945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * {@link ProvisioningParams#deviceAdminComponentName}.</p>
45945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz *
46945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * <p>The second check verifies that the package or signature checksum matches the ones given via
47945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * {@link PackageDownloadInfo#packageChecksum} or {@link PackageDownloadInfo#signatureChecksum}
48945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz * respectively. The package checksum takes priority in case both are present.</p>
49945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz */
50945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franzpublic class VerifyPackageTask extends AbstractProvisioningTask {
51945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    public static final int ERROR_HASH_MISMATCH = 0;
52945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    public static final int ERROR_DEVICE_ADMIN_MISSING = 1;
53945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
54945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    private final Utils mUtils;
55945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    private final DownloadPackageTask mDownloadPackageTask;
56945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    private final PackageManager mPackageManager;
57945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    private final PackageDownloadInfo mDownloadInfo;
58945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
59945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    public VerifyPackageTask(
60945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            DownloadPackageTask downloadPackageTask,
61945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            Context context,
62945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            ProvisioningParams params,
63945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            Callback callback) {
64945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        this(new Utils(), downloadPackageTask, context, params, callback);
65945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    }
66945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
67945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    @VisibleForTesting
68945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    VerifyPackageTask(
69945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            Utils utils,
70945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            DownloadPackageTask downloadPackageTask,
71945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            Context context,
72945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            ProvisioningParams params,
73945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            Callback callback) {
74945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        super(context, params, callback);
75945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
76945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        mUtils = checkNotNull(utils);
77945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        mDownloadPackageTask = checkNotNull(downloadPackageTask);
78945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        mPackageManager = mContext.getPackageManager();
79945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        mDownloadInfo = checkNotNull(params.deviceAdminDownloadInfo);
80945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    }
81945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
82945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    @Override
83945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    public void run(int userId) {
84945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        final String downloadLocation = mDownloadPackageTask.getDownloadedPackageLocation();
85945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (TextUtils.isEmpty(downloadLocation)) {
86945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            ProvisionLogger.logw("VerifyPackageTask invoked, but download location is null");
87945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            success();
88945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            return;
89945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
90945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
91945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        PackageInfo packageInfo = mPackageManager.getPackageArchiveInfo(downloadLocation,
92945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                PackageManager.GET_SIGNATURES | PackageManager.GET_RECEIVERS);
93be71433cf40426a420be70cd6388b198403e423dVictor Chang        String packageName = mProvisioningParams.inferDeviceAdminPackageName();
94be71433cf40426a420be70cd6388b198403e423dVictor Chang        // Device admin package name can't be null
95be71433cf40426a420be70cd6388b198403e423dVictor Chang        if (packageInfo == null || packageName == null) {
96be71433cf40426a420be70cd6388b198403e423dVictor Chang            ProvisionLogger.loge("Device admin package info or name is null");
97be71433cf40426a420be70cd6388b198403e423dVictor Chang            error(ERROR_DEVICE_ADMIN_MISSING);
98be71433cf40426a420be70cd6388b198403e423dVictor Chang            return;
99be71433cf40426a420be70cd6388b198403e423dVictor Chang        }
100be71433cf40426a420be70cd6388b198403e423dVictor Chang
101be71433cf40426a420be70cd6388b198403e423dVictor Chang        if (mUtils.findDeviceAdminInPackageInfo(packageName,
102be71433cf40426a420be70cd6388b198403e423dVictor Chang                mProvisioningParams.deviceAdminComponentName, packageInfo) == null) {
103945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            error(ERROR_DEVICE_ADMIN_MISSING);
104945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            return;
105945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
106945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
107945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (mDownloadInfo.packageChecksum.length > 0) {
108945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            if (!doesPackageHashMatch(downloadLocation, mDownloadInfo.packageChecksum,
109945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                    mDownloadInfo.packageChecksumSupportsSha1)) {
110945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                error(ERROR_HASH_MISMATCH);
111945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                return;
112945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            }
113945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        } else {
114945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            if (!doesASignatureHashMatch(packageInfo, mDownloadInfo.signatureChecksum)) {
115945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                error(ERROR_HASH_MISMATCH);
116945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                return;
117945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            }
118945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
119945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
120945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        success();
121945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    }
122945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
123945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    @Override
124945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    public int getStatusMsgId() {
125945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        return R.string.progress_install;
126945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    }
127945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
128945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    private List<byte[]> computeHashesOfAllSignatures(Signature[] signatures) {
129945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (signatures == null) {
130945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            return null;
131945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
132945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
133945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        List<byte[]> hashes = new LinkedList<>();
134945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        for (Signature signature : signatures) {
135945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            byte[] hash = mUtils.computeHashOfByteArray(signature.toByteArray());
136945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            hashes.add(hash);
137945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
138945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        return hashes;
139945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    }
140945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
141945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    private boolean doesASignatureHashMatch(PackageInfo packageInfo, byte[] signatureChecksum) {
142945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        // Check whether a signature hash of downloaded apk matches the hash given in constructor.
143945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        ProvisionLogger.logd("Checking " + Utils.SHA256_TYPE
144945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                + "-hashes of all signatures of downloaded package.");
145945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        List<byte[]> sigHashes = computeHashesOfAllSignatures(packageInfo.signatures);
146945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (sigHashes == null || sigHashes.isEmpty()) {
147945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            ProvisionLogger.loge("Downloaded package does not have any signatures.");
148945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            return false;
149945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
150945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
151945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        for (byte[] sigHash : sigHashes) {
152945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            if (Arrays.equals(sigHash, signatureChecksum)) {
153945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                return true;
154945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            }
155945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
156945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
157945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        ProvisionLogger.loge("Provided hash does not match any signature hash.");
158945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        ProvisionLogger.loge("Hash provided by programmer: "
159945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                + StoreUtils.byteArrayToString(signatureChecksum));
160945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        ProvisionLogger.loge("Hashes computed from package signatures: ");
161945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        for (byte[] sigHash : sigHashes) {
162945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            if (sigHash != null) {
163945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                ProvisionLogger.loge(StoreUtils.byteArrayToString(sigHash));
164945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            }
165945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
166945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
167945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        return false;
168945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    }
169945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
170945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    /**
171945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz     * Check whether package hash of downloaded file matches the hash given in PackageDownloadInfo.
172945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz     * By default, SHA-256 is used to verify the file hash.
173945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz     * If mPackageDownloadInfo.packageChecksumSupportsSha1 == true, SHA-1 hash is also supported for
174945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz     * backwards compatibility.
175945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz     */
176945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    private boolean doesPackageHashMatch(String downloadLocation, byte[] packageChecksum,
177945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            boolean supportsSha1) {
178945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        byte[] packageSha256Hash, packageSha1Hash = null;
179945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
180945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        ProvisionLogger.logd("Checking file hash of entire apk file.");
181945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        packageSha256Hash = mUtils.computeHashOfFile(downloadLocation, Utils.SHA256_TYPE);
182945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (Arrays.equals(packageChecksum, packageSha256Hash)) {
183945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            return true;
184945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
185945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
186945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        // Fall back to SHA-1
187945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (supportsSha1) {
188945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            packageSha1Hash = mUtils.computeHashOfFile(downloadLocation, Utils.SHA1_TYPE);
189945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            if (Arrays.equals(packageChecksum, packageSha1Hash)) {
190945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                return true;
191945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            }
192945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
193945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz
194945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        ProvisionLogger.loge("Provided hash does not match file hash.");
195945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        ProvisionLogger.loge("Hash provided by programmer: "
196945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                + StoreUtils.byteArrayToString(packageChecksum));
197945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (packageSha256Hash != null) {
198945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            ProvisionLogger.loge("SHA-256 Hash computed from file: "
199945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                    + StoreUtils.byteArrayToString(packageSha256Hash));
200945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
201945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        if (packageSha1Hash != null) {
202945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz            ProvisionLogger.loge("SHA-1 Hash computed from file: "
203945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz                    + StoreUtils.byteArrayToString(packageSha1Hash));
204945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        }
205945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz        return false;
206945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz    }
207945e609e967c33897df9e5f53b86e0eaa6e53e2eBenjamin Franz}
208