From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tad Date: Mon, 3 Jul 2023 12:00:12 -0400 Subject: [PATCH] Hardened signature spoofing - Must be enabled by user - Must match microG package ID - Must meet minimum respective targetSdk and versionCode - Must match official microG build signing key - Only spoofs the Google package signature This is an effective merge + tweak of two existing patches, credits: Dylanger Daly https://github.com/dylangerdaly/platform_frameworks_base/commit/b58aa11631fadab3309a1d9268118bd9f2c2a79f Chirayu Desai of CalyxOS https://gitlab.com/CalyxOS/platform_frameworks_base/-/commit/76485abb36dc01b65506b010d0458e96e0116369 Change-Id: I64a252aac9bb196a11ed7b4b5d8c7e59a3413bd4 --- .../android/content/pm/SigningDetails.java | 36 +++++++++++++++- core/res/res/values/config.xml | 2 + .../com/android/server/pm/ComputerEngine.java | 42 +++++++++++++++++-- 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/core/java/android/content/pm/SigningDetails.java b/core/java/android/content/pm/SigningDetails.java index 1e659b74db77..00d669ab24e7 100644 --- a/core/java/android/content/pm/SigningDetails.java +++ b/core/java/android/content/pm/SigningDetails.java @@ -798,6 +798,38 @@ public final class SigningDetails implements Parcelable { return false; } + /** + * Return the Cerificate's Digest + */ + public @Nullable String getSha256Certificate() { + return getSha256CertificateInternal(); + } + + private @Nullable String getSha256CertificateInternal() { + String digest; + if (this == UNKNOWN) { + return null; + } + if (hasPastSigningCertificates()) { + + // check all past certs, except for the last one, which automatically gets all + // capabilities, since it is the same as the current signature, and is checked below + for (int i = 0; i < mPastSigningCertificates.length - 1; i++) { + digest = PackageUtils.computeSha256Digest( + mPastSigningCertificates[i].toByteArray()); + return digest; + } + } + + // not in previous certs signing history, just check the current signer + if (mSignatures.length == 1) { + digest = + PackageUtils.computeSha256Digest(mSignatures[0].toByteArray()); + return digest; + } + return null; + } + /** Returns true if the signatures in this and other match exactly. */ public boolean signaturesMatchExactly(@NonNull SigningDetails other) { return Signature.areExactMatch(mSignatures, other.mSignatures); @@ -1001,10 +1033,10 @@ public final class SigningDetails implements Parcelable { } @DataClass.Generated( - time = 1650058974710L, + time = 1688403190848L, codegenVersion = "1.0.23", sourceFile = "frameworks/base/core/java/android/content/pm/SigningDetails.java", - inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mSignatures\nprivate final @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate final @android.annotation.Nullable android.util.ArraySet mPublicKeys\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\nprivate static final int PAST_CERT_EXISTS\npublic static final android.content.pm.SigningDetails UNKNOWN\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator CREATOR\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails)\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails,int)\nprivate @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWithAncestorOrSelf(android.content.pm.SigningDetails,int)\npublic boolean hasCommonAncestor(android.content.pm.SigningDetails)\npublic boolean hasAncestorOrSelfWithDigest(java.util.Set)\nprivate @android.annotation.Nullable android.content.pm.SigningDetails getDescendantOrSelf(android.content.pm.SigningDetails)\npublic boolean hasSignatures()\npublic boolean hasPastSigningCertificates()\npublic boolean hasAncestorOrSelf(android.content.pm.SigningDetails)\npublic boolean hasAncestor(android.content.pm.SigningDetails)\npublic boolean hasCommonSignerWithCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapabilityRecover(android.content.pm.SigningDetails,int)\npublic boolean hasCertificate(android.content.pm.Signature)\npublic boolean hasCertificate(android.content.pm.Signature,int)\npublic boolean hasCertificate(byte[])\nprivate boolean hasCertificateInternal(android.content.pm.Signature,int)\npublic boolean checkCapability(java.lang.String,int)\npublic boolean hasSha256Certificate(byte[])\npublic boolean hasSha256Certificate(byte[],int)\nprivate boolean hasSha256CertificateInternal(byte[],int)\npublic boolean signaturesMatchExactly(android.content.pm.SigningDetails)\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\npublic @java.lang.Override boolean equals(java.lang.Object)\npublic @java.lang.Override int hashCode()\npublic static android.util.ArraySet toSigningKeys(android.content.pm.Signature[])\nclass SigningDetails extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.NonNull android.content.pm.Signature[] mSignatures\nprivate @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\npublic android.content.pm.SigningDetails.Builder setSignatures(android.content.pm.Signature[])\npublic android.content.pm.SigningDetails.Builder setSignatureSchemeVersion(int)\npublic android.content.pm.SigningDetails.Builder setPastSigningCertificates(android.content.pm.Signature[])\nprivate void checkInvariants()\npublic android.content.pm.SigningDetails build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false, genParcelable=true, genAidl=false)") + inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mSignatures\nprivate final @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate final @android.annotation.Nullable android.util.ArraySet mPublicKeys\nprivate final @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\nprivate static final int PAST_CERT_EXISTS\npublic static final android.content.pm.SigningDetails UNKNOWN\npublic static final @android.annotation.NonNull android.os.Parcelable.Creator CREATOR\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails)\npublic @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWith(android.content.pm.SigningDetails,int)\nprivate @android.annotation.NonNull android.content.pm.SigningDetails mergeLineageWithAncestorOrSelf(android.content.pm.SigningDetails,int)\npublic boolean hasCommonAncestor(android.content.pm.SigningDetails)\npublic boolean hasAncestorOrSelfWithDigest(java.util.Set)\nprivate @android.annotation.Nullable android.content.pm.SigningDetails getDescendantOrSelf(android.content.pm.SigningDetails)\npublic boolean hasSignatures()\npublic boolean hasPastSigningCertificates()\npublic boolean hasAncestorOrSelf(android.content.pm.SigningDetails)\npublic boolean hasAncestor(android.content.pm.SigningDetails)\npublic boolean hasCommonSignerWithCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapability(android.content.pm.SigningDetails,int)\npublic boolean checkCapabilityRecover(android.content.pm.SigningDetails,int)\npublic boolean hasCertificate(android.content.pm.Signature)\npublic boolean hasCertificate(android.content.pm.Signature,int)\npublic boolean hasCertificate(byte[])\nprivate boolean hasCertificateInternal(android.content.pm.Signature,int)\npublic boolean checkCapability(java.lang.String,int)\npublic boolean hasSha256Certificate(byte[])\npublic boolean hasSha256Certificate(byte[],int)\nprivate boolean hasSha256CertificateInternal(byte[],int)\npublic @android.annotation.Nullable java.lang.String getSha256Certificate()\nprivate @android.annotation.Nullable java.lang.String getSha256CertificateInternal()\npublic boolean signaturesMatchExactly(android.content.pm.SigningDetails)\npublic @java.lang.Override int describeContents()\npublic @java.lang.Override void writeToParcel(android.os.Parcel,int)\npublic @java.lang.Override boolean equals(java.lang.Object)\npublic @java.lang.Override int hashCode()\npublic static android.util.ArraySet toSigningKeys(android.content.pm.Signature[])\nclass SigningDetails extends java.lang.Object implements [android.os.Parcelable]\nprivate @android.annotation.NonNull android.content.pm.Signature[] mSignatures\nprivate @android.content.pm.SigningDetails.SignatureSchemeVersion int mSignatureSchemeVersion\nprivate @android.annotation.Nullable android.content.pm.Signature[] mPastSigningCertificates\npublic android.content.pm.SigningDetails.Builder setSignatures(android.content.pm.Signature[])\npublic android.content.pm.SigningDetails.Builder setSignatureSchemeVersion(int)\npublic android.content.pm.SigningDetails.Builder setPastSigningCertificates(android.content.pm.Signature[])\nprivate void checkInvariants()\npublic android.content.pm.SigningDetails build()\nclass Builder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false, genParcelable=true, genAidl=false)") @Deprecated private void __metadata() {} diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index a01ec67630de..20ab9e79ae79 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2011,6 +2011,8 @@ com.android.location.fused +