[apkverify] Use PKey<Public> instead of raw bytes for public key
This CL changes the type of the field Signer.public key from raw
bytes to PKey<Public>.
Test: libapkverify.integration_test
Bug: 247689066
Change-Id: Ib17815b0b4a65c0d5e5aab2c947f9bf30f8a068f
diff --git a/libs/apkverify/src/v3.rs b/libs/apkverify/src/v3.rs
index a3e738b..05694ff 100644
--- a/libs/apkverify/src/v3.rs
+++ b/libs/apkverify/src/v3.rs
@@ -43,7 +43,7 @@
min_sdk: u32,
max_sdk: u32,
signatures: LengthPrefixed<Vec<LengthPrefixed<Signature>>>,
- public_key: LengthPrefixed<Bytes>,
+ public_key: PKey<pkey::Public>,
}
impl Signer {
@@ -119,7 +119,7 @@
let apk = File::open(apk_path.as_ref())?;
let mut sections = ApkSections::new(apk)?;
find_signer_and_then(&mut sections, |(signer, _)| {
- Ok(signer.public_key.to_vec().into_boxed_slice())
+ Ok(signer.public_key.public_key_to_der()?.into_boxed_slice())
})
}
@@ -160,23 +160,31 @@
))
}
+ /// Verifies the strongest signature from signatures against signed data using public key.
+ /// Returns the verified signed data.
+ fn verify_signature(&self, strongest: &Signature) -> Result<SignedData> {
+ let mut verifier = strongest
+ .signature_algorithm_id
+ .context("Unsupported algorithm")?
+ .new_verifier(&self.public_key)?;
+ verifier.update(&self.signed_data)?;
+ ensure!(verifier.verify(&strongest.signature)?, "Signature is invalid.");
+ // It is now safe to parse signed data.
+ self.signed_data.slice(..).read()
+ }
+
/// The steps in this method implements APK Signature Scheme v3 verification step 3.
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.)
- let public_key = PKey::public_key_from_der(self.public_key.as_ref())?;
- verify_signed_data(&self.signed_data, strongest, &public_key)?;
-
- // It is now safe to parse signed data.
- let signed_data: SignedData = self.signed_data.slice(..).read()?;
+ let verified_signed_data = self.verify_signature(strongest)?;
// 3. Verify the min and max SDK versions in the signed data match those specified for the
// signer.
ensure!(
- self.sdk_range() == signed_data.sdk_range(),
+ self.sdk_range() == verified_signed_data.sdk_range(),
"SDK versions mismatch between signed and unsigned in v3 signer block."
);
@@ -186,13 +194,13 @@
self.signatures
.iter()
.map(|sig| sig.signature_algorithm_id)
- .eq(signed_data.digests.iter().map(|dig| dig.signature_algorithm_id)),
+ .eq(verified_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.
- let digest = signed_data
+ let digest = verified_signed_data
.digests
.iter()
.find(|&dig| dig.signature_algorithm_id == strongest.signature_algorithm_id)
@@ -210,35 +218,20 @@
// 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 = verified_signed_data.certificates.first().context("No certificates listed")?;
let cert = X509::from_der(cert.as_ref())?;
ensure!(
- cert.public_key()?.public_eq(&public_key),
+ cert.public_key()?.public_eq(&self.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
// struct is valid and this signer is the last certificate in the list.
- Ok(self.public_key.to_vec().into_boxed_slice())
+ Ok(self.public_key.public_key_to_der()?.into_boxed_slice())
}
}
-fn verify_signed_data(
- data: &Bytes,
- signature: &Signature,
- public_key: &PKey<pkey::Public>,
-) -> Result<()> {
- let mut verifier = signature
- .signature_algorithm_id
- .context("Unsupported algorithm")?
- .new_verifier(public_key)?;
- verifier.update(data)?;
- let verified = verifier.verify(&signature.signature)?;
- ensure!(verified, "Signature is invalid ");
- Ok(())
-}
-
// ReadFromBytes implementations
// TODO(b/190343842): add derive macro: #[derive(ReadFromBytes)]
@@ -278,6 +271,13 @@
}
}
+impl ReadFromBytes for PKey<pkey::Public> {
+ fn read_from_bytes(buf: &mut Bytes) -> Result<Self> {
+ let raw_public_key = buf.read::<LengthPrefixed<Bytes>>()?;
+ Ok(PKey::public_key_from_der(raw_public_key.as_ref())?)
+ }
+}
+
#[inline]
pub(crate) fn to_hex_string(buf: &[u8]) -> String {
buf.iter().map(|b| format!("{:02X}", b)).collect()