summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2019-12-18 13:36:49 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-12-18 13:36:49 +0000
commit10197b127a9563ba51b7a4f99d95be5f1b12e172 (patch)
tree2308aec5237a5c542728efde8bee2d5a3201077f
parent32e4875f6b9a23f95d1ef38f9fd7c3efe575883b (diff)
parent30749c8f86e9c0a715ee06fd968496ead594c941 (diff)
Merge "Extend integrity component indexing type identification to also return the key value that the indexing will be done with."
-rw-r--r--services/core/java/com/android/server/integrity/serializer/RuleIndexTypeIdentifier.java117
-rw-r--r--services/core/java/com/android/server/integrity/serializer/RuleIndexingDetails.java67
-rw-r--r--services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java127
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java (renamed from services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexTypeIdentifierTest.java)37
4 files changed, 216 insertions, 132 deletions
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleIndexTypeIdentifier.java b/services/core/java/com/android/server/integrity/serializer/RuleIndexTypeIdentifier.java
deleted file mode 100644
index 4d3961df6092..000000000000
--- a/services/core/java/com/android/server/integrity/serializer/RuleIndexTypeIdentifier.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.serializer;
-
-import android.annotation.IntDef;
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.Formula;
-import android.content.integrity.Rule;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/** A helper class for identifying the indexing type of a given rule. */
-public class RuleIndexTypeIdentifier {
-
- static final int NOT_INDEXED = 0;
- static final int PACKAGE_NAME_INDEXED = 1;
- static final int APP_CERTIFICATE_INDEXED = 2;
-
- /** Represents which indexed file the rule should be located. */
- @IntDef(
- value = {
- NOT_INDEXED,
- PACKAGE_NAME_INDEXED,
- APP_CERTIFICATE_INDEXED
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface IndexType {
- }
-
- /** Determines the indexing file type that a given rule should be located at. */
- public static int getIndexType(Rule rule) {
- if (rule == null) {
- throw new IllegalArgumentException("Indexing type cannot be determined for null rule.");
- }
- return getIndexType(rule.getFormula());
- }
-
- private static int getIndexType(Formula formula) {
- if (formula == null) {
- throw new IllegalArgumentException(
- "Indexing type cannot be determined for null formula.");
- }
-
- switch (formula.getTag()) {
- case Formula.COMPOUND_FORMULA_TAG:
- return getIndexTypeForCompoundFormula((CompoundFormula) formula);
- case Formula.STRING_ATOMIC_FORMULA_TAG:
- return getIndexTypeForAtomicStringFormula((AtomicFormula) formula);
- case Formula.INT_ATOMIC_FORMULA_TAG:
- case Formula.BOOLEAN_ATOMIC_FORMULA_TAG:
- // Package name and app certificate related formulas are string atomic formulas.
- return NOT_INDEXED;
- default:
- throw new IllegalArgumentException(
- String.format("Invalid formula tag type: %s", formula.getTag()));
- }
- }
-
- private static int getIndexTypeForCompoundFormula(CompoundFormula compoundFormula) {
- int connector = compoundFormula.getConnector();
- List<Formula> formulas = compoundFormula.getFormulas();
-
- switch (connector) {
- case CompoundFormula.NOT:
- // Having a NOT operator in the indexing messes up the indexing; e.g., deny
- // installation if app certificate is NOT X (should not be indexed with app cert
- // X). We will not keep these rules indexed.
- return NOT_INDEXED;
- case CompoundFormula.AND:
- case CompoundFormula.OR:
- Set<Integer> indexingTypesForAllFormulas =
- formulas.stream()
- .map(formula -> getIndexType(formula))
- .collect(Collectors.toSet());
- if (indexingTypesForAllFormulas.contains(PACKAGE_NAME_INDEXED)) {
- return PACKAGE_NAME_INDEXED;
- } else if (indexingTypesForAllFormulas.contains(APP_CERTIFICATE_INDEXED)) {
- return APP_CERTIFICATE_INDEXED;
- } else {
- return NOT_INDEXED;
- }
- default:
- return NOT_INDEXED;
- }
- }
-
- private static int getIndexTypeForAtomicStringFormula(AtomicFormula atomicFormula) {
- switch (atomicFormula.getKey()) {
- case AtomicFormula.PACKAGE_NAME:
- return PACKAGE_NAME_INDEXED;
- case AtomicFormula.APP_CERTIFICATE:
- return APP_CERTIFICATE_INDEXED;
- default:
- return NOT_INDEXED;
- }
- }
-}
-
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetails.java b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetails.java
new file mode 100644
index 000000000000..dd871e2bbe6c
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetails.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.serializer;
+
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Holds the indexing type and indexing key of a given formula. */
+class RuleIndexingDetails {
+
+ static final int NOT_INDEXED = 0;
+ static final int PACKAGE_NAME_INDEXED = 1;
+ static final int APP_CERTIFICATE_INDEXED = 2;
+
+ /** Represents which indexed file the rule should be located. */
+ @IntDef(
+ value = {
+ NOT_INDEXED,
+ PACKAGE_NAME_INDEXED,
+ APP_CERTIFICATE_INDEXED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface IndexType {
+ }
+
+ private @IndexType int mIndexType;
+ private String mRuleKey;
+
+ /** Constructor without a ruleKey for {@code NOT_INDEXED}. */
+ RuleIndexingDetails(@IndexType int indexType) {
+ this.mIndexType = indexType;
+ this.mRuleKey = null;
+ }
+
+ /** Constructor with a ruleKey for indexed rules. */
+ RuleIndexingDetails(@IndexType int indexType, String ruleKey) {
+ this.mIndexType = indexType;
+ this.mRuleKey = ruleKey;
+ }
+
+ /** Returns the indexing type for the rule. */
+ @IndexType
+ public int getIndexType() {
+ return mIndexType;
+ }
+
+ /** Returns the identified rule key. */
+ public String getRuleKey() {
+ return mRuleKey;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java
new file mode 100644
index 000000000000..4aabb1c87b34
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifier.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.integrity.serializer;
+
+import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
+
+import android.content.integrity.AtomicFormula;
+import android.content.integrity.CompoundFormula;
+import android.content.integrity.Formula;
+import android.content.integrity.Rule;
+
+import java.util.List;
+import java.util.Optional;
+
+/** A helper class for identifying the indexing type and key of a given rule. */
+class RuleIndexingDetailsIdentifier {
+
+ /** Determines the indexing type and key for a given rule. */
+ public static RuleIndexingDetails getIndexingDetails(Rule rule) {
+ if (rule == null) {
+ throw new IllegalArgumentException("Indexing type cannot be determined for null rule.");
+ }
+ return getIndexingDetails(rule.getFormula());
+ }
+
+ private static RuleIndexingDetails getIndexingDetails(Formula formula) {
+ if (formula == null) {
+ throw new IllegalArgumentException(
+ "Indexing type cannot be determined for null formula.");
+ }
+
+ switch (formula.getTag()) {
+ case Formula.COMPOUND_FORMULA_TAG:
+ return getIndexingDetailsForCompoundFormula((CompoundFormula) formula);
+ case Formula.STRING_ATOMIC_FORMULA_TAG:
+ return getIndexingDetailsForAtomicStringFormula((AtomicFormula) formula);
+ case Formula.INT_ATOMIC_FORMULA_TAG:
+ case Formula.BOOLEAN_ATOMIC_FORMULA_TAG:
+ // Package name and app certificate related formulas are string atomic formulas.
+ return new RuleIndexingDetails(NOT_INDEXED);
+ default:
+ throw new IllegalArgumentException(
+ String.format("Invalid formula tag type: %s", formula.getTag()));
+ }
+ }
+
+ private static RuleIndexingDetails getIndexingDetailsForCompoundFormula(
+ CompoundFormula compoundFormula) {
+ int connector = compoundFormula.getConnector();
+ List<Formula> formulas = compoundFormula.getFormulas();
+
+ switch (connector) {
+ case CompoundFormula.AND:
+ case CompoundFormula.OR:
+ // If there is a package name related atomic rule, return package name indexed.
+ Optional<RuleIndexingDetails> packageNameRule =
+ formulas.stream()
+ .map(formula -> getIndexingDetails(formula))
+ .filter(ruleIndexingDetails -> ruleIndexingDetails.getIndexType()
+ == PACKAGE_NAME_INDEXED)
+ .findAny();
+ if (packageNameRule.isPresent()) {
+ return packageNameRule.get();
+ }
+
+ // If there is an app certificate related atomic rule but no package name related
+ // atomic rule, return app certificate indexed.
+ Optional<RuleIndexingDetails> appCertificateRule =
+ formulas.stream()
+ .map(formula -> getIndexingDetails(formula))
+ .filter(ruleIndexingDetails -> ruleIndexingDetails.getIndexType()
+ == APP_CERTIFICATE_INDEXED)
+ .findAny();
+ if (appCertificateRule.isPresent()) {
+ return appCertificateRule.get();
+ }
+
+ // Do not index when there is not package name or app certificate indexing.
+ return new RuleIndexingDetails(NOT_INDEXED);
+ default:
+ // Having a NOT operator in the indexing messes up the indexing; e.g., deny
+ // installation if app certificate is NOT X (should not be indexed with app cert
+ // X). We will not keep these rules indexed.
+ // Also any other type of unknown operators will not be indexed.
+ return new RuleIndexingDetails(NOT_INDEXED);
+ }
+ }
+
+ private static RuleIndexingDetails getIndexingDetailsForAtomicStringFormula(
+ AtomicFormula atomicFormula) {
+ switch (atomicFormula.getKey()) {
+ case AtomicFormula.PACKAGE_NAME:
+ return new RuleIndexingDetails(PACKAGE_NAME_INDEXED,
+ getValueFromAtomicRuleString(atomicFormula.toString()));
+ case AtomicFormula.APP_CERTIFICATE:
+ return new RuleIndexingDetails(APP_CERTIFICATE_INDEXED,
+ getValueFromAtomicRuleString(atomicFormula.toString()));
+ default:
+ return new RuleIndexingDetails(NOT_INDEXED);
+ }
+ }
+
+ // The AtomRule API does not allow direct access to the {@link AtomicFormula} value. However,
+ // this value is printed as "(%s %s %s)" where the last %s stands for the value. This method
+ // parses the last.
+ private static String getValueFromAtomicRuleString(String ruleString) {
+ // TODO (b/145488708): Make an API change and get rid of this trick.
+ return ruleString.split(" ")[2].split("[)]")[0];
+ }
+}
+
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexTypeIdentifierTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java
index 18b91b0b1009..abb1787cede5 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexTypeIdentifierTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleIndexingDetailsIdentifierTest.java
@@ -16,6 +16,9 @@
package com.android.server.integrity.serializer;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
import static com.android.server.testutils.TestUtils.assertExpectException;
import static com.google.common.truth.Truth.assertThat;
@@ -34,9 +37,9 @@ import org.junit.runners.JUnit4;
import java.util.Arrays;
-/** Unit tests for {@link RuleIndexTypeIdentifier}. */
+/** Unit tests for {@link RuleIndexingDetailsIdentifier}. */
@RunWith(JUnit4.class)
-public class RuleIndexTypeIdentifierTest {
+public class RuleIndexingDetailsIdentifierTest {
@Test
public void getIndexType_nullRule() {
@@ -46,7 +49,7 @@ public class RuleIndexTypeIdentifierTest {
IllegalArgumentException.class,
/* expectedExceptionMessageRegex= */
"Indexing type cannot be determined for null rule.",
- () -> RuleIndexTypeIdentifier.getIndexType(rule));
+ () -> RuleIndexingDetailsIdentifier.getIndexingDetails(rule));
}
@Test
@@ -56,7 +59,7 @@ public class RuleIndexTypeIdentifierTest {
assertExpectException(
IllegalArgumentException.class,
/* expectedExceptionMessageRegex= */ "Invalid formula tag type.",
- () -> RuleIndexTypeIdentifier.getIndexType(rule));
+ () -> RuleIndexingDetailsIdentifier.getIndexingDetails(rule));
}
@Test
@@ -78,8 +81,10 @@ public class RuleIndexTypeIdentifierTest {
/* isHashedValue= */ false))),
Rule.DENY);
- assertThat(RuleIndexTypeIdentifier.getIndexType(rule))
- .isEqualTo(RuleIndexTypeIdentifier.PACKAGE_NAME_INDEXED);
+ RuleIndexingDetails result = RuleIndexingDetailsIdentifier.getIndexingDetails(rule);
+
+ assertThat(result.getIndexType()).isEqualTo(PACKAGE_NAME_INDEXED);
+ assertThat(result.getRuleKey()).isEqualTo(packageName);
}
@Test
@@ -101,8 +106,11 @@ public class RuleIndexTypeIdentifierTest {
/* isHashedValue= */ false))),
Rule.DENY);
- assertThat(RuleIndexTypeIdentifier.getIndexType(rule))
- .isEqualTo(RuleIndexTypeIdentifier.APP_CERTIFICATE_INDEXED);
+
+ RuleIndexingDetails result = RuleIndexingDetailsIdentifier.getIndexingDetails(rule);
+
+ assertThat(result.getIndexType()).isEqualTo(APP_CERTIFICATE_INDEXED);
+ assertThat(result.getRuleKey()).isEqualTo(appCertificate);
}
@Test
@@ -124,8 +132,8 @@ public class RuleIndexTypeIdentifierTest {
/* isHashedValue= */ false))),
Rule.DENY);
- assertThat(RuleIndexTypeIdentifier.getIndexType(rule))
- .isEqualTo(RuleIndexTypeIdentifier.NOT_INDEXED);
+ assertThat(RuleIndexingDetailsIdentifier.getIndexingDetails(rule).getIndexType())
+ .isEqualTo(NOT_INDEXED);
}
@Test
@@ -145,8 +153,8 @@ public class RuleIndexTypeIdentifierTest {
appVersion))),
Rule.DENY);
- assertThat(RuleIndexTypeIdentifier.getIndexType(rule))
- .isEqualTo(RuleIndexTypeIdentifier.NOT_INDEXED);
+ assertThat(RuleIndexingDetailsIdentifier.getIndexingDetails(rule).getIndexType())
+ .isEqualTo(NOT_INDEXED);
}
@Test
@@ -171,8 +179,8 @@ public class RuleIndexTypeIdentifierTest {
/* isHashedValue= */ false))))),
Rule.DENY);
- assertThat(RuleIndexTypeIdentifier.getIndexType(rule))
- .isEqualTo(RuleIndexTypeIdentifier.NOT_INDEXED);
+ assertThat(RuleIndexingDetailsIdentifier.getIndexingDetails(rule).getIndexType())
+ .isEqualTo(NOT_INDEXED);
}
private Formula getInvalidFormula() {
@@ -215,4 +223,3 @@ public class RuleIndexTypeIdentifierTest {
};
}
}
-