diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index c1f72c5f46825..75dbe21cba1c9 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3842,6 +3842,7 @@ public abstract class Context { UWB_SERVICE, MEDIA_METRICS_SERVICE, SUPPLEMENTAL_PROCESS_SERVICE, + //@hide: ATTESTATION_VERIFICATION_SERVICE, //@hide: SAFETY_CENTER_SERVICE, }) @Retention(RetentionPolicy.SOURCE) @@ -5738,6 +5739,15 @@ public abstract class Context { */ public static final String INCREMENTAL_SERVICE = "incremental"; + /** + * Use with {@link #getSystemService(String)} to retrieve an + * {@link android.security.attestationverification.AttestationVerificationManager}. + * @see #getSystemService(String) + * @see android.security.attestationverification.AttestationVerificationManager + * @hide + */ + public static final String ATTESTATION_VERIFICATION_SERVICE = "attestation_verification"; + /** * Use with {@link #getSystemService(String)} to retrieve an * {@link android.security.FileIntegrityManager}. diff --git a/core/java/android/security/attestationverification/AttestationProfile.aidl b/core/java/android/security/attestationverification/AttestationProfile.aidl new file mode 100644 index 0000000000000..51696a94cd88c --- /dev/null +++ b/core/java/android/security/attestationverification/AttestationProfile.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2021 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.security.attestationverification; + +/** + * {@hide} + */ +parcelable AttestationProfile; diff --git a/core/java/android/security/attestationverification/AttestationProfile.java b/core/java/android/security/attestationverification/AttestationProfile.java new file mode 100644 index 0000000000000..7a43dac87fc52 --- /dev/null +++ b/core/java/android/security/attestationverification/AttestationProfile.java @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2021 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.security.attestationverification; + +import static android.security.attestationverification.AttestationVerificationManager.PROFILE_APP_DEFINED; +import static android.security.attestationverification.AttestationVerificationManager.PROFILE_UNKNOWN; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcelable; +import android.security.attestationverification.AttestationVerificationManager.AttestationProfileId; +import android.util.Log; + +import com.android.internal.util.DataClass; + + +/** + * An attestation profile defining the security requirements for verifying the attestation of a + * remote compute environment. + * + *
This class is immutable and thread-safe. When checking this profile against an expected + * profile, it is recommended to construct the expected profile and compare them with {@code + * equals()}. + * + * @hide + * @see AttestationVerificationManager + */ +@DataClass( + genConstructor = false, + genEqualsHashCode = true +) +public final class AttestationProfile implements Parcelable { + + private static final String TAG = "AVF"; + + /** + * The ID of a system-defined attestation profile. + * + * See constants in {@link AttestationVerificationManager} prefixed with {@code PROFILE_}. If + * this has the value of {@link AttestationVerificationManager#PROFILE_APP_DEFINED}, then the + * packageName and profileName are non-null. + */ + @AttestationProfileId + private final int mAttestationProfileId; + + /** + * The package name of a app-defined attestation profile. + * + * This value will be null unless the value of attestationProfileId is {@link + * AttestationVerificationManager#PROFILE_APP_DEFINED}. + */ + @Nullable + private final String mPackageName; + + + /** + * The name of an app-defined attestation profile. + * + * This value will be null unless the value of attestationProfileId is {@link + * AttestationVerificationManager#PROFILE_APP_DEFINED}. + */ + @Nullable + private final String mProfileName; + + private AttestationProfile( + @AttestationProfileId int attestationProfileId, + @Nullable String packageName, + @Nullable String profileName) { + mAttestationProfileId = attestationProfileId; + mPackageName = packageName; + mProfileName = profileName; + } + + /** + * Create a profile with the given id. + * + *
This constructor is for specifying a profile which is defined by the system. These are + * available as constants in the {@link AttestationVerificationManager} class prefixed with + * {@code PROFILE_}. + * + * @param attestationProfileId the ID of the system-defined profile + * @throws IllegalArgumentException when called with + * {@link AttestationVerificationManager#PROFILE_APP_DEFINED} + * (use {@link #AttestationProfile(String, String)}) + */ + public AttestationProfile(@AttestationProfileId int attestationProfileId) { + this(attestationProfileId, null, null); + if (attestationProfileId == PROFILE_APP_DEFINED) { + throw new IllegalArgumentException("App-defined profiles must be specified with the " + + "constructor AttestationProfile#constructor(String, String)"); + } + } + + /** + * Create a profile with the given package name and profile name. + * + *
This constructor is for specifying a profile defined by an app. The packageName must
+ * match the package name of the app that defines the profile (as specified in the {@code
+ * package} attribute of the {@code
+ * Apps must declare profiles in their manifest as an {@code This method verifies that at least one system-registered {@linkplain
+ * AttestationVerificationService attestation verifier} associated with {@code profile} and
+ * {@code localBindingType} has verified that {@code attestation} attests that the remote
+ * environment matching the local binding data (determined by {@code localBindingType}) in
+ * {@code requirements} meets the requirements of the profile.
+ *
+ * For successful verification, the {@code requirements} bundle must contain locally-known
+ * data which must match {@code attestation}. The required data in the bundle is defined by the
+ * {@code localBindingType} (see documentation for the type). Verifiers will fail to verify the
+ * attestation if the bundle contains unsupported data.
+ *
+ * The {@code localBindingType} specifies how {@code attestation} is bound to a local
+ * secure channel endpoint or similar connection with the target remote environment described by
+ * the attestation. The binding is expected to be related to a cryptographic protocol, and each
+ * binding type requires specific arguments to be present in the {@code requirements} bundle. It
+ * is this binding to something known locally that ensures an attestation is not only valid, but
+ * is also associated with a particular connection.
+ *
+ * The {@code callback} is called with a result and {@link VerificationToken} (which may be
+ * null). The result is an integer (see constants in this class with the prefix {@code RESULT_}.
+ * The result is {@link #RESULT_SUCCESS} when at least one verifier has passed its checks. The
+ * token may be used in calls to other parts of the system.
+ *
+ * It's expected that a verifier will be able to decode and understand the passed values,
+ * otherwise fail to verify. {@code attestation} should contain some type data to prevent parse
+ * errors.
+ *
+ * The values put into the {@code requirements} Bundle depend on the {@code
+ * localBindingType} used.
+ *
+ * @param profile the attestation profile which defines the security requirements which
+ * must be met by the environment described by {@code attestation}
+ * @param localBindingType the type of the local binding data; see constants in this class with
+ * the prefix {@code TYPE_}
+ * @param requirements a {@link Bundle} containing locally-known data which must match
+ * {@code attestation}
+ * @param attestation attestation data which describes a remote computing environment
+ * @param executor {@code callback} will be executed on this executor
+ * @param callback will be called with the results of the verification
+ * @see AttestationVerificationService
+ */
+ @RequiresPermission(Manifest.permission.USE_ATTESTATION_VERIFICATION_SERVICE)
+ public void verifyAttestation(
+ @NonNull AttestationProfile profile,
+ @LocalBindingType int localBindingType,
+ @NonNull Bundle requirements,
+ @NonNull byte[] attestation,
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull BiConsumer<@VerificationResult Integer, VerificationToken> callback) {
+ executor.execute(() -> callback.accept(RESULT_UNKNOWN, null));
+ }
+
+ /**
+ * Verifies that {@code token} is a valid token, returning the result contained in valid
+ * tokens.
+ *
+ * This verifies that the token was issued by the platform and thus the system verified
+ * attestation data against the specified {@code profile}, {@code localBindingType}, and {@code
+ * requirements}. The value returned by this method is the same as the one originally returned
+ * when the token was generated. Callers of this method should not trust the provider of the
+ * token to also specify the profile, local binding type, or requirements, but instead have
+ * their own security requirements about these arguments.
+ *
+ * This method, in contrast to {@code verifyAttestation}, executes synchronously and only
+ * checks that a previous verification succeeded. This allows callers to pass the token to
+ * others, including system APIs, without those components needing to re-verify the attestation
+ * data, an operation which can take several seconds.
+ *
+ * When {@code maximumAge} is not specified (null), this method verifies the token was
+ * generated in the past hour. Otherwise, it verifies the token was generated between now and
+ * {@code maximumAge} ago. The maximum value of {@code maximumAge} is one hour; specifying a
+ * duration greater than one hour will result in an {@link IllegalArgumentException}.
+ *
+ * @param profile the attestation profile which must be in the token
+ * @param localBindingType the local binding type which must be in the token
+ * @param requirements the requirements which must be in the token
+ * @param token the token to be verified
+ * @param maximumAge the maximum age to accept for the token
+ */
+ @RequiresPermission(Manifest.permission.USE_ATTESTATION_VERIFICATION_SERVICE)
+ @CheckResult
+ @VerificationResult
+ public int verifyToken(
+ @NonNull AttestationProfile profile,
+ @LocalBindingType int localBindingType,
+ @NonNull Bundle requirements,
+ @NonNull VerificationToken token,
+ @Nullable java.time.Duration maximumAge) {
+ return RESULT_UNKNOWN;
+ }
+
+ /** @hide */
+ public AttestationVerificationManager() {
+ }
+
+ /** @hide */
+ @IntDef(
+ prefix = {"PROFILE_"},
+ value = {
+ PROFILE_UNKNOWN,
+ PROFILE_APP_DEFINED,
+ PROFILE_SELF_TRUSTED,
+ PROFILE_PEER_DEVICE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AttestationProfileId {
+ }
+
+ /**
+ * The profile is unknown because it is a profile unknown to this version of the SDK.
+ */
+ public static final int PROFILE_UNKNOWN = 0;
+
+ /** The profile is defined by an app. */
+ public static final int PROFILE_APP_DEFINED = 1;
+
+ /**
+ * A system-defined profile which verifies that the attesting environment can create an
+ * attestation with the same root certificate as the verifying device with a matching
+ * attestation challenge.
+ *
+ * This profile is intended to be used only for testing.
+ */
+ public static final int PROFILE_SELF_TRUSTED = 2;
+
+ /**
+ * A system-defined profile which verifies that the attesting environment environment is similar
+ * to the current device in terms of security model and security configuration. This category is
+ * fairly broad and most securely configured Android devices should qualify, along with a
+ * variety of non-Android devices.
+ */
+ public static final int PROFILE_PEER_DEVICE = 3;
+
+ /** @hide */
+ @IntDef(
+ prefix = {"TYPE_"},
+ value = {
+ TYPE_UNKNOWN,
+ TYPE_APP_DEFINED,
+ TYPE_PUBLIC_KEY,
+ TYPE_CHALLENGE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface LocalBindingType {
+ }
+
+ /**
+ * The type of the local binding data is unknown because it is a type unknown to this version of
+ * the SDK.
+ */
+ public static final int TYPE_UNKNOWN = 0;
+
+ /**
+ * A local binding type for app-defined profiles which use local binding data which does not
+ * match any of the existing system-defined types.
+ */
+ public static final int TYPE_APP_DEFINED = 1;
+
+ /**
+ * A local binding type where the attestation is bound to a public key negotiated and
+ * authenticated to a public key.
+ *
+ * When using this type, the {@code requirements} bundle contains values for:
+ * When using this type, the {@code requirements} bundle contains values for:
+ * This should contain the encoded key bytes according to the ASN.1 type
+ * {@code SubjectPublicKeyInfo} defined in the X.509 standard, the same as a call to {@link
+ * java.security.spec.X509EncodedKeySpec#getEncoded()} would produce.
+ *
+ * @see Bundle#putByteArray(String, byte[])
+ */
+ public static final String PARAM_PUBLIC_KEY = "localbinding.public_key";
+
+ /** Requirements bundle parameter key for an ID, String. */
+ public static final String PARAM_ID = "localbinding.id";
+
+ /** Requirements bundle parameter for a challenge. */
+ public static final String PARAM_CHALLENGE = "localbinding.challenge";
+}
diff --git a/core/java/android/security/attestationverification/AttestationVerificationService.java b/core/java/android/security/attestationverification/AttestationVerificationService.java
new file mode 100644
index 0000000000000..26c3051f7f38b
--- /dev/null
+++ b/core/java/android/security/attestationverification/AttestationVerificationService.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2021 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.security.attestationverification;
+
+import android.annotation.CheckResult;
+import android.annotation.NonNull;
+import android.app.Service;
+import android.os.Bundle;
+import android.security.attestationverification.AttestationVerificationManager.VerificationResult;
+
+/**
+ * A verifier which can be implemented by apps to verify an attestation (as described in {@link
+ * AttestationVerificationManager}).
+ *
+ * In the manifest for this service, specify the profile and local binding type this verifier
+ * supports. Create a new service for each combination of profile & local binding type that your app
+ * supports. Each service must declare an {@code intent-filter} action of {@link #SERVICE_INTERFACE}
+ * and permission of {@link android.Manifest.permission#BIND_ATTESTATION_VERIFICATION_SERVICE}.
+ *
+ * Example:
+ * {@code
+ * For app-defined profiles, an example of the {@code The app will be kept alive for a short duration between verification calls after which
+ * the system will unbind from this service making the app eligible for cleanup.
+ *
+ * The service must also require permission
+ * {@link android.Manifest.permission#BIND_ATTESTATION_VERIFICATION_SERVICE}.
+ */
+ public static final String SERVICE_INTERFACE =
+ "android.security.attestationverification.AttestationVerificationService";
+
+ /**
+ * Verifies that {@code attestation} attests that the device identified by the local binding
+ * data in {@code requirements} meets the minimum requirements of this verifier for this
+ * verifier's profile.
+ *
+ * Called by the system to verify an attestation.
+ *
+ * The data passed into this method comes directly from apps and should be treated as
+ * potentially dangerous user input.
+ *
+ * @param requirements a {@link Bundle} containing locally-known data which must match {@code
+ * attestation}
+ * @param attestation the attestation to verify
+ * @return whether the verification passed
+ * @see AttestationVerificationManager#verifyAttestation(AttestationProfile, int, Bundle,
+ * byte[], java.util.concurrent.Executor, java.util.function.BiConsumer)
+ */
+ @CheckResult
+ @VerificationResult
+ public abstract int onVerifyPeerDeviceAttestation(
+ @NonNull Bundle requirements,
+ @NonNull byte[] attestation);
+}
diff --git a/core/java/android/security/attestationverification/VerificationToken.aidl b/core/java/android/security/attestationverification/VerificationToken.aidl
new file mode 100644
index 0000000000000..666a8b04aac24
--- /dev/null
+++ b/core/java/android/security/attestationverification/VerificationToken.aidl
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2021 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.security.attestationverification;
+
+/**
+ * {@hide}
+ */
+parcelable VerificationToken;
diff --git a/core/java/android/security/attestationverification/VerificationToken.java b/core/java/android/security/attestationverification/VerificationToken.java
new file mode 100644
index 0000000000000..ae26823a9c7d0
--- /dev/null
+++ b/core/java/android/security/attestationverification/VerificationToken.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2021 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.security.attestationverification;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.security.attestationverification.AttestationVerificationManager.LocalBindingType;
+import android.security.attestationverification.AttestationVerificationManager.VerificationResult;
+
+import com.android.internal.util.DataClass;
+import com.android.internal.util.Parcelling;
+import com.android.internal.util.Parcelling.BuiltIn.ForInstant;
+
+import java.time.Duration;
+import java.util.concurrent.Executor;
+import java.util.function.BiConsumer;
+
+/**
+ * Token representing the result of an attestation verification, which can be passed to other parts
+ * of the OS or other apps as proof of the verification.
+ *
+ * Tokens are only valid within the same UID (which means within a single app unless the deprecated
+ * android:sharedUserId manifest value is used).
+ *
+ * @hide
+ * @see Bundle#putParcelable(String, Parcelable)
+ */
+@DataClass(
+ genConstructor = false,
+ genHiddenBuilder = true
+)
+public final class VerificationToken implements Parcelable {
+
+ /**
+ * The attestation profile which was used to perform the verification.
+ * @hide
+ */
+ @NonNull
+ private final AttestationProfile mAttestationProfile;
+
+ /**
+ * The local binding type of the local binding data used to perform the verification.
+ * @hide
+ */
+ @LocalBindingType
+ private final int mLocalBindingType;
+
+ /**
+ * The requirements used to perform the verification.
+ * @hide
+ */
+ @NonNull
+ private final Bundle mRequirements;
+
+ /**
+ * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
+ * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
+ * accidentally reading this value without calling {@code verifyToken}. Do not use this
+ * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
+ * Duration)} to verify a valid token and it will return this value.
+ *
+ * If the token is valid, this value is returned directly by {#verifyToken}.
+ *
+ * @hide
+ */
+ @VerificationResult
+ private final int mVerificationResult;
+
+ /**
+ * Time when the token was generated, set by the system.
+ */
+ @NonNull
+ @DataClass.ParcelWith(ForInstant.class)
+ private final java.time.Instant mVerificationTime;
+
+ /**
+ * A Hash-based message authentication code used to verify the contents and authenticity of the
+ * rest of the token. The hash is created using a secret key known only to the system server.
+ * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
+ * the same.
+ *
+ * @hide
+ */
+ @NonNull
+ private final byte[] mHmac;
+
+ /**
+ * The UID of the process which called {@code verifyAttestation} to create the token, as
+ * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
+ * of calling process does not match this value. This ensures that tokens cannot be shared
+ * between UIDs.
+ *
+ * @hide
+ */
+ private int mUid;
+
+
+ // Code below generated by codegen v1.0.23.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/security/attestationverification/VerificationToken.java
+ //
+ // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
+ // Settings > Editor > Code Style > Formatter Control
+ //@formatter:off
+
+
+ @DataClass.Generated.Member
+ /* package-private */ VerificationToken(
+ @NonNull AttestationProfile attestationProfile,
+ @LocalBindingType int localBindingType,
+ @NonNull Bundle requirements,
+ @VerificationResult int verificationResult,
+ @NonNull java.time.Instant verificationTime,
+ @NonNull byte[] hmac,
+ int uid) {
+ this.mAttestationProfile = attestationProfile;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mAttestationProfile);
+ this.mLocalBindingType = localBindingType;
+ com.android.internal.util.AnnotationValidations.validate(
+ LocalBindingType.class, null, mLocalBindingType);
+ this.mRequirements = requirements;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mRequirements);
+ this.mVerificationResult = verificationResult;
+ com.android.internal.util.AnnotationValidations.validate(
+ VerificationResult.class, null, mVerificationResult);
+ this.mVerificationTime = verificationTime;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mVerificationTime);
+ this.mHmac = hmac;
+ com.android.internal.util.AnnotationValidations.validate(
+ NonNull.class, null, mHmac);
+ this.mUid = uid;
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ /**
+ * The attestation profile which was used to perform the verification.
+ */
+ @DataClass.Generated.Member
+ public @NonNull AttestationProfile getAttestationProfile() {
+ return mAttestationProfile;
+ }
+
+ /**
+ * The local binding type of the local binding data used to perform the verification.
+ */
+ @DataClass.Generated.Member
+ public @LocalBindingType int getLocalBindingType() {
+ return mLocalBindingType;
+ }
+
+ /**
+ * The requirements used to perform the verification.
+ */
+ @DataClass.Generated.Member
+ public @NonNull Bundle getRequirements() {
+ return mRequirements;
+ }
+
+ /**
+ * The result of the {@link AttestationVerificationManager#verifyAttestation(int, int, Bundle,
+ * byte[], Executor, BiConsumer)} call. This value is kept hidden to prevent token holders from
+ * accidentally reading this value without calling {@code verifyToken}. Do not use this
+ * value directly; call {@link AttestationVerificationManager#verifyToken(VerificationToken,
+ * Duration)} to verify a valid token and it will return this value.
+ *
+ * If the token is valid, this value is returned directly by {#verifyToken}.
+ *
+ * @hide
+ */
+ @DataClass.Generated.Member
+ public @VerificationResult int getVerificationResult() {
+ return mVerificationResult;
+ }
+
+ /**
+ * Time when the token was generated, set by the system.
+ */
+ @DataClass.Generated.Member
+ public @NonNull java.time.Instant getVerificationTime() {
+ return mVerificationTime;
+ }
+
+ /**
+ * A Hash-based message authentication code used to verify the contents and authenticity of the
+ * rest of the token. The hash is created using a secret key known only to the system server.
+ * When verifying the token, the system re-hashes the token and verifies the generated HMAC is
+ * the same.
+ *
+ * @hide
+ */
+ @DataClass.Generated.Member
+ public @NonNull byte[] getHmac() {
+ return mHmac;
+ }
+
+ /**
+ * The UID of the process which called {@code verifyAttestation} to create the token, as
+ * returned by {@link Binder#getCallingUid()}. Calls to {@code verifyToken} will fail if the UID
+ * of calling process does not match this value. This ensures that tokens cannot be shared
+ * between UIDs.
+ *
+ * @hide
+ */
+ @DataClass.Generated.Member
+ public int getUid() {
+ return mUid;
+ }
+
+ @DataClass.Generated.Member
+ static Parcelling
+ *
+ */
+ public static final int TYPE_PUBLIC_KEY = 2;
+
+ /**
+ * A local binding type where the attestation is bound to a challenge.
+ *
+ *
+ *
+ */
+ public static final int TYPE_CHALLENGE = 3;
+
+ /** @hide */
+ @IntDef(
+ prefix = {"RESULT_"},
+ value = {
+ RESULT_UNKNOWN,
+ RESULT_SUCCESS,
+ RESULT_FAILURE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE})
+ public @interface VerificationResult {
+ }
+
+ /** The result of the verification is unknown because it has a value unknown to this SDK. */
+ public static final int RESULT_UNKNOWN = 0;
+
+ /** The result of the verification was successful. */
+ public static final int RESULT_SUCCESS = 1;
+
+ /**
+ * The result of the attestation verification was failure. The attestation could not be
+ * verified.
+ */
+ public static final int RESULT_FAILURE = 2;
+
+ /**
+ * Requirements bundle parameter key for a public key, a byte array.
+ *
+ *
+ *
+ * }
+ *
+ *
+ *
+ * }
+ *
+ * @hide
+ */
+public abstract class AttestationVerificationService extends Service {
+
+ /**
+ * An intent action for a service to be bound and act as an attestation verifier.
+ *
+ *