From a86e1ab30a174f0003aeafa662450e443be4dc8a Mon Sep 17 00:00:00 2001 From: Yo Chiang Date: Thu, 6 Feb 2020 03:44:08 +0800 Subject: [PATCH] Check DSU public key with key revocation list Throw RevocationListFetchException if failed to fetch key revocation list. Throw KeyRevokedException if DSU intent or image public key is revoked. Throw PublicKeyException if getAvbPublicKey() failed. Bug: 128892201 Test: adb shell am start-activity \ -n com.android.dynsystem/com.android.dynsystem.VerificationActivity \ -a android.os.image.action.START_INSTALL \ --el KEY_USERDATA_SIZE 8192 \ -d file:///storage/emulated/0/Download/aosp_arm64-dsu_test.zip \ --es KEY_PUBKEY ${IMAGE_KEY} Test: edit the code so that imageValidationThrowOrWarning() always Test: throw and observe the logcat and device notification Change-Id: I33733c019b305c45e7d2511c44ef1d9b446ea52e --- .../res/values/strings.xml | 2 + .../DynamicSystemInstallationService.java | 19 +++- .../dynsystem/InstallationAsyncTask.java | 87 +++++++++++++++---- 3 files changed, 89 insertions(+), 19 deletions(-) diff --git a/packages/DynamicSystemInstallationService/res/values/strings.xml b/packages/DynamicSystemInstallationService/res/values/strings.xml index 7595d2b1eea3d..25b7fc1b5ce25 100644 --- a/packages/DynamicSystemInstallationService/res/values/strings.xml +++ b/packages/DynamicSystemInstallationService/res/values/strings.xml @@ -18,6 +18,8 @@ Install in progress Install failed + + Image validation failed. Abort installation. Currently running a dynamic system. Restart to use the original Android version. diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java index 9bae223a0a3e3..7affe88886283 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/DynamicSystemInstallationService.java @@ -80,6 +80,7 @@ public class DynamicSystemInstallationService extends Service static final String KEY_ENABLE_WHEN_COMPLETED = "KEY_ENABLE_WHEN_COMPLETED"; static final String KEY_DSU_SLOT = "KEY_DSU_SLOT"; static final String DEFAULT_DSU_SLOT = "dsu"; + static final String KEY_PUBKEY = "KEY_PUBKEY"; /* * Intent actions @@ -267,6 +268,7 @@ public class DynamicSystemInstallationService extends Service long userdataSize = intent.getLongExtra(DynamicSystemClient.KEY_USERDATA_SIZE, 0); mEnableWhenCompleted = intent.getBooleanExtra(KEY_ENABLE_WHEN_COMPLETED, false); String dsuSlot = intent.getStringExtra(KEY_DSU_SLOT); + String publicKey = intent.getStringExtra(KEY_PUBKEY); if (TextUtils.isEmpty(dsuSlot)) { dsuSlot = DEFAULT_DSU_SLOT; @@ -274,7 +276,7 @@ public class DynamicSystemInstallationService extends Service // TODO: better constructor or builder mInstallTask = new InstallationAsyncTask( - url, dsuSlot, systemSize, userdataSize, this, mDynSystem, this); + url, dsuSlot, publicKey, systemSize, userdataSize, this, mDynSystem, this); mInstallTask.execute(); @@ -408,6 +410,10 @@ public class DynamicSystemInstallationService extends Service } private Notification buildNotification(int status, int cause) { + return buildNotification(status, cause, null); + } + + private Notification buildNotification(int status, int cause, Throwable detail) { Notification.Builder builder = new Notification.Builder(this, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.ic_system_update_googblue_24dp) .setProgress(0, 0, false); @@ -463,7 +469,12 @@ public class DynamicSystemInstallationService extends Service case STATUS_NOT_STARTED: if (cause != CAUSE_NOT_SPECIFIED && cause != CAUSE_INSTALL_CANCELLED) { - builder.setContentText(getString(R.string.notification_install_failed)); + if (detail instanceof InstallationAsyncTask.ImageValidationException) { + builder.setContentText( + getString(R.string.notification_image_validation_failed)); + } else { + builder.setContentText(getString(R.string.notification_install_failed)); + } } else { // no need to notify the user if the task is not started, or cancelled. } @@ -525,7 +536,7 @@ public class DynamicSystemInstallationService extends Service break; } - Log.d(TAG, "status=" + statusString + ", cause=" + causeString); + Log.d(TAG, "status=" + statusString + ", cause=" + causeString + ", detail=" + detail); boolean notifyOnNotificationBar = true; @@ -538,7 +549,7 @@ public class DynamicSystemInstallationService extends Service } if (notifyOnNotificationBar) { - mNM.notify(NOTIFICATION_ID, buildNotification(status, cause)); + mNM.notify(NOTIFICATION_ID, buildNotification(status, cause, detail)); } for (int i = mClients.size() - 1; i >= 0; i--) { diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java index 438c435ef0e45..7093914aa8474 100644 --- a/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java +++ b/packages/DynamicSystemInstallationService/src/com/android/dynsystem/InstallationAsyncTask.java @@ -17,6 +17,7 @@ package com.android.dynsystem; import android.content.Context; +import android.gsi.AvbPublicKey; import android.net.Uri; import android.os.AsyncTask; import android.os.MemoryFile; @@ -51,18 +52,46 @@ class InstallationAsyncTask extends AsyncTask UNSUPPORTED_PARTITIONS = Arrays.asList("vbmeta", "boot", "userdata", "dtbo", "super_empty", "system_other"); - private class UnsupportedUrlException extends RuntimeException { + private class UnsupportedUrlException extends Exception { private UnsupportedUrlException(String message) { super(message); } } - private class UnsupportedFormatException extends RuntimeException { + private class UnsupportedFormatException extends Exception { private UnsupportedFormatException(String message) { super(message); } } + static class ImageValidationException extends Exception { + ImageValidationException(String message) { + super(message); + } + + ImageValidationException(Throwable cause) { + super(cause); + } + } + + static class RevocationListFetchException extends ImageValidationException { + RevocationListFetchException(Throwable cause) { + super(cause); + } + } + + static class KeyRevokedException extends ImageValidationException { + KeyRevokedException(String message) { + super(message); + } + } + + static class PublicKeyException extends ImageValidationException { + PublicKeyException(String message) { + super(message); + } + } + /** UNSET means the installation is not completed */ static final int RESULT_UNSET = 0; static final int RESULT_OK = 1; @@ -97,6 +126,7 @@ class InstallationAsyncTask extends AsyncTask entries = mZipFile.entries(); @@ -349,8 +386,9 @@ class InstallationAsyncTask extends AsyncTask