[apkverify] Use ensure!() instead of bail!() in apk verification
This cl replaces the usage of `if (false) bail!` with ensure! in
apk verification to make the code more concise.
Test: libapkverify.integration_test
Bug: 246254355
Change-Id: If6e4673141ed463f8fd4ded61a993bb8afc1543a
diff --git a/libs/apkverify/src/bytes_ext.rs b/libs/apkverify/src/bytes_ext.rs
index 22a3085..8fb36ee 100644
--- a/libs/apkverify/src/bytes_ext.rs
+++ b/libs/apkverify/src/bytes_ext.rs
@@ -16,7 +16,7 @@
//! Provides extension methods Bytes::read<T>(), which calls back ReadFromBytes::read_from_byte()
-use anyhow::{bail, Result};
+use anyhow::{ensure, Result};
use bytes::{Buf, Bytes};
use std::ops::Deref;
@@ -79,20 +79,18 @@
}
fn read_length_prefixed_slice(buf: &mut Bytes) -> Result<Bytes> {
- if buf.remaining() < 4 {
- bail!(
- "Remaining buffer too short to contain length of length-prefixed field. Remaining: {}",
- buf.remaining()
- );
- }
+ ensure!(
+ buf.remaining() >= 4,
+ "Remaining buffer too short to contain length of length-prefixed field. Remaining: {}",
+ buf.remaining()
+ );
let len = buf.get_u32_le() as usize;
- if len > buf.remaining() {
- bail!(
- "length-prefixed field longer than remaining buffer. Field length: {}, remaining: {}",
- len,
- buf.remaining()
- );
- }
+ ensure!(
+ buf.remaining() >= len,
+ "length-prefixed field longer than remaining buffer. Field length: {}, remaining: {}",
+ len,
+ buf.remaining()
+ );
Ok(buf.split_to(len))
}
diff --git a/libs/apkverify/src/v3.rs b/libs/apkverify/src/v3.rs
index 557abcd..5313a9b 100644
--- a/libs/apkverify/src/v3.rs
+++ b/libs/apkverify/src/v3.rs
@@ -18,7 +18,7 @@
//!
//! [v3 verification]: https://source.android.com/security/apksigning/v3#verification
-use anyhow::{anyhow, bail, ensure, Context, Result};
+use anyhow::{ensure, Context, Result};
use bytes::Bytes;
use num_traits::FromPrimitive;
use openssl::pkey::{self, PKey};
@@ -105,12 +105,11 @@
let supported = signers.iter().filter(|s| s.sdk_range().contains(&SDK_INT)).collect::<Vec<_>>();
// there should be exactly one
- if supported.len() != 1 {
- bail!(
- "APK Signature Scheme V3 only supports one signer: {} signers found.",
- supported.len()
- )
- }
+ ensure!(
+ supported.len() == 1,
+ "APK Signature Scheme V3 only supports one signer: {} signers found.",
+ supported.len()
+ );
// Call the supplied function
f((supported[0], sections))
@@ -145,7 +144,7 @@
.iter()
.filter(|sig| SignatureAlgorithmID::from_u32(sig.signature_algorithm_id).is_some())
.max_by_key(|sig| SignatureAlgorithmID::from_u32(sig.signature_algorithm_id).unwrap())
- .ok_or_else(|| anyhow!("No supported signatures found"))?)
+ .context("No supported signatures found")?)
}
fn pick_v4_apk_digest(&self) -> Result<(u32, Box<[u8]>)> {
@@ -155,7 +154,7 @@
.digests
.iter()
.find(|&dig| dig.signature_algorithm_id == strongest.signature_algorithm_id)
- .ok_or_else(|| anyhow!("Digest not found"))?;
+ .context("Digest not found")?;
Ok((digest.signature_algorithm_id, digest.digest.as_ref().to_vec().into_boxed_slice()))
}
@@ -174,20 +173,20 @@
// 3. Verify the min and max SDK versions in the signed data match those specified for the
// signer.
- if self.sdk_range() != signed_data.sdk_range() {
- bail!("SDK versions mismatch between signed and unsigned in v3 signer block.");
- }
+ ensure!(
+ self.sdk_range() == signed_data.sdk_range(),
+ "SDK versions mismatch between signed and unsigned in v3 signer block."
+ );
// 4. Verify that the ordered list of signature algorithm IDs in digests and signatures is
// identical. (This is to prevent signature stripping/addition.)
- if !self
- .signatures
- .iter()
- .map(|sig| sig.signature_algorithm_id)
- .eq(signed_data.digests.iter().map(|dig| dig.signature_algorithm_id))
- {
- bail!("Signature algorithms don't match between digests and signatures records");
- }
+ ensure!(
+ self.signatures
+ .iter()
+ .map(|sig| sig.signature_algorithm_id)
+ .eq(signed_data.digests.iter().map(|dig| dig.signature_algorithm_id)),
+ "Signature algorithms don't match between digests and signatures records"
+ );
// 5. Compute the digest of APK contents using the same digest algorithm as the digest
// algorithm used by the signature algorithm.
@@ -199,21 +198,21 @@
let computed = sections.compute_digest(digest.signature_algorithm_id)?;
// 6. Verify that the computed digest is identical to the corresponding digest from digests.
- if computed != digest.digest.as_ref() {
- bail!(
- "Digest mismatch: computed={:?} vs expected={:?}",
- to_hex_string(&computed),
- to_hex_string(&digest.digest),
- );
- }
+ ensure!(
+ computed == digest.digest.as_ref(),
+ "Digest mismatch: computed={:?} vs expected={:?}",
+ to_hex_string(&computed),
+ to_hex_string(&digest.digest),
+ );
// 7. Verify that public key of the first certificate of certificates is identical
// to public key.
let cert = signed_data.certificates.first().context("No certificates listed")?;
let cert = X509::from_der(cert.as_ref())?;
- if !cert.public_key()?.public_eq(&public_key) {
- bail!("Public key mismatch between certificate and signature record");
- }
+ ensure!(
+ cert.public_key()?.public_eq(&public_key),
+ "Public key mismatch between certificate and signature record"
+ );
// TODO(b/245914104)
// 8. If the proof-of-rotation attribute exists for the signer verify that the
diff --git a/libs/apkverify/src/ziputil.rs b/libs/apkverify/src/ziputil.rs
index 8badff2..eb2826a 100644
--- a/libs/apkverify/src/ziputil.rs
+++ b/libs/apkverify/src/ziputil.rs
@@ -16,7 +16,7 @@
//! Utilities for zip handling of APK files.
-use anyhow::{bail, Result};
+use anyhow::{ensure, Result};
use bytes::{Buf, BufMut};
use std::io::{Read, Seek, SeekFrom};
use zip::ZipArchive;
@@ -41,25 +41,26 @@
// open a zip to parse EOCD
let archive = ZipArchive::new(reader)?;
let eocd_size = archive.comment().len() + EOCD_SIZE_WITHOUT_COMMENT;
- if archive.offset() != 0 {
- bail!("Invalid ZIP: offset should be 0, but {}.", archive.offset());
- }
+ ensure!(archive.offset() == 0, "Invalid ZIP: offset should be 0, but {}.", archive.offset());
// retrieve reader back
reader = archive.into_inner();
// the current position should point EOCD offset
let eocd_offset = reader.seek(SeekFrom::Current(0))? as u32;
let mut eocd = vec![0u8; eocd_size as usize];
reader.read_exact(&mut eocd)?;
- if (&eocd[0..]).get_u32_le() != EOCD_SIGNATURE {
- bail!("Invalid ZIP: ZipArchive::new() should point EOCD after reading.");
- }
+ ensure!(
+ (&eocd[0..]).get_u32_le() == EOCD_SIGNATURE,
+ "Invalid ZIP: ZipArchive::new() should point EOCD after reading."
+ );
let (central_directory_size, central_directory_offset) = get_central_directory(&eocd)?;
- if central_directory_offset == ZIP64_MARK || central_directory_size == ZIP64_MARK {
- bail!("Unsupported ZIP: ZIP64 is not supported.");
- }
- if central_directory_offset + central_directory_size != eocd_offset {
- bail!("Invalid ZIP: EOCD should follow CD with no extra data or overlap.");
- }
+ ensure!(
+ central_directory_offset != ZIP64_MARK && central_directory_size != ZIP64_MARK,
+ "Unsupported ZIP: ZIP64 is not supported."
+ );
+ ensure!(
+ central_directory_offset + central_directory_size == eocd_offset,
+ "Invalid ZIP: EOCD should follow CD with no extra data or overlap."
+ );
Ok((
reader,
@@ -73,9 +74,7 @@
}
fn get_central_directory(buf: &[u8]) -> Result<(u32, u32)> {
- if buf.len() < EOCD_SIZE_WITHOUT_COMMENT {
- bail!("Invalid EOCD size: {}", buf.len());
- }
+ ensure!(buf.len() >= EOCD_SIZE_WITHOUT_COMMENT, "Invalid EOCD size: {}", buf.len());
let mut buf = &buf[EOCD_CENTRAL_DIRECTORY_SIZE_FIELD_OFFSET..];
let size = buf.get_u32_le();
let offset = buf.get_u32_le();
@@ -84,9 +83,7 @@
/// Update EOCD's central_directory_offset field.
pub fn set_central_directory_offset(buf: &mut [u8], value: u32) -> Result<()> {
- if buf.len() < EOCD_SIZE_WITHOUT_COMMENT {
- bail!("Invalid EOCD size: {}", buf.len());
- }
+ ensure!(buf.len() >= EOCD_SIZE_WITHOUT_COMMENT, "Invalid EOCD size: {}", buf.len());
(&mut buf[EOCD_CENTRAL_DIRECTORY_OFFSET_FIELD_OFFSET..]).put_u32_le(value);
Ok(())
}