[apkverify] Get message digest directly from signature algorithm
This will add additional support to the following algorithms
when computing the apk digest:
- VerityRsaPkcs1V15WithSha256
- VerityEcdsaWithSha256
Bug: 197052981
Test: libapkverify.integration_test
Change-Id: I6dda896cf84a53b4a2bbf57e80d79506d42eba35
diff --git a/libs/apkverify/src/algorithms.rs b/libs/apkverify/src/algorithms.rs
index 4b9d747..edfa946 100644
--- a/libs/apkverify/src/algorithms.rs
+++ b/libs/apkverify/src/algorithms.rs
@@ -16,7 +16,7 @@
//! Algorithms used for APK Signature Scheme.
-use anyhow::{bail, ensure, Result};
+use anyhow::{ensure, Result};
use num_derive::FromPrimitive;
use openssl::hash::MessageDigest;
use openssl::pkey::{self, PKey};
@@ -63,23 +63,6 @@
}
impl SignatureAlgorithmID {
- pub(crate) fn to_content_digest_algorithm(&self) -> ContentDigestAlgorithm {
- match self {
- SignatureAlgorithmID::RsaPssWithSha256
- | SignatureAlgorithmID::RsaPkcs1V15WithSha256
- | SignatureAlgorithmID::EcdsaWithSha256
- | SignatureAlgorithmID::DsaWithSha256 => ContentDigestAlgorithm::ChunkedSha256,
- SignatureAlgorithmID::RsaPssWithSha512
- | SignatureAlgorithmID::RsaPkcs1V15WithSha512
- | SignatureAlgorithmID::EcdsaWithSha512 => ContentDigestAlgorithm::ChunkedSha512,
- SignatureAlgorithmID::VerityRsaPkcs1V15WithSha256
- | SignatureAlgorithmID::VerityEcdsaWithSha256
- | SignatureAlgorithmID::VerityDsaWithSha256 => {
- ContentDigestAlgorithm::VerityChunkedSha256
- }
- }
- }
-
pub(crate) fn new_verifier<'a>(
&self,
public_key: &'a PKey<pkey::Public>,
@@ -102,7 +85,7 @@
/// Returns the message digest corresponding to the signature algorithm
/// according to the spec [Signature Algorithm IDs].
- fn new_message_digest(&self) -> MessageDigest {
+ pub(crate) fn new_message_digest(&self) -> MessageDigest {
match self {
SignatureAlgorithmID::RsaPssWithSha256
| SignatureAlgorithmID::RsaPkcs1V15WithSha256
@@ -148,6 +131,23 @@
| SignatureAlgorithmID::VerityDsaWithSha256 => Padding::NONE,
}
}
+
+ fn to_content_digest_algorithm(&self) -> ContentDigestAlgorithm {
+ match self {
+ SignatureAlgorithmID::RsaPssWithSha256
+ | SignatureAlgorithmID::RsaPkcs1V15WithSha256
+ | SignatureAlgorithmID::EcdsaWithSha256
+ | SignatureAlgorithmID::DsaWithSha256 => ContentDigestAlgorithm::ChunkedSha256,
+ SignatureAlgorithmID::RsaPssWithSha512
+ | SignatureAlgorithmID::RsaPkcs1V15WithSha512
+ | SignatureAlgorithmID::EcdsaWithSha512 => ContentDigestAlgorithm::ChunkedSha512,
+ SignatureAlgorithmID::VerityRsaPkcs1V15WithSha256
+ | SignatureAlgorithmID::VerityEcdsaWithSha256
+ | SignatureAlgorithmID::VerityDsaWithSha256 => {
+ ContentDigestAlgorithm::VerityChunkedSha256
+ }
+ }
+ }
}
/// The rank of the content digest algorithm in this enum is used to help pick
@@ -160,20 +160,8 @@
/// [apk digest]: https://source.android.com/docs/security/features/apksigning/v4#apk-digest
/// [v3 verification]: https://source.android.com/docs/security/apksigning/v3#v3-verification
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
-pub(crate) enum ContentDigestAlgorithm {
+enum ContentDigestAlgorithm {
ChunkedSha256 = 1,
VerityChunkedSha256,
ChunkedSha512,
}
-
-impl ContentDigestAlgorithm {
- pub(crate) fn new_message_digest(&self) -> Result<MessageDigest> {
- match self {
- ContentDigestAlgorithm::ChunkedSha256 => Ok(MessageDigest::sha256()),
- ContentDigestAlgorithm::ChunkedSha512 => Ok(MessageDigest::sha512()),
- ContentDigestAlgorithm::VerityChunkedSha256 => {
- bail!("TODO(b/197052981): CONTENT_DIGEST_VERITY_CHUNKED_SHA256 is not implemented")
- }
- }
- }
-}
diff --git a/libs/apkverify/src/sigutil.rs b/libs/apkverify/src/sigutil.rs
index 98edf49..3832c09 100644
--- a/libs/apkverify/src/sigutil.rs
+++ b/libs/apkverify/src/sigutil.rs
@@ -99,7 +99,7 @@
// TODO(b/246254355): Passes the enum SignatureAlgorithmID directly to this method.
let signature_algorithm_id = SignatureAlgorithmID::from_u32(signature_algorithm_id)
.ok_or_else(|| anyhow!("Unsupported algorithm ID: {}", signature_algorithm_id))?;
- let digester = Digester::new(signature_algorithm_id)?;
+ let digester = Digester { message_digest: signature_algorithm_id.new_message_digest() };
let mut digests_of_chunks = BytesMut::new();
let mut chunk_count = 0u32;
@@ -172,12 +172,6 @@
const CHUNK_HEADER_MID: &[u8] = &[0xa5];
impl Digester {
- fn new(signature_algorithm_id: SignatureAlgorithmID) -> Result<Digester> {
- let message_digest =
- signature_algorithm_id.to_content_digest_algorithm().new_message_digest()?;
- Ok(Digester { message_digest })
- }
-
// v2/v3 digests are computed after prepending "header" byte and "size" info.
fn digest(&self, data: &[u8], header: &[u8], size: u32) -> Result<DigestBytes> {
let mut hasher = Hasher::new(self.message_digest)?;