diff options
5 files changed, 101 insertions, 34 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 70ab98c86cda..9a0553d7aa0c 100644 --- a/services/core/java/com/android/server/integrity/model/AtomicFormula.java +++ b/services/core/java/com/android/server/integrity/model/AtomicFormula.java @@ -46,12 +46,12 @@ public abstract class AtomicFormula implements Formula { @IntDef( value = { - PACKAGE_NAME, - APP_CERTIFICATE, - INSTALLER_NAME, - INSTALLER_CERTIFICATE, - VERSION_CODE, - PRE_INSTALLED, + PACKAGE_NAME, + APP_CERTIFICATE, + INSTALLER_NAME, + INSTALLER_CERTIFICATE, + VERSION_CODE, + PRE_INSTALLED, }) @Retention(RetentionPolicy.SOURCE) public @interface Key {} @@ -60,11 +60,47 @@ public abstract class AtomicFormula implements Formula { @Retention(RetentionPolicy.SOURCE) public @interface Operator {} + /** + * Package name of the app. + * + * <p>Can only be used in {@link StringAtomicFormula}. + */ public static final int PACKAGE_NAME = 0; + + /** + * SHA-256 of the app certificate of the app. + * + * <p>Can only be used in {@link StringAtomicFormula}. + */ public static final int APP_CERTIFICATE = 1; + + /** + * Package name of the installer. Will be empty string if installed by the system (e.g., adb). + * + * <p>Can only be used in {@link StringAtomicFormula}. + */ public static final int INSTALLER_NAME = 2; + + /** + * SHA-256 of the cert of the installer. Will be empty string if installed by the system (e.g., + * adb). + * + * <p>Can only be used in {@link StringAtomicFormula}. + */ public static final int INSTALLER_CERTIFICATE = 3; + + /** + * Version code of the app. + * + * <p>Can only be used in {@link IntAtomicFormula}. + */ public static final int VERSION_CODE = 4; + + /** + * If the app is pre-installed on the device. + * + * <p>Can only be used in {@link BooleanAtomicFormula}. + */ public static final int PRE_INSTALLED = 5; public static final int EQ = 0; @@ -91,7 +127,7 @@ public abstract class AtomicFormula implements Formula { * specified by {@code key} is of the correct relationship to {@code value} as specified by * {@code operator}. * - * @throws IllegalArgumentException if {@code key} is not {@link #VERSION_CODE} + * @throws IllegalArgumentException if {@code key} cannot be used with integer value */ public IntAtomicFormula(@Key int key, @Operator int operator, int value) { super(key); @@ -143,6 +179,11 @@ public abstract class AtomicFormula implements Formula { } @Override + public int getTag() { + return Formula.INT_ATOMIC_FORMULA_TAG; + } + + @Override public String toString() { return String.format( "(%s %s %s)", keyToString(getKey()), operatorToString(mOperator), mValue); @@ -157,7 +198,9 @@ public abstract class AtomicFormula implements Formula { return false; } IntAtomicFormula that = (IntAtomicFormula) o; - return getKey() == that.getKey() && mValue == that.mValue; + return getKey() == that.getKey() + && mValue == that.mValue + && mOperator == that.mOperator; } @Override @@ -206,8 +249,7 @@ public abstract class AtomicFormula implements Formula { * <p>This formula will hold if and only if the corresponding information of an install * specified by {@code key} equals {@code value}. * - * @throws IllegalArgumentException if {@code key} is not one of {@link #PACKAGE_NAME}, - * {@link #APP_CERTIFICATE}, {@link #INSTALLER_NAME} and {@link #INSTALLER_CERTIFICATE} + * @throws IllegalArgumentException if {@code key} cannot be used with string value */ public StringAtomicFormula(@Key int key, @NonNull String value) { super(key); @@ -247,6 +289,11 @@ public abstract class AtomicFormula implements Formula { } @Override + public int getTag() { + return Formula.STRING_ATOMIC_FORMULA_TAG; + } + + @Override public String toString() { return String.format("(%s %s %s)", keyToString(getKey()), operatorToString(EQ), mValue); } @@ -279,6 +326,7 @@ public abstract class AtomicFormula implements Formula { dest.writeStringNoHelper(mValue); } + @NonNull public String getValue() { return mValue; } @@ -310,7 +358,7 @@ public abstract class AtomicFormula implements Formula { * <p>This formula will hold if and only if the corresponding information of an install * specified by {@code key} equals {@code value}. * - * @throws IllegalArgumentException if {@code key} is not {@link #PRE_INSTALLED} + * @throws IllegalArgumentException if {@code key} cannot be used with boolean value */ public BooleanAtomicFormula(@Key int key, boolean value) { super(key); @@ -347,6 +395,11 @@ public abstract class AtomicFormula implements Formula { } @Override + public int getTag() { + return Formula.BOOLEAN_ATOMIC_FORMULA_TAG; + } + + @Override public String toString() { return String.format("(%s %s %s)", keyToString(getKey()), operatorToString(EQ), mValue); } @@ -398,7 +451,7 @@ public abstract class AtomicFormula implements Formula { return mKey; } - String keyToString(int key) { + static String keyToString(int key) { switch (key) { case PACKAGE_NAME: return "PACKAGE_NAME"; @@ -417,7 +470,7 @@ public abstract class AtomicFormula implements Formula { } } - String operatorToString(int op) { + static String operatorToString(int op) { switch (op) { case EQ: return "EQ"; diff --git a/services/core/java/com/android/server/integrity/model/Formula.java b/services/core/java/com/android/server/integrity/model/Formula.java index 852ece536f31..67698277800f 100644 --- a/services/core/java/com/android/server/integrity/model/Formula.java +++ b/services/core/java/com/android/server/integrity/model/Formula.java @@ -16,6 +16,7 @@ package com.android.server.integrity.model; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.Parcel; @@ -26,6 +27,9 @@ import com.android.server.integrity.model.AtomicFormula.BooleanAtomicFormula; import com.android.server.integrity.model.AtomicFormula.IntAtomicFormula; import com.android.server.integrity.model.AtomicFormula.StringAtomicFormula; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * Represents a rule logic/content. * @@ -34,6 +38,15 @@ import com.android.server.integrity.model.AtomicFormula.StringAtomicFormula; @SystemApi @VisibleForTesting public interface Formula { + @IntDef( + value = { + OPEN_FORMULA_TAG, + STRING_ATOMIC_FORMULA_TAG, + INT_ATOMIC_FORMULA_TAG, + BOOLEAN_ATOMIC_FORMULA_TAG + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Tag {} int OPEN_FORMULA_TAG = 0; int STRING_ATOMIC_FORMULA_TAG = 1; @@ -46,6 +59,9 @@ public interface Formula { */ boolean isSatisfied(@NonNull AppInstallMetadata appInstallMetadata); + /** Returns the tag that identifies the current class. */ + @Tag int getTag(); + /** * Write a {@link Formula} to {@link android.os.Parcel}. * @@ -55,21 +71,8 @@ public interface Formula { * @throws IllegalArgumentException if {@link Formula} is not a recognized subclass */ static void writeToParcel(@NonNull Formula formula, @NonNull Parcel dest, int flags) { - if (formula instanceof OpenFormula) { - dest.writeInt(OPEN_FORMULA_TAG); - ((OpenFormula) formula).writeToParcel(dest, flags); - } else if (formula instanceof StringAtomicFormula) { - dest.writeInt(STRING_ATOMIC_FORMULA_TAG); - ((StringAtomicFormula) formula).writeToParcel(dest, flags); - } else if (formula instanceof IntAtomicFormula) { - dest.writeInt(INT_ATOMIC_FORMULA_TAG); - ((IntAtomicFormula) formula).writeToParcel(dest, flags); - } else if (formula instanceof BooleanAtomicFormula) { - dest.writeInt(BOOLEAN_ATOMIC_FORMULA_TAG); - ((BooleanAtomicFormula) formula).writeToParcel(dest, flags); - } else { - throw new IllegalArgumentException("Unrecognized class " + formula.getClass()); - } + dest.writeInt(formula.getTag()); + ((Parcelable) formula).writeToParcel(dest, flags); } /** 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 f29706adeebb..7a3600f7a4fe 100644 --- a/services/core/java/com/android/server/integrity/model/OpenFormula.java +++ b/services/core/java/com/android/server/integrity/model/OpenFormula.java @@ -63,7 +63,7 @@ public final class OpenFormula implements Formula, Parcelable { public static final int NOT = 2; private final @Connector int mConnector; - private final List<Formula> mFormulas; + private final @NonNull List<Formula> mFormulas; @NonNull public static final Creator<OpenFormula> CREATOR = @@ -99,6 +99,7 @@ public final class OpenFormula implements Formula, Parcelable { for (int i = 0; i < length; i++) { mFormulas.add(Formula.readFromParcel(in)); } + validateFormulas(mConnector, mFormulas); } public @Connector int getConnector() { @@ -128,6 +129,11 @@ public final class OpenFormula implements Formula, Parcelable { } @Override + public int getTag() { + return Formula.OPEN_FORMULA_TAG; + } + + @Override public String toString() { StringBuilder sb = new StringBuilder(); if (mFormulas.size() == 1) { @@ -175,7 +181,7 @@ public final class OpenFormula implements Formula, Parcelable { } } - private void validateFormulas(@Connector int connector, List<Formula> formulas) { + private static void validateFormulas(@Connector int connector, List<Formula> formulas) { switch (connector) { case AND: case OR: @@ -195,7 +201,7 @@ public final class OpenFormula implements Formula, Parcelable { } } - private String connectorToString(int connector) { + private static String connectorToString(int connector) { switch (connector) { case AND: return "AND"; 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 14dcb26d1025..f87e4e875eef 100644 --- a/services/core/java/com/android/server/integrity/model/Rule.java +++ b/services/core/java/com/android/server/integrity/model/Rule.java @@ -58,7 +58,7 @@ public final class Rule implements Parcelable { */ public static final int FORCE_ALLOW = 1; - private final Formula mFormula; + private final @NonNull Formula mFormula; private final @Effect int mEffect; public Rule(@NonNull Formula formula, @Effect int effect) { @@ -119,7 +119,7 @@ public final class Rule implements Parcelable { return false; } Rule that = (Rule) o; - return Objects.equals(mFormula, that.mFormula) && mEffect == that.mEffect; + return mEffect == that.mEffect && Objects.equals(mFormula, that.mFormula); } @Override @@ -127,7 +127,7 @@ public final class Rule implements Parcelable { return Objects.hash(mFormula, mEffect); } - private String effectToString(int effect) { + private static String effectToString(int effect) { switch (effect) { case DENY: return "DENY"; 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 a25627155950..77886c89c416 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 @@ -298,6 +298,11 @@ public class RuleXmlSerializerTest { } @Override + public int getTag() { + return 0; + } + + @Override public int hashCode() { return super.hashCode(); } |