Skip to content
Snippets Groups Projects
Commit 45183e55 authored by Andrew Scull's avatar Andrew Scull Committed by Automerger Merge Worker
Browse files

Merge changes from topic "idsig" am: cbace730 am: 0a244764 am: 9013c70d...

Merge changes from topic "idsig" am: cbace730 am: 0a244764 am: 9013c70d am: 9a46fc8d am: 8b4ff718

Original change: https://android-review.googlesource.com/c/platform/packages/modules/Virtualization/+/2112012



Change-Id: I6e1242559ec5eed76d66acc54eac9e710db98bfd
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 91a23ab7 8b4ff718
No related branches found
No related tags found
No related merge requests found
......@@ -24,6 +24,7 @@ rust_library {
defaults: ["libapkverify.defaults"],
// TODO(b/204562227): move to host_supported to the defaults to include tests
host_supported: true,
apex_available: ["com.android.virt"],
}
rust_test {
......
......@@ -24,4 +24,4 @@ mod v3;
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};
......@@ -282,6 +282,7 @@ fn to_content_digest_algorithm(algorithm_id: u32) -> Result<u32> {
}
}
/// Rank the signature algorithm according to the preferences of the v4 signing scheme.
pub fn rank_signature_algorithm(algo: u32) -> Result<u32> {
rank_content_digest_algorithm(to_content_digest_algorithm(algo)?)
}
......
......@@ -128,16 +128,43 @@ pub fn get_public_key_der<P: AsRef<Path>>(path: P) -> Result<Box<[u8]>> {
})
}
/// 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 {
fn verify<R: Read + Seek>(&self, sections: &mut ApkSections<R>) -> Result<Box<[u8]>> {
// 1. Choose the strongest supported signature algorithm ID from signatures. The strength
// ordering is up to each implementation/platform version.
let strongest: &Signature = self
/// Select the signature that uses the strongest algorithm according to the preferences of the
/// v4 signing scheme.
fn strongest_signature(&self) -> Result<&Signature> {
Ok(self
.signatures
.iter()
.filter(|sig| is_supported_signature_algorithm(sig.signature_algorithm_id))
.max_by_key(|sig| rank_signature_algorithm(sig.signature_algorithm_id).unwrap())
.ok_or_else(|| anyhow!("No supported signatures found"))?;
.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()?;
// 2. Verify the corresponding signature from signatures against signed data using public key.
// (It is now safe to parse signed data.)
......
......@@ -10,6 +10,7 @@ rust_defaults {
prefer_rlib: true,
rustlibs: [
"libanyhow",
"libapkverify",
"libbyteorder",
"libnum_traits",
"libopenssl",
......
......@@ -15,6 +15,7 @@
*/
use anyhow::{anyhow, bail, Context, Result};
use apkverify::pick_v4_apk_digest;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use num_derive::{FromPrimitive, ToPrimitive};
use num_traits::{FromPrimitive, ToPrimitive};
......@@ -190,9 +191,12 @@ impl<R: Read + Seek> V4Signature<R> {
ret.hashing_info.raw_root_hash = hash_tree.root_hash.into_boxed_slice();
ret.hashing_info.log2_blocksize = log2(block_size);
// TODO(jiyong): fill the signing_info struct by reading the APK file. The information,
// especially `apk_digest` is needed to check if `V4Signature` is outdated, in which case
// it needs to be created from the updated APK.
apk.seek(SeekFrom::Start(start))?;
let (signature_algorithm_id, apk_digest) = pick_v4_apk_digest(apk)?;
ret.signing_info.signature_algorithm_id =
SignatureAlgorithmId::from(signature_algorithm_id)?;
ret.signing_info.apk_digest = apk_digest;
// TODO(jiyong): add a signature to the signing_info struct
Ok(ret)
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment