diff options
| author | 2024-11-08 10:08:59 +0000 | |
|---|---|---|
| committer | 2024-11-25 14:24:24 +0000 | |
| commit | 7d9b085db25e0a8f8da733304374cd22b64bc7a7 (patch) | |
| tree | 8ef84e6746448cd9d17caf7cff514f428067c26b | |
| parent | 7846e2fc3be1c3acc7937cd7e87627bcf7443dde (diff) | |
Expose an API for APK signature verification.
Bug: 378045287
Test: TBD
Change-Id: I4a41d26f0d42d93328d46c79633fe1dbae20217c
| -rw-r--r-- | core/api/module-lib-current.txt | 13 | ||||
| -rw-r--r-- | core/java/android/content/pm/PackageManager.java | 31 | ||||
| -rw-r--r-- | core/java/android/content/pm/SigningInfo.java | 66 | ||||
| -rw-r--r-- | core/java/android/content/pm/SigningInfoException.java | 50 |
4 files changed, 160 insertions, 0 deletions
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 0b891f6e0a71..95bf649e8185 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -129,6 +129,7 @@ package android.content.pm { public abstract class PackageManager { method @NonNull public String getSdkSandboxPackageName(); + method @FlaggedApi("android.content.pm.cloud_compilation_pm") @NonNull public static android.content.pm.SigningInfo getVerifiedSigningInfo(@NonNull String, int) throws android.content.pm.SigningInfoException; method @RequiresPermission(android.Manifest.permission.MAKE_UID_VISIBLE) public void makeUidVisible(int, int); field public static final String EXTRA_VERIFICATION_ROOT_HASH = "android.content.pm.extra.VERIFICATION_ROOT_HASH"; field public static final int MATCH_STATIC_SHARED_AND_SDK_LIBRARIES = 67108864; // 0x4000000 @@ -139,6 +140,18 @@ package android.content.pm { method @NonNull public String getPackageName(); } + public final class SigningInfo implements android.os.Parcelable { + method @FlaggedApi("android.content.pm.cloud_compilation_pm") public boolean signersMatchExactly(@NonNull android.content.pm.SigningInfo); + field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_JAR = 1; // 0x1 + field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V2 = 2; // 0x2 + field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V3 = 3; // 0x3 + field @FlaggedApi("android.content.pm.cloud_compilation_pm") public static final int VERSION_SIGNING_BLOCK_V4 = 4; // 0x4 + } + + @FlaggedApi("android.content.pm.cloud_compilation_pm") public class SigningInfoException extends java.lang.Exception { + method @FlaggedApi("android.content.pm.cloud_compilation_pm") public int getCode(); + } + } package android.hardware.usb { diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 0ed9c87e3d51..3971e98442bc 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -16,6 +16,7 @@ package android.content.pm; +import static android.content.pm.SigningInfo.AppSigningSchemeVersion; import static android.media.audio.Flags.FLAG_FEATURE_SPATIAL_AUDIO_HEADTRACKING_LOW_LATENCY; import static com.android.internal.pm.pkg.parsing.ParsingPackageUtils.PARSE_COLLECT_CERTIFICATES; @@ -59,6 +60,8 @@ import android.content.IntentFilter; import android.content.IntentSender; import android.content.pm.PackageInstaller.SessionParams; import android.content.pm.dex.ArtManager; +import android.content.pm.parsing.result.ParseResult; +import android.content.pm.parsing.result.ParseTypeImpl; import android.content.pm.verify.domain.DomainVerificationManager; import android.content.res.Configuration; import android.content.res.Resources; @@ -94,6 +97,7 @@ import android.telephony.ims.RcsUceAdapter; import android.telephony.ims.SipDelegateManager; import android.util.AndroidException; import android.util.Log; +import android.util.apk.ApkSignatureVerifier; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.pm.parsing.PackageInfoCommonUtils; @@ -11838,4 +11842,31 @@ public abstract class PackageManager { throw new UnsupportedOperationException( "parseServiceMetadata not implemented in subclass"); } + + /** + * Verifies and returns the + * <a href="https://source.android.com/docs/security/features/apksigning">app signing</a> + * information of the file at the given path. This operation takes a few milliseconds. + * + * Unlike {@link #getPackageArchiveInfo(String, PackageInfoFlags)} with {@link + * #GET_SIGNING_CERTIFICATES}, this method does not require the file to be a package archive + * file. + * + * @throws SigningInfoException if the verification fails + * + * @hide + */ + @FlaggedApi(android.content.pm.Flags.FLAG_CLOUD_COMPILATION_PM) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static @NonNull SigningInfo getVerifiedSigningInfo(@NonNull String path, + @AppSigningSchemeVersion int minAppSigningSchemeVersion) throws SigningInfoException { + ParseTypeImpl input = ParseTypeImpl.forDefaultParsing(); + ParseResult<SigningDetails> result = + ApkSignatureVerifier.verify(input, path, minAppSigningSchemeVersion); + if (result.isError()) { + throw new SigningInfoException( + result.getErrorCode(), result.getErrorMessage(), result.getException()); + } + return new SigningInfo(result.getResult()); + } } diff --git a/core/java/android/content/pm/SigningInfo.java b/core/java/android/content/pm/SigningInfo.java index 23daaf2d4138..e4fbd1f28dbb 100644 --- a/core/java/android/content/pm/SigningInfo.java +++ b/core/java/android/content/pm/SigningInfo.java @@ -16,14 +16,20 @@ package android.content.pm; +import static android.content.pm.SigningDetails.SignatureSchemeVersion; + import android.annotation.FlaggedApi; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.content.pm.SigningDetails.SignatureSchemeVersion; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.security.PublicKey; import java.util.Collection; @@ -31,6 +37,55 @@ import java.util.Collection; * Information pertaining to the signing certificates used to sign a package. */ public final class SigningInfo implements Parcelable { + /** + * JAR signing (v1 scheme). + * See https://source.android.com/docs/security/features/apksigning#v1. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int VERSION_JAR = SignatureSchemeVersion.JAR; + + /** + * APK signature scheme v2. + * See https://source.android.com/docs/security/features/apksigning/v2. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int VERSION_SIGNING_BLOCK_V2 = SignatureSchemeVersion.SIGNING_BLOCK_V2; + + /** + * APK signature scheme v3. + * See https://source.android.com/docs/security/features/apksigning/v3. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int VERSION_SIGNING_BLOCK_V3 = SignatureSchemeVersion.SIGNING_BLOCK_V3; + + /** + * APK signature scheme v4. + * See https://source.android.com/docs/security/features/apksigning/v4. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int VERSION_SIGNING_BLOCK_V4 = SignatureSchemeVersion.SIGNING_BLOCK_V4; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"VERSION_"}, value = { + VERSION_JAR, + VERSION_SIGNING_BLOCK_V2, + VERSION_SIGNING_BLOCK_V3, + VERSION_SIGNING_BLOCK_V4, + }) + public @interface AppSigningSchemeVersion {} @NonNull private final SigningDetails mSigningDetails; @@ -198,6 +253,17 @@ public final class SigningInfo implements Parcelable { return mSigningDetails; } + /** + * Returns true if the signing certificates in this and other match exactly. + * + * @hide + */ + @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public boolean signersMatchExactly(@NonNull SigningInfo other) { + return mSigningDetails.signaturesMatchExactly(other.mSigningDetails); + } + public static final @android.annotation.NonNull Parcelable.Creator<SigningInfo> CREATOR = new Parcelable.Creator<SigningInfo>() { @Override diff --git a/core/java/android/content/pm/SigningInfoException.java b/core/java/android/content/pm/SigningInfoException.java new file mode 100644 index 000000000000..a81e07e73685 --- /dev/null +++ b/core/java/android/content/pm/SigningInfoException.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2024 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.pm; + +import android.annotation.FlaggedApi; +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.annotation.SystemApi; + +/** + * Indicates an error when verifying the + * <a href="https://source.android.com/docs/security/features/apksigning">app signing</a> + * information. + * + * @hide + */ +@FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM) +@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) +public class SigningInfoException extends Exception { + private final int mCode; + + /** @hide */ + public SigningInfoException(int code, @NonNull String message, @Nullable Throwable cause) { + super(message, cause); + mCode = code; + } + + /** + * Returns a code representing the cause, in one of the installation parse return codes in + * {@link PackageManager}. + */ + @FlaggedApi(Flags.FLAG_CLOUD_COMPILATION_PM) + public int getCode() { + return mCode; + } +} |