Add APK details to the DICE chain
Include the information from the manifest in ApkData (which also means
it is persisted in the instance image - which is not necessary but
harmless).
Add a CDDL file descibing what the VM config descriptor looks like.
Add information about the APKs to the Microdroid payload configuration
descriptor.
Also make some formatting fixes to open_dice error messages (since I
managed to trigger some).
Bug: 299591171
Test: composd_cmd test-compile; manually inspect BCC
Test: atest MicrodroidTests
Test: atest microdroid_manager_test
Change-Id: Iad7e8407cd9ad1d6715806aa4479641b9b9173cf
diff --git a/microdroid_manager/src/verify.rs b/microdroid_manager/src/verify.rs
index 06b15f7..22f3414 100644
--- a/microdroid_manager/src/verify.rs
+++ b/microdroid_manager/src/verify.rs
@@ -145,19 +145,26 @@
// taken only when the root_hash is un-trustful which can be either when this is the first boot
// of the VM or APK was updated in the host.
// TODO(jooyung): consider multithreading to make this faster
- let main_apk_pubkey = get_public_key_from_apk(DM_MOUNTED_APK_PATH, root_hash_trustful)?;
+
+ let main_apk_data =
+ get_data_from_apk(DM_MOUNTED_APK_PATH, root_hash_from_idsig, root_hash_trustful)?;
+
let extra_apks_data = extra_root_hashes_from_idsig
.into_iter()
.enumerate()
.map(|(i, extra_root_hash)| {
let mount_path = format!("/dev/block/mapper/{}", &extra_apk_names[i]);
- let apk_pubkey = get_public_key_from_apk(&mount_path, extra_root_hashes_trustful[i])?;
- Ok(ApkData { root_hash: extra_root_hash, pubkey: apk_pubkey })
+ get_data_from_apk(&mount_path, extra_root_hash, extra_root_hashes_trustful[i])
})
.collect::<Result<Vec<_>>>()?;
info!("payload verification successful. took {:#?}", start_time.elapsed().unwrap());
+ // At this point, we can ensure that the root hashes from the idsig files are trusted, either
+ // because we have fully verified the APK signature (and apkdmverity checks all the data we
+ // verified is consistent with the root hash) or because we have the saved APK data which will
+ // be checked as identical to the data we have verified.
+
// Use the salt from a verified instance, or generate a salt for a new instance.
let salt = if let Some(saved_data) = saved_data {
saved_data.salt.clone()
@@ -170,16 +177,36 @@
salt
};
- // At this point, we can ensure that the root_hash from the idsig file is trusted, either by
- // fully verifying the APK or by comparing it with the saved root_hash.
Ok(MicrodroidData {
salt,
- apk_data: ApkData { root_hash: root_hash_from_idsig, pubkey: main_apk_pubkey },
+ apk_data: main_apk_data,
extra_apks_data,
apex_data: apex_data_from_payload,
})
}
+fn get_data_from_apk(
+ apk_path: &str,
+ root_hash: Box<RootHash>,
+ root_hash_trustful: bool,
+) -> Result<ApkData> {
+ let pubkey = get_public_key_from_apk(apk_path, root_hash_trustful)?;
+ // Read package name etc from the APK manifest. In the unlikely event that they aren't present
+ // we use the default values. We simply put these values in the DICE node for the payload, and
+ // users of that can decide how to handle blank information - there's no reason for us
+ // to fail starting a VM even with such a weird APK.
+ let manifest_info = get_manifest_info(apk_path)
+ .map_err(|e| warn!("Failed to read manifest info from APK: {e:?}"))
+ .unwrap_or_default();
+
+ Ok(ApkData {
+ root_hash,
+ pubkey,
+ package_name: manifest_info.package,
+ version_code: manifest_info.version_code,
+ })
+}
+
fn get_apk_root_hash_from_idsig<P: AsRef<Path>>(idsig_path: P) -> Result<Box<RootHash>> {
Ok(V4Signature::from_idsig_path(idsig_path)?.hashing_info.raw_root_hash)
}
@@ -187,24 +214,14 @@
fn get_public_key_from_apk(apk: &str, root_hash_trustful: bool) -> Result<Box<[u8]>> {
let current_sdk = get_current_sdk()?;
- let public_key_der = if !root_hash_trustful {
+ if !root_hash_trustful {
verify(apk, current_sdk).context(MicrodroidError::PayloadVerificationFailed(format!(
"failed to verify {}",
apk
- )))?
+ )))
} else {
- get_public_key_der(apk, current_sdk)?
- };
-
- match get_manifest_info(apk) {
- Ok(manifest_info) => {
- // TODO (b/299591171): Do something with this info
- info!("Manifest info is {manifest_info:?}")
- }
- Err(e) => warn!("Failed to read manifest info from APK: {e:?}"),
- };
-
- Ok(public_key_der)
+ get_public_key_der(apk, current_sdk)
+ }
}
fn get_current_sdk() -> Result<u32> {