[idsig] Simplify building V4Signature from idsig
Bug: 248999133
Test: libidsig.test apkdmverity.test microdroid_manager_test
Change-Id: I383a2f9827d1c292e2a2afec1e2092f60728267f
diff --git a/apkdmverity/Android.bp b/apkdmverity/Android.bp
index 97a6174..51ef4dd 100644
--- a/apkdmverity/Android.bp
+++ b/apkdmverity/Android.bp
@@ -43,4 +43,8 @@
rustlibs: [
"libtempfile",
],
+ data: [
+ "testdata/*.apk",
+ "testdata/*.idsig",
+ ],
}
diff --git a/apkdmverity/src/main.rs b/apkdmverity/src/main.rs
index de7f5bb..b99ed1c 100644
--- a/apkdmverity/src/main.rs
+++ b/apkdmverity/src/main.rs
@@ -31,7 +31,6 @@
use itertools::Itertools;
use std::fmt::Debug;
use std::fs;
-use std::fs::File;
use std::os::unix::fs::FileTypeExt;
use std::path::{Path, PathBuf};
@@ -104,9 +103,7 @@
// Parse the idsig file to locate the merkle tree in it, then attach the file to a loop device
// with the offset so that the start of the merkle tree becomes the beginning of the loop
// device.
- let sig = V4Signature::from(
- File::open(&idsig).context(format!("Failed to open idsig file {:?}", &idsig))?,
- )?;
+ let sig = V4Signature::from_idsig_path(&idsig)?;
let offset = sig.merkle_tree_offset;
let size = sig.merkle_tree_size as u64;
// Due to unknown reason(b/191344832), we can't enable "direct IO" for the IDSIG file (backing
@@ -143,8 +140,8 @@
#[cfg(test)]
mod tests {
use crate::*;
- use std::fs::OpenOptions;
- use std::io::{Cursor, Write};
+ use std::fs::{File, OpenOptions};
+ use std::io::Write;
use std::os::unix::fs::FileExt;
struct TestContext<'a> {
@@ -251,7 +248,9 @@
let idsig = include_bytes!("../testdata/test.apk.idsig");
// Make a single-byte change to the merkle tree
- let offset = V4Signature::from(Cursor::new(&idsig)).unwrap().merkle_tree_offset as usize;
+ let offset = V4Signature::from_idsig_path("testdata/test.apk.idsig")
+ .unwrap()
+ .merkle_tree_offset as usize;
let mut modified_idsig = Vec::new();
modified_idsig.extend_from_slice(idsig);
@@ -354,7 +353,10 @@
fn correct_custom_roothash() {
let apk = include_bytes!("../testdata/test.apk");
let idsig = include_bytes!("../testdata/test.apk.idsig");
- let roothash = V4Signature::from(Cursor::new(&idsig)).unwrap().hashing_info.raw_root_hash;
+ let roothash = V4Signature::from_idsig_path("testdata/test.apk.idsig")
+ .unwrap()
+ .hashing_info
+ .raw_root_hash;
run_test_with_hash(
apk.as_ref(),
idsig.as_ref(),
diff --git a/libs/idsig/Android.bp b/libs/idsig/Android.bp
index 9f7d377..615d70e 100644
--- a/libs/idsig/Android.bp
+++ b/libs/idsig/Android.bp
@@ -31,5 +31,7 @@
compile_multilib: "first",
data: [
"testdata/input.*",
+ "testdata/*.apk",
+ "testdata/*.idsig",
],
}
diff --git a/libs/idsig/src/apksigv4.rs b/libs/idsig/src/apksigv4.rs
index 29def3b..3f73df3 100644
--- a/libs/idsig/src/apksigv4.rs
+++ b/libs/idsig/src/apksigv4.rs
@@ -19,7 +19,9 @@
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
+use std::fs;
use std::io::{copy, Cursor, Read, Seek, SeekFrom, Write};
+use std::path::Path;
use crate::hashtree::*;
@@ -114,9 +116,17 @@
}
}
+impl V4Signature<fs::File> {
+ /// Creates a `V4Signature` struct from the given idsig path.
+ pub fn from_idsig_path<P: AsRef<Path>>(idsig_path: P) -> Result<Self> {
+ let idsig = fs::File::open(idsig_path).context("Cannot find idsig file")?;
+ Self::from_idsig(idsig)
+ }
+}
+
impl<R: Read + Seek> V4Signature<R> {
/// Consumes a stream for an idsig file into a `V4Signature` struct.
- pub fn from(mut r: R) -> Result<V4Signature<R>> {
+ pub fn from_idsig(mut r: R) -> Result<V4Signature<R>> {
Ok(V4Signature {
version: Version::from(r.read_u32::<LittleEndian>()?)?,
hashing_info: HashingInfo::from(&mut r)?,
@@ -293,14 +303,15 @@
use super::*;
use std::io::Cursor;
+ const TEST_APK_PATH: &str = "testdata/v4-digest-v3-Sha256withEC.apk";
+
fn hexstring_from(s: &[u8]) -> String {
s.iter().map(|byte| format!("{:02x}", byte)).reduce(|i, j| i + &j).unwrap_or_default()
}
#[test]
fn parse_idsig_file() {
- let idsig = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
- let parsed = V4Signature::from(idsig).unwrap();
+ let parsed = V4Signature::from_idsig_path(format!("{}.idsig", TEST_APK_PATH)).unwrap();
assert_eq!(Version::V2, parsed.version);
@@ -334,13 +345,13 @@
/// the input file.
#[test]
fn parse_and_compose() {
- let input = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
- let mut parsed = V4Signature::from(input.clone()).unwrap();
+ let idsig_path = format!("{}.idsig", TEST_APK_PATH);
+ let mut v4_signature = V4Signature::from_idsig_path(&idsig_path).unwrap();
let mut output = Cursor::new(Vec::new());
- parsed.write_into(&mut output).unwrap();
+ v4_signature.write_into(&mut output).unwrap();
- assert_eq!(input.get_ref().as_ref(), output.get_ref().as_slice());
+ assert_eq!(fs::read(&idsig_path).unwrap(), output.get_ref().as_slice());
}
/// Create V4Signature by hashing an APK. Merkle tree and the root hash should be the same
@@ -351,8 +362,7 @@
let mut created =
V4Signature::create(&mut input, 4096, &[], HashAlgorithm::SHA256).unwrap();
- let golden = Cursor::new(include_bytes!("../testdata/v4-digest-v3-Sha256withEC.apk.idsig"));
- let mut golden = V4Signature::from(golden).unwrap();
+ let mut golden = V4Signature::from_idsig_path(format!("{}.idsig", TEST_APK_PATH)).unwrap();
// Compare the root hash
assert_eq!(
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index 7629291..c50bcbe 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -481,7 +481,7 @@
.map(|(i, extra_idsig)| {
(
format!("extra-apk-{}", i),
- get_apk_root_hash_from_idsig(extra_idsig.to_str().unwrap())
+ get_apk_root_hash_from_idsig(extra_idsig)
.expect("Can't find root hash from extra idsig"),
)
})
@@ -601,10 +601,8 @@
Ok(())
}
-fn get_apk_root_hash_from_idsig(path: &str) -> Result<Box<RootHash>> {
- let mut idsig = File::open(path)?;
- let idsig = V4Signature::from(&mut idsig)?;
- Ok(idsig.hashing_info.raw_root_hash)
+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)
}
fn get_public_key_from_apk(apk: &str, root_hash_trustful: bool) -> Result<Box<[u8]>> {