apkverify: Add function to pick v4 apk digest
The v4 signing scheme includes an APK digest to match the strongest
digest available in the v3 or v2. Add a function to extract that digest
from an APK.
Test: libapkverify.test
Bug: 234564414
Change-Id: I69ce9c9c5ff6daf1f09e1bd4620ebf1ce015b5fa
diff --git a/libs/apkverify/src/lib.rs b/libs/apkverify/src/lib.rs
index 290a79a..c5aa9e5 100644
--- a/libs/apkverify/src/lib.rs
+++ b/libs/apkverify/src/lib.rs
@@ -24,4 +24,4 @@
mod ziputil;
// TODO(jooyung) fallback to v2 when v3 not found
-pub use v3::{get_public_key_der, verify};
+pub use v3::{get_public_key_der, pick_v4_apk_digest, verify};
diff --git a/libs/apkverify/src/v3.rs b/libs/apkverify/src/v3.rs
index 710c9c3..96ca7bc 100644
--- a/libs/apkverify/src/v3.rs
+++ b/libs/apkverify/src/v3.rs
@@ -128,6 +128,17 @@
})
}
+/// Gets the APK digest.
+pub fn pick_v4_apk_digest<R: Read + Seek>(apk: R) -> Result<(u32, Box<[u8]>)> {
+ let mut sections = ApkSections::new(apk)?;
+ let mut block = sections.find_signature(APK_SIGNATURE_SCHEME_V3_BLOCK_ID)?;
+ let signers = block.read::<Signers>()?;
+ if signers.len() != 1 {
+ bail!("should only have one signer");
+ }
+ signers[0].pick_v4_apk_digest()
+}
+
impl Signer {
/// Select the signature that uses the strongest algorithm according to the preferences of the
/// v4 signing scheme.
@@ -140,6 +151,17 @@
.ok_or_else(|| anyhow!("No supported signatures found"))?)
}
+ fn pick_v4_apk_digest(&self) -> Result<(u32, Box<[u8]>)> {
+ let strongest = self.strongest_signature()?;
+ let signed_data: SignedData = self.signed_data.slice(..).read()?;
+ let digest = signed_data
+ .digests
+ .iter()
+ .find(|&dig| dig.signature_algorithm_id == strongest.signature_algorithm_id)
+ .ok_or_else(|| anyhow!("Digest not found"))?;
+ Ok((digest.signature_algorithm_id, digest.digest.as_ref().to_vec().into_boxed_slice()))
+ }
+
fn verify<R: Read + Seek>(&self, sections: &mut ApkSections<R>) -> Result<Box<[u8]>> {
// 1. Choose the strongest supported signature algorithm ID from signatures.
let strongest = self.strongest_signature()?;