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

Commit 76a0bb89 authored by Song Pan's avatar Song Pan
Browse files

Two API changes:

1. Add a new formula type "INSTALLER_ALLOWD_BY_MANIFEST" that evaluates to true
when installer is specified in the manifest.

This CL only adds this class without actually removing the part where we
propagate allowed installers. That will be changed in a new CL.

2. Change the AppIntegrityComponent API so that it is type-safe.

Test: atest frameworks/base/services/tests/servicestests/src/com/android/server/integrity
Test: atest frameworks/base/core/tests/coretests/src/android/content/integrity
Bug: 148780440, 147835536
Change-Id: Icfb996b2f6de241d9790a423dd01992edaf35117
parent d9e45183
Loading
Loading
Loading
Loading
+15 −11
Original line number Diff line number Diff line
@@ -1922,18 +1922,22 @@ package android.content.integrity {
  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 static final class IntegrityFormula.Application {
    method @NonNull public static android.content.integrity.IntegrityFormula certificatesContain(@NonNull String);
    method @NonNull public static android.content.integrity.IntegrityFormula isPreInstalled();
    method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
    method @NonNull public static android.content.integrity.IntegrityFormula versionCodeEquals(@NonNull long);
    method @NonNull public static android.content.integrity.IntegrityFormula versionCodeGreaterThan(@NonNull long);
    method @NonNull public static android.content.integrity.IntegrityFormula versionCodeGreaterThanOrEqualTo(@NonNull long);
  }
  public static final class IntegrityFormula.Installer {
    method @NonNull public static android.content.integrity.IntegrityFormula certificatesContain(@NonNull String);
    method @NonNull public static android.content.integrity.IntegrityFormula notAllowedByManifest();
    method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
  }
  public final class Rule implements android.os.Parcelable {
+15 −11
Original line number Diff line number Diff line
@@ -812,18 +812,22 @@ package android.content.integrity {
  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 static final class IntegrityFormula.Application {
    method @NonNull public static android.content.integrity.IntegrityFormula certificatesContain(@NonNull String);
    method @NonNull public static android.content.integrity.IntegrityFormula isPreInstalled();
    method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
    method @NonNull public static android.content.integrity.IntegrityFormula versionCodeEquals(@NonNull long);
    method @NonNull public static android.content.integrity.IntegrityFormula versionCodeGreaterThan(@NonNull long);
    method @NonNull public static android.content.integrity.IntegrityFormula versionCodeGreaterThanOrEqualTo(@NonNull long);
  }

  public static final class IntegrityFormula.Installer {
    method @NonNull public static android.content.integrity.IntegrityFormula certificatesContain(@NonNull String);
    method @NonNull public static android.content.integrity.IntegrityFormula notAllowedByManifest();
    method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
  }

  public final class Rule implements android.os.Parcelable {
+28 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ package android.content.integrity;

import android.annotation.NonNull;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
@@ -40,6 +42,7 @@ public final class AppInstallMetadata {
    private final List<String> mInstallerCertificates;
    private final long mVersionCode;
    private final boolean mIsPreInstalled;
    private final Map<String, String> mAllowedInstallersAndCertificates;

    private AppInstallMetadata(Builder builder) {
        this.mPackageName = builder.mPackageName;
@@ -48,6 +51,7 @@ public final class AppInstallMetadata {
        this.mInstallerCertificates = builder.mInstallerCertificates;
        this.mVersionCode = builder.mVersionCode;
        this.mIsPreInstalled = builder.mIsPreInstalled;
        this.mAllowedInstallersAndCertificates = builder.mAllowedInstallersAndCertificates;
    }

    @NonNull
@@ -80,6 +84,13 @@ public final class AppInstallMetadata {
        return mIsPreInstalled;
    }

    /**
     * Get the allowed installers and their corresponding cert.
     */
    public Map<String, String> getAllowedInstallersAndCertificates() {
        return mAllowedInstallersAndCertificates;
    }

    @Override
    public String toString() {
        return String.format(
@@ -101,6 +112,23 @@ public final class AppInstallMetadata {
        private List<String> mInstallerCertificates;
        private long mVersionCode;
        private boolean mIsPreInstalled;
        private Map<String, String> mAllowedInstallersAndCertificates;

        public Builder() {
            mAllowedInstallersAndCertificates = new HashMap<>();
        }

        /**
         * Add allowed installers and cert.
         *
         * @see AppInstallMetadata#getAllowedInstallersAndCertificates()
         */
        @NonNull
        public Builder setAllowedInstallersAndCert(
                @NonNull Map<String, String> allowedInstallersAndCertificates) {
            this.mAllowedInstallersAndCertificates = allowedInstallersAndCertificates;
            return this;
        }

        /**
         * Set package name of the app to be installed.
+4 −5
Original line number Diff line number Diff line
@@ -55,14 +55,12 @@ public abstract class AtomicFormula extends IntegrityFormula {
                    PRE_INSTALLED,
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Key {
    }
    public @interface Key {}

    /** @hide */
    @IntDef(value = {EQ, GT, GTE})
    @Retention(RetentionPolicy.SOURCE)
    public @interface Operator {
    }
    public @interface Operator {}

    /**
     * Package name of the app.
@@ -354,7 +352,8 @@ public abstract class AtomicFormula extends IntegrityFormula {
                            "Key %s cannot be used with StringAtomicFormula", keyToString(key)));
            mValue = hashValue(key, value);
            mIsHashedValue =
                    key == APP_CERTIFICATE || key == INSTALLER_CERTIFICATE
                    key == APP_CERTIFICATE
                            || key == INSTALLER_CERTIFICATE
                            ? true
                            : !mValue.equals(value);
        }
+63 −0
Original line number Diff line number Diff line
/*
 * 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.
 * 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 java.util.Map;

/**
 * An atomic formula that evaluates to true if the installer of the current install is specified in
 * the "allowed installer" field in the android manifest. Note that an empty "allowed installer" by
 * default means containing all possible installers.
 *
 * @hide
 */
public class InstallerAllowedByManifestFormula extends IntegrityFormula {

    @Override
    public int getTag() {
        return IntegrityFormula.INSTALLER_ALLOWED_BY_MANIFEST_FORMULA_TAG;
    }

    @Override
    public boolean matches(AppInstallMetadata appInstallMetadata) {
        Map<String, String> allowedInstallersAndCertificates =
                appInstallMetadata.getAllowedInstallersAndCertificates();
        return allowedInstallersAndCertificates.isEmpty()
                || installerInAllowedInstallersFromManifest(
                appInstallMetadata, allowedInstallersAndCertificates);
    }

    @Override
    public boolean isAppCertificateFormula() {
        return false;
    }

    @Override
    public boolean isInstallerFormula() {
        return true;
    }

    private static boolean installerInAllowedInstallersFromManifest(
            AppInstallMetadata appInstallMetadata,
            Map<String, String> allowedInstallersAndCertificates) {
        return allowedInstallersAndCertificates.containsKey(appInstallMetadata.getInstallerName())
                && appInstallMetadata.getInstallerCertificates()
                .contains(
                        allowedInstallersAndCertificates
                        .get(appInstallMetadata.getInstallerName()));
    }
}
Loading