diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 8b35092ae322c..1bca2c30fddb4 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -8957,11 +8957,8 @@ package android.service.attestation { public abstract class ImpressionAttestationService extends android.app.Service { ctor public ImpressionAttestationService(); method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent); - method @Nullable public abstract android.service.attestation.ImpressionToken onGenerateImpressionToken(@NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String); - method public abstract int onVerifyImpressionToken(@NonNull android.service.attestation.ImpressionToken); - field public static final int VERIFICATION_STATUS_APP_DECLARED = 2; // 0x2 - field public static final int VERIFICATION_STATUS_OS_VERIFIED = 1; // 0x1 - field public static final int VERIFICATION_STATUS_UNKNOWN = 0; // 0x0 + method @Nullable public abstract android.service.attestation.ImpressionToken onGenerateImpressionToken(@NonNull String, @NonNull android.hardware.HardwareBuffer, @NonNull android.graphics.Rect, @NonNull String); + method public abstract boolean onVerifyImpressionToken(@NonNull String, @NonNull android.service.attestation.ImpressionToken); } public final class ImpressionToken implements android.os.Parcelable { diff --git a/core/java/android/service/attestation/IImpressionAttestationService.aidl b/core/java/android/service/attestation/IImpressionAttestationService.aidl index 8e858b8aea77a..fcbc51febadac 100644 --- a/core/java/android/service/attestation/IImpressionAttestationService.aidl +++ b/core/java/android/service/attestation/IImpressionAttestationService.aidl @@ -18,8 +18,8 @@ package android.service.attestation; import android.graphics.Rect; import android.hardware.HardwareBuffer; -import android.service.attestation.ImpressionToken; import android.os.RemoteCallback; +import android.service.attestation.ImpressionToken; /** * Service used to handle impression attestation requests. @@ -31,22 +31,26 @@ oneway interface IImpressionAttestationService { * Generates the impression token that can be used to validate that the system generated the * token. * - * @param screenshot The token for the window where the view is shown. + * @param salt The salt to use when generating the hmac. This should be unique to the caller so + * the token cannot be verified by any other process. + * @param screenshot The screenshot to generate the hash and add to the token. * @param bounds The size and position of the content being attested in the window. * @param hashAlgorithm The String for the hashing algorithm to use based on values in * {@link #SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS}. * @param Callback The callback invoked to send back the impression token. */ - void generateImpressionToken(in HardwareBuffer screenshot, in Rect bounds, + void generateImpressionToken(in String salt, in HardwareBuffer screenshot, in Rect bounds, in String hashAlgorithm, in RemoteCallback callback); /** * Call to verify that the impressionToken passed in was generated by the system. The result - * will be sent in the callback as an integer with the key {@link #EXTRA_VERIFICATION_STATUS} - * and will be one of the values in {@link VerificationStatus}. + * will be sent in the callback as a boolean with the key {@link #EXTRA_VERIFICATION_STATUS}. * + * @param salt The salt value to use when verifying the hmac. This should be the same value that + * was passed to {@link generateImpressionToken()} to generate the token. * @param impressionToken The token to verify that it was generated by the system. * @param callback The callback invoked to send back the verification status. */ - void verifyImpressionToken(in ImpressionToken impressionToken, in RemoteCallback callback); + void verifyImpressionToken(in String salt, in ImpressionToken impressionToken, + in RemoteCallback callback); } diff --git a/core/java/android/service/attestation/ImpressionAttestationService.java b/core/java/android/service/attestation/ImpressionAttestationService.java index 923ab7a65d1b0..05ad5f02efe53 100644 --- a/core/java/android/service/attestation/ImpressionAttestationService.java +++ b/core/java/android/service/attestation/ImpressionAttestationService.java @@ -18,7 +18,6 @@ package android.service.attestation; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; -import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; @@ -50,22 +49,10 @@ public abstract class ImpressionAttestationService extends Service { public static final String EXTRA_VERIFICATION_STATUS = "android.service.attestation.extra.VERIFICATION_STATUS"; - /** @hide */ - @IntDef(prefix = {"VERIFICATION_STATUS_"}, value = { - VERIFICATION_STATUS_UNKNOWN, - VERIFICATION_STATUS_OS_VERIFIED, - VERIFICATION_STATUS_APP_DECLARED - }) - public @interface VerificationStatus { - } - - public static final int VERIFICATION_STATUS_UNKNOWN = 0; - public static final int VERIFICATION_STATUS_OS_VERIFIED = 1; - public static final int VERIFICATION_STATUS_APP_DECLARED = 2; - /** * Manifest metadata key for the resource string array containing the names of all impression * attestation algorithms provided by the service. + * * @hide */ public static final String SERVICE_META_DATA_KEY_AVAILABLE_ALGORITHMS = @@ -74,6 +61,7 @@ public abstract class ImpressionAttestationService extends Service { /** * The {@link Intent} action that must be declared as handled by a service in its manifest * for the system to recognize it as an impression attestation providing service. + * * @hide */ public static final String SERVICE_INTERFACE = @@ -102,6 +90,8 @@ public abstract class ImpressionAttestationService extends Service { * Generates the impression token that can be used to validate that the system * generated the token. * + * @param salt The salt to use when generating the hmac. This should be unique to the + * caller so the token cannot be verified by any other process. * @param screenshot The screenshot buffer for the content to attest. * @param bounds The size and position of the content being attested in the window. * @param hashAlgorithm The String for the hashing algorithm to use based values in @@ -110,51 +100,57 @@ public abstract class ImpressionAttestationService extends Service { * Returns null when the arguments sent are invalid. */ @Nullable - public abstract ImpressionToken onGenerateImpressionToken(@NonNull HardwareBuffer screenshot, - @NonNull Rect bounds, @NonNull String hashAlgorithm); + public abstract ImpressionToken onGenerateImpressionToken(@NonNull String salt, + @NonNull HardwareBuffer screenshot, @NonNull Rect bounds, + @NonNull String hashAlgorithm); /** * Call to verify that the impressionToken passed in was generated by the system. * + * @param salt The salt value to use when verifying the hmac. This should be the + * same value that was passed to + * {@link #onGenerateImpressionToken(String, + * HardwareBuffer, Rect, String)} to + * generate the token. * @param impressionToken The token to verify that it was generated by the system. - * @return A {@link VerificationStatus} about whether the token was generated by the system. + * @return true if the token can be verified that it was generated by the system. */ - public abstract @VerificationStatus int onVerifyImpressionToken( + public abstract boolean onVerifyImpressionToken(@NonNull String salt, @NonNull ImpressionToken impressionToken); - private void generateImpressionToken(HardwareBuffer screenshot, Rect bounds, + private void generateImpressionToken(String salt, HardwareBuffer screenshot, Rect bounds, String hashAlgorithm, RemoteCallback callback) { - ImpressionToken impressionToken = onGenerateImpressionToken(screenshot, bounds, + ImpressionToken impressionToken = onGenerateImpressionToken(salt, screenshot, bounds, hashAlgorithm); final Bundle data = new Bundle(); data.putParcelable(EXTRA_IMPRESSION_TOKEN, impressionToken); callback.sendResult(data); } - private void verifyImpressionToken(ImpressionToken impressionToken, + private void verifyImpressionToken(String salt, ImpressionToken impressionToken, RemoteCallback callback) { - @VerificationStatus int verificationStatus = onVerifyImpressionToken(impressionToken); + boolean verificationStatus = onVerifyImpressionToken(salt, impressionToken); final Bundle data = new Bundle(); - data.putInt(EXTRA_VERIFICATION_STATUS, verificationStatus); + data.putBoolean(EXTRA_VERIFICATION_STATUS, verificationStatus); callback.sendResult(data); } private final class ImpressionAttestationServiceWrapper extends IImpressionAttestationService.Stub { @Override - public void generateImpressionToken(HardwareBuffer screenshot, Rect bounds, + public void generateImpressionToken(String salt, HardwareBuffer screenshot, Rect bounds, String hashAlgorithm, RemoteCallback callback) { mHandler.sendMessage( obtainMessage(ImpressionAttestationService::generateImpressionToken, - ImpressionAttestationService.this, screenshot, bounds, hashAlgorithm, - callback)); + ImpressionAttestationService.this, salt, screenshot, bounds, + hashAlgorithm, callback)); } @Override - public void verifyImpressionToken(ImpressionToken impressionToken, + public void verifyImpressionToken(String salt, ImpressionToken impressionToken, RemoteCallback callback) { mHandler.sendMessage(obtainMessage(ImpressionAttestationService::verifyImpressionToken, - ImpressionAttestationService.this, impressionToken, callback)); + ImpressionAttestationService.this, salt, impressionToken, callback)); } } } diff --git a/services/core/java/com/android/server/wm/ImpressionAttestationController.java b/services/core/java/com/android/server/wm/ImpressionAttestationController.java index d00faef1c147f..4793e1b6fb9f0 100644 --- a/services/core/java/com/android/server/wm/ImpressionAttestationController.java +++ b/services/core/java/com/android/server/wm/ImpressionAttestationController.java @@ -47,6 +47,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; +import java.util.UUID; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; @@ -78,6 +79,8 @@ public class ImpressionAttestationController { private final Handler mHandler; + private final String mSalt; + private interface Command { void run(IImpressionAttestationService service) throws RemoteException; } @@ -85,6 +88,7 @@ public class ImpressionAttestationController { ImpressionAttestationController(Context context) { mContext = context; mHandler = new Handler(Looper.getMainLooper()); + mSalt = UUID.randomUUID().toString(); } String[] getSupportedImpressionAlgorithms() { @@ -118,17 +122,17 @@ public class ImpressionAttestationController { } } - int verifyImpressionToken(ImpressionToken impressionToken) { + boolean verifyImpressionToken(ImpressionToken impressionToken) { final SyncCommand syncCommand = new SyncCommand(); Bundle results = syncCommand.run((service, remoteCallback) -> { try { - service.verifyImpressionToken(impressionToken, remoteCallback); + service.verifyImpressionToken(mSalt, impressionToken, remoteCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to invoke verifyImpressionToken command"); } }); - return results.getInt(ImpressionAttestationService.EXTRA_VERIFICATION_STATUS); + return results.getBoolean(ImpressionAttestationService.EXTRA_VERIFICATION_STATUS); } ImpressionToken generateImpressionToken(HardwareBuffer screenshot, Rect bounds, @@ -136,7 +140,8 @@ public class ImpressionAttestationController { final SyncCommand syncCommand = new SyncCommand(); Bundle results = syncCommand.run((service, remoteCallback) -> { try { - service.generateImpressionToken(screenshot, bounds, hashAlgorithm, remoteCallback); + service.generateImpressionToken(mSalt, screenshot, bounds, hashAlgorithm, + remoteCallback); } catch (RemoteException e) { Slog.e(TAG, "Failed to invoke generateImpressionToken command", e); }