From 5809a5f28644cf7adef5d2f83da62f68594e8d95 Mon Sep 17 00:00:00 2001 From: Khaled Abdelmohsen Date: Mon, 25 Nov 2019 18:20:46 +0000 Subject: [PATCH 1/3] Add rule component validations Bug: 141979167 Test: atest FrameworksServicesTests:RuleTest Test: atest FrameworksServicesTests:AtomicFormulaTest Test: atest FrameworksServicesTests:OpenFormulaTest Change-Id: I3411a0fba37e7f3f9b9f6bbc5b2b895203bbd701 --- .../server/integrity/model/AtomicFormula.java | 20 +++++++++++++++++++ .../server/integrity/model/OpenFormula.java | 8 ++++++++ .../android/server/integrity/model/Rule.java | 7 +++++++ .../integrity/model/AtomicFormulaTest.java | 16 +++++++++++++++ .../integrity/model/OpenFormulaTest.java | 19 ++++++++++++++---- .../server/integrity/model/RuleTest.java | 8 ++++++++ 6 files changed, 74 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/integrity/model/AtomicFormula.java b/services/core/java/com/android/server/integrity/model/AtomicFormula.java index 9a0553d7aa0c7..7514da80b5fbc 100644 --- a/services/core/java/com/android/server/integrity/model/AtomicFormula.java +++ b/services/core/java/com/android/server/integrity/model/AtomicFormula.java @@ -112,6 +112,7 @@ public abstract class AtomicFormula implements Formula { private final @Key int mKey; public AtomicFormula(@Key int key) { + checkArgument(isValidKey(key), String.format("Unknown key: %d", key)); mKey = key; } @@ -134,6 +135,8 @@ public abstract class AtomicFormula implements Formula { checkArgument( key == VERSION_CODE, String.format("Key %s cannot be used with IntAtomicFormula", keyToString(key))); + checkArgument(isValidOperator(operator), + String.format("Unknown operator: %d", operator)); mOperator = operator; mValue = value; } @@ -237,6 +240,14 @@ public abstract class AtomicFormula implements Formula { "Unexpected key in IntAtomicFormula" + getKey()); } } + + private static boolean isValidOperator(int operator) { + return operator == EQ + || operator == LT + || operator == LE + || operator == GT + || operator == GE; + } } /** An {@link AtomicFormula} with a key and string value. */ @@ -486,4 +497,13 @@ public abstract class AtomicFormula implements Formula { throw new IllegalArgumentException("Unknown operator " + op); } } + + private static boolean isValidKey(int key) { + return key == PACKAGE_NAME + || key == APP_CERTIFICATE + || key == VERSION_CODE + || key == INSTALLER_NAME + || key == INSTALLER_CERTIFICATE + || key == PRE_INSTALLED; + } } diff --git a/services/core/java/com/android/server/integrity/model/OpenFormula.java b/services/core/java/com/android/server/integrity/model/OpenFormula.java index 7a3600f7a4fef..f7ea9208f7fef 100644 --- a/services/core/java/com/android/server/integrity/model/OpenFormula.java +++ b/services/core/java/com/android/server/integrity/model/OpenFormula.java @@ -86,6 +86,8 @@ public final class OpenFormula implements Formula, Parcelable { * for that operator (at least 2 for {@link #AND} and {@link #OR}, 1 for {@link #NOT}). */ public OpenFormula(@Connector int connector, @NonNull List formulas) { + checkArgument(isValidConnector(connector), + String.format("Unknown connector: %d", connector)); validateFormulas(connector, formulas); this.mConnector = connector; this.mFormulas = Collections.unmodifiableList(formulas); @@ -213,4 +215,10 @@ public final class OpenFormula implements Formula, Parcelable { throw new IllegalArgumentException("Unknown connector " + connector); } } + + private static boolean isValidConnector(int connector) { + return connector == AND + || connector == OR + || connector == NOT; + } } diff --git a/services/core/java/com/android/server/integrity/model/Rule.java b/services/core/java/com/android/server/integrity/model/Rule.java index f87e4e875eef4..3ad876292ab45 100644 --- a/services/core/java/com/android/server/integrity/model/Rule.java +++ b/services/core/java/com/android/server/integrity/model/Rule.java @@ -16,6 +16,7 @@ package com.android.server.integrity.model; +import static com.android.internal.util.Preconditions.checkArgument; import static com.android.internal.util.Preconditions.checkNotNull; import android.annotation.IntDef; @@ -62,6 +63,7 @@ public final class Rule implements Parcelable { private final @Effect int mEffect; public Rule(@NonNull Formula formula, @Effect int effect) { + checkArgument(isValidEffect(effect), String.format("Unknown effect: %d", effect)); this.mFormula = checkNotNull(formula); this.mEffect = effect; } @@ -137,4 +139,9 @@ public final class Rule implements Parcelable { throw new IllegalArgumentException("Unknown effect " + effect); } } + + private static boolean isValidEffect(int effect) { + return effect == DENY + || effect == FORCE_ALLOW; + } } diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java index c8c5ecaed43a7..1abca0cf833c6 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java @@ -263,6 +263,22 @@ public class AtomicFormulaTest { assertEquals(formula, newFormula); } + @Test + public void testInvalidAtomicFormula_invalidKey() { + assertExpectException( + IllegalArgumentException.class, + /* expectedExceptionMessageRegex */ "Unknown key: -1", + () -> new IntAtomicFormula(/* key= */ -1, AtomicFormula.EQ, 0)); + } + + @Test + public void testInvalidAtomicFormula_invalidOperator() { + assertExpectException( + IllegalArgumentException.class, + /* expectedExceptionMessageRegex */ "Unknown operator: -1", + () -> new IntAtomicFormula(AtomicFormula.VERSION_CODE, /* operator= */ -1, 0)); + } + /** Returns a builder with all fields filled with some dummy data. */ private AppInstallMetadata.Builder getAppInstallMetadataBuilder() { return new AppInstallMetadata.Builder() diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java index ecabb52767907..d15f957ef14e2 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java @@ -53,7 +53,7 @@ public class OpenFormulaTest { assertExpectException( IllegalArgumentException.class, /* expectedExceptionMessageRegex */ - String.format("Connector AND must have at least 2 formulas"), + "Connector AND must have at least 2 formulas", () -> new OpenFormula( OpenFormula.AND, Collections.singletonList(ATOMIC_FORMULA_1))); @@ -64,7 +64,7 @@ public class OpenFormulaTest { assertExpectException( IllegalArgumentException.class, /* expectedExceptionMessageRegex */ - String.format("Connector NOT must have 1 formula only"), + "Connector NOT must have 1 formula only", () -> new OpenFormula( OpenFormula.NOT, @@ -73,7 +73,8 @@ public class OpenFormulaTest { @Test public void testIsSatisfiable_notFalse_true() { - OpenFormula openFormula = new OpenFormula(OpenFormula.NOT, Arrays.asList(ATOMIC_FORMULA_1)); + OpenFormula openFormula = new OpenFormula(OpenFormula.NOT, + Collections.singletonList(ATOMIC_FORMULA_1)); AppInstallMetadata appInstallMetadata = getAppInstallMetadataBuilder().setPackageName("test2").build(); // validate assumptions about the metadata @@ -84,7 +85,8 @@ public class OpenFormulaTest { @Test public void testIsSatisfiable_notTrue_false() { - OpenFormula openFormula = new OpenFormula(OpenFormula.NOT, Arrays.asList(ATOMIC_FORMULA_1)); + OpenFormula openFormula = new OpenFormula(OpenFormula.NOT, + Collections.singletonList(ATOMIC_FORMULA_1)); AppInstallMetadata appInstallMetadata = getAppInstallMetadataBuilder().setPackageName("test1").build(); // validate assumptions about the metadata @@ -209,6 +211,15 @@ public class OpenFormulaTest { assertEquals(formula, newFormula); } + @Test + public void testInvalidOpenFormula_invalidConnector() { + assertExpectException( + IllegalArgumentException.class, + /* expectedExceptionMessageRegex */ "Unknown connector: -1", + () -> new OpenFormula(/* connector= */ -1, + Arrays.asList(ATOMIC_FORMULA_1, ATOMIC_FORMULA_2))); + } + /** Returns a builder with all fields filled with some dummy data. */ private AppInstallMetadata.Builder getAppInstallMetadataBuilder() { return new AppInstallMetadata.Builder() diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java index e0c36fdfc546b..f97e2e6da8e86 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java @@ -106,4 +106,12 @@ public class RuleTest { assertEquals(newRule, rule); } + + @Test + public void testInvalidRule_invalidEffect() { + assertExpectException( + IllegalArgumentException.class, + /* expectedExceptionMessageRegex */ "Unknown effect: -1", + () -> new Rule(PACKAGE_NAME_ATOMIC_FORMULA, /* effect= */ -1)); + } } From e39fa0fd2fddf0f1a9688d136a3b074e8d77af89 Mon Sep 17 00:00:00 2001 From: Khaled Abdelmohsen Date: Mon, 25 Nov 2019 17:24:22 +0000 Subject: [PATCH 2/3] Support optional rule attributes in XML parser Bug: 143697198 Test: atest FrameworksServicesTests:RuleXmlParserTest Change-Id: Ib7118228f325f8fcb88fa27cf88d48af0319e320 --- .../integrity/parser/RuleXmlParser.java | 23 ++++--- .../integrity/parser/RuleXmlParserTest.java | 60 +++++++++++++------ 2 files changed, 53 insertions(+), 30 deletions(-) diff --git a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java index 11a397948b145..5459a77705f2e 100644 --- a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java +++ b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java @@ -32,6 +32,7 @@ import java.io.StringReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.Optional; /** * A helper class to parse rules into the {@link Rule} model from Xml representation. @@ -106,7 +107,7 @@ public final class RuleXmlParser implements RuleParser { private static Rule parseRule(XmlPullParser parser) throws IOException, XmlPullParserException { Formula formula = null; - @Rule.Effect int effect = Integer.parseInt(extractAttributeValue(parser, EFFECT_ATTRIBUTE)); + int effect = Integer.parseInt(extractAttributeValue(parser, EFFECT_ATTRIBUTE).orElse("-1")); int eventType; while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) { @@ -139,8 +140,8 @@ public final class RuleXmlParser implements RuleParser { private static Formula parseOpenFormula(XmlPullParser parser) throws IOException, XmlPullParserException { - @OpenFormula.Connector int connector = Integer.parseInt( - extractAttributeValue(parser, CONNECTOR_ATTRIBUTE)); + int connector = Integer.parseInt( + extractAttributeValue(parser, CONNECTOR_ATTRIBUTE).orElse("-1")); List formulas = new ArrayList<>(); int eventType; @@ -174,10 +175,10 @@ public final class RuleXmlParser implements RuleParser { private static Formula parseAtomicFormula(XmlPullParser parser) throws IOException, XmlPullParserException { - @AtomicFormula.Key int key = Integer.parseInt(extractAttributeValue(parser, KEY_ATTRIBUTE)); - @AtomicFormula.Operator int operator = Integer.parseInt( - extractAttributeValue(parser, OPERATOR_ATTRIBUTE)); - String value = extractAttributeValue(parser, VALUE_ATTRIBUTE); + int key = Integer.parseInt(extractAttributeValue(parser, KEY_ATTRIBUTE).orElse("-1")); + int operator = Integer.parseInt( + extractAttributeValue(parser, OPERATOR_ATTRIBUTE).orElse("-1")); + String value = extractAttributeValue(parser, VALUE_ATTRIBUTE).orElse(null); int eventType; while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) { @@ -205,11 +206,7 @@ public final class RuleXmlParser implements RuleParser { } } - private static String extractAttributeValue(XmlPullParser parser, String attribute) { - String attributeValue = parser.getAttributeValue(NAMESPACE, attribute); - if (attributeValue == null) { - throw new RuntimeException(String.format("Attribute not found: %s", attribute)); - } - return attributeValue; + private static Optional extractAttributeValue(XmlPullParser parser, String attribute) { + return Optional.ofNullable(parser.getAttributeValue(NAMESPACE, attribute)); } } diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java index be6a31fa949eb..eca1b8556496a 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java @@ -43,7 +43,6 @@ public class RuleXmlParserTest { public void testXmlStream_validOpenFormula() throws Exception { Map atomicFormulaAttrs = new HashMap<>(); atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - atomicFormulaAttrs.put("O", String.valueOf(AtomicFormula.EQ)); atomicFormulaAttrs.put("V", "com.app.test"); String ruleXmlOpenFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -71,7 +70,6 @@ public class RuleXmlParserTest { public void testXmlString_validOpenFormula_notConnector() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); String ruleXmlOpenFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -98,11 +96,9 @@ public class RuleXmlParserTest { public void testXmlString_validOpenFormula_andConnector() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); Map appCertificateAttrs = new HashMap<>(); appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE)); - appCertificateAttrs.put("O", String.valueOf(AtomicFormula.EQ)); appCertificateAttrs.put("V", "test_cert"); String ruleXmlOpenFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -131,11 +127,9 @@ public class RuleXmlParserTest { public void testXmlString_validOpenFormula_orConnector() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); Map appCertificateAttrs = new HashMap<>(); appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE)); - appCertificateAttrs.put("O", String.valueOf(AtomicFormula.EQ)); appCertificateAttrs.put("V", "test_cert"); String ruleXmlOpenFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -165,7 +159,6 @@ public class RuleXmlParserTest { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); String ruleXmlOpenFormula = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -191,7 +184,6 @@ public class RuleXmlParserTest { public void testXmlString_invalidOpenFormula_invalidNumberOfFormulas() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); Map versionCodeAttrs = new HashMap<>(); versionCodeAttrs.put("K", String.valueOf(AtomicFormula.VERSION_CODE)); @@ -246,7 +238,6 @@ public class RuleXmlParserTest { public void testXmlString_invalidOpenFormula_invalidEffect() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); String ruleXmlOpenFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -271,7 +262,6 @@ public class RuleXmlParserTest { public void testXmlString_invalidOpenFormula_invalidTags() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); String ruleXmlOpenFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -297,7 +287,6 @@ public class RuleXmlParserTest { public void testXmlString_validAtomicFormula_stringValue() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); String ruleXmlAtomicFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -343,7 +332,6 @@ public class RuleXmlParserTest { public void testXmlString_validAtomicFormula_booleanValue() throws Exception { Map preInstalledAttrs = new HashMap<>(); preInstalledAttrs.put("K", String.valueOf(AtomicFormula.PRE_INSTALLED)); - preInstalledAttrs.put("O", String.valueOf(AtomicFormula.EQ)); preInstalledAttrs.put("V", "true"); String ruleXmlAtomicFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -367,7 +355,6 @@ public class RuleXmlParserTest { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); String ruleXmlAtomicFormula = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -389,7 +376,6 @@ public class RuleXmlParserTest { public void testXmlString_invalidAtomicFormula_invalidAttribute() throws Exception { Map packageNameAttrs = new HashMap<>(); packageNameAttrs.put("BadKey", String.valueOf(AtomicFormula.PACKAGE_NAME)); - packageNameAttrs.put("O", String.valueOf(AtomicFormula.EQ)); packageNameAttrs.put("V", "com.app.test"); String ruleXmlAtomicFormula = "" + generateTagWithAttribute(/* tag= */ "R", @@ -402,10 +388,52 @@ public class RuleXmlParserTest { assertExpectException( RuleParseException.class, - /* expectedExceptionMessageRegex */ "Attribute not found: K", + /* expectedExceptionMessageRegex */ "Found unexpected key: -1", () -> xmlParser.parse(ruleXmlAtomicFormula)); } + @Test + public void testXmlString_invalidRule_invalidAttribute() throws Exception { + Map packageNameAttrs = new HashMap<>(); + packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); + packageNameAttrs.put("V", "com.app.test"); + String ruleXmlAtomicFormula = "" + + generateTagWithAttribute(/* tag= */ "R", + Collections.singletonMap("BadEffect", String.valueOf(Rule.DENY)), + /* closed= */ false) + + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true) + + "" + + ""; + RuleParser xmlParser = new RuleXmlParser(); + assertExpectException( + RuleParseException.class, + /* expectedExceptionMessageRegex */ "Unknown effect: -1", + () -> xmlParser.parse(ruleXmlAtomicFormula)); + } + + @Test + public void testXmlString_invalidOpenFormula_invalidAttribute() throws Exception { + Map packageNameAttrs = new HashMap<>(); + packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); + packageNameAttrs.put("V", "com.app.test"); + String ruleXmlOpenFormula = "" + + generateTagWithAttribute(/* tag= */ "R", + Collections.singletonMap("E", String.valueOf(Rule.DENY)), + /* closed= */ false) + + generateTagWithAttribute(/* tag= */ "OF", + Collections.singletonMap("BadConnector", String.valueOf(OpenFormula.NOT)), + /* closed= */ false) + + generateTagWithAttribute(/* tag= */ "AF", packageNameAttrs, /* closed= */ true) + + "" + + "" + + ""; + RuleParser xmlParser = new RuleXmlParser(); + assertExpectException( + RuleParseException.class, + /* expectedExceptionMessageRegex */ "Unknown connector: -1", + () -> xmlParser.parse(ruleXmlOpenFormula)); + } + @Test public void testXmlString_invalidAtomicFormula() throws Exception { Map packageNameAttrs = new HashMap<>(); @@ -431,7 +459,6 @@ public class RuleXmlParserTest { public void testXmlString_withNoRuleList() { Map atomicFormulaAttrs = new HashMap<>(); atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - atomicFormulaAttrs.put("O", String.valueOf(AtomicFormula.EQ)); atomicFormulaAttrs.put("V", "com.app.test"); String ruleXmlWithNoRuleList = generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -454,7 +481,6 @@ public class RuleXmlParserTest { public void testXmlStream_withNoRuleList() { Map atomicFormulaAttrs = new HashMap<>(); atomicFormulaAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); - atomicFormulaAttrs.put("O", String.valueOf(AtomicFormula.EQ)); atomicFormulaAttrs.put("V", "com.app.test"); String ruleXmlWithNoRuleList = generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), From 1efff8745c6674b0ff113d4f643706fe75ce5fb2 Mon Sep 17 00:00:00 2001 From: Khaled Abdelmohsen Date: Mon, 25 Nov 2019 16:44:20 +0000 Subject: [PATCH 3/3] Include isHashedValue in rule structure Bug: 141979167 Test: atest FrameworksServicesTests:RuleXmlSerializerTest Test: atest FrameworksServicesTests:RuleXmlParserTest Change-Id: Ic4587c5bcd65e0748c15655f79136eaa50a4eb1f --- .../server/integrity/model/AtomicFormula.java | 11 ++++- .../integrity/parser/RuleXmlParser.java | 10 ++-- .../serializer/RuleXmlSerializer.java | 5 ++ .../integrity/engine/RuleEvaluatorTest.java | 48 ++++++++++++------- .../integrity/model/AtomicFormulaTest.java | 15 ++++-- .../integrity/model/OpenFormulaTest.java | 3 +- .../server/integrity/model/RuleTest.java | 6 ++- .../integrity/parser/RuleXmlParserTest.java | 27 +++++++---- .../serializer/RuleXmlSerializerTest.java | 26 ++++++---- 9 files changed, 106 insertions(+), 45 deletions(-) diff --git a/services/core/java/com/android/server/integrity/model/AtomicFormula.java b/services/core/java/com/android/server/integrity/model/AtomicFormula.java index 7514da80b5fbc..a16f6b9b59701 100644 --- a/services/core/java/com/android/server/integrity/model/AtomicFormula.java +++ b/services/core/java/com/android/server/integrity/model/AtomicFormula.java @@ -253,6 +253,8 @@ public abstract class AtomicFormula implements Formula { /** An {@link AtomicFormula} with a key and string value. */ public static final class StringAtomicFormula extends AtomicFormula implements Parcelable { private final String mValue; + // Indicates whether the value is the actual value or the hashed value. + private final boolean mIsHashedValue; /** * Constructs a new {@link StringAtomicFormula}. @@ -262,8 +264,9 @@ public abstract class AtomicFormula implements Formula { * * @throws IllegalArgumentException if {@code key} cannot be used with string value */ - public StringAtomicFormula(@Key int key, @NonNull String value) { + public StringAtomicFormula(@Key int key, @NonNull String value, boolean isHashedValue) { super(key); + mIsHashedValue = isHashedValue; checkArgument( key == PACKAGE_NAME || key == APP_CERTIFICATE @@ -277,6 +280,7 @@ public abstract class AtomicFormula implements Formula { StringAtomicFormula(Parcel in) { super(in.readInt()); mValue = in.readStringNoHelper(); + mIsHashedValue = in.readByte() != 0; } @NonNull @@ -335,6 +339,7 @@ public abstract class AtomicFormula implements Formula { public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(getKey()); dest.writeStringNoHelper(mValue); + dest.writeByte((byte) (mIsHashedValue ? 1 : 0)); } @NonNull @@ -342,6 +347,10 @@ public abstract class AtomicFormula implements Formula { return mValue; } + public boolean getIsHashedValue() { + return mIsHashedValue; + } + private String getMetadataValueByKey(AppInstallMetadata appInstallMetadata) { switch (getKey()) { case PACKAGE_NAME: diff --git a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java index 5459a77705f2e..1508c273f553b 100644 --- a/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java +++ b/services/core/java/com/android/server/integrity/parser/RuleXmlParser.java @@ -51,6 +51,7 @@ public final class RuleXmlParser implements RuleParser { private static final String OPERATOR_ATTRIBUTE = "O"; private static final String VALUE_ATTRIBUTE = "V"; private static final String CONNECTOR_ATTRIBUTE = "C"; + private static final String IS_HASHED_VALUE_ATTRIBUTE = "H"; @Override public List parse(String ruleText) throws RuleParseException { @@ -179,6 +180,8 @@ public final class RuleXmlParser implements RuleParser { int operator = Integer.parseInt( extractAttributeValue(parser, OPERATOR_ATTRIBUTE).orElse("-1")); String value = extractAttributeValue(parser, VALUE_ATTRIBUTE).orElse(null); + String isHashedValue = extractAttributeValue(parser, IS_HASHED_VALUE_ATTRIBUTE).orElse( + null); int eventType; while ((eventType = parser.next()) != XmlPullParser.END_DOCUMENT) { @@ -186,17 +189,18 @@ public final class RuleXmlParser implements RuleParser { break; } } - return constructAtomicFormulaBasedOnKey(key, operator, value); + return constructAtomicFormulaBasedOnKey(key, operator, value, isHashedValue); } private static Formula constructAtomicFormulaBasedOnKey(@AtomicFormula.Key int key, - @AtomicFormula.Operator int operator, String value) { + @AtomicFormula.Operator int operator, String value, String isHashedValue) { switch (key) { case AtomicFormula.PACKAGE_NAME: case AtomicFormula.INSTALLER_NAME: case AtomicFormula.APP_CERTIFICATE: case AtomicFormula.INSTALLER_CERTIFICATE: - return new AtomicFormula.StringAtomicFormula(key, value); + return new AtomicFormula.StringAtomicFormula(key, value, + Boolean.parseBoolean(isHashedValue)); case AtomicFormula.PRE_INSTALLED: return new AtomicFormula.BooleanAtomicFormula(key, Boolean.parseBoolean(value)); case AtomicFormula.VERSION_CODE: diff --git a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java index 1f22afb0e9bfa..f2ba756ee0d16 100644 --- a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java +++ b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java @@ -48,6 +48,7 @@ public class RuleXmlSerializer implements RuleSerializer { private static final String OPERATOR_ATTRIBUTE = "O"; private static final String VALUE_ATTRIBUTE = "V"; private static final String CONNECTOR_ATTRIBUTE = "C"; + private static final String IS_HASHED_VALUE_ATTRIBUTE = "H"; @Override public void serialize(List rules, OutputStream outputStream) @@ -129,6 +130,10 @@ public class RuleXmlSerializer implements RuleSerializer { if (atomicFormula instanceof AtomicFormula.StringAtomicFormula) { serializeAttributeValue(VALUE_ATTRIBUTE, ((AtomicFormula.StringAtomicFormula) atomicFormula).getValue(), xmlSerializer); + serializeAttributeValue(IS_HASHED_VALUE_ATTRIBUTE, + String.valueOf( + ((AtomicFormula.StringAtomicFormula) atomicFormula).getIsHashedValue()), + xmlSerializer); } else if (atomicFormula instanceof AtomicFormula.IntAtomicFormula) { serializeAttributeValue(OPERATOR_ATTRIBUTE, String.valueOf(((AtomicFormula.IntAtomicFormula) atomicFormula).getOperator()), diff --git a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java index e52aca36bb050..d6773d45c5ede 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/engine/RuleEvaluatorTest.java @@ -63,7 +63,8 @@ public class RuleEvaluatorTest { public void testEvaluateRules_noMatchedRules_allow() { Rule rule1 = new Rule( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2, + /* isHashedValue= */ false), Rule.DENY); IntegrityCheckResult result = @@ -76,11 +77,13 @@ public class RuleEvaluatorTest { public void testEvaluateRules_oneMatch_deny() { Rule rule1 = new Rule( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1, + /* isHashedValue= */ false), Rule.DENY); Rule rule2 = new Rule( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2, + /* isHashedValue= */ false), Rule.DENY); IntegrityCheckResult result = @@ -94,15 +97,18 @@ public class RuleEvaluatorTest { public void testEvaluateRules_multipleMatches_deny() { Rule rule1 = new Rule( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1, + /* isHashedValue= */ false), Rule.DENY); OpenFormula openFormula2 = new OpenFormula( OpenFormula.AND, Arrays.asList( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1, + /* isHashedValue= */ false), new StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE))); + AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE, + /* isHashedValue= */ false))); Rule rule2 = new Rule(openFormula2, Rule.DENY); IntegrityCheckResult result = @@ -119,7 +125,8 @@ public class RuleEvaluatorTest { OpenFormula.NOT, Collections.singletonList( new StringAtomicFormula( - AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2))); + AtomicFormula.PACKAGE_NAME, + PACKAGE_NAME_2, /* isHashedValue= */ false))); Rule rule = new Rule(openFormula, Rule.DENY); IntegrityCheckResult result = @@ -150,9 +157,11 @@ public class RuleEvaluatorTest { new OpenFormula( OpenFormula.AND, Arrays.asList( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1, + /* isHashedValue= */ false), new StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE))); + AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE, + /* isHashedValue= */ false))); Rule rule = new Rule(openFormula, Rule.DENY); IntegrityCheckResult result = @@ -168,9 +177,11 @@ public class RuleEvaluatorTest { new OpenFormula( OpenFormula.OR, Arrays.asList( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1, + /* isHashedValue= */ false), new StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE))); + AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE, + /* isHashedValue= */ false))); Rule rule = new Rule(openFormula, Rule.DENY); IntegrityCheckResult result = @@ -185,9 +196,11 @@ public class RuleEvaluatorTest { new OpenFormula( OpenFormula.AND, Arrays.asList( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_2, + /* isHashedValue= */ false), new StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE))); + AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE, + /* isHashedValue= */ false))); OpenFormula openFormula = new OpenFormula(OpenFormula.NOT, Collections.singletonList(openSubFormula)); Rule rule = new Rule(openFormula, Rule.DENY); @@ -202,15 +215,18 @@ public class RuleEvaluatorTest { public void testEvaluateRules_forceAllow() { Rule rule1 = new Rule( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1, + /* isHashedValue= */ false), Rule.FORCE_ALLOW); OpenFormula openFormula2 = new OpenFormula( OpenFormula.AND, Arrays.asList( - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1), + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME_1, + /* isHashedValue= */ false), new StringAtomicFormula( - AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE))); + AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE, + /* isHashedValue= */ false))); Rule rule2 = new Rule(openFormula2, Rule.DENY); IntegrityCheckResult result = diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java index 1abca0cf833c6..988e18b8e1946 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/model/AtomicFormulaTest.java @@ -38,7 +38,8 @@ public class AtomicFormulaTest { @Test public void testValidAtomicFormula_stringValue() { StringAtomicFormula stringAtomicFormula = - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.test.app"); + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, + "com.test.app", /* isHashedValue= */ false); assertEquals(AtomicFormula.PACKAGE_NAME, stringAtomicFormula.getKey()); } @@ -66,7 +67,8 @@ public class AtomicFormulaTest { /* expectedExceptionMessageRegex */ String.format( "Key VERSION_CODE cannot be used with StringAtomicFormula"), - () -> new StringAtomicFormula(AtomicFormula.VERSION_CODE, "test-value")); + () -> new StringAtomicFormula(AtomicFormula.VERSION_CODE, "test-value", + /* isHashedValue= */ false)); } @Test @@ -92,7 +94,8 @@ public class AtomicFormulaTest { @Test public void testIsSatisfiable_string_true() { StringAtomicFormula stringAtomicFormula = - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.test.app"); + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, + "com.test.app", /* isHashedValue= */ false); AppInstallMetadata appInstallMetadata = getAppInstallMetadataBuilder().setPackageName("com.test.app").build(); @@ -102,7 +105,8 @@ public class AtomicFormulaTest { @Test public void testIsSatisfiable_string_false() { StringAtomicFormula stringAtomicFormula = - new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.test.app"); + new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, + "com.test.app", /* isHashedValue= */ false); AppInstallMetadata appInstallMetadata = getAppInstallMetadataBuilder().setPackageName("com.foo.bar").build(); @@ -231,7 +235,8 @@ public class AtomicFormulaTest { @Test public void testParcelUnparcel_string() { - StringAtomicFormula formula = new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "abc"); + StringAtomicFormula formula = new StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "abc", + /* isHashedValue= */ false); Parcel p = Parcel.obtain(); formula.writeToParcel(p, 0); p.setDataPosition(0); diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java index d15f957ef14e2..b58ffd7dd6c60 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/model/OpenFormulaTest.java @@ -35,7 +35,8 @@ import java.util.Collections; public class OpenFormulaTest { private static final AtomicFormula ATOMIC_FORMULA_1 = - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "test1"); + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "test1", + /* isHashedValue= */ false); private static final AtomicFormula ATOMIC_FORMULA_2 = new AtomicFormula.IntAtomicFormula(AtomicFormula.VERSION_CODE, AtomicFormula.EQ, 1); diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java index f97e2e6da8e86..cad392826d420 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java @@ -36,9 +36,11 @@ public class RuleTest { private static final String PACKAGE_NAME = "com.test.app"; private static final String APP_CERTIFICATE = "test_cert"; private static final Formula PACKAGE_NAME_ATOMIC_FORMULA = - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME); + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, PACKAGE_NAME, + /* isHashedValue= */ false); private static final Formula APP_CERTIFICATE_ATOMIC_FORMULA = - new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE); + new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, APP_CERTIFICATE, + /* isHashedValue= */ false); @Test public void testValidRule() { diff --git a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java index eca1b8556496a..7d71cd4c1b7f8 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/parser/RuleXmlParserTest.java @@ -58,7 +58,8 @@ public class RuleXmlParserTest { RuleParser xmlParser = new RuleXmlParser(); InputStream inputStream = new ByteArrayInputStream(ruleXmlOpenFormula.getBytes()); Rule expectedRule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"))), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false))), Rule.DENY); List rules = xmlParser.parse(inputStream); @@ -84,7 +85,8 @@ public class RuleXmlParserTest { + ""; RuleParser xmlParser = new RuleXmlParser(); Rule expectedRule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"))), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false))), Rule.DENY); List rules = xmlParser.parse(ruleXmlOpenFormula); @@ -114,8 +116,10 @@ public class RuleXmlParserTest { + ""; RuleParser xmlParser = new RuleXmlParser(); Rule expectedRule = new Rule(new OpenFormula(OpenFormula.AND, Arrays.asList( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"), - new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert"))), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false), + new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert", + /* isHashedValue= */ false))), Rule.DENY); List rules = xmlParser.parse(ruleXmlOpenFormula); @@ -145,8 +149,10 @@ public class RuleXmlParserTest { + ""; RuleParser xmlParser = new RuleXmlParser(); Rule expectedRule = new Rule(new OpenFormula(OpenFormula.OR, Arrays.asList( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"), - new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert"))), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false), + new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, "test_cert", + /* isHashedValue= */ false))), Rule.DENY); List rules = xmlParser.parse(ruleXmlOpenFormula); @@ -172,7 +178,8 @@ public class RuleXmlParserTest { + ""; RuleParser xmlParser = new RuleXmlParser(); Rule expectedRule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"))), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false))), Rule.DENY); List rules = xmlParser.parse(ruleXmlOpenFormula); @@ -297,7 +304,8 @@ public class RuleXmlParserTest { + ""; RuleParser xmlParser = new RuleXmlParser(); Rule expectedRule = new Rule( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false), Rule.DENY); List rules = xmlParser.parse(ruleXmlAtomicFormula); @@ -364,7 +372,8 @@ public class RuleXmlParserTest { + ""; RuleParser xmlParser = new RuleXmlParser(); Rule expectedRule = new Rule( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false), Rule.DENY); List rules = xmlParser.parse(ruleXmlAtomicFormula); diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java index 77886c89c4165..7eac0b912bf82 100644 --- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java +++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java @@ -57,12 +57,14 @@ public class RuleXmlSerializerTest { public void testXmlString_serializeMultipleRules_oneEmpty() throws Exception { Rule rule1 = null; Rule rule2 = new Rule( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false), Rule.DENY); RuleSerializer xmlSerializer = new RuleXmlSerializer(); Map packageNameAttrs = new LinkedHashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); + packageNameAttrs.put("H", "false"); String expectedRules = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -81,12 +83,13 @@ public class RuleXmlSerializerTest { Rule rule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList( new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, - "com.app.test"))), Rule.DENY); + "com.app.test", /* isHashedValue= */ false))), Rule.DENY); RuleSerializer xmlSerializer = new RuleXmlSerializer(); OutputStream outputStream = new ByteArrayOutputStream(); Map packageNameAttrs = new LinkedHashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); + packageNameAttrs.put("H", "false"); String expectedRules = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -110,11 +113,12 @@ public class RuleXmlSerializerTest { Rule rule = new Rule(new OpenFormula(OpenFormula.NOT, Collections.singletonList( new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, - "com.app.test"))), Rule.DENY); + "com.app.test", /* isHashedValue= */ false))), Rule.DENY); RuleSerializer xmlSerializer = new RuleXmlSerializer(); Map packageNameAttrs = new LinkedHashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); + packageNameAttrs.put("H", "false"); String expectedRules = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -136,16 +140,18 @@ public class RuleXmlSerializerTest { public void testXmlString_serializeValidOpenFormula_andConnector() throws Exception { Rule rule = new Rule(new OpenFormula(OpenFormula.AND, Arrays.asList(new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, - "com.app.test"), + "com.app.test", /* isHashedValue= */ false), new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, - "test_cert"))), Rule.DENY); + "test_cert", /* isHashedValue= */ false))), Rule.DENY); RuleSerializer xmlSerializer = new RuleXmlSerializer(); Map packageNameAttrs = new LinkedHashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); + packageNameAttrs.put("H", "false"); Map appCertificateAttrs = new LinkedHashMap<>(); appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE)); appCertificateAttrs.put("V", "test_cert"); + appCertificateAttrs.put("H", "false"); String expectedRules = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -168,16 +174,18 @@ public class RuleXmlSerializerTest { public void testXmlString_serializeValidOpenFormula_orConnector() throws Exception { Rule rule = new Rule(new OpenFormula(OpenFormula.OR, Arrays.asList(new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, - "com.app.test"), + "com.app.test", /* isHashedValue= */ false), new AtomicFormula.StringAtomicFormula(AtomicFormula.APP_CERTIFICATE, - "test_cert"))), Rule.DENY); + "test_cert", /* isHashedValue= */ false))), Rule.DENY); RuleSerializer xmlSerializer = new RuleXmlSerializer(); Map packageNameAttrs = new LinkedHashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); + packageNameAttrs.put("H", "false"); Map appCertificateAttrs = new LinkedHashMap<>(); appCertificateAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE)); appCertificateAttrs.put("V", "test_cert"); + appCertificateAttrs.put("H", "false"); String expectedRules = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)), @@ -199,12 +207,14 @@ public class RuleXmlSerializerTest { @Test public void testXmlString_serializeValidAtomicFormula_stringValue() throws Exception { Rule rule = new Rule( - new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test"), + new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME, "com.app.test", + /* isHashedValue= */ false), Rule.DENY); RuleSerializer xmlSerializer = new RuleXmlSerializer(); Map packageNameAttrs = new LinkedHashMap<>(); packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME)); packageNameAttrs.put("V", "com.app.test"); + packageNameAttrs.put("H", "false"); String expectedRules = "" + generateTagWithAttribute(/* tag= */ "R", Collections.singletonMap("E", String.valueOf(Rule.DENY)),