diff options
15 files changed, 157 insertions, 619 deletions
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java index 514112f1e81f..5b3d3e595a91 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -544,16 +544,4 @@ public abstract class PackageManagerInternal { /** Updates the flags for the given permission. */ public abstract void updatePermissionFlagsTEMP(@NonNull String permName, @NonNull String packageName, int flagMask, int flagValues, int userId); - - /** - * Returns true if it's still safe to restore data backed up from this app's version - * that was signed with restoringFromSigHash. - */ - public abstract boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName); - - /** - * Returns true if it's still safe to restore data backed up from this app's version - * that was signed with restoringFromSig. - */ - public abstract boolean isDataRestoreSafe(Signature restoringFromSig, String packageName); } diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java index 4443130005dc..3cf374faada4 100644 --- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java +++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java @@ -23,7 +23,6 @@ import android.content.ComponentName; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.ResolveInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; @@ -31,7 +30,6 @@ import android.os.Build; import android.os.ParcelFileDescriptor; import android.util.Slog; -import com.android.server.LocalServices; import com.android.server.backup.utils.AppBackupUtils; import java.io.BufferedInputStream; @@ -237,7 +235,7 @@ public class PackageManagerBackupAgent extends BackupAgent { if (home != null) { try { homeInfo = mPackageManager.getPackageInfo(home.getPackageName(), - PackageManager.GET_SIGNING_CERTIFICATES); + PackageManager.GET_SIGNATURES); homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName()); homeVersion = homeInfo.getLongVersionCode(); homeSigHashes = BackupUtils.hashSignatureArray(homeInfo.signatures); @@ -254,11 +252,10 @@ public class PackageManagerBackupAgent extends BackupAgent { // 2. the home app [or absence] we now use differs from the prior state, // OR 3. it looks like we use the same home app + version as before, but // the signatures don't match so we treat them as different apps. - PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); final boolean needHomeBackup = (homeVersion != mStoredHomeVersion) || !Objects.equals(home, mStoredHomeComponent) || (home != null - && !BackupUtils.signaturesMatch(mStoredHomeSigHashes, homeInfo, pmi)); + && !BackupUtils.signaturesMatch(mStoredHomeSigHashes, homeInfo)); if (needHomeBackup) { if (DEBUG) { Slog.i(TAG, "Home preference changed; backing up new state " + home); diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java index c1a1c1dc10e7..0ca4f25093ce 100644 --- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java +++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java @@ -36,13 +36,11 @@ import android.app.backup.IFullBackupRestoreObserver; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.util.Slog; -import com.android.server.LocalServices; import com.android.server.backup.BackupRestoreTask; import com.android.server.backup.FileMetadata; import com.android.server.backup.KeyValueAdbRestoreEngine; @@ -209,11 +207,8 @@ public class FullRestoreEngine extends RestoreEngine { if (info.path.equals(BACKUP_MANIFEST_FILENAME)) { Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures( info); - PackageManagerInternal pmi = LocalServices.getService( - PackageManagerInternal.class); RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy( - mBackupManagerService.getPackageManager(), allowApks, info, signatures, - pmi); + mBackupManagerService.getPackageManager(), allowApks, info, signatures); mManifestSignatures.put(info.packageName, signatures); mPackagePolicies.put(pkg, restorePolicy); mPackageInstallers.put(pkg, info.installerPackageName); diff --git a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java index dacde0b9af68..e576b3c32859 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformAdbRestoreTask.java @@ -40,7 +40,6 @@ import android.app.backup.IFullBackupRestoreObserver; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.os.Environment; import android.os.ParcelFileDescriptor; @@ -48,7 +47,6 @@ import android.os.RemoteException; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.LocalServices; import com.android.server.backup.BackupManagerService; import com.android.server.backup.FileMetadata; import com.android.server.backup.KeyValueAdbRestoreEngine; @@ -472,11 +470,9 @@ public class PerformAdbRestoreTask implements Runnable { if (info.path.equals(BACKUP_MANIFEST_FILENAME)) { Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures( info); - PackageManagerInternal pmi = LocalServices.getService( - PackageManagerInternal.class); RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy( mBackupManagerService.getPackageManager(), allowApks, - info, signatures, pmi); + info, signatures); mManifestSignatures.put(info.packageName, signatures); mPackagePolicies.put(pkg, restorePolicy); mPackageInstallers.put(pkg, info.installerPackageName); diff --git a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java index 4b467e5a0399..3caa1e7fab79 100644 --- a/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java +++ b/services/backup/java/com/android/server/backup/restore/PerformUnifiedRestoreTask.java @@ -43,7 +43,6 @@ import android.app.backup.RestoreDescription; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; import android.os.Message; @@ -58,7 +57,6 @@ import android.util.Slog; import com.android.internal.backup.IBackupTransport; import com.android.server.AppWidgetBackupBridge; import com.android.server.EventLogTags; -import com.android.server.LocalServices; import com.android.server.backup.BackupRestoreTask; import com.android.server.backup.BackupUtils; import com.android.server.backup.PackageManagerBackupAgent; @@ -506,7 +504,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { try { mCurrentPackage = backupManagerService.getPackageManager().getPackageInfo( - pkgName, PackageManager.GET_SIGNING_CERTIFICATES); + pkgName, PackageManager.GET_SIGNATURES); } catch (NameNotFoundException e) { // Whoops, we thought we could restore this package but it // turns out not to be present. Skip it. @@ -621,8 +619,7 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask { } Metadata metaInfo = mPmAgent.getRestoredMetadata(packageName); - PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); - if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage, pmi)) { + if (!BackupUtils.signaturesMatch(metaInfo.sigHashes, mCurrentPackage)) { Slog.w(TAG, "Signature mismatch restoring " + packageName); mMonitor = BackupManagerMonitorUtils.monitorEvent(mMonitor, BackupManagerMonitor.LOG_EVENT_ID_SIGNATURE_MISMATCH, mCurrentPackage, diff --git a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java index 90c1387fd176..6780563120e3 100644 --- a/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java +++ b/services/backup/java/com/android/server/backup/utils/AppBackupUtils.java @@ -25,7 +25,6 @@ import android.app.backup.BackupTransport; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.os.Process; import android.util.Slog; @@ -38,9 +37,6 @@ import com.android.server.backup.transport.TransportClient; * Utility methods wrapping operations on ApplicationInfo and PackageInfo. */ public class AppBackupUtils { - - private static final boolean DEBUG = false; - /** * Returns whether app is eligible for backup. * @@ -92,8 +88,7 @@ public class AppBackupUtils { public static boolean appIsRunningAndEligibleForBackupWithTransport( @Nullable TransportClient transportClient, String packageName, PackageManager pm) { try { - PackageInfo packageInfo = pm.getPackageInfo(packageName, - PackageManager.GET_SIGNING_CERTIFICATES); + PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); ApplicationInfo applicationInfo = packageInfo.applicationInfo; if (!appIsEligibleForBackup(applicationInfo, pm) || appIsStopped(applicationInfo) @@ -170,18 +165,12 @@ public class AppBackupUtils { * * <ul> * <li>Source and target have at least one signature each - * <li>Target contains all signatures in source, and nothing more + * <li>Target contains all signatures in source * </ul> * - * or if both source and target have exactly one signature, and they don't match, we check - * if the app was ever signed with source signature (i.e. app has rotated key) - * Note: key rotation is only supported for apps ever signed with one key, and those apps will - * not be allowed to be signed by more certificates in the future - * * Note that if {@param target} is null we return false. */ - public static boolean signaturesMatch(Signature[] storedSigs, PackageInfo target, - PackageManagerInternal pmi) { + public static boolean signaturesMatch(Signature[] storedSigs, PackageInfo target) { if (target == null) { return false; } @@ -198,52 +187,33 @@ public class AppBackupUtils { return true; } - // Don't allow unsigned apps on either end - if (ArrayUtils.isEmpty(storedSigs)) { - return false; + Signature[] deviceSigs = target.signatures; + if (MORE_DEBUG) { + Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceSigs); } - Signature[][] deviceHistorySigs = target.signingCertificateHistory; - if (ArrayUtils.isEmpty(deviceHistorySigs)) { - Slog.w(TAG, "signingCertificateHistory is empty, app was either unsigned or the flag" + - " PackageManager#GET_SIGNING_CERTIFICATES was not specified"); + // Don't allow unsigned apps on either end + if (ArrayUtils.isEmpty(storedSigs) || ArrayUtils.isEmpty(deviceSigs)) { return false; } - if (DEBUG) { - Slog.v(TAG, "signaturesMatch(): stored=" + storedSigs + " device=" + deviceHistorySigs); - } - - final int nStored = storedSigs.length; - if (nStored == 1) { - // if the app is only signed with one sig, it's possible it has rotated its key - // (the checks with signing history are delegated to PackageManager) - // TODO: address the case that app has declared restoreAnyVersion and is restoring - // from higher version to lower after having rotated the key (i.e. higher version has - // different sig than lower version that we want to restore to) - return pmi.isDataRestoreSafe(storedSigs[0], target.packageName); - } else { - // the app couldn't have rotated keys, since it was signed with multiple sigs - do - // a comprehensive 1-to-1 signatures check - // since app hasn't rotated key, we only need to check with deviceHistorySigs[0] - Signature[] deviceSigs = deviceHistorySigs[0]; - int nDevice = deviceSigs.length; - - // ensure that each stored sig matches an on-device sig - for (int i = 0; i < nStored; i++) { - boolean match = false; - for (int j = 0; j < nDevice; j++) { - if (storedSigs[i].equals(deviceSigs[j])) { - match = true; - break; - } - } - if (!match) { - return false; + // Signatures can be added over time, so the target-device apk needs to contain all the + // source-device apk signatures, but not necessarily the other way around. + int nStored = storedSigs.length; + int nDevice = deviceSigs.length; + + for (int i = 0; i < nStored; i++) { + boolean match = false; + for (int j = 0; j < nDevice; j++) { + if (storedSigs[i].equals(deviceSigs[j])) { + match = true; + break; } } - // we have found a match for all stored sigs - return true; + if (!match) { + return false; + } } + return true; } } diff --git a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java index df7e6d45ba0f..10f06954f17f 100644 --- a/services/backup/java/com/android/server/backup/utils/RestoreUtils.java +++ b/services/backup/java/com/android/server/backup/utils/RestoreUtils.java @@ -30,7 +30,6 @@ import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.Session; import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.os.Bundle; import android.os.IBinder; @@ -38,7 +37,6 @@ import android.os.Process; import android.util.Slog; import com.android.internal.annotations.GuardedBy; -import com.android.server.LocalServices; import com.android.server.backup.FileMetadata; import com.android.server.backup.restore.RestoreDeleteObserver; import com.android.server.backup.restore.RestorePolicy; @@ -144,8 +142,9 @@ public class RestoreUtils { uninstall = true; } else { try { - PackageInfo pkg = packageManager.getPackageInfo(info.packageName, - PackageManager.GET_SIGNING_CERTIFICATES); + PackageInfo pkg = packageManager.getPackageInfo( + info.packageName, + PackageManager.GET_SIGNATURES); if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_ALLOW_BACKUP) == 0) { Slog.w(TAG, "Restore stream contains apk of package " @@ -155,9 +154,7 @@ public class RestoreUtils { } else { // So far so good -- do the signatures match the manifest? Signature[] sigs = manifestSignatures.get(info.packageName); - PackageManagerInternal pmi = LocalServices.getService( - PackageManagerInternal.class); - if (AppBackupUtils.signaturesMatch(sigs, pkg, pmi)) { + if (AppBackupUtils.signaturesMatch(sigs, pkg)) { // If this is a system-uid app without a declared backup agent, // don't restore any of the file data. if ((pkg.applicationInfo.uid < Process.FIRST_APPLICATION_UID) diff --git a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java index 6dd5284879f0..cc26ff8b5090 100644 --- a/services/backup/java/com/android/server/backup/utils/TarBackupReader.java +++ b/services/backup/java/com/android/server/backup/utils/TarBackupReader.java @@ -50,7 +50,6 @@ import android.app.backup.IBackupManagerMonitor; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.os.Bundle; import android.os.Process; @@ -386,8 +385,7 @@ public class TarBackupReader { * @return a restore policy constant. */ public RestorePolicy chooseRestorePolicy(PackageManager packageManager, - boolean allowApks, FileMetadata info, Signature[] signatures, - PackageManagerInternal pmi) { + boolean allowApks, FileMetadata info, Signature[] signatures) { if (signatures == null) { return RestorePolicy.IGNORE; } @@ -397,7 +395,7 @@ public class TarBackupReader { // Okay, got the manifest info we need... try { PackageInfo pkgInfo = packageManager.getPackageInfo( - info.packageName, PackageManager.GET_SIGNING_CERTIFICATES); + info.packageName, PackageManager.GET_SIGNATURES); // Fall through to IGNORE if the app explicitly disallows backup final int flags = pkgInfo.applicationInfo.flags; if ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0) { @@ -413,7 +411,7 @@ public class TarBackupReader { // such packages are signed with the platform cert instead of // the app developer's cert, so they're different on every // device. - if (AppBackupUtils.signaturesMatch(signatures, pkgInfo, pmi)) { + if (AppBackupUtils.signaturesMatch(signatures, pkgInfo)) { if ((pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_RESTORE_ANY_VERSION) != 0) { Slog.i(TAG, "Package has restoreAnyVersion; taking data"); diff --git a/services/core/java/com/android/server/backup/BackupUtils.java b/services/core/java/com/android/server/backup/BackupUtils.java index f44afe458c4a..e5d564dec459 100644 --- a/services/core/java/com/android/server/backup/BackupUtils.java +++ b/services/core/java/com/android/server/backup/BackupUtils.java @@ -18,12 +18,9 @@ package com.android.server.backup; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.util.Slog; -import com.android.internal.util.ArrayUtils; - import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; @@ -33,10 +30,9 @@ import java.util.List; public class BackupUtils { private static final String TAG = "BackupUtils"; - private static final boolean DEBUG = false; + private static final boolean DEBUG = false; // STOPSHIP if true - public static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target, - PackageManagerInternal pmi) { + public static boolean signaturesMatch(ArrayList<byte[]> storedSigHashes, PackageInfo target) { if (target == null) { return false; } @@ -51,54 +47,48 @@ public class BackupUtils { return true; } - // Don't allow unsigned apps on either end - if (ArrayUtils.isEmpty(storedSigHashes)) { - return false; + // Allow unsigned apps, but not signed on one device and unsigned on the other + // !!! TODO: is this the right policy? + Signature[] deviceSigs = target.signatures; + if (DEBUG) Slog.v(TAG, "signaturesMatch(): stored=" + storedSigHashes + + " device=" + deviceSigs); + if ((storedSigHashes == null || storedSigHashes.size() == 0) + && (deviceSigs == null || deviceSigs.length == 0)) { + return true; } - - Signature[][] deviceHistorySigs = target.signingCertificateHistory; - if (ArrayUtils.isEmpty(deviceHistorySigs)) { - Slog.w(TAG, "signingCertificateHistory is empty, app was either unsigned or the flag" + - " PackageManager#GET_SIGNING_CERTIFICATES was not specified"); + if (storedSigHashes == null || deviceSigs == null) { return false; } - if (DEBUG) { - Slog.v(TAG, "signaturesMatch(): stored=" + storedSigHashes - + " device=" + deviceHistorySigs); + // !!! TODO: this demands that every stored signature match one + // that is present on device, and does not demand the converse. + // Is this this right policy? + final int nStored = storedSigHashes.size(); + final int nDevice = deviceSigs.length; + + // hash each on-device signature + ArrayList<byte[]> deviceHashes = new ArrayList<byte[]>(nDevice); + for (int i = 0; i < nDevice; i++) { + deviceHashes.add(hashSignature(deviceSigs[i])); } - final int nStored = storedSigHashes.size(); - if (nStored == 1) { - // if the app is only signed with one sig, it's possible it has rotated its key - // the checks with signing history are delegated to PackageManager - // TODO: address the case that app has declared restoreAnyVersion and is restoring - // from higher version to lower after having rotated the key (i.e. higher version has - // different sig than lower version that we want to restore to) - return pmi.isDataRestoreSafe(storedSigHashes.get(0), target.packageName); - } else { - // the app couldn't have rotated keys, since it was signed with multiple sigs - do - // a comprehensive 1-to-1 signatures check - // since app hasn't rotated key, we only need to check with deviceHistorySigs[0] - ArrayList<byte[]> deviceHashes = hashSignatureArray(deviceHistorySigs[0]); - int nDevice = deviceHashes.size(); - - // ensure that each stored sig matches an on-device sig - for (int i = 0; i < nStored; i++) { - boolean match = false; - for (int j = 0; j < nDevice; j++) { - if (Arrays.equals(storedSigHashes.get(i), deviceHashes.get(j))) { - match = true; - break; - } - } - if (!match) { - return false; + // now ensure that each stored sig (hash) matches an on-device sig (hash) + for (int n = 0; n < nStored; n++) { + boolean match = false; + final byte[] storedHash = storedSigHashes.get(n); + for (int i = 0; i < nDevice; i++) { + if (Arrays.equals(storedHash, deviceHashes.get(i))) { + match = true; + break; } } - // we have found a match for all stored sigs - return true; + // match is false when no on-device sig matched one of the stored ones + if (!match) { + return false; + } } + + return true; } public static byte[] hashSignature(byte[] signature) { diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 651368381d58..0da7b01fc0b5 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -176,7 +176,6 @@ import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.content.pm.PackageParser.ParseFlags; import android.content.pm.PackageParser.ServiceIntentInfo; -import android.content.pm.PackageParser.SigningDetails; import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion; import android.content.pm.PackageStats; import android.content.pm.PackageUserState; @@ -23329,39 +23328,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } @Override - public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) { - SigningDetails sd = getSigningDetails(packageName); - if (sd == null) { - return false; - } - return sd.hasSha256Certificate(restoringFromSigHash, - SigningDetails.CertCapabilities.INSTALLED_DATA); - } - - @Override - public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) { - SigningDetails sd = getSigningDetails(packageName); - if (sd == null) { - return false; - } - return sd.hasCertificate(restoringFromSig, - SigningDetails.CertCapabilities.INSTALLED_DATA); - } - - private SigningDetails getSigningDetails(String packageName) { - synchronized (mPackages) { - if (packageName == null) { - return null; - } - PackageParser.Package p = mPackages.get(packageName); - if (p == null) { - return null; - } - return p.mSigningDetails; - } - } - - @Override public int getPermissionFlagsTEMP(String permName, String packageName, int userId) { return PackageManagerService.this.getPermissionFlags(permName, packageName, userId); } diff --git a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java index 44dd924cd1f3..520ed2526b17 100644 --- a/services/core/java/com/android/server/pm/ShortcutPackageInfo.java +++ b/services/core/java/com/android/server/pm/ShortcutPackageInfo.java @@ -18,12 +18,10 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.pm.PackageInfo; -import android.content.pm.PackageManagerInternal; import android.content.pm.ShortcutInfo; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; -import com.android.server.LocalServices; import com.android.server.backup.BackupUtils; import libcore.util.HexEncoding; @@ -139,8 +137,7 @@ class ShortcutPackageInfo { //@DisabledReason public int canRestoreTo(ShortcutService s, PackageInfo currentPackage, boolean anyVersionOkay) { - PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); - if (!BackupUtils.signaturesMatch(mSigHashes, currentPackage, pmi)) { + if (!BackupUtils.signaturesMatch(mSigHashes, currentPackage)) { Slog.w(TAG, "Can't restore: Package signature mismatch"); return ShortcutInfo.DISABLED_REASON_SIGNATURE_MISMATCH; } diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 70fb616b5cb0..8c3518831b7b 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -3125,8 +3125,7 @@ public class ShortcutService extends IShortcutService.Stub { try { return mIPackageManager.getPackageInfo( packageName, PACKAGE_MATCH_FLAGS - | (getSignatures ? PackageManager.GET_SIGNING_CERTIFICATES : 0), - userId); + | (getSignatures ? PackageManager.GET_SIGNATURES : 0), userId); } catch (RemoteException e) { // Shouldn't happen. Slog.wtf(TAG, "RemoteException", e); diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java index 8ccacb8d5d91..86c83d6707b6 100644 --- a/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/utils/AppBackupUtilsTest.java @@ -18,14 +18,9 @@ package com.android.server.backup.utils; import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.os.Process; import android.platform.test.annotations.Presubmit; @@ -35,7 +30,6 @@ import android.support.test.runner.AndroidJUnit4; import com.android.server.backup.BackupManagerService; import com.android.server.backup.testutils.PackageManagerStub; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -51,14 +45,7 @@ public class AppBackupUtilsTest { private static final Signature SIGNATURE_3 = generateSignature((byte) 3); private static final Signature SIGNATURE_4 = generateSignature((byte) 4); - private PackageManagerStub mPackageManagerStub; - private PackageManagerInternal mMockPackageManagerInternal; - - @Before - public void setUp() throws Exception { - mPackageManagerStub = new PackageManagerStub(); - mMockPackageManagerInternal = mock(PackageManagerInternal.class); - } + private final PackageManagerStub mPackageManagerStub = new PackageManagerStub(); @Test public void appIsEligibleForBackup_backupNotAllowed_returnsFalse() throws Exception { @@ -371,8 +358,7 @@ public class AppBackupUtilsTest { @Test public void signaturesMatch_targetIsNull_returnsFalse() throws Exception { - boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, null, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, null); assertThat(result).isFalse(); } @@ -383,8 +369,7 @@ public class AppBackupUtilsTest { packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; - boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo); assertThat(result).isTrue(); } @@ -393,11 +378,10 @@ public class AppBackupUtilsTest { public void signaturesMatch_disallowsUnsignedApps_storedSignatureNull_returnsFalse() throws Exception { PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}}; + packageInfo.signatures = new Signature[] {SIGNATURE_1}; packageInfo.applicationInfo = new ApplicationInfo(); - boolean result = AppBackupUtils.signaturesMatch(null, packageInfo, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(null, packageInfo); assertThat(result).isFalse(); } @@ -406,11 +390,10 @@ public class AppBackupUtilsTest { public void signaturesMatch_disallowsUnsignedApps_storedSignatureEmpty_returnsFalse() throws Exception { PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}}; + packageInfo.signatures = new Signature[] {SIGNATURE_1}; packageInfo.applicationInfo = new ApplicationInfo(); - boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo); assertThat(result).isFalse(); } @@ -421,11 +404,11 @@ public class AppBackupUtilsTest { signaturesMatch_disallowsUnsignedApps_targetSignatureEmpty_returnsFalse() throws Exception { PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[0][0]; + packageInfo.signatures = new Signature[0]; packageInfo.applicationInfo = new ApplicationInfo(); - boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, + packageInfo); assertThat(result).isFalse(); } @@ -435,11 +418,11 @@ public class AppBackupUtilsTest { signaturesMatch_disallowsUnsignedApps_targetSignatureNull_returnsFalse() throws Exception { PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = null; + packageInfo.signatures = null; packageInfo.applicationInfo = new ApplicationInfo(); - boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, packageInfo, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(new Signature[] {SIGNATURE_1}, + packageInfo); assertThat(result).isFalse(); } @@ -448,11 +431,10 @@ public class AppBackupUtilsTest { public void signaturesMatch_disallowsUnsignedApps_bothSignaturesNull_returnsFalse() throws Exception { PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = null; + packageInfo.signatures = null; packageInfo.applicationInfo = new ApplicationInfo(); - boolean result = AppBackupUtils.signaturesMatch(null, packageInfo, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(null, packageInfo); assertThat(result).isFalse(); } @@ -461,11 +443,10 @@ public class AppBackupUtilsTest { public void signaturesMatch_disallowsUnsignedApps_bothSignaturesEmpty_returnsFalse() throws Exception { PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[0][0]; + packageInfo.signatures = new Signature[0]; packageInfo.applicationInfo = new ApplicationInfo(); - boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo, - mMockPackageManagerInternal); + boolean result = AppBackupUtils.signaturesMatch(new Signature[0], packageInfo); assertThat(result).isFalse(); } @@ -477,14 +458,11 @@ public class AppBackupUtilsTest { Signature signature3Copy = new Signature(SIGNATURE_3.toByteArray()); PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] { - {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3} - }; + packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}; packageInfo.applicationInfo = new ApplicationInfo(); boolean result = AppBackupUtils.signaturesMatch( - new Signature[] {signature3Copy, signature1Copy, signature2Copy}, packageInfo, - mMockPackageManagerInternal); + new Signature[]{signature3Copy, signature1Copy, signature2Copy}, packageInfo); assertThat(result).isTrue(); } @@ -495,14 +473,11 @@ public class AppBackupUtilsTest { Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray()); PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] { - {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3} - }; + packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}; packageInfo.applicationInfo = new ApplicationInfo(); boolean result = AppBackupUtils.signaturesMatch( - new Signature[]{signature2Copy, signature1Copy}, packageInfo, - mMockPackageManagerInternal); + new Signature[]{signature2Copy, signature1Copy}, packageInfo); assertThat(result).isTrue(); } @@ -513,14 +488,11 @@ public class AppBackupUtilsTest { Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray()); PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] { - {signature1Copy, signature2Copy} - }; + packageInfo.signatures = new Signature[]{signature1Copy, signature2Copy}; packageInfo.applicationInfo = new ApplicationInfo(); boolean result = AppBackupUtils.signaturesMatch( - new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}, packageInfo, - mMockPackageManagerInternal); + new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}, packageInfo); assertThat(result).isFalse(); } @@ -531,76 +503,11 @@ public class AppBackupUtilsTest { Signature signature2Copy = new Signature(SIGNATURE_2.toByteArray()); PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] { - {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3} - }; + packageInfo.signatures = new Signature[]{SIGNATURE_1, SIGNATURE_2, SIGNATURE_3}; packageInfo.applicationInfo = new ApplicationInfo(); boolean result = AppBackupUtils.signaturesMatch( - new Signature[]{signature1Copy, signature2Copy, SIGNATURE_4}, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - @Test - public void signaturesMatch_singleStoredSignatureNoRotation_returnsTrue() - throws Exception { - Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray()); - - PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}}; - packageInfo.applicationInfo = new ApplicationInfo(); - - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy, - packageInfo.packageName); - - boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy}, - packageInfo, mMockPackageManagerInternal); - - assertThat(result).isTrue(); - } - - @Test - public void signaturesMatch_singleStoredSignatureWithRotationAssumeDataCapability_returnsTrue() - throws Exception { - Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray()); - - PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}}; - packageInfo.applicationInfo = new ApplicationInfo(); - - // we know signature1Copy is in history, and we want to assume it has - // SigningDetails.CertCapabilities.INSTALLED_DATA capability - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy, - packageInfo.packageName); - - boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy}, - packageInfo, mMockPackageManagerInternal); - - assertThat(result).isTrue(); - } - - @Test - public void - signaturesMatch_singleStoredSignatureWithRotationAssumeNoDataCapability_returnsFalse() - throws Exception { - Signature signature1Copy = new Signature(SIGNATURE_1.toByteArray()); - - PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}}; - packageInfo.applicationInfo = new ApplicationInfo(); - - // we know signature1Copy is in history, but we want to assume it does not have - // SigningDetails.CertCapabilities.INSTALLED_DATA capability - doReturn(false).when(mMockPackageManagerInternal).isDataRestoreSafe(signature1Copy, - packageInfo.packageName); - - boolean result = AppBackupUtils.signaturesMatch(new Signature[] {signature1Copy}, - packageInfo, mMockPackageManagerInternal); + new Signature[]{signature1Copy, signature2Copy, SIGNATURE_4}, packageInfo); assertThat(result).isFalse(); } diff --git a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java index 5f052ceb2e26..0cdf04bda2d0 100644 --- a/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java +++ b/services/tests/servicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java @@ -28,9 +28,6 @@ import static android.app.backup.BackupManagerMonitor.LOG_EVENT_ID_VERSION_OF_BA import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; @@ -40,7 +37,6 @@ import android.app.backup.IBackupManagerMonitor; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; -import android.content.pm.PackageManagerInternal; import android.content.pm.Signature; import android.os.Bundle; import android.os.Process; @@ -83,7 +79,6 @@ public class TarBackupReaderTest { @Mock private BytesReadListener mBytesReadListenerMock; @Mock private IBackupManagerMonitor mBackupManagerMonitorMock; - @Mock private PackageManagerInternal mMockPackageManagerInternal; private final PackageManagerStub mPackageManagerStub = new PackageManagerStub(); private Context mContext; @@ -144,8 +139,7 @@ public class TarBackupReaderTest { Signature[] signatures = tarBackupReader.readAppManifestAndReturnSignatures( fileMetadata); RestorePolicy restorePolicy = tarBackupReader.chooseRestorePolicy( - mPackageManagerStub, false /* allowApks */, fileMetadata, signatures, - mMockPackageManagerInternal); + mPackageManagerStub, false /* allowApks */, fileMetadata, signatures); assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE); assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME); @@ -158,8 +152,7 @@ public class TarBackupReaderTest { signatures = tarBackupReader.readAppManifestAndReturnSignatures( fileMetadata); restorePolicy = tarBackupReader.chooseRestorePolicy( - mPackageManagerStub, false /* allowApks */, fileMetadata, signatures, - mMockPackageManagerInternal); + mPackageManagerStub, false /* allowApks */, fileMetadata, signatures); assertThat(restorePolicy).isEqualTo(RestorePolicy.IGNORE); assertThat(fileMetadata.packageName).isEqualTo(TEST_PACKAGE_NAME); @@ -221,8 +214,7 @@ public class TarBackupReaderTest { mBytesReadListenerMock, mBackupManagerMonitorMock); RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - true /* allowApks */, new FileMetadata(), null /* signatures */, - mMockPackageManagerInternal); + true /* allowApks */, new FileMetadata(), null /* signatures */); assertThat(policy).isEqualTo(RestorePolicy.IGNORE); verifyZeroInteractions(mBackupManagerMonitorMock); @@ -242,8 +234,7 @@ public class TarBackupReaderTest { PackageManagerStub.sPackageInfo = null; RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - true /* allowApks */, info, new Signature[0] /* signatures */, - mMockPackageManagerInternal); + true /* allowApks */, info, new Signature[0] /* signatures */); assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -267,8 +258,7 @@ public class TarBackupReaderTest { PackageManagerStub.sPackageInfo = null; RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - true /* allowApks */, info, new Signature[0] /* signatures */, - mMockPackageManagerInternal); + true /* allowApks */, info, new Signature[0] /* signatures */); assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -293,8 +283,7 @@ public class TarBackupReaderTest { PackageManagerStub.sPackageInfo = null; RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */, - mMockPackageManagerInternal); + false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */); assertThat(policy).isEqualTo(RestorePolicy.IGNORE); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -318,8 +307,7 @@ public class TarBackupReaderTest { PackageManagerStub.sPackageInfo = packageInfo; RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */, - mMockPackageManagerInternal); + false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */); assertThat(policy).isEqualTo(RestorePolicy.IGNORE); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -345,8 +333,7 @@ public class TarBackupReaderTest { PackageManagerStub.sPackageInfo = packageInfo; RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */, - mMockPackageManagerInternal); + false /* allowApks */, new FileMetadata(), new Signature[0] /* signatures */); assertThat(policy).isEqualTo(RestorePolicy.IGNORE); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -371,11 +358,11 @@ public class TarBackupReaderTest { packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; packageInfo.applicationInfo.backupAgentName = null; - packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_2}}; + packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_2}; PackageManagerStub.sPackageInfo = packageInfo; RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal); + false /* allowApks */, new FileMetadata(), signatures); assertThat(policy).isEqualTo(RestorePolicy.IGNORE); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -396,19 +383,16 @@ public class TarBackupReaderTest { Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION; packageInfo.applicationInfo.uid = Process.SYSTEM_UID; packageInfo.applicationInfo.backupAgentName = "backup.agent"; - packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}}; + packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1}; PackageManagerStub.sPackageInfo = packageInfo; - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, - packageInfo.packageName); RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal); + false /* allowApks */, new FileMetadata(), signatures); assertThat(policy).isEqualTo(RestorePolicy.ACCEPT); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -428,19 +412,16 @@ public class TarBackupReaderTest { Signature[] signatures = new Signature[]{FAKE_SIGNATURE_1}; PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP | ApplicationInfo.FLAG_RESTORE_ANY_VERSION; packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; packageInfo.applicationInfo.backupAgentName = null; - packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}}; + packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1}; PackageManagerStub.sPackageInfo = packageInfo; - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, - packageInfo.packageName); RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, new FileMetadata(), signatures, mMockPackageManagerInternal); + false /* allowApks */, new FileMetadata(), signatures); assertThat(policy).isEqualTo(RestorePolicy.ACCEPT); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -463,20 +444,17 @@ public class TarBackupReaderTest { info.version = 1; PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION; packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; packageInfo.applicationInfo.backupAgentName = null; - packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}}; + packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1}; packageInfo.versionCode = 2; PackageManagerStub.sPackageInfo = packageInfo; - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, - packageInfo.packageName); RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, info, signatures, mMockPackageManagerInternal); + false /* allowApks */, info, signatures); assertThat(policy).isEqualTo(RestorePolicy.ACCEPT); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); @@ -501,20 +479,17 @@ public class TarBackupReaderTest { info.hasApk = true; PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION; packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; packageInfo.applicationInfo.backupAgentName = null; - packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}}; + packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1}; packageInfo.versionCode = 1; PackageManagerStub.sPackageInfo = packageInfo; - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, - packageInfo.packageName); RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - true /* allowApks */, info, signatures, mMockPackageManagerInternal); + true /* allowApks */, info, signatures); assertThat(policy).isEqualTo(RestorePolicy.ACCEPT_IF_APK); verifyNoMoreInteractions(mBackupManagerMonitorMock); @@ -535,20 +510,17 @@ public class TarBackupReaderTest { info.version = 2; PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; packageInfo.applicationInfo = new ApplicationInfo(); packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_ALLOW_BACKUP; packageInfo.applicationInfo.flags &= ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION; packageInfo.applicationInfo.uid = Process.FIRST_APPLICATION_UID; packageInfo.applicationInfo.backupAgentName = null; - packageInfo.signingCertificateHistory = new Signature[][] {{FAKE_SIGNATURE_1}}; + packageInfo.signatures = new Signature[]{FAKE_SIGNATURE_1}; packageInfo.versionCode = 1; PackageManagerStub.sPackageInfo = packageInfo; - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(FAKE_SIGNATURE_1, - packageInfo.packageName); RestorePolicy policy = tarBackupReader.chooseRestorePolicy(mPackageManagerStub, - false /* allowApks */, info, signatures, mMockPackageManagerInternal); + false /* allowApks */, info, signatures); assertThat(policy).isEqualTo(RestorePolicy.IGNORE); ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); diff --git a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java index a0cefbfc58e9..c016e6104755 100644 --- a/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/backup/BackupUtilsTest.java @@ -15,298 +15,73 @@ */ package com.android.server.pm.backup; -import static com.google.common.truth.Truth.assertThat; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; -import android.content.pm.PackageManagerInternal; import android.content.pm.PackageParser.Package; import android.content.pm.Signature; +import android.test.AndroidTestCase; import android.test.MoreAsserts; -import android.platform.test.annotations.Presubmit; -import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; import com.android.server.backup.BackupUtils; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - import java.util.ArrayList; import java.util.Arrays; @SmallTest -@Presubmit -@RunWith(AndroidJUnit4.class) -public class BackupUtilsTest { - - private static final Signature SIGNATURE_1 = generateSignature((byte) 1); - private static final Signature SIGNATURE_2 = generateSignature((byte) 2); - private static final Signature SIGNATURE_3 = generateSignature((byte) 3); - private static final Signature SIGNATURE_4 = generateSignature((byte) 4); - private static final byte[] SIGNATURE_HASH_1 = BackupUtils.hashSignature(SIGNATURE_1); - private static final byte[] SIGNATURE_HASH_2 = BackupUtils.hashSignature(SIGNATURE_2); - private static final byte[] SIGNATURE_HASH_3 = BackupUtils.hashSignature(SIGNATURE_3); - private static final byte[] SIGNATURE_HASH_4 = BackupUtils.hashSignature(SIGNATURE_4); - - private PackageManagerInternal mMockPackageManagerInternal; - - @Before - public void setUp() throws Exception { - mMockPackageManagerInternal = mock(PackageManagerInternal.class); - } - - @Test - public void signaturesMatch_targetIsNull_returnsFalse() throws Exception { - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, null, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - @Test - public void signaturesMatch_systemApplication_returnsTrue() throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.applicationInfo = new ApplicationInfo(); - packageInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isTrue(); - } - - @Test - public void signaturesMatch_disallowsUnsignedApps_storedSignatureNull_returnsFalse() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}}; - packageInfo.applicationInfo = new ApplicationInfo(); - - boolean result = BackupUtils.signaturesMatch(null, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - @Test - public void signaturesMatch_disallowsUnsignedApps_storedSignatureEmpty_returnsFalse() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}}; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - - @Test - public void - signaturesMatch_disallowsUnsignedApps_targetSignatureEmpty_returnsFalse() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[0][0]; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - @Test - public void - signaturesMatch_disallowsUnsignedApps_targetSignatureNull_returnsFalse() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = null; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); +public class BackupUtilsTest extends AndroidTestCase { - assertThat(result).isFalse(); + private Signature[] genSignatures(String... signatures) { + final Signature[] sigs = new Signature[signatures.length]; + for (int i = 0; i < signatures.length; i++){ + sigs[i] = new Signature(signatures[i].getBytes()); + } + return sigs; } - @Test - public void signaturesMatch_disallowsUnsignedApps_bothSignaturesNull_returnsFalse() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = null; - packageInfo.applicationInfo = new ApplicationInfo(); + private PackageInfo genPackage(String... signatures) { + final PackageInfo pi = new PackageInfo(); + pi.packageName = "package"; + pi.applicationInfo = new ApplicationInfo(); + pi.signatures = genSignatures(signatures); - boolean result = BackupUtils.signaturesMatch(null, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - @Test - public void signaturesMatch_disallowsUnsignedApps_bothSignaturesEmpty_returnsFalse() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[0][0]; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); + return pi; } - @Test - public void signaturesMatch_equalSignatures_returnsTrue() throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] { - {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3} - }; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - storedSigHashes.add(SIGNATURE_HASH_2); - storedSigHashes.add(SIGNATURE_HASH_3); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isTrue(); - } - - @Test - public void signaturesMatch_extraSignatureInTarget_returnsTrue() throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] { - {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3} - }; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - storedSigHashes.add(SIGNATURE_HASH_2); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isTrue(); - } - - @Test - public void signaturesMatch_extraSignatureInStored_returnsFalse() throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1, SIGNATURE_2}}; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - storedSigHashes.add(SIGNATURE_HASH_2); - storedSigHashes.add(SIGNATURE_HASH_3); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - @Test - public void signaturesMatch_oneNonMatchingSignature_returnsFalse() throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.signingCertificateHistory = new Signature[][] { - {SIGNATURE_1, SIGNATURE_2, SIGNATURE_3} - }; - packageInfo.applicationInfo = new ApplicationInfo(); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - storedSigHashes.add(SIGNATURE_HASH_2); - storedSigHashes.add(SIGNATURE_HASH_4); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); - } - - @Test - public void signaturesMatch_singleStoredSignatureNoRotation_returnsTrue() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}}; - packageInfo.applicationInfo = new ApplicationInfo(); - - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(SIGNATURE_HASH_1, - packageInfo.packageName); - - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); + public void testSignaturesMatch() { + final ArrayList<byte[]> stored1 = BackupUtils.hashSignatureArray(Arrays.asList( + "abc".getBytes())); + final ArrayList<byte[]> stored2 = BackupUtils.hashSignatureArray(Arrays.asList( + "abc".getBytes(), "def".getBytes())); - assertThat(result).isTrue(); - } + PackageInfo pi; - @Test - public void signaturesMatch_singleStoredSignatureWithRotationAssumeDataCapability_returnsTrue() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}}; - packageInfo.applicationInfo = new ApplicationInfo(); + // False for null package. + assertFalse(BackupUtils.signaturesMatch(stored1, null)); - // we know SIGNATURE_1 is in history, and we want to assume it has - // SigningDetails.CertCapabilities.INSTALLED_DATA capability - doReturn(true).when(mMockPackageManagerInternal).isDataRestoreSafe(SIGNATURE_HASH_1, - packageInfo.packageName); + // If it's a system app, signatures don't matter. + pi = genPackage("xyz"); + pi.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM; + assertTrue(BackupUtils.signaturesMatch(stored1, pi)); - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); + // Non system apps. + assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("abc"))); - assertThat(result).isTrue(); - } + // Superset is okay. + assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("abc", "xyz"))); + assertTrue(BackupUtils.signaturesMatch(stored1, genPackage("xyz", "abc"))); - @Test - public void - signaturesMatch_singleStoredSignatureWithRotationAssumeNoDataCapability_returnsFalse() - throws Exception { - PackageInfo packageInfo = new PackageInfo(); - packageInfo.packageName = "test"; - packageInfo.signingCertificateHistory = new Signature[][] {{SIGNATURE_1}, {SIGNATURE_2}}; - packageInfo.applicationInfo = new ApplicationInfo(); + assertFalse(BackupUtils.signaturesMatch(stored1, genPackage("xyz"))); + assertFalse(BackupUtils.signaturesMatch(stored1, genPackage("xyz", "def"))); - // we know SIGNATURE_1 is in history, but we want to assume it does not have - // SigningDetails.CertCapabilities.INSTALLED_DATA capability - doReturn(false).when(mMockPackageManagerInternal).isDataRestoreSafe(SIGNATURE_HASH_1, - packageInfo.packageName); + assertTrue(BackupUtils.signaturesMatch(stored2, genPackage("def", "abc"))); + assertTrue(BackupUtils.signaturesMatch(stored2, genPackage("x", "def", "abc", "y"))); - ArrayList<byte[]> storedSigHashes = new ArrayList<>(); - storedSigHashes.add(SIGNATURE_HASH_1); - boolean result = BackupUtils.signaturesMatch(storedSigHashes, packageInfo, - mMockPackageManagerInternal); - - assertThat(result).isFalse(); + // Subset is not okay. + assertFalse(BackupUtils.signaturesMatch(stored2, genPackage("abc"))); + assertFalse(BackupUtils.signaturesMatch(stored2, genPackage("def"))); } - @Test public void testHashSignature() { final byte[] sig1 = "abc".getBytes(); final byte[] sig2 = "def".getBytes(); @@ -340,10 +115,4 @@ public class BackupUtilsTest { MoreAsserts.assertEquals(hash2a, listA.get(1)); MoreAsserts.assertEquals(hash2a, listB.get(1)); } - - private static Signature generateSignature(byte i) { - byte[] signatureBytes = new byte[256]; - signatureBytes[0] = i; - return new Signature(signatureBytes); - } } |