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

Commit a15d8009 authored by Khaled Abdelmohsen's avatar Khaled Abdelmohsen Committed by Android (Google) Code Review
Browse files

Merge "Create rule atom for source stamp"

parents 8244b684 41456aa9
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1958,6 +1958,11 @@ package android.content.integrity {
    method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
  }
  public static final class IntegrityFormula.SourceStamp {
    method @NonNull public static android.content.integrity.IntegrityFormula notTrusted();
    method @NonNull public static android.content.integrity.IntegrityFormula stampCertificateHashEquals(@NonNull String);
  }
  public final class Rule implements android.os.Parcelable {
    ctor public Rule(@NonNull android.content.integrity.IntegrityFormula, int);
    method public int describeContents();
+5 −0
Original line number Diff line number Diff line
@@ -846,6 +846,11 @@ package android.content.integrity {
    method @NonNull public static android.content.integrity.IntegrityFormula packageNameEquals(@NonNull String);
  }

  public static final class IntegrityFormula.SourceStamp {
    method @NonNull public static android.content.integrity.IntegrityFormula notTrusted();
    method @NonNull public static android.content.integrity.IntegrityFormula stampCertificateHashEquals(@NonNull String);
  }

  public final class Rule implements android.os.Parcelable {
    ctor public Rule(@NonNull android.content.integrity.IntegrityFormula, int);
    method public int describeContents();
+48 −5
Original line number Diff line number Diff line
@@ -42,6 +42,9 @@ public final class AppInstallMetadata {
    private final List<String> mInstallerCertificates;
    private final long mVersionCode;
    private final boolean mIsPreInstalled;
    private final boolean mIsStampTrusted;
    // Raw string encoding for the SHA-256 hash of the certificate of the stamp.
    private final String mStampCertificateHash;
    private final Map<String, String> mAllowedInstallersAndCertificates;

    private AppInstallMetadata(Builder builder) {
@@ -51,6 +54,8 @@ public final class AppInstallMetadata {
        this.mInstallerCertificates = builder.mInstallerCertificates;
        this.mVersionCode = builder.mVersionCode;
        this.mIsPreInstalled = builder.mIsPreInstalled;
        this.mIsStampTrusted = builder.mIsStampTrusted;
        this.mStampCertificateHash = builder.mStampCertificateHash;
        this.mAllowedInstallersAndCertificates = builder.mAllowedInstallersAndCertificates;
    }

@@ -84,9 +89,17 @@ public final class AppInstallMetadata {
        return mIsPreInstalled;
    }

    /**
     * Get the allowed installers and their corresponding cert.
     */
    /** @see AppInstallMetadata.Builder#setIsStampTrusted(boolean) */
    public boolean isStampTrusted() {
        return mIsStampTrusted;
    }

    /** @see AppInstallMetadata.Builder#setStampCertificateHash(String) */
    public String getStampCertificateHash() {
        return mStampCertificateHash;
    }

    /** Get the allowed installers and their corresponding cert. */
    public Map<String, String> getAllowedInstallersAndCertificates() {
        return mAllowedInstallersAndCertificates;
    }
@@ -95,13 +108,16 @@ public final class AppInstallMetadata {
    public String toString() {
        return String.format(
                "AppInstallMetadata { PackageName = %s, AppCerts = %s, InstallerName = %s,"
                    + " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b }",
                        + " InstallerCerts = %s, VersionCode = %d, PreInstalled = %b, "
                        + "StampTrusted = %b, StampCert = %s }",
                mPackageName,
                mAppCertificates,
                mInstallerName == null ? "null" : mInstallerName,
                mInstallerCertificates == null ? "null" : mInstallerCertificates,
                mVersionCode,
                mIsPreInstalled);
                mIsPreInstalled,
                mIsStampTrusted,
                mStampCertificateHash == null ? "null" : mStampCertificateHash);
    }

    /** Builder class for constructing {@link AppInstallMetadata} objects. */
@@ -112,6 +128,8 @@ public final class AppInstallMetadata {
        private List<String> mInstallerCertificates;
        private long mVersionCode;
        private boolean mIsPreInstalled;
        private boolean mIsStampTrusted;
        private String mStampCertificateHash;
        private Map<String, String> mAllowedInstallersAndCertificates;

        public Builder() {
@@ -202,6 +220,31 @@ public final class AppInstallMetadata {
            return this;
        }

        /**
         * Set certificate hash of the stamp embedded in the APK.
         *
         * <p>It is represented as the raw string encoding for the SHA-256 hash of the certificate
         * of the stamp.
         *
         * @see AppInstallMetadata#getStampCertificateHash()
         */
        @NonNull
        public Builder setStampCertificateHash(@NonNull String stampCertificateHash) {
            this.mStampCertificateHash = Objects.requireNonNull(stampCertificateHash);
            return this;
        }

        /**
         * Set whether the stamp embedded in the APK is trusted or not.
         *
         * @see AppInstallMetadata#isStampTrusted()
         */
        @NonNull
        public Builder setIsStampTrusted(boolean isStampTrusted) {
            this.mIsStampTrusted = isStampTrusted;
            return this;
        }

        /**
         * Build {@link AppInstallMetadata}.
         *
+50 −23
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ public abstract class AtomicFormula extends IntegrityFormula {
                INSTALLER_CERTIFICATE,
                VERSION_CODE,
                PRE_INSTALLED,
                STAMP_TRUSTED,
                STAMP_CERTIFICATE_HASH,
            })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Key {}
@@ -105,6 +107,20 @@ public abstract class AtomicFormula extends IntegrityFormula {
     */
    public static final int PRE_INSTALLED = 5;

    /**
     * If the APK has an embedded trusted stamp.
     *
     * <p>Can only be used in {@link BooleanAtomicFormula}.
     */
    public static final int STAMP_TRUSTED = 6;

    /**
     * SHA-256 of the certificate used to sign the stamp embedded in the APK.
     *
     * <p>Can only be used in {@link StringAtomicFormula}.
     */
    public static final int STAMP_CERTIFICATE_HASH = 7;

    public static final int EQ = 0;
    public static final int GT = 1;
    public static final int GTE = 2;
@@ -266,9 +282,7 @@ public abstract class AtomicFormula extends IntegrityFormula {
        }

        private static boolean isValidOperator(int operator) {
            return operator == EQ
                    || operator == GT
                    || operator == GTE;
            return operator == EQ || operator == GT || operator == GTE;
        }

        private static long getLongMetadataValue(AppInstallMetadata appInstallMetadata, int key) {
@@ -300,7 +314,8 @@ public abstract class AtomicFormula extends IntegrityFormula {
                    key == PACKAGE_NAME
                            || key == APP_CERTIFICATE
                            || key == INSTALLER_CERTIFICATE
                            || key == INSTALLER_NAME,
                            || key == INSTALLER_NAME
                            || key == STAMP_CERTIFICATE_HASH,
                    String.format(
                            "Key %s cannot be used with StringAtomicFormula", keyToString(key)));
            mValue = null;
@@ -321,7 +336,8 @@ public abstract class AtomicFormula extends IntegrityFormula {
                    key == PACKAGE_NAME
                            || key == APP_CERTIFICATE
                            || key == INSTALLER_CERTIFICATE
                            || key == INSTALLER_NAME,
                            || key == INSTALLER_NAME
                            || key == STAMP_CERTIFICATE_HASH,
                    String.format(
                            "Key %s cannot be used with StringAtomicFormula", keyToString(key)));
            mValue = value;
@@ -329,15 +345,14 @@ public abstract class AtomicFormula extends IntegrityFormula {
        }

        /**
         * Constructs a new {@link StringAtomicFormula} together with handling the necessary
         * hashing for the given key.
         * Constructs a new {@link StringAtomicFormula} together with handling the necessary hashing
         * for the given key.
         *
         * <p> The value will be automatically hashed with SHA256 and the hex digest will be
         * computed when the key is PACKAGE_NAME or INSTALLER_NAME and the value is more than 32
         * characters.
         * <p>The value will be automatically hashed with SHA256 and the hex digest will be computed
         * when the key is PACKAGE_NAME or INSTALLER_NAME and the value is more than 32 characters.
         *
         * <p> The APP_CERTIFICATES and INSTALLER_CERTIFICATES are always delivered in hashed
         * form. So the isHashedValue is set to true by default.
         * <p>The APP_CERTIFICATES, INSTALLER_CERTIFICATES, and STAMP_CERTIFICATE_HASH are always
         * delivered in hashed form. So the isHashedValue is set to true by default.
         *
         * @throws IllegalArgumentException if {@code key} cannot be used with string value.
         */
@@ -347,13 +362,15 @@ public abstract class AtomicFormula extends IntegrityFormula {
                    key == PACKAGE_NAME
                            || key == APP_CERTIFICATE
                            || key == INSTALLER_CERTIFICATE
                            || key == INSTALLER_NAME,
                            || key == INSTALLER_NAME
                            || key == STAMP_CERTIFICATE_HASH,
                    String.format(
                            "Key %s cannot be used with StringAtomicFormula", keyToString(key)));
            mValue = hashValue(key, value);
            mIsHashedValue =
                    key == APP_CERTIFICATE
                                    || key == INSTALLER_CERTIFICATE
                                    || key == STAMP_CERTIFICATE_HASH
                            ? true
                            : !mValue.equals(value);
        }
@@ -460,6 +477,8 @@ public abstract class AtomicFormula extends IntegrityFormula {
                    return appInstallMetadata.getInstallerCertificates();
                case AtomicFormula.INSTALLER_NAME:
                    return Collections.singletonList(appInstallMetadata.getInstallerName());
                case AtomicFormula.STAMP_CERTIFICATE_HASH:
                    return Collections.singletonList(appInstallMetadata.getStampCertificateHash());
                default:
                    throw new IllegalStateException(
                            "Unexpected key in StringAtomicFormula: " + key);
@@ -502,7 +521,7 @@ public abstract class AtomicFormula extends IntegrityFormula {
        public BooleanAtomicFormula(@Key int key) {
            super(key);
            checkArgument(
                    key == PRE_INSTALLED,
                    key == PRE_INSTALLED || key == STAMP_TRUSTED,
                    String.format(
                            "Key %s cannot be used with BooleanAtomicFormula", keyToString(key)));
            mValue = null;
@@ -519,7 +538,7 @@ public abstract class AtomicFormula extends IntegrityFormula {
        public BooleanAtomicFormula(@Key int key, boolean value) {
            super(key);
            checkArgument(
                    key == PRE_INSTALLED,
                    key == PRE_INSTALLED || key == STAMP_TRUSTED,
                    String.format(
                            "Key %s cannot be used with BooleanAtomicFormula", keyToString(key)));
            mValue = value;
@@ -615,6 +634,8 @@ public abstract class AtomicFormula extends IntegrityFormula {
            switch (key) {
                case AtomicFormula.PRE_INSTALLED:
                    return appInstallMetadata.isPreInstalled();
                case AtomicFormula.STAMP_TRUSTED:
                    return appInstallMetadata.isStampTrusted();
                default:
                    throw new IllegalStateException(
                            "Unexpected key in BooleanAtomicFormula: " + key);
@@ -640,6 +661,10 @@ public abstract class AtomicFormula extends IntegrityFormula {
                return "INSTALLER_CERTIFICATE";
            case PRE_INSTALLED:
                return "PRE_INSTALLED";
            case STAMP_TRUSTED:
                return "STAMP_TRUSTED";
            case STAMP_CERTIFICATE_HASH:
                return "STAMP_CERTIFICATE_HASH";
            default:
                throw new IllegalArgumentException("Unknown key " + key);
        }
@@ -664,6 +689,8 @@ public abstract class AtomicFormula extends IntegrityFormula {
                || key == VERSION_CODE
                || key == INSTALLER_NAME
                || key == INSTALLER_CERTIFICATE
                || key == PRE_INSTALLED;
                || key == PRE_INSTALLED
                || key == STAMP_TRUSTED
                || key == STAMP_CERTIFICATE_HASH;
    }
}
+34 −19
Original line number Diff line number Diff line
@@ -90,8 +90,7 @@ public abstract class IntegrityFormula {
            return new BooleanAtomicFormula(AtomicFormula.PRE_INSTALLED, true);
        }

        private Application() {
        }
        private Application() {}
    }

    /** Factory class for creating integrity formulas based on installer. */
@@ -117,12 +116,32 @@ public abstract class IntegrityFormula {
         */
        @NonNull
        public static IntegrityFormula certificatesContain(@NonNull String installerCertificate) {
            return new StringAtomicFormula(AtomicFormula.INSTALLER_CERTIFICATE,
                    installerCertificate);
            return new StringAtomicFormula(
                    AtomicFormula.INSTALLER_CERTIFICATE, installerCertificate);
        }

        private Installer() {}
    }

        private Installer() {
    /** Factory class for creating integrity formulas based on source stamp. */
    public static final class SourceStamp {
        /** Returns an integrity formula that checks the equality to a stamp certificate hash. */
        @NonNull
        public static IntegrityFormula stampCertificateHashEquals(
                @NonNull String stampCertificateHash) {
            return new StringAtomicFormula(
                    AtomicFormula.STAMP_CERTIFICATE_HASH, stampCertificateHash);
        }

        /**
         * Returns an integrity formula that is valid when stamp embedded in the APK is NOT trusted.
         */
        @NonNull
        public static IntegrityFormula notTrusted() {
            return new BooleanAtomicFormula(AtomicFormula.STAMP_TRUSTED, /* value= */ false);
        }

        private SourceStamp() {}
    }

    /** @hide */
@@ -135,8 +154,7 @@ public abstract class IntegrityFormula {
                INSTALLER_ALLOWED_BY_MANIFEST_FORMULA_TAG
            })
    @Retention(RetentionPolicy.SOURCE)
    @interface Tag {
    }
    @interface Tag {}

    /** @hide */
    public static final int COMPOUND_FORMULA_TAG = 0;
@@ -171,8 +189,8 @@ public abstract class IntegrityFormula {
    public abstract boolean isAppCertificateFormula();

    /**
     * Returns true when the formula (or one of its atomic formulas) has installer package name
     * or installer certificate as key.
     * Returns true when the formula (or one of its atomic formulas) has installer package name or
     * installer certificate as key.
     *
     * @hide
     */
@@ -243,15 +261,12 @@ public abstract class IntegrityFormula {
        return new CompoundFormula(CompoundFormula.AND, Arrays.asList(formulae));
    }

    /**
     * Returns a formula that evaluates to true when {@code formula} evaluates to false.
     */
    /** Returns a formula that evaluates to true when {@code formula} evaluates to false. */
    @NonNull
    public static IntegrityFormula not(@NonNull IntegrityFormula formula) {
        return new CompoundFormula(CompoundFormula.NOT, Arrays.asList(formula));
    }

    // Constructor is package private so it cannot be inherited outside of this package.
    IntegrityFormula() {
    }
    IntegrityFormula() {}
}
Loading