Skip to content
Snippets Groups Projects
Commit 462636d3 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 8843601 from fe501cd3 to udc-release

Change-Id: Id7915e0d853bbcf24ed0720e58d1c1e2c91995b2
parents e6f953db fe501cd3
No related branches found
No related tags found
Loading
......@@ -93,6 +93,19 @@ fn find_root_digest(vbmeta: &VbMetaImage) -> Result<Vec<u8>, ApexParseError> {
Err(ApexParseError::DescriptorNotHashtree)
}
/// Gets the hash of the payload's verified VBMeta image data.
pub fn get_payload_vbmeta_image_hash(path: &str) -> Result<Vec<u8>, ApexVerificationError> {
let apex_file = File::open(path).map_err(ApexParseError::Io)?;
let (_, offset, size) = get_public_key_and_image_info(&apex_file)?;
let vbmeta = VbMetaImage::verify_reader_region(apex_file, offset, size)?;
Ok(vbmeta.hash().ok_or(ApexVerificationError::ApexPubkeyMistmatch)?.to_vec())
}
/// Converts the buffer to a Hex String
pub fn to_hex_string(buf: &[u8]) -> String {
buf.iter().map(|b| format!("{:02x}", b)).collect()
}
fn get_public_key_and_image_info(apex_file: &File) -> Result<(Vec<u8>, u64, u64), ApexParseError> {
let mut z = ZipArchive::new(apex_file).map_err(|err| match err {
ZipError::Io(err) => ApexParseError::Io(err),
......@@ -130,9 +143,7 @@ fn get_public_key_and_image_info(apex_file: &File) -> Result<(Vec<u8>, u64, u64)
#[cfg(test)]
mod tests {
use super::*;
fn to_hex_string(buf: &[u8]) -> String {
buf.iter().map(|b| format!("{:02x}", b)).collect()
}
#[test]
fn test_open_apex() {
let res = verify("tests/data/test.apex").unwrap();
......@@ -141,4 +152,13 @@ mod tests {
"fe11ab17da0a3a738b54bdc3a13f6139cbdf91ec32f001f8d4bbbf8938e04e39"
);
}
#[test]
fn test_payload_vbmeta_image_hash() {
let result = get_payload_vbmeta_image_hash("tests/data/test.apex").unwrap();
assert_eq!(
to_hex_string(&result),
"296e32a76544de9da01713e471403ab4667705ad527bb4f1fac0cf61e7ce122d"
);
}
}
......@@ -14,7 +14,6 @@ rust_defaults {
"libbytes",
"liblog_rust",
"libopenssl",
"libx509_parser",
"libzip",
],
}
......
......@@ -25,11 +25,11 @@ use openssl::hash::MessageDigest;
use openssl::pkey::{self, PKey};
use openssl::rsa::Padding;
use openssl::sign::Verifier;
use openssl::x509::X509;
use std::fs::File;
use std::io::{Read, Seek};
use std::ops::Range;
use std::path::Path;
use x509_parser::{parse_x509_certificate, prelude::FromDer, x509::SubjectPublicKeyInfo};
use crate::bytes_ext::{BytesExt, LengthPrefixed, ReadFromBytes};
use crate::sigutil::*;
......@@ -168,8 +168,8 @@ impl Signer {
// 2. Verify the corresponding signature from signatures against signed data using public key.
// (It is now safe to parse signed data.)
let (_, key_info) = SubjectPublicKeyInfo::from_der(self.public_key.as_ref())?;
verify_signed_data(&self.signed_data, strongest, &key_info)?;
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()?;
......@@ -209,11 +209,11 @@ impl Signer {
);
}
// 7. Verify that SubjectPublicKeyInfo of the first certificate of certificates is identical
// 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) = parse_x509_certificate(cert.as_ref())?;
if cert.tbs_certificate.subject_pki != key_info {
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");
}
......@@ -222,11 +222,7 @@ impl Signer {
}
}
fn verify_signed_data(
data: &Bytes,
signature: &Signature,
key_info: &SubjectPublicKeyInfo,
) -> Result<()> {
fn verify_signed_data(data: &Bytes, signature: &Signature, key: &PKey<pkey::Public>) -> Result<()> {
let (pkey_id, padding, digest) = match signature.signature_algorithm_id {
SIGNATURE_RSA_PSS_WITH_SHA256 => {
(pkey::Id::RSA, Padding::PKCS1_PSS, MessageDigest::sha256())
......@@ -254,9 +250,8 @@ fn verify_signed_data(
}
_ => bail!("Unsupported signature algorithm: {:#x}", signature.signature_algorithm_id),
};
let key = PKey::public_key_from_der(key_info.raw)?;
ensure!(key.id() == pkey_id, "Public key has the wrong ID");
let mut verifier = Verifier::new(digest, &key)?;
let mut verifier = Verifier::new(digest, key)?;
if pkey_id == pkey::Id::RSA {
verifier.set_rsa_padding(padding)?;
}
......
......@@ -138,6 +138,18 @@ impl VbMetaImage {
Some(&self.data[begin..end])
}
/// Get the hash of the verified data in the VBMeta image from the authentication block. If the
/// image was not signed, there might not be a hash and, if there is, it's not known to be
/// correct.
pub fn hash(&self) -> Option<&[u8]> {
if self.header.algorithm_type == AvbAlgorithmType_AVB_ALGORITHM_TYPE_NONE {
return None;
}
let begin = size_of::<AvbVBMetaImageHeader>() + self.header.hash_offset as usize;
let end = begin + self.header.hash_size as usize;
Some(&self.data[begin..end])
}
/// Get the descriptors of the VBMeta image.
pub fn descriptors(&self) -> Result<Descriptors<'_>, VbMetaImageParseError> {
Descriptors::from_image(&self.data)
......
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