Create a wrapper class for update package
Creates a new class handle the package in memory and package read from fd. Define the new interface functions, and make approximate changes to the verify and install functions. Bug: 127071893 Test: unit tests pass, sideload a package Change-Id: I66ab00654df92471184536fd147b237a86e9c5b5
This commit is contained in:
+35
-31
@@ -117,19 +117,9 @@ static bool read_pkcs7(const uint8_t* pkcs7_der, size_t pkcs7_der_len,
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks for an RSA signature embedded in the .ZIP file comment given the path to the zip. Verifies
|
||||
* that it matches one of the given public keys. A callback function can be optionally provided for
|
||||
* posting the progress.
|
||||
*
|
||||
* Returns VERIFY_SUCCESS or VERIFY_FAILURE (if any error is encountered or no key matches the
|
||||
* signature).
|
||||
*/
|
||||
int verify_file(const unsigned char* addr, size_t length, const std::vector<Certificate>& keys,
|
||||
const std::function<void(float)>& set_progress) {
|
||||
if (set_progress) {
|
||||
set_progress(0.0);
|
||||
}
|
||||
int verify_file(VerifierInterface* package, const std::vector<Certificate>& keys) {
|
||||
CHECK(package);
|
||||
package->SetProgress(0.0);
|
||||
|
||||
// An archive with a whole-file signature will end in six bytes:
|
||||
//
|
||||
@@ -140,13 +130,18 @@ int verify_file(const unsigned char* addr, size_t length, const std::vector<Cert
|
||||
// the whole comment.
|
||||
|
||||
#define FOOTER_SIZE 6
|
||||
uint64_t length = package->GetPackageSize();
|
||||
|
||||
if (length < FOOTER_SIZE) {
|
||||
LOG(ERROR) << "not big enough to contain footer";
|
||||
return VERIFY_FAILURE;
|
||||
}
|
||||
|
||||
const unsigned char* footer = addr + length - FOOTER_SIZE;
|
||||
uint8_t footer[FOOTER_SIZE];
|
||||
if (!package->ReadFullyAtOffset(footer, FOOTER_SIZE, length - FOOTER_SIZE)) {
|
||||
LOG(ERROR) << "Failed to read footer";
|
||||
return VERIFY_FAILURE;
|
||||
}
|
||||
|
||||
if (footer[2] != 0xff || footer[3] != 0xff) {
|
||||
LOG(ERROR) << "footer is wrong";
|
||||
@@ -182,9 +177,13 @@ int verify_file(const unsigned char* addr, size_t length, const std::vector<Cert
|
||||
// Determine how much of the file is covered by the signature. This is everything except the
|
||||
// signature data and length, which includes all of the EOCD except for the comment length field
|
||||
// (2 bytes) and the comment data.
|
||||
size_t signed_len = length - eocd_size + EOCD_HEADER_SIZE - 2;
|
||||
uint64_t signed_len = length - eocd_size + EOCD_HEADER_SIZE - 2;
|
||||
|
||||
const unsigned char* eocd = addr + length - eocd_size;
|
||||
uint8_t eocd[eocd_size];
|
||||
if (!package->ReadFullyAtOffset(eocd, eocd_size, length - eocd_size)) {
|
||||
LOG(ERROR) << "Failed to read EOCD of " << eocd_size << " bytes";
|
||||
return VERIFY_FAILURE;
|
||||
}
|
||||
|
||||
// If this is really is the EOCD record, it will begin with the magic number $50 $4b $05 $06.
|
||||
if (eocd[0] != 0x50 || eocd[1] != 0x4b || eocd[2] != 0x05 || eocd[3] != 0x06) {
|
||||
@@ -216,24 +215,29 @@ int verify_file(const unsigned char* addr, size_t length, const std::vector<Cert
|
||||
SHA1_Init(&sha1_ctx);
|
||||
SHA256_Init(&sha256_ctx);
|
||||
|
||||
std::vector<HasherUpdateCallback> hashers;
|
||||
if (need_sha1) {
|
||||
hashers.emplace_back(
|
||||
std::bind(&SHA1_Update, &sha1_ctx, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
if (need_sha256) {
|
||||
hashers.emplace_back(
|
||||
std::bind(&SHA256_Update, &sha256_ctx, std::placeholders::_1, std::placeholders::_2));
|
||||
}
|
||||
|
||||
double frac = -1.0;
|
||||
size_t so_far = 0;
|
||||
uint64_t so_far = 0;
|
||||
while (so_far < signed_len) {
|
||||
// On a Nexus 5X, experiment showed 16MiB beat 1MiB by 6% faster for a
|
||||
// 1196MiB full OTA and 60% for an 89MiB incremental OTA.
|
||||
// http://b/28135231.
|
||||
size_t size = std::min(signed_len - so_far, 16 * MiB);
|
||||
// On a Nexus 5X, experiment showed 16MiB beat 1MiB by 6% faster for a 1196MiB full OTA and
|
||||
// 60% for an 89MiB incremental OTA. http://b/28135231.
|
||||
uint64_t read_size = std::min<uint64_t>(signed_len - so_far, 16 * MiB);
|
||||
package->UpdateHashAtOffset(hashers, so_far, read_size);
|
||||
so_far += read_size;
|
||||
|
||||
if (need_sha1) SHA1_Update(&sha1_ctx, addr + so_far, size);
|
||||
if (need_sha256) SHA256_Update(&sha256_ctx, addr + so_far, size);
|
||||
so_far += size;
|
||||
|
||||
if (set_progress) {
|
||||
double f = so_far / (double)signed_len;
|
||||
if (f > frac + 0.02 || size == so_far) {
|
||||
set_progress(f);
|
||||
frac = f;
|
||||
}
|
||||
double f = so_far / static_cast<double>(signed_len);
|
||||
if (f > frac + 0.02 || read_size == so_far) {
|
||||
package->SetProgress(f);
|
||||
frac = f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user