Merge "Implement the necessary methods for identifying the DENY / FORCE_ALLOW causes for logging purposes."

This commit is contained in:
TreeHugger Robot
2020-01-29 14:36:21 +00:00
committed by Android (Google) Code Review
10 changed files with 307 additions and 31 deletions

View File

@@ -204,6 +204,16 @@ public abstract class AtomicFormula extends IntegrityFormula {
}
}
@Override
public boolean isAppCertificateFormula() {
return false;
}
@Override
public boolean isInstallerFormula() {
return false;
}
@Override
public String toString() {
if (mValue == null || mOperator == null) {
@@ -374,6 +384,16 @@ public abstract class AtomicFormula extends IntegrityFormula {
return getStringMetadataValue(appInstallMetadata, getKey()).equals(mValue);
}
@Override
public boolean isAppCertificateFormula() {
return getKey() == APP_CERTIFICATE;
}
@Override
public boolean isInstallerFormula() {
return getKey() == INSTALLER_NAME || getKey() == INSTALLER_CERTIFICATE;
}
@Override
public String toString() {
if (mValue == null || mIsHashedValue == null) {
@@ -530,6 +550,16 @@ public abstract class AtomicFormula extends IntegrityFormula {
return getBooleanMetadataValue(appInstallMetadata, getKey()) == mValue;
}
@Override
public boolean isAppCertificateFormula() {
return false;
}
@Override
public boolean isInstallerFormula() {
return false;
}
@Override
public String toString() {
if (mValue == null) {

View File

@@ -130,6 +130,16 @@ public final class CompoundFormula extends IntegrityFormula implements Parcelabl
}
}
@Override
public boolean isAppCertificateFormula() {
return getFormulas().stream().anyMatch(formula -> formula.isAppCertificateFormula());
}
@Override
public boolean isInstallerFormula() {
return getFormulas().stream().anyMatch(formula -> formula.isInstallerFormula());
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();

View File

@@ -135,6 +135,21 @@ public abstract class IntegrityFormula {
*/
public abstract @Tag boolean matches(AppInstallMetadata appInstallMetadata);
/**
* Returns true when the formula (or one of its atomic formulas) has app certificate as key.
*
* @hide
*/
public abstract @Tag boolean isAppCertificateFormula();
/**
* Returns true when the formula (or one of its atomic formulas) has installer package name
* or installer certificate as key.
*
* @hide
*/
public abstract @Tag boolean isInstallerFormula();
/**
* Write an {@link IntegrityFormula} to {@link android.os.Parcel}.
*

View File

@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.testng.Assert.expectThrows;
import android.content.integrity.AtomicFormula.BooleanAtomicFormula;
import android.content.integrity.AtomicFormula.LongAtomicFormula;
import android.content.integrity.AtomicFormula.StringAtomicFormula;
import android.os.Parcel;
@@ -114,8 +115,8 @@ public class AtomicFormulaTest {
@Test
public void testValidAtomicFormula_longValue() {
AtomicFormula.LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.GTE, 1);
assertThat(longAtomicFormula.getKey()).isEqualTo(AtomicFormula.VERSION_CODE);
@@ -151,7 +152,7 @@ public class AtomicFormulaTest {
expectThrows(
IllegalArgumentException.class,
() ->
new AtomicFormula.LongAtomicFormula(
new LongAtomicFormula(
AtomicFormula.PACKAGE_NAME, AtomicFormula.EQ, 1));
assertThat(e.getMessage()).matches(
"Key PACKAGE_NAME cannot be used with LongAtomicFormula");
@@ -182,14 +183,14 @@ public class AtomicFormulaTest {
@Test
public void testParcelUnparcel_int() {
AtomicFormula.LongAtomicFormula formula =
new AtomicFormula.LongAtomicFormula(
LongAtomicFormula formula =
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.GT, 1);
Parcel p = Parcel.obtain();
formula.writeToParcel(p, 0);
p.setDataPosition(0);
AtomicFormula.LongAtomicFormula newFormula =
AtomicFormula.LongAtomicFormula.CREATOR.createFromParcel(p);
LongAtomicFormula newFormula =
LongAtomicFormula.CREATOR.createFromParcel(p);
assertThat(newFormula).isEqualTo(formula);
}
@@ -211,7 +212,7 @@ public class AtomicFormulaTest {
Exception e =
expectThrows(
IllegalArgumentException.class,
() -> new AtomicFormula.LongAtomicFormula(/* key= */ -1,
() -> new LongAtomicFormula(/* key= */ -1,
AtomicFormula.EQ, /* value= */0));
assertThat(e.getMessage()).matches("Unknown key: -1");
}
@@ -222,7 +223,7 @@ public class AtomicFormulaTest {
expectThrows(
IllegalArgumentException.class,
() ->
new AtomicFormula.LongAtomicFormula(
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, /* operator= */ -1, /* value= */
0));
assertThat(e.getMessage()).matches("Unknown operator: -1");
@@ -252,10 +253,59 @@ public class AtomicFormulaTest {
assertThat(stringAtomicFormula.matches(appInstallMetadata)).isFalse();
}
@Test
public void testIsAppCertificateFormula_string_true() {
StringAtomicFormula stringAtomicFormula =
new StringAtomicFormula(
AtomicFormula.APP_CERTIFICATE, "cert", /* isHashedValue= */false);
assertThat(stringAtomicFormula.isAppCertificateFormula()).isTrue();
}
@Test
public void testIsAppCertificateFormula_string_false() {
StringAtomicFormula stringAtomicFormula =
new StringAtomicFormula(
AtomicFormula.PACKAGE_NAME, "com.test.app", /* isHashedValue= */
false);
assertThat(stringAtomicFormula.isAppCertificateFormula()).isFalse();
}
@Test
public void testIsInstallerFormula_string_false() {
StringAtomicFormula stringAtomicFormula =
new StringAtomicFormula(
AtomicFormula.APP_CERTIFICATE, "cert", /* isHashedValue= */false);
assertThat(stringAtomicFormula.isInstallerFormula()).isFalse();
}
@Test
public void testIsInstallerFormula_string_installerName_true() {
StringAtomicFormula stringAtomicFormula =
new StringAtomicFormula(
AtomicFormula.INSTALLER_NAME,
"com.test.installer",
/* isHashedValue= */false);
assertThat(stringAtomicFormula.isInstallerFormula()).isTrue();
}
@Test
public void testIsInstallerFormula_string_installerCertificate_true() {
StringAtomicFormula stringAtomicFormula =
new StringAtomicFormula(
AtomicFormula.INSTALLER_CERTIFICATE, "cert", /* isHashedValue= */false);
assertThat(stringAtomicFormula.isInstallerFormula()).isTrue();
}
@Test
public void testFormulaMatches_long_eq_true() {
AtomicFormula.LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 0);
AppInstallMetadata appInstallMetadata =
getAppInstallMetadataBuilder().setVersionCode(0).build();
@@ -265,8 +315,8 @@ public class AtomicFormulaTest {
@Test
public void testFormulaMatches_long_eq_false() {
AtomicFormula.LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 0);
AppInstallMetadata appInstallMetadata =
getAppInstallMetadataBuilder().setVersionCode(1).build();
@@ -276,8 +326,8 @@ public class AtomicFormulaTest {
@Test
public void testFormulaMatches_long_gt_true() {
AtomicFormula.LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.GT,
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.GT,
0);
AppInstallMetadata appInstallMetadata =
getAppInstallMetadataBuilder().setVersionCode(1).build();
@@ -287,8 +337,8 @@ public class AtomicFormulaTest {
@Test
public void testFormulaMatches_long_gt_false() {
AtomicFormula.LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.GT,
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.GT,
1);
AppInstallMetadata appInstallMetadata =
getAppInstallMetadataBuilder().setVersionCode(0).build();
@@ -298,8 +348,8 @@ public class AtomicFormulaTest {
@Test
public void testFormulaMatches_long_gte_true() {
AtomicFormula.LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.GTE, 1);
AppInstallMetadata appInstallMetadata1 =
@@ -313,8 +363,8 @@ public class AtomicFormulaTest {
@Test
public void testFormulaMatches_long_gte_false() {
AtomicFormula.LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.GTE, 1);
AppInstallMetadata appInstallMetadata =
getAppInstallMetadataBuilder().setVersionCode(0).build();
@@ -322,6 +372,24 @@ public class AtomicFormulaTest {
assertThat(longAtomicFormula.matches(appInstallMetadata)).isFalse();
}
@Test
public void testIsAppCertificateFormula_long_false() {
LongAtomicFormula longAtomicFormula =
new AtomicFormula.LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.GTE, 1);
assertThat(longAtomicFormula.isAppCertificateFormula()).isFalse();
}
@Test
public void testIsInstallerFormula_long_false() {
LongAtomicFormula longAtomicFormula =
new LongAtomicFormula(
AtomicFormula.VERSION_CODE, AtomicFormula.GTE, 1);
assertThat(longAtomicFormula.isInstallerFormula()).isFalse();
}
@Test
public void testFormulaMatches_bool_true() {
BooleanAtomicFormula boolFormula =
@@ -342,6 +410,22 @@ public class AtomicFormulaTest {
assertThat(boolFormula.matches(appInstallMetadata)).isFalse();
}
@Test
public void testIsAppCertificateFormula_bool_false() {
BooleanAtomicFormula boolFormula =
new BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true);
assertThat(boolFormula.isAppCertificateFormula()).isFalse();
}
@Test
public void testIsInstallerFormula_bool_false() {
BooleanAtomicFormula boolFormula =
new BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true);
assertThat(boolFormula.isInstallerFormula()).isFalse();
}
/** Returns a builder with all fields filled with some dummy data. */
private AppInstallMetadata.Builder getAppInstallMetadataBuilder() {
return new AppInstallMetadata.Builder()

View File

@@ -225,6 +225,63 @@ public class CompoundFormulaTest {
assertThat(compoundFormula.matches(appInstallMetadata)).isFalse();
}
@Test
public void testIsAppCertificateFormula_false() {
CompoundFormula compoundFormula =
new CompoundFormula(
CompoundFormula.AND, Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2));
assertThat(compoundFormula.isAppCertificateFormula()).isFalse();
}
@Test
public void testIsAppCertificateFormula_true() {
AtomicFormula appCertFormula =
new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE,
"app.cert", /* isHashed= */false);
CompoundFormula compoundFormula =
new CompoundFormula(
CompoundFormula.AND,
Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2, appCertFormula));
assertThat(compoundFormula.isAppCertificateFormula()).isTrue();
}
@Test
public void testIsInstallerFormula_false() {
CompoundFormula compoundFormula =
new CompoundFormula(
CompoundFormula.AND, Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2));
assertThat(compoundFormula.isInstallerFormula()).isFalse();
}
@Test
public void testIsInstallerFormula_installerName_true() {
AtomicFormula installerNameFormula =
new AtomicFormula.StringAtomicFormula(AtomicFormula.INSTALLER_NAME,
"com.test.installer", /* isHashed= */false);
CompoundFormula compoundFormula =
new CompoundFormula(
CompoundFormula.AND,
Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2, installerNameFormula));
assertThat(compoundFormula.isInstallerFormula()).isTrue();
}
@Test
public void testIsInstallerFormula_installerCertificate_true() {
AtomicFormula installerCertificateFormula =
new AtomicFormula.StringAtomicFormula(AtomicFormula.INSTALLER_CERTIFICATE,
"cert", /* isHashed= */false);
CompoundFormula compoundFormula =
new CompoundFormula(
CompoundFormula.AND, Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2,
installerCertificateFormula));
assertThat(compoundFormula.isInstallerFormula()).isTrue();
}
/** Returns a builder with all fields filled with some dummy data. */
private AppInstallMetadata.Builder getAppInstallMetadataBuilder() {
return new AppInstallMetadata.Builder()

View File

@@ -96,20 +96,14 @@ public final class IntegrityCheckResult {
}
}
/**
* Returns true when the {@code Effect.DENY} result is caused by an app certificate mismatch.
*/
/** Returns true when the {@code mEffect} is caused by an app certificate mismatch. */
public boolean isCausedByAppCertRule() {
// TODO(b/147095027): implement this.
return true;
return mRuleList.stream().anyMatch(rule -> rule.getFormula().isAppCertificateFormula());
}
/**
* Returns true when the {@code Effect.DENY} result is caused by an installer rule.
*/
/** Returns true when the {@code mEffect} is caused by an installer rule. */
public boolean isCausedByInstallerRule() {
// TODO(b/147095027): implement this.
return true;
return mRuleList.stream().anyMatch(rule -> rule.getFormula().isInstallerFormula());
}
}

View File

@@ -19,6 +19,7 @@ package com.android.server.integrity.model;
import static com.google.common.truth.Truth.assertThat;
import android.content.integrity.AtomicFormula;
import android.content.integrity.CompoundFormula;
import android.content.integrity.Rule;
import android.util.StatsLog;
@@ -26,6 +27,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import java.util.Arrays;
import java.util.Collections;
@RunWith(JUnit4.class)
@@ -76,4 +78,58 @@ public class IntegrityCheckResultTest {
assertThat(denyResult.getLoggingResponse())
.isEqualTo(StatsLog.INTEGRITY_CHECK_RESULT_REPORTED__RESPONSE__REJECTED);
}
@Test
public void isDenyCausedByAppCertificate() {
String packageName = "com.test.deny";
String appCert = "app-cert";
Rule failedRule =
new Rule(
new CompoundFormula(
CompoundFormula.AND,
Arrays.asList(
new AtomicFormula.StringAtomicFormula(
AtomicFormula.PACKAGE_NAME, packageName),
new AtomicFormula.StringAtomicFormula(
AtomicFormula.APP_CERTIFICATE, appCert))),
Rule.DENY);
Rule otherFailedRule =
new Rule(
new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE,
AtomicFormula.EQ, 12),
Rule.DENY);
IntegrityCheckResult denyResult =
IntegrityCheckResult.deny(Arrays.asList(failedRule, otherFailedRule));
assertThat(denyResult.isCausedByAppCertRule()).isTrue();
assertThat(denyResult.isCausedByInstallerRule()).isFalse();
}
@Test
public void isDenyCausedByInstaller() {
String packageName = "com.test.deny";
String appCert = "app-cert";
Rule failedRule =
new Rule(
new CompoundFormula(
CompoundFormula.AND,
Arrays.asList(
new AtomicFormula.StringAtomicFormula(
AtomicFormula.PACKAGE_NAME, packageName),
new AtomicFormula.StringAtomicFormula(
AtomicFormula.INSTALLER_CERTIFICATE, appCert))),
Rule.DENY);
Rule otherFailedRule =
new Rule(
new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE,
AtomicFormula.EQ, 12),
Rule.DENY);
IntegrityCheckResult denyResult =
IntegrityCheckResult.deny(Arrays.asList(failedRule, otherFailedRule));
assertThat(denyResult.isCausedByAppCertRule()).isFalse();
assertThat(denyResult.isCausedByInstallerRule()).isTrue();
}
}

View File

@@ -871,6 +871,16 @@ public class RuleBinarySerializerTest {
return false;
}
@Override
public boolean isAppCertificateFormula() {
return false;
}
@Override
public boolean isInstallerFormula() {
return false;
}
@Override
public int hashCode() {
return super.hashCode();

View File

@@ -298,6 +298,16 @@ public class RuleIndexingDetailsIdentifierTest {
return false;
}
@Override
public boolean isAppCertificateFormula() {
return false;
}
@Override
public boolean isInstallerFormula() {
return false;
}
@Override
public int hashCode() {
return super.hashCode();

View File

@@ -542,6 +542,16 @@ public class RuleXmlSerializerTest {
return false;
}
@Override
public boolean isAppCertificateFormula() {
return false;
}
@Override
public boolean isInstallerFormula() {
return false;
}
@Override
public int hashCode() {
return super.hashCode();