Test APK section zip methods with real APK files
This CL also renames some variables to make them consistent with
the apk structure spec.
Test: atest libapkverify.test
Change-Id: Iba2a060916a59f295e702d4ef5a3618076acf4ed
diff --git a/libs/apkverify/src/sigutil.rs b/libs/apkverify/src/sigutil.rs
index 2b2f9da..7034527 100644
--- a/libs/apkverify/src/sigutil.rs
+++ b/libs/apkverify/src/sigutil.rs
@@ -49,6 +49,13 @@
const CHUNK_SIZE_BYTES: u64 = 1024 * 1024;
+/// The [APK structure] has four major sections:
+///
+/// | Zip contents | APK Signing Block | Central directory | EOCD(End of Central Directory) |
+///
+/// This structure contains the offset/size information of all the sections except the Zip contents.
+///
+/// [APK structure]: https://source.android.com/docs/security/apksigning/v2#apk-signing-block
pub struct ApkSections<R> {
inner: R,
signing_block_offset: u32,
@@ -295,3 +302,44 @@
_ => bail!("Unknown digest algorithm: {}", id),
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use byteorder::LittleEndian;
+ use std::fs::File;
+ use std::mem::size_of_val;
+
+ const CENTRAL_DIRECTORY_HEADER_SIGNATURE: u32 = 0x02014b50;
+
+ #[test]
+ fn test_apk_sections() {
+ let apk_file = File::open("tests/data/v3-only-with-ecdsa-sha512-p521.apk").unwrap();
+ let apk_sections = ApkSections::new(apk_file).unwrap();
+ let mut reader = &apk_sections.inner;
+
+ // Checks APK Signing Block.
+ assert_eq!(
+ apk_sections.signing_block_offset + apk_sections.signing_block_size,
+ apk_sections.central_directory_offset
+ );
+ let apk_signature_offset = SeekFrom::Start(
+ apk_sections.central_directory_offset as u64 - size_of_val(&APK_SIG_BLOCK_MAGIC) as u64,
+ );
+ reader.seek(apk_signature_offset).unwrap();
+ assert_eq!(reader.read_u128::<LittleEndian>().unwrap(), APK_SIG_BLOCK_MAGIC);
+
+ // Checks Central directory.
+ assert_eq!(reader.read_u32::<LittleEndian>().unwrap(), CENTRAL_DIRECTORY_HEADER_SIGNATURE);
+ assert_eq!(
+ apk_sections.central_directory_offset + apk_sections.central_directory_size,
+ apk_sections.eocd_offset
+ );
+
+ // Checks EOCD.
+ assert_eq!(
+ reader.metadata().unwrap().len(),
+ (apk_sections.eocd_offset + apk_sections.eocd_size) as u64
+ );
+ }
+}