Create idsig file automatically
Before a VM is started, the idsig file is created (or updated) by the
virtualization service. This is needed because the idsig file is usually
not available, especially when the APK is downloaded from the store.
Note that the generated idsig file is not a signed one. Therefore, the
APK is first verified using the APK signature scheme V3 (or V2) over a
dm-verity device backed by the APK and the merkle tree (and root hash)
from the idsig file. Only if the verification is successful, the root
hash stored to the instance.img and then used for the subsequent boots
of the VM.
Bug: 193504400
Test: atest MicrodroidHostTestCases
Test: run MicrodroidDemoApp without having the idsig file in
/data/local/tmp/virt.
Change-Id: I9fad05ca9562ae0666431102a8147d0f76f04e6a
diff --git a/virtualizationservice/src/aidl.rs b/virtualizationservice/src/aidl.rs
index 96e3c44..23a9c03 100644
--- a/virtualizationservice/src/aidl.rs
+++ b/virtualizationservice/src/aidl.rs
@@ -37,6 +37,7 @@
};
use anyhow::{bail, Context, Result};
use disk::QcowFile;
+use idsig::{V4Signature, HashAlgorithm};
use log::{debug, error, warn, info};
use microdroid_payload_config::VmPayloadConfig;
use std::convert::TryInto;
@@ -209,6 +210,24 @@
Ok(())
}
+ /// Creates or update the idsig file by digesting the input APK file.
+ fn createOrUpdateIdsigFile(
+ &self,
+ input_fd: &ParcelFileDescriptor,
+ idsig_fd: &ParcelFileDescriptor,
+ ) -> binder::Result<()> {
+ // TODO(b/193504400): do this only when (1) idsig_fd is empty or (2) the APK digest in
+ // idsig_fd is different from APK digest in input_fd
+
+ let mut input = clone_file(input_fd)?;
+ let mut sig = V4Signature::create(&mut input, 4096, &[], HashAlgorithm::SHA256).unwrap();
+
+ let mut output = clone_file(idsig_fd)?;
+ output.set_len(0).unwrap();
+ sig.write_into(&mut output).unwrap();
+ Ok(())
+ }
+
/// Get a list of all currently running VMs. This method is only intended for debug purposes,
/// and as such is only permitted from the shell user.
fn debugListVms(&self) -> binder::Result<Vec<VirtualMachineDebugInfo>> {