Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15395f59 authored by Omer Nebil Yaveroglu's avatar Omer Nebil Yaveroglu
Browse files

Various API changes including:

1. Move isSatisifed into RuleEvaluator to minimise the API surface.
2. Add a new global settings for skipping integrity component for rule
providers.
3. Incorporate changes suggested by API review in http://b/147835536.

Note that this change is forked from ag/9974531.

Test: atest frameworks/base/core/tests/coretests/src/android/content/integrity/
Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/integrity
Bug: 145290357, 147835536
Change-Id: Ic358a83b6bdcd4cb783e6904869f7dc2d136a55e
parent 8f00f6a2
Loading
Loading
Loading
Loading
+17 −93
Original line number Diff line number Diff line
@@ -1898,26 +1898,6 @@ package android.content {
package android.content.integrity {
  public final class AppInstallMetadata {
    method @NonNull public String getAppCertificate();
    method @Nullable public String getInstallerCertificate();
    method @Nullable public String getInstallerName();
    method @NonNull public String getPackageName();
    method public int getVersionCode();
    method public boolean isPreInstalled();
  }
  public static final class AppInstallMetadata.Builder {
    ctor public AppInstallMetadata.Builder();
    method @NonNull public android.content.integrity.AppInstallMetadata build();
    method @NonNull public android.content.integrity.AppInstallMetadata.Builder setAppCertificate(@NonNull String);
    method @NonNull public android.content.integrity.AppInstallMetadata.Builder setInstallerCertificate(@NonNull String);
    method @NonNull public android.content.integrity.AppInstallMetadata.Builder setInstallerName(@NonNull String);
    method @NonNull public android.content.integrity.AppInstallMetadata.Builder setIsPreInstalled(boolean);
    method @NonNull public android.content.integrity.AppInstallMetadata.Builder setPackageName(@NonNull String);
    method @NonNull public android.content.integrity.AppInstallMetadata.Builder setVersionCode(int);
  }
  public class AppIntegrityManager {
    method @NonNull public String getCurrentRuleSetProvider();
    method @NonNull public String getCurrentRuleSetVersion();
@@ -1927,84 +1907,28 @@ package android.content.integrity {
    field public static final int STATUS_SUCCESS = 0; // 0x0
  }
  public abstract class AtomicFormula implements android.content.integrity.Formula {
    ctor public AtomicFormula(int);
    method public int getKey();
    field public static final int APP_CERTIFICATE = 1; // 0x1
    field public static final int EQ = 0; // 0x0
    field public static final int GE = 4; // 0x4
    field public static final int GT = 3; // 0x3
    field public static final int INSTALLER_CERTIFICATE = 3; // 0x3
    field public static final int INSTALLER_NAME = 2; // 0x2
    field public static final int LE = 2; // 0x2
    field public static final int LT = 1; // 0x1
    field public static final int PACKAGE_NAME = 0; // 0x0
    field public static final int PRE_INSTALLED = 5; // 0x5
    field public static final int VERSION_CODE = 4; // 0x4
  }
  public static final class AtomicFormula.BooleanAtomicFormula extends android.content.integrity.AtomicFormula implements android.os.Parcelable {
    ctor public AtomicFormula.BooleanAtomicFormula(int, boolean);
    method public int describeContents();
    method public int getTag();
    method public boolean getValue();
    method public boolean isSatisfied(@NonNull android.content.integrity.AppInstallMetadata);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.integrity.AtomicFormula.BooleanAtomicFormula> CREATOR;
  }
  public static final class AtomicFormula.IntAtomicFormula extends android.content.integrity.AtomicFormula implements android.os.Parcelable {
    ctor public AtomicFormula.IntAtomicFormula(int, int, int);
    method public int describeContents();
    method public int getOperator();
    method public int getTag();
    method public int getValue();
    method public boolean isSatisfied(@NonNull android.content.integrity.AppInstallMetadata);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.integrity.AtomicFormula.IntAtomicFormula> CREATOR;
  }
  public static final class AtomicFormula.StringAtomicFormula extends android.content.integrity.AtomicFormula implements android.os.Parcelable {
    ctor public AtomicFormula.StringAtomicFormula(int, @NonNull String, boolean);
    method public int describeContents();
    method public boolean getIsHashedValue();
    method public int getTag();
    method @NonNull public String getValue();
    method public boolean isSatisfied(@NonNull android.content.integrity.AppInstallMetadata);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.integrity.AtomicFormula.StringAtomicFormula> CREATOR;
  }
  public final class CompoundFormula implements android.content.integrity.Formula android.os.Parcelable {
    ctor public CompoundFormula(int, @NonNull java.util.List<android.content.integrity.Formula>);
    method public int describeContents();
    method public int getConnector();
    method @NonNull public java.util.List<android.content.integrity.Formula> getFormulas();
    method public int getTag();
    method public boolean isSatisfied(@NonNull android.content.integrity.AppInstallMetadata);
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field public static final int AND = 0; // 0x0
    field @NonNull public static final android.os.Parcelable.Creator<android.content.integrity.CompoundFormula> CREATOR;
    field public static final int NOT = 2; // 0x2
    field public static final int OR = 1; // 0x1
  }
  public interface Formula {
    method public int getTag();
    method public boolean isSatisfied(@NonNull android.content.integrity.AppInstallMetadata);
    method @NonNull public static android.content.integrity.Formula readFromParcel(@NonNull android.os.Parcel);
    method public static void writeToParcel(@NonNull android.content.integrity.Formula, @NonNull android.os.Parcel, int);
    field public static final int BOOLEAN_ATOMIC_FORMULA_TAG = 3; // 0x3
    field public static final int COMPOUND_FORMULA_TAG = 0; // 0x0
    field public static final int INT_ATOMIC_FORMULA_TAG = 2; // 0x2
    field public static final int STRING_ATOMIC_FORMULA_TAG = 1; // 0x1
  public abstract class IntegrityFormula {
    method @NonNull public static android.content.integrity.IntegrityFormula all(@NonNull android.content.integrity.IntegrityFormula...);
    method @NonNull public static android.content.integrity.IntegrityFormula any(@NonNull android.content.integrity.IntegrityFormula...);
    method @NonNull public android.content.integrity.IntegrityFormula equalTo(@NonNull String);
    method @NonNull public android.content.integrity.IntegrityFormula equalTo(boolean);
    method @NonNull public android.content.integrity.IntegrityFormula equalTo(long);
    method @NonNull public android.content.integrity.IntegrityFormula greaterThan(long);
    method @NonNull public android.content.integrity.IntegrityFormula greaterThanOrEquals(long);
    method @NonNull public static android.content.integrity.IntegrityFormula not(@NonNull android.content.integrity.IntegrityFormula);
    field @NonNull public static final android.content.integrity.IntegrityFormula APP_CERTIFICATE;
    field @NonNull public static final android.content.integrity.IntegrityFormula INSTALLER_CERTIFICATE;
    field @NonNull public static final android.content.integrity.IntegrityFormula INSTALLER_NAME;
    field @NonNull public static final android.content.integrity.IntegrityFormula PACKAGE_NAME;
    field @NonNull public static final android.content.integrity.IntegrityFormula PRE_INSTALLED;
    field @NonNull public static final android.content.integrity.IntegrityFormula VERSION_CODE;
  }
  public final class Rule implements android.os.Parcelable {
    ctor public Rule(@NonNull android.content.integrity.Formula, int);
    ctor public Rule(@NonNull android.content.integrity.IntegrityFormula, int);
    method public int describeContents();
    method public int getEffect();
    method @NonNull public android.content.integrity.Formula getFormula();
    method @NonNull public android.content.integrity.IntegrityFormula getFormula();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.content.integrity.Rule> CREATOR;
    field public static final int DENY = 0; // 0x0
+8 −14
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 * Copyright (C) 2020 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.
@@ -17,10 +17,6 @@
package android.content.integrity;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;

import com.android.internal.annotations.VisibleForTesting;

import java.util.Objects;

@@ -34,8 +30,6 @@ import java.util.Objects;
 *
 * @hide
 */
@SystemApi
@VisibleForTesting
public final class AppInstallMetadata {
    private final String mPackageName;
    // Raw string encoding for the SHA-256 hash of the certificate of the app.
@@ -43,7 +37,7 @@ public final class AppInstallMetadata {
    private final String mInstallerName;
    // Raw string encoding for the SHA-256 hash of the certificate of the installer.
    private final String mInstallerCertificate;
    private final int mVersionCode;
    private final long mVersionCode;
    private final boolean mIsPreInstalled;

    private AppInstallMetadata(Builder builder) {
@@ -65,18 +59,18 @@ public final class AppInstallMetadata {
        return mAppCertificate;
    }

    @Nullable
    @NonNull
    public String getInstallerName() {
        return mInstallerName;
    }

    @Nullable
    @NonNull
    public String getInstallerCertificate() {
        return mInstallerCertificate;
    }

    /** @see AppInstallMetadata.Builder#setVersionCode(int) */
    public int getVersionCode() {
    /** @see AppInstallMetadata.Builder#setVersionCode(long) */
    public long getVersionCode() {
        return mVersionCode;
    }

@@ -104,7 +98,7 @@ public final class AppInstallMetadata {
        private String mAppCertificate;
        private String mInstallerName;
        private String mInstallerCertificate;
        private int mVersionCode;
        private long mVersionCode;
        private boolean mIsPreInstalled;

        /**
@@ -163,7 +157,7 @@ public final class AppInstallMetadata {
         * @see AppInstallMetadata#getVersionCode()
         */
        @NonNull
        public Builder setVersionCode(int versionCode) {
        public Builder setVersionCode(long versionCode) {
            this.mVersionCode = versionCode;
            return this;
        }
+217 −105

File changed.

Preview size limit exceeded, changes collapsed.

+25 −31
Original line number Diff line number Diff line
@@ -20,10 +20,8 @@ import static com.android.internal.util.Preconditions.checkArgument;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;

@@ -42,16 +40,11 @@ import java.util.Objects;
 *
 * @hide
 */
@SystemApi
@VisibleForTesting
public final class CompoundFormula implements Formula, Parcelable {
    private static final String TAG = "OpenFormula";
public final class CompoundFormula extends IntegrityFormula implements Parcelable {

    /** @hide */
    @IntDef(
            value = {
                AND, OR, NOT,
            })
    @IntDef(value = {AND, OR, NOT})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Connector {}

@@ -65,7 +58,7 @@ public final class CompoundFormula implements Formula, Parcelable {
    public static final int NOT = 2;

    private final @Connector int mConnector;
    private final @NonNull List<Formula> mFormulas;
    private final @NonNull List<IntegrityFormula> mFormulas;

    @NonNull
    public static final Creator<CompoundFormula> CREATOR =
@@ -85,9 +78,10 @@ public final class CompoundFormula implements Formula, Parcelable {
     * Create a new formula from operator and operands.
     *
     * @throws IllegalArgumentException if the number of operands is not matching the requirements
     *     for that operator (at least 2 for {@link #AND} and {@link #OR}, 1 for {@link #NOT}).
     *                                  for that operator (at least 2 for {@link #AND} and {@link
     *                                  #OR}, 1 for {@link #NOT}).
     */
    public CompoundFormula(@Connector int connector, @NonNull List<Formula> formulas) {
    public CompoundFormula(@Connector int connector, List<IntegrityFormula> formulas) {
        checkArgument(
                isValidConnector(connector), String.format("Unknown connector: %d", connector));
        validateFormulas(connector, formulas);
@@ -101,7 +95,7 @@ public final class CompoundFormula implements Formula, Parcelable {
        checkArgument(length >= 0, "Must have non-negative length. Got " + length);
        mFormulas = new ArrayList<>(length);
        for (int i = 0; i < length; i++) {
            mFormulas.add(Formula.readFromParcel(in));
            mFormulas.add(IntegrityFormula.readFromParcel(in));
        }
        validateFormulas(mConnector, mFormulas);
    }
@@ -111,32 +105,31 @@ public final class CompoundFormula implements Formula, Parcelable {
    }

    @NonNull
    public List<Formula> getFormulas() {
    public List<IntegrityFormula> getFormulas() {
        return mFormulas;
    }

    @Override
    public boolean isSatisfied(@NonNull AppInstallMetadata appInstallMetadata) {
        switch (mConnector) {
    public int getTag() {
        return IntegrityFormula.COMPOUND_FORMULA_TAG;
    }

    @Override
    public boolean matches(AppInstallMetadata appInstallMetadata) {
        switch (getConnector()) {
            case NOT:
                return !mFormulas.get(0).isSatisfied(appInstallMetadata);
                return !getFormulas().get(0).matches(appInstallMetadata);
            case AND:
                return mFormulas.stream()
                        .allMatch(formula -> formula.isSatisfied(appInstallMetadata));
                return getFormulas().stream()
                        .allMatch(formula -> formula.matches(appInstallMetadata));
            case OR:
                return mFormulas.stream()
                        .anyMatch(formula -> formula.isSatisfied(appInstallMetadata));
                return getFormulas().stream()
                        .anyMatch(formula -> formula.matches(appInstallMetadata));
            default:
                Slog.i(TAG, "Unknown connector " + mConnector);
                return false;
                throw new IllegalArgumentException("Unknown connector " + getConnector());
        }
    }

    @Override
    public int getTag() {
        return Formula.COMPOUND_FORMULA_TAG;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
@@ -180,12 +173,13 @@ public final class CompoundFormula implements Formula, Parcelable {
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeInt(mConnector);
        dest.writeInt(mFormulas.size());
        for (Formula formula : mFormulas) {
            Formula.writeToParcel(formula, dest, flags);
        for (IntegrityFormula formula : mFormulas) {
            IntegrityFormula.writeToParcel(formula, dest, flags);
        }
    }

    private static void validateFormulas(@Connector int connector, List<Formula> formulas) {
    private static void validateFormulas(
            @Connector int connector, List<IntegrityFormula> formulas) {
        switch (connector) {
            case AND:
            case OR:
+0 −103
Original line number Diff line number Diff line
/*
 * 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 android.content.integrity;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.content.integrity.AtomicFormula.BooleanAtomicFormula;
import android.content.integrity.AtomicFormula.IntAtomicFormula;
import android.content.integrity.AtomicFormula.StringAtomicFormula;
import android.os.Parcel;
import android.os.Parcelable;

import com.android.internal.annotations.VisibleForTesting;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * Represents a rule logic/content.
 *
 * @hide
 */
@SystemApi
@VisibleForTesting
public interface Formula {
    /** @hide */
    @IntDef(
            value = {
                    COMPOUND_FORMULA_TAG,
                    STRING_ATOMIC_FORMULA_TAG,
                    INT_ATOMIC_FORMULA_TAG,
                    BOOLEAN_ATOMIC_FORMULA_TAG
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Tag {}

    int COMPOUND_FORMULA_TAG = 0;
    int STRING_ATOMIC_FORMULA_TAG = 1;
    int INT_ATOMIC_FORMULA_TAG = 2;
    int BOOLEAN_ATOMIC_FORMULA_TAG = 3;

    /**
     * Returns if this formula can be satisfied by substituting the corresponding information of
     * {@code appInstallMetadata} into the 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}.
     *
     * <p>This helper method is needed because non-final class/interface are not allowed to be
     * {@link Parcelable}.
     *
     * @throws IllegalArgumentException if {@link Formula} is not a recognized subclass
     */
    static void writeToParcel(@NonNull Formula formula, @NonNull Parcel dest, int flags) {
        dest.writeInt(formula.getTag());
        ((Parcelable) formula).writeToParcel(dest, flags);
    }

    /**
     * Read a {@link Formula} from a {@link android.os.Parcel}.
     *
     * <p>We need this (hacky) helper method because non-final class/interface cannot be {@link
     * Parcelable} (api lint error).
     *
     * @throws IllegalArgumentException if the parcel cannot be parsed
     */
    @NonNull
    static Formula readFromParcel(@NonNull Parcel in) {
        int tag = in.readInt();
        switch (tag) {
            case COMPOUND_FORMULA_TAG:
                return CompoundFormula.CREATOR.createFromParcel(in);
            case STRING_ATOMIC_FORMULA_TAG:
                return StringAtomicFormula.CREATOR.createFromParcel(in);
            case INT_ATOMIC_FORMULA_TAG:
                return IntAtomicFormula.CREATOR.createFromParcel(in);
            case BOOLEAN_ATOMIC_FORMULA_TAG:
                return BooleanAtomicFormula.CREATOR.createFromParcel(in);
            default:
                throw new IllegalArgumentException("Unknown formula tag " + tag);
        }
    }
}
Loading