Merge "Extract source stamp during app install" into rvc-dev am: 759dbb7cf6
Change-Id: Ia7aee5979b5efd2ec99fe6bd026e1b522af84f08
This commit is contained in:
@@ -42,6 +42,8 @@ public final class AppInstallMetadata {
|
||||
private final List<String> mInstallerCertificates;
|
||||
private final long mVersionCode;
|
||||
private final boolean mIsPreInstalled;
|
||||
private final boolean mIsStampPresent;
|
||||
private final boolean mIsStampVerified;
|
||||
private final boolean mIsStampTrusted;
|
||||
// Raw string encoding for the SHA-256 hash of the certificate of the stamp.
|
||||
private final String mStampCertificateHash;
|
||||
@@ -54,6 +56,8 @@ public final class AppInstallMetadata {
|
||||
this.mInstallerCertificates = builder.mInstallerCertificates;
|
||||
this.mVersionCode = builder.mVersionCode;
|
||||
this.mIsPreInstalled = builder.mIsPreInstalled;
|
||||
this.mIsStampPresent = builder.mIsStampPresent;
|
||||
this.mIsStampVerified = builder.mIsStampVerified;
|
||||
this.mIsStampTrusted = builder.mIsStampTrusted;
|
||||
this.mStampCertificateHash = builder.mStampCertificateHash;
|
||||
this.mAllowedInstallersAndCertificates = builder.mAllowedInstallersAndCertificates;
|
||||
@@ -89,6 +93,16 @@ public final class AppInstallMetadata {
|
||||
return mIsPreInstalled;
|
||||
}
|
||||
|
||||
/** @see AppInstallMetadata.Builder#setIsStampPresent(boolean) */
|
||||
public boolean isStampPresent() {
|
||||
return mIsStampPresent;
|
||||
}
|
||||
|
||||
/** @see AppInstallMetadata.Builder#setIsStampVerified(boolean) */
|
||||
public boolean isStampVerified() {
|
||||
return mIsStampVerified;
|
||||
}
|
||||
|
||||
/** @see AppInstallMetadata.Builder#setIsStampTrusted(boolean) */
|
||||
public boolean isStampTrusted() {
|
||||
return mIsStampTrusted;
|
||||
@@ -108,14 +122,16 @@ public final class AppInstallMetadata {
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"AppInstallMetadata { PackageName = %s, AppCerts = %s, InstallerName = %s,"
|
||||
+ " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, "
|
||||
+ "StampTrusted = %b, StampCert = %s }",
|
||||
+ " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, StampPresent ="
|
||||
+ " %b, StampVerified = %b, StampTrusted = %b, StampCert = %s }",
|
||||
mPackageName,
|
||||
mAppCertificates,
|
||||
mInstallerName == null ? "null" : mInstallerName,
|
||||
mInstallerCertificates == null ? "null" : mInstallerCertificates,
|
||||
mVersionCode,
|
||||
mIsPreInstalled,
|
||||
mIsStampPresent,
|
||||
mIsStampVerified,
|
||||
mIsStampTrusted,
|
||||
mStampCertificateHash == null ? "null" : mStampCertificateHash);
|
||||
}
|
||||
@@ -128,6 +144,8 @@ public final class AppInstallMetadata {
|
||||
private List<String> mInstallerCertificates;
|
||||
private long mVersionCode;
|
||||
private boolean mIsPreInstalled;
|
||||
private boolean mIsStampPresent;
|
||||
private boolean mIsStampVerified;
|
||||
private boolean mIsStampTrusted;
|
||||
private String mStampCertificateHash;
|
||||
private Map<String, String> mAllowedInstallersAndCertificates;
|
||||
@@ -221,16 +239,24 @@ public final class AppInstallMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set certificate hash of the stamp embedded in the APK.
|
||||
* Set whether the stamp embedded in the APK is present or not.
|
||||
*
|
||||
* <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
|
||||
* of the stamp.
|
||||
*
|
||||
* @see AppInstallMetadata#getStampCertificateHash()
|
||||
* @see AppInstallMetadata#isStampPresent()
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setStampCertificateHash(@NonNull String stampCertificateHash) {
|
||||
this.mStampCertificateHash = Objects.requireNonNull(stampCertificateHash);
|
||||
public Builder setIsStampPresent(boolean isStampPresent) {
|
||||
this.mIsStampPresent = isStampPresent;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether the stamp embedded in the APK is verified or not.
|
||||
*
|
||||
* @see AppInstallMetadata#isStampVerified()
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setIsStampVerified(boolean isStampVerified) {
|
||||
this.mIsStampVerified = isStampVerified;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -245,6 +271,20 @@ public final class AppInstallMetadata {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set certificate hash of the stamp embedded in the APK.
|
||||
*
|
||||
* <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
|
||||
* of the stamp.
|
||||
*
|
||||
* @see AppInstallMetadata#getStampCertificateHash()
|
||||
*/
|
||||
@NonNull
|
||||
public Builder setStampCertificateHash(@NonNull String stampCertificateHash) {
|
||||
this.mStampCertificateHash = Objects.requireNonNull(stampCertificateHash);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build {@link AppInstallMetadata}.
|
||||
*
|
||||
|
||||
@@ -368,11 +368,10 @@ public abstract class AtomicFormula extends IntegrityFormula {
|
||||
"Key %s cannot be used with StringAtomicFormula", keyToString(key)));
|
||||
mValue = hashValue(key, value);
|
||||
mIsHashedValue =
|
||||
key == APP_CERTIFICATE
|
||||
(key == APP_CERTIFICATE
|
||||
|| key == INSTALLER_CERTIFICATE
|
||||
|| key == STAMP_CERTIFICATE_HASH
|
||||
? true
|
||||
: !mValue.equals(value);
|
||||
|| key == STAMP_CERTIFICATE_HASH)
|
||||
|| !mValue.equals(value);
|
||||
}
|
||||
|
||||
StringAtomicFormula(Parcel in) {
|
||||
|
||||
@@ -52,7 +52,10 @@ import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.security.FileIntegrityManager;
|
||||
import android.util.Slog;
|
||||
import android.util.apk.SourceStampVerificationResult;
|
||||
import android.util.apk.SourceStampVerifier;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
@@ -108,8 +111,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
private static final String ALLOWED_INSTALLER_DELIMITER = ",";
|
||||
private static final String INSTALLER_PACKAGE_CERT_DELIMITER = "\\|";
|
||||
|
||||
private static final Set<String> PACKAGE_INSTALLER = new HashSet<>(
|
||||
Arrays.asList("com.google.android.packageinstaller", "com.android.packageinstaller"));
|
||||
private static final Set<String> PACKAGE_INSTALLER =
|
||||
new HashSet<>(
|
||||
Arrays.asList(
|
||||
"com.google.android.packageinstaller", "com.android.packageinstaller"));
|
||||
|
||||
// Access to files inside mRulesDir is protected by mRulesLock;
|
||||
private final Context mContext;
|
||||
@@ -117,6 +122,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
private final PackageManagerInternal mPackageManagerInternal;
|
||||
private final RuleEvaluationEngine mEvaluationEngine;
|
||||
private final IntegrityFileManager mIntegrityFileManager;
|
||||
private final FileIntegrityManager mFileIntegrityManager;
|
||||
|
||||
/** Create an instance of {@link AppIntegrityManagerServiceImpl}. */
|
||||
public static AppIntegrityManagerServiceImpl create(Context context) {
|
||||
@@ -128,6 +134,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
LocalServices.getService(PackageManagerInternal.class),
|
||||
RuleEvaluationEngine.getRuleEvaluationEngine(),
|
||||
IntegrityFileManager.getInstance(),
|
||||
(FileIntegrityManager) context.getSystemService(Context.FILE_INTEGRITY_SERVICE),
|
||||
handlerThread.getThreadHandler());
|
||||
}
|
||||
|
||||
@@ -137,11 +144,13 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
PackageManagerInternal packageManagerInternal,
|
||||
RuleEvaluationEngine evaluationEngine,
|
||||
IntegrityFileManager integrityFileManager,
|
||||
FileIntegrityManager fileIntegrityManager,
|
||||
Handler handler) {
|
||||
mContext = context;
|
||||
mPackageManagerInternal = packageManagerInternal;
|
||||
mEvaluationEngine = evaluationEngine;
|
||||
mIntegrityFileManager = integrityFileManager;
|
||||
mFileIntegrityManager = fileIntegrityManager;
|
||||
mHandler = handler;
|
||||
|
||||
IntentFilter integrityVerificationFilter = new IntentFilter();
|
||||
@@ -183,8 +192,11 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
success = false;
|
||||
}
|
||||
|
||||
FrameworkStatsLog.write(FrameworkStatsLog.INTEGRITY_RULES_PUSHED, success,
|
||||
ruleProvider, version);
|
||||
FrameworkStatsLog.write(
|
||||
FrameworkStatsLog.INTEGRITY_RULES_PUSHED,
|
||||
success,
|
||||
ruleProvider,
|
||||
version);
|
||||
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_STATUS, success ? STATUS_SUCCESS : STATUS_FAILURE);
|
||||
@@ -242,8 +254,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
String installerPackageName = getInstallerPackageName(intent);
|
||||
|
||||
// Skip integrity verification if the verifier is doing the install.
|
||||
if (!integrityCheckIncludesRuleProvider()
|
||||
&& isRuleProvider(installerPackageName)) {
|
||||
if (!integrityCheckIncludesRuleProvider() && isRuleProvider(installerPackageName)) {
|
||||
Slog.i(TAG, "Verifier doing the install. Skipping integrity check.");
|
||||
mPackageManagerInternal.setIntegrityVerificationResult(
|
||||
verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
|
||||
@@ -274,15 +285,17 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
builder.setInstallerCertificates(installerCertificates);
|
||||
builder.setIsPreInstalled(isSystemApp(packageName));
|
||||
builder.setAllowedInstallersAndCert(getAllowedInstallers(packageInfo));
|
||||
extractSourceStamp(intent.getData(), builder);
|
||||
|
||||
AppInstallMetadata appInstallMetadata = builder.build();
|
||||
|
||||
Slog.i(
|
||||
TAG,
|
||||
"To be verified: " + appInstallMetadata + " installers " + getAllowedInstallers(
|
||||
packageInfo));
|
||||
IntegrityCheckResult result =
|
||||
mEvaluationEngine.evaluate(appInstallMetadata);
|
||||
"To be verified: "
|
||||
+ appInstallMetadata
|
||||
+ " installers "
|
||||
+ getAllowedInstallers(packageInfo));
|
||||
IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata);
|
||||
Slog.i(
|
||||
TAG,
|
||||
"Integrity check result: "
|
||||
@@ -323,7 +336,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
* Verify the UID and return the installer package name.
|
||||
*
|
||||
* @return the package name of the installer, or null if it cannot be determined or it is
|
||||
* installed via adb.
|
||||
* installed via adb.
|
||||
*/
|
||||
@Nullable
|
||||
private String getInstallerPackageName(Intent intent) {
|
||||
@@ -442,7 +455,8 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
String cert = packageAndCert[1];
|
||||
packageCertMap.put(packageName, cert);
|
||||
} else if (packageAndCert.length == 1) {
|
||||
packageCertMap.put(getPackageNameNormalized(packageAndCert[0]),
|
||||
packageCertMap.put(
|
||||
getPackageNameNormalized(packageAndCert[0]),
|
||||
INSTALLER_CERTIFICATE_NOT_EVALUATED);
|
||||
}
|
||||
}
|
||||
@@ -452,6 +466,41 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
return packageCertMap;
|
||||
}
|
||||
|
||||
/** Extract the source stamp embedded in the APK, if present. */
|
||||
private void extractSourceStamp(Uri dataUri, AppInstallMetadata.Builder appInstallMetadata) {
|
||||
File installationPath = getInstallationPath(dataUri);
|
||||
if (installationPath == null) {
|
||||
throw new IllegalArgumentException("Installation path is null, package not found");
|
||||
}
|
||||
SourceStampVerificationResult sourceStampVerificationResult =
|
||||
SourceStampVerifier.verify(installationPath.getAbsolutePath());
|
||||
appInstallMetadata.setIsStampPresent(sourceStampVerificationResult.isPresent());
|
||||
appInstallMetadata.setIsStampVerified(sourceStampVerificationResult.isVerified());
|
||||
if (sourceStampVerificationResult.isVerified()) {
|
||||
X509Certificate sourceStampCertificate =
|
||||
(X509Certificate) sourceStampVerificationResult.getCertificate();
|
||||
// Sets source stamp certificate digest.
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
byte[] certificateDigest = digest.digest(sourceStampCertificate.getEncoded());
|
||||
appInstallMetadata.setStampCertificateHash(getHexDigest(certificateDigest));
|
||||
} catch (NoSuchAlgorithmException | CertificateEncodingException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Error computing source stamp certificate digest", e);
|
||||
}
|
||||
// Checks if the source stamp certificate is trusted.
|
||||
try {
|
||||
appInstallMetadata.setIsStampTrusted(
|
||||
mFileIntegrityManager.isApkVeritySupported()
|
||||
&& mFileIntegrityManager.isAppSourceCertificateTrusted(
|
||||
sourceStampCertificate));
|
||||
} catch (CertificateEncodingException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"Error checking if source stamp certificate is trusted", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Signature[] getSignatures(@NonNull PackageInfo packageInfo) {
|
||||
SigningInfo signingInfo = packageInfo.signingInfo;
|
||||
|
||||
@@ -505,8 +554,16 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
ParsedPackage pkg = parser.parsePackage(installationPath, 0, false);
|
||||
int flags = PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_META_DATA;
|
||||
pkg.setSigningDetails(ParsingPackageUtils.collectCertificates(pkg, false));
|
||||
return PackageInfoUtils.generate(pkg, null, flags, 0, 0, null, new PackageUserState(),
|
||||
UserHandle.getCallingUserId(), null);
|
||||
return PackageInfoUtils.generate(
|
||||
pkg,
|
||||
null,
|
||||
flags,
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
new PackageUserState(),
|
||||
UserHandle.getCallingUserId(),
|
||||
null);
|
||||
} catch (Exception e) {
|
||||
Slog.w(TAG, "Exception reading " + dataUri, e);
|
||||
return null;
|
||||
@@ -633,9 +690,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
|
||||
|
||||
private boolean integrityCheckIncludesRuleProvider() {
|
||||
return Settings.Global.getInt(
|
||||
mContext.getContentResolver(),
|
||||
Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
|
||||
0)
|
||||
mContext.getContentResolver(),
|
||||
Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
|
||||
0)
|
||||
== 1;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -28,6 +28,7 @@ import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
@@ -61,6 +62,7 @@ import android.net.Uri;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.provider.Settings;
|
||||
import android.security.FileIntegrityManager;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
@@ -96,6 +98,9 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
private static final String TEST_APP_TWO_CERT_PATH =
|
||||
"AppIntegrityManagerServiceImplTest/DummyAppTwoCerts.apk";
|
||||
|
||||
private static final String TEST_APP_SOURCE_STAMP_PATH =
|
||||
"AppIntegrityManagerServiceImplTest/SourceStampTestApk.apk";
|
||||
|
||||
private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
|
||||
private static final String VERSION = "version";
|
||||
private static final String TEST_FRAMEWORK_PACKAGE = "com.android.frameworks.servicestests";
|
||||
@@ -111,6 +116,8 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
// We use SHA256 for package names longer than 32 characters.
|
||||
private static final String INSTALLER_SHA256 =
|
||||
"30F41A7CBF96EE736A54DD6DF759B50ED3CC126ABCEF694E167C324F5976C227";
|
||||
private static final String SOURCE_STAMP_CERTIFICATE_HASH =
|
||||
"681B0E56A796350C08647352A4DB800CC44B2ADC8F4C72FA350BD05D4D50264D";
|
||||
|
||||
private static final String DUMMY_APP_TWO_CERTS_CERT_1 =
|
||||
"C0369C2A1096632429DFA8433068AECEAD00BAC337CA92A175036D39CC9AFE94";
|
||||
@@ -121,27 +128,22 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
private static final String ADB_INSTALLER = "adb";
|
||||
private static final String PLAY_STORE_CERT = "play_store_cert";
|
||||
|
||||
@org.junit.Rule
|
||||
public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
@org.junit.Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
PackageManagerInternal mPackageManagerInternal;
|
||||
@Mock
|
||||
Context mMockContext;
|
||||
@Mock
|
||||
Resources mMockResources;
|
||||
@Mock
|
||||
RuleEvaluationEngine mRuleEvaluationEngine;
|
||||
@Mock
|
||||
IntegrityFileManager mIntegrityFileManager;
|
||||
@Mock
|
||||
Handler mHandler;
|
||||
@Mock PackageManagerInternal mPackageManagerInternal;
|
||||
@Mock Context mMockContext;
|
||||
@Mock Resources mMockResources;
|
||||
@Mock RuleEvaluationEngine mRuleEvaluationEngine;
|
||||
@Mock IntegrityFileManager mIntegrityFileManager;
|
||||
@Mock Handler mHandler;
|
||||
FileIntegrityManager mFileIntegrityManager;
|
||||
|
||||
private final Context mRealContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
private PackageManager mSpyPackageManager;
|
||||
private File mTestApk;
|
||||
private File mTestApkTwoCerts;
|
||||
private File mTestApkSourceStamp;
|
||||
|
||||
// under test
|
||||
private AppIntegrityManagerServiceImpl mService;
|
||||
@@ -158,19 +160,28 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
Files.copy(inputStream, mTestApkTwoCerts.toPath(), REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
mTestApkSourceStamp = File.createTempFile("AppIntegritySourceStamp", ".apk");
|
||||
try (InputStream inputStream = mRealContext.getAssets().open(TEST_APP_SOURCE_STAMP_PATH)) {
|
||||
Files.copy(inputStream, mTestApkSourceStamp.toPath(), REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
mFileIntegrityManager =
|
||||
(FileIntegrityManager)
|
||||
mRealContext.getSystemService(Context.FILE_INTEGRITY_SERVICE);
|
||||
mService =
|
||||
new AppIntegrityManagerServiceImpl(
|
||||
mMockContext,
|
||||
mPackageManagerInternal,
|
||||
mRuleEvaluationEngine,
|
||||
mIntegrityFileManager,
|
||||
mFileIntegrityManager,
|
||||
mHandler);
|
||||
|
||||
mSpyPackageManager = spy(mRealContext.getPackageManager());
|
||||
// setup mocks to prevent NPE
|
||||
when(mMockContext.getPackageManager()).thenReturn(mSpyPackageManager);
|
||||
when(mMockContext.getResources()).thenReturn(mMockResources);
|
||||
when(mMockResources.getStringArray(anyInt())).thenReturn(new String[]{});
|
||||
when(mMockResources.getStringArray(anyInt())).thenReturn(new String[] {});
|
||||
when(mIntegrityFileManager.initialized()).thenReturn(true);
|
||||
// These are needed to override the Settings.Global.get result.
|
||||
when(mMockContext.getContentResolver()).thenReturn(mRealContext.getContentResolver());
|
||||
@@ -181,6 +192,7 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
public void tearDown() throws Exception {
|
||||
mTestApk.delete();
|
||||
mTestApkTwoCerts.delete();
|
||||
mTestApkSourceStamp.delete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -241,7 +253,8 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
IntentSender mockReceiver = mock(IntentSender.class);
|
||||
List<Rule> rules =
|
||||
Arrays.asList(
|
||||
new Rule(IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME),
|
||||
new Rule(
|
||||
IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME),
|
||||
Rule.DENY));
|
||||
|
||||
mService.updateRuleSet(VERSION, new ParceledListSlice<>(rules), mockReceiver);
|
||||
@@ -261,7 +274,8 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
IntentSender mockReceiver = mock(IntentSender.class);
|
||||
List<Rule> rules =
|
||||
Arrays.asList(
|
||||
new Rule(IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME),
|
||||
new Rule(
|
||||
IntegrityFormula.Application.packageNameEquals(PACKAGE_NAME),
|
||||
Rule.DENY));
|
||||
|
||||
mService.updateRuleSet(VERSION, new ParceledListSlice<>(rules), mockReceiver);
|
||||
@@ -305,8 +319,7 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
|
||||
ArgumentCaptor<AppInstallMetadata> metadataCaptor =
|
||||
ArgumentCaptor.forClass(AppInstallMetadata.class);
|
||||
verify(mRuleEvaluationEngine)
|
||||
.evaluate(metadataCaptor.capture());
|
||||
verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture());
|
||||
AppInstallMetadata appInstallMetadata = metadataCaptor.getValue();
|
||||
assertEquals(PACKAGE_NAME, appInstallMetadata.getPackageName());
|
||||
assertThat(appInstallMetadata.getAppCertificates()).containsExactly(APP_CERT);
|
||||
@@ -341,8 +354,33 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
ArgumentCaptor.forClass(AppInstallMetadata.class);
|
||||
verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture());
|
||||
AppInstallMetadata appInstallMetadata = metadataCaptor.getValue();
|
||||
assertThat(appInstallMetadata.getAppCertificates()).containsExactly(
|
||||
DUMMY_APP_TWO_CERTS_CERT_1, DUMMY_APP_TWO_CERTS_CERT_2);
|
||||
assertThat(appInstallMetadata.getAppCertificates())
|
||||
.containsExactly(DUMMY_APP_TWO_CERTS_CERT_1, DUMMY_APP_TWO_CERTS_CERT_2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleBroadcast_correctArgs_sourceStamp() throws Exception {
|
||||
whitelistUsAsRuleProvider();
|
||||
makeUsSystemApp();
|
||||
ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
|
||||
ArgumentCaptor.forClass(BroadcastReceiver.class);
|
||||
verify(mMockContext)
|
||||
.registerReceiver(broadcastReceiverCaptor.capture(), any(), any(), any());
|
||||
Intent intent = makeVerificationIntent();
|
||||
intent.setDataAndType(Uri.fromFile(mTestApkSourceStamp), PACKAGE_MIME_TYPE);
|
||||
when(mRuleEvaluationEngine.evaluate(any())).thenReturn(IntegrityCheckResult.allow());
|
||||
|
||||
broadcastReceiverCaptor.getValue().onReceive(mMockContext, intent);
|
||||
runJobInHandler();
|
||||
|
||||
ArgumentCaptor<AppInstallMetadata> metadataCaptor =
|
||||
ArgumentCaptor.forClass(AppInstallMetadata.class);
|
||||
verify(mRuleEvaluationEngine).evaluate(metadataCaptor.capture());
|
||||
AppInstallMetadata appInstallMetadata = metadataCaptor.getValue();
|
||||
assertTrue(appInstallMetadata.isStampPresent());
|
||||
assertTrue(appInstallMetadata.isStampVerified());
|
||||
assertFalse(appInstallMetadata.isStampTrusted());
|
||||
assertEquals(SOURCE_STAMP_CERTIFICATE_HASH, appInstallMetadata.getStampCertificateHash());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -445,7 +483,7 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
private void whitelistUsAsRuleProvider() {
|
||||
Resources mockResources = mock(Resources.class);
|
||||
when(mockResources.getStringArray(R.array.config_integrityRuleProviderPackages))
|
||||
.thenReturn(new String[]{TEST_FRAMEWORK_PACKAGE});
|
||||
.thenReturn(new String[] {TEST_FRAMEWORK_PACKAGE});
|
||||
when(mMockContext.getResources()).thenReturn(mockResources);
|
||||
}
|
||||
|
||||
@@ -478,8 +516,8 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
PackageInfo packageInfo =
|
||||
mRealContext
|
||||
.getPackageManager()
|
||||
.getPackageInfo(TEST_FRAMEWORK_PACKAGE,
|
||||
PackageManager.GET_SIGNING_CERTIFICATES);
|
||||
.getPackageInfo(
|
||||
TEST_FRAMEWORK_PACKAGE, PackageManager.GET_SIGNING_CERTIFICATES);
|
||||
doReturn(packageInfo).when(mSpyPackageManager).getPackageInfo(eq(INSTALLER), anyInt());
|
||||
doReturn(1).when(mSpyPackageManager).getPackageUid(eq(INSTALLER), anyInt());
|
||||
return makeVerificationIntent(INSTALLER);
|
||||
@@ -501,10 +539,16 @@ public class AppIntegrityManagerServiceImplTest {
|
||||
|
||||
private void setIntegrityCheckIncludesRuleProvider(boolean shouldInclude) throws Exception {
|
||||
int value = shouldInclude ? 1 : 0;
|
||||
Settings.Global.putInt(mRealContext.getContentResolver(),
|
||||
Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, value);
|
||||
assertThat(Settings.Global.getInt(mRealContext.getContentResolver(),
|
||||
Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER, -1) == 1).isEqualTo(
|
||||
shouldInclude);
|
||||
Settings.Global.putInt(
|
||||
mRealContext.getContentResolver(),
|
||||
Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
|
||||
value);
|
||||
assertThat(
|
||||
Settings.Global.getInt(
|
||||
mRealContext.getContentResolver(),
|
||||
Settings.Global.INTEGRITY_CHECK_INCLUDES_RULE_PROVIDER,
|
||||
-1)
|
||||
== 1)
|
||||
.isEqualTo(shouldInclude);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user