1*9e94795aSAndroid Build Coastguard Worker#!/usr/bin/env python 2*9e94795aSAndroid Build Coastguard Worker 3*9e94795aSAndroid Build Coastguard Worker# Copyright (C) 2017 The Android Open Source Project 4*9e94795aSAndroid Build Coastguard Worker# 5*9e94795aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 6*9e94795aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 7*9e94795aSAndroid Build Coastguard Worker# You may obtain a copy of the License at 8*9e94795aSAndroid Build Coastguard Worker# 9*9e94795aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 10*9e94795aSAndroid Build Coastguard Worker# 11*9e94795aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 12*9e94795aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 13*9e94795aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*9e94795aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 15*9e94795aSAndroid Build Coastguard Worker# limitations under the License. 16*9e94795aSAndroid Build Coastguard Worker 17*9e94795aSAndroid Build Coastguard Worker""" 18*9e94795aSAndroid Build Coastguard WorkerValidate a given (signed) target_files.zip. 19*9e94795aSAndroid Build Coastguard Worker 20*9e94795aSAndroid Build Coastguard WorkerIt performs the following checks to assert the integrity of the input zip. 21*9e94795aSAndroid Build Coastguard Worker 22*9e94795aSAndroid Build Coastguard Worker - It verifies the file consistency between the ones in IMAGES/system.img (read 23*9e94795aSAndroid Build Coastguard Worker via IMAGES/system.map) and the ones under unpacked folder of SYSTEM/. The 24*9e94795aSAndroid Build Coastguard Worker same check also applies to the vendor image if present. 25*9e94795aSAndroid Build Coastguard Worker 26*9e94795aSAndroid Build Coastguard Worker - It verifies the install-recovery script consistency, by comparing the 27*9e94795aSAndroid Build Coastguard Worker checksums in the script against the ones of IMAGES/{boot,recovery}.img. 28*9e94795aSAndroid Build Coastguard Worker 29*9e94795aSAndroid Build Coastguard Worker - It verifies the signed Verified Boot related images, for both of Verified 30*9e94795aSAndroid Build Coastguard Worker Boot 1.0 and 2.0 (aka AVB). 31*9e94795aSAndroid Build Coastguard Worker""" 32*9e94795aSAndroid Build Coastguard Worker 33*9e94795aSAndroid Build Coastguard Workerimport argparse 34*9e94795aSAndroid Build Coastguard Workerimport filecmp 35*9e94795aSAndroid Build Coastguard Workerimport logging 36*9e94795aSAndroid Build Coastguard Workerimport os.path 37*9e94795aSAndroid Build Coastguard Workerimport re 38*9e94795aSAndroid Build Coastguard Workerimport zipfile 39*9e94795aSAndroid Build Coastguard Worker 40*9e94795aSAndroid Build Coastguard Workerfrom hashlib import sha1 41*9e94795aSAndroid Build Coastguard Workerfrom common import IsSparseImage 42*9e94795aSAndroid Build Coastguard Worker 43*9e94795aSAndroid Build Coastguard Workerimport common 44*9e94795aSAndroid Build Coastguard Workerimport rangelib 45*9e94795aSAndroid Build Coastguard Worker 46*9e94795aSAndroid Build Coastguard Worker 47*9e94795aSAndroid Build Coastguard Workerdef _ReadFile(file_name, unpacked_name, round_up=False): 48*9e94795aSAndroid Build Coastguard Worker """Constructs and returns a File object. Rounds up its size if needed.""" 49*9e94795aSAndroid Build Coastguard Worker assert os.path.exists(unpacked_name) 50*9e94795aSAndroid Build Coastguard Worker with open(unpacked_name, 'rb') as f: 51*9e94795aSAndroid Build Coastguard Worker file_data = f.read() 52*9e94795aSAndroid Build Coastguard Worker file_size = len(file_data) 53*9e94795aSAndroid Build Coastguard Worker if round_up: 54*9e94795aSAndroid Build Coastguard Worker file_size_rounded_up = common.RoundUpTo4K(file_size) 55*9e94795aSAndroid Build Coastguard Worker file_data += b'\0' * (file_size_rounded_up - file_size) 56*9e94795aSAndroid Build Coastguard Worker return common.File(file_name, file_data) 57*9e94795aSAndroid Build Coastguard Worker 58*9e94795aSAndroid Build Coastguard Worker 59*9e94795aSAndroid Build Coastguard Workerdef ValidateFileAgainstSha1(input_tmp, file_name, file_path, expected_sha1): 60*9e94795aSAndroid Build Coastguard Worker """Check if the file has the expected SHA-1.""" 61*9e94795aSAndroid Build Coastguard Worker 62*9e94795aSAndroid Build Coastguard Worker logging.info('Validating the SHA-1 of %s', file_name) 63*9e94795aSAndroid Build Coastguard Worker unpacked_name = os.path.join(input_tmp, file_path) 64*9e94795aSAndroid Build Coastguard Worker assert os.path.exists(unpacked_name) 65*9e94795aSAndroid Build Coastguard Worker actual_sha1 = _ReadFile(file_name, unpacked_name, False).sha1 66*9e94795aSAndroid Build Coastguard Worker assert actual_sha1 == expected_sha1, \ 67*9e94795aSAndroid Build Coastguard Worker 'SHA-1 mismatches for {}. actual {}, expected {}'.format( 68*9e94795aSAndroid Build Coastguard Worker file_name, actual_sha1, expected_sha1) 69*9e94795aSAndroid Build Coastguard Worker 70*9e94795aSAndroid Build Coastguard Worker 71*9e94795aSAndroid Build Coastguard Workerdef ValidateFileConsistency(input_zip, input_tmp, info_dict): 72*9e94795aSAndroid Build Coastguard Worker """Compare the files from image files and unpacked folders.""" 73*9e94795aSAndroid Build Coastguard Worker 74*9e94795aSAndroid Build Coastguard Worker def CheckAllFiles(which): 75*9e94795aSAndroid Build Coastguard Worker logging.info('Checking %s image.', which) 76*9e94795aSAndroid Build Coastguard Worker path = os.path.join(input_tmp, "IMAGES", which + ".img") 77*9e94795aSAndroid Build Coastguard Worker if not IsSparseImage(path): 78*9e94795aSAndroid Build Coastguard Worker logging.info("%s is non-sparse image", which) 79*9e94795aSAndroid Build Coastguard Worker image = common.GetNonSparseImage(which, input_tmp) 80*9e94795aSAndroid Build Coastguard Worker else: 81*9e94795aSAndroid Build Coastguard Worker logging.info("%s is sparse image", which) 82*9e94795aSAndroid Build Coastguard Worker # Allow having shared blocks when loading the sparse image, because allowing 83*9e94795aSAndroid Build Coastguard Worker # that doesn't affect the checks below (we will have all the blocks on file, 84*9e94795aSAndroid Build Coastguard Worker # unless it's skipped due to the holes). 85*9e94795aSAndroid Build Coastguard Worker image = common.GetSparseImage(which, input_tmp, input_zip, True) 86*9e94795aSAndroid Build Coastguard Worker prefix = '/' + which 87*9e94795aSAndroid Build Coastguard Worker for entry in image.file_map: 88*9e94795aSAndroid Build Coastguard Worker # Skip entries like '__NONZERO-0'. 89*9e94795aSAndroid Build Coastguard Worker if not entry.startswith(prefix): 90*9e94795aSAndroid Build Coastguard Worker continue 91*9e94795aSAndroid Build Coastguard Worker 92*9e94795aSAndroid Build Coastguard Worker # Read the blocks that the file resides. Note that it will contain the 93*9e94795aSAndroid Build Coastguard Worker # bytes past the file length, which is expected to be padded with '\0's. 94*9e94795aSAndroid Build Coastguard Worker ranges = image.file_map[entry] 95*9e94795aSAndroid Build Coastguard Worker 96*9e94795aSAndroid Build Coastguard Worker # Use the original RangeSet if applicable, which includes the shared 97*9e94795aSAndroid Build Coastguard Worker # blocks. And this needs to happen before checking the monotonicity flag. 98*9e94795aSAndroid Build Coastguard Worker if ranges.extra.get('uses_shared_blocks'): 99*9e94795aSAndroid Build Coastguard Worker file_ranges = ranges.extra['uses_shared_blocks'] 100*9e94795aSAndroid Build Coastguard Worker else: 101*9e94795aSAndroid Build Coastguard Worker file_ranges = ranges 102*9e94795aSAndroid Build Coastguard Worker 103*9e94795aSAndroid Build Coastguard Worker incomplete = file_ranges.extra.get('incomplete', False) 104*9e94795aSAndroid Build Coastguard Worker if incomplete: 105*9e94795aSAndroid Build Coastguard Worker logging.warning('Skipping %s that has incomplete block list', entry) 106*9e94795aSAndroid Build Coastguard Worker continue 107*9e94795aSAndroid Build Coastguard Worker 108*9e94795aSAndroid Build Coastguard Worker # If the file has non-monotonic ranges, read each range in order. 109*9e94795aSAndroid Build Coastguard Worker if not file_ranges.monotonic: 110*9e94795aSAndroid Build Coastguard Worker h = sha1() 111*9e94795aSAndroid Build Coastguard Worker for file_range in file_ranges.extra['text_str'].split(' '): 112*9e94795aSAndroid Build Coastguard Worker for data in image.ReadRangeSet(rangelib.RangeSet(file_range)): 113*9e94795aSAndroid Build Coastguard Worker h.update(data) 114*9e94795aSAndroid Build Coastguard Worker blocks_sha1 = h.hexdigest() 115*9e94795aSAndroid Build Coastguard Worker else: 116*9e94795aSAndroid Build Coastguard Worker blocks_sha1 = image.RangeSha1(file_ranges) 117*9e94795aSAndroid Build Coastguard Worker 118*9e94795aSAndroid Build Coastguard Worker # The filename under unpacked directory, such as SYSTEM/bin/sh. 119*9e94795aSAndroid Build Coastguard Worker unpacked_name = os.path.join( 120*9e94795aSAndroid Build Coastguard Worker input_tmp, which.upper(), entry[(len(prefix) + 1):]) 121*9e94795aSAndroid Build Coastguard Worker unpacked_file = _ReadFile(entry, unpacked_name, True) 122*9e94795aSAndroid Build Coastguard Worker file_sha1 = unpacked_file.sha1 123*9e94795aSAndroid Build Coastguard Worker assert blocks_sha1 == file_sha1, \ 124*9e94795aSAndroid Build Coastguard Worker 'file: %s, range: %s, blocks_sha1: %s, file_sha1: %s' % ( 125*9e94795aSAndroid Build Coastguard Worker entry, file_ranges, blocks_sha1, file_sha1) 126*9e94795aSAndroid Build Coastguard Worker 127*9e94795aSAndroid Build Coastguard Worker logging.info('Validating file consistency.') 128*9e94795aSAndroid Build Coastguard Worker 129*9e94795aSAndroid Build Coastguard Worker # TODO(b/79617342): Validate non-sparse images. 130*9e94795aSAndroid Build Coastguard Worker if info_dict.get('extfs_sparse_flag') != '-s': 131*9e94795aSAndroid Build Coastguard Worker logging.warning('Skipped due to target using non-sparse images') 132*9e94795aSAndroid Build Coastguard Worker return 133*9e94795aSAndroid Build Coastguard Worker 134*9e94795aSAndroid Build Coastguard Worker # Verify IMAGES/system.img if applicable. 135*9e94795aSAndroid Build Coastguard Worker # Some targets are system.img-less. 136*9e94795aSAndroid Build Coastguard Worker if 'IMAGES/system.img' in input_zip.namelist(): 137*9e94795aSAndroid Build Coastguard Worker CheckAllFiles('system') 138*9e94795aSAndroid Build Coastguard Worker 139*9e94795aSAndroid Build Coastguard Worker # Verify IMAGES/vendor.img if applicable. 140*9e94795aSAndroid Build Coastguard Worker if 'VENDOR/' in input_zip.namelist(): 141*9e94795aSAndroid Build Coastguard Worker CheckAllFiles('vendor') 142*9e94795aSAndroid Build Coastguard Worker 143*9e94795aSAndroid Build Coastguard Worker # Not checking IMAGES/system_other.img since it doesn't have the map file. 144*9e94795aSAndroid Build Coastguard Worker 145*9e94795aSAndroid Build Coastguard Worker 146*9e94795aSAndroid Build Coastguard Workerdef ValidateInstallRecoveryScript(input_tmp, info_dict): 147*9e94795aSAndroid Build Coastguard Worker """Validate the SHA-1 embedded in install-recovery.sh. 148*9e94795aSAndroid Build Coastguard Worker 149*9e94795aSAndroid Build Coastguard Worker install-recovery.sh is written in common.py and has the following format: 150*9e94795aSAndroid Build Coastguard Worker 151*9e94795aSAndroid Build Coastguard Worker 1. full recovery: 152*9e94795aSAndroid Build Coastguard Worker ... 153*9e94795aSAndroid Build Coastguard Worker if ! applypatch --check type:device:size:sha1; then 154*9e94795aSAndroid Build Coastguard Worker applypatch --flash /vendor/etc/recovery.img \\ 155*9e94795aSAndroid Build Coastguard Worker type:device:size:sha1 && \\ 156*9e94795aSAndroid Build Coastguard Worker ... 157*9e94795aSAndroid Build Coastguard Worker 158*9e94795aSAndroid Build Coastguard Worker 2. recovery from boot: 159*9e94795aSAndroid Build Coastguard Worker ... 160*9e94795aSAndroid Build Coastguard Worker if ! applypatch --check type:recovery_device:recovery_size:recovery_sha1; then 161*9e94795aSAndroid Build Coastguard Worker applypatch [--bonus bonus_args] \\ 162*9e94795aSAndroid Build Coastguard Worker --patch /vendor/recovery-from-boot.p \\ 163*9e94795aSAndroid Build Coastguard Worker --source type:boot_device:boot_size:boot_sha1 \\ 164*9e94795aSAndroid Build Coastguard Worker --target type:recovery_device:recovery_size:recovery_sha1 && \\ 165*9e94795aSAndroid Build Coastguard Worker ... 166*9e94795aSAndroid Build Coastguard Worker 167*9e94795aSAndroid Build Coastguard Worker For full recovery, we want to calculate the SHA-1 of /vendor/etc/recovery.img 168*9e94795aSAndroid Build Coastguard Worker and compare it against the one embedded in the script. While for recovery 169*9e94795aSAndroid Build Coastguard Worker from boot, we want to check the SHA-1 for both recovery.img and boot.img 170*9e94795aSAndroid Build Coastguard Worker under IMAGES/. 171*9e94795aSAndroid Build Coastguard Worker """ 172*9e94795aSAndroid Build Coastguard Worker 173*9e94795aSAndroid Build Coastguard Worker board_uses_vendorimage = info_dict.get("board_uses_vendorimage") == "true" 174*9e94795aSAndroid Build Coastguard Worker 175*9e94795aSAndroid Build Coastguard Worker if board_uses_vendorimage: 176*9e94795aSAndroid Build Coastguard Worker script_path = 'VENDOR/bin/install-recovery.sh' 177*9e94795aSAndroid Build Coastguard Worker recovery_img = 'VENDOR/etc/recovery.img' 178*9e94795aSAndroid Build Coastguard Worker else: 179*9e94795aSAndroid Build Coastguard Worker script_path = 'SYSTEM/vendor/bin/install-recovery.sh' 180*9e94795aSAndroid Build Coastguard Worker recovery_img = 'SYSTEM/vendor/etc/recovery.img' 181*9e94795aSAndroid Build Coastguard Worker 182*9e94795aSAndroid Build Coastguard Worker if not os.path.exists(os.path.join(input_tmp, script_path)): 183*9e94795aSAndroid Build Coastguard Worker logging.info('%s does not exist in input_tmp', script_path) 184*9e94795aSAndroid Build Coastguard Worker return 185*9e94795aSAndroid Build Coastguard Worker 186*9e94795aSAndroid Build Coastguard Worker logging.info('Checking %s', script_path) 187*9e94795aSAndroid Build Coastguard Worker with open(os.path.join(input_tmp, script_path), 'r') as script: 188*9e94795aSAndroid Build Coastguard Worker lines = script.read().strip().split('\n') 189*9e94795aSAndroid Build Coastguard Worker assert len(lines) >= 10 190*9e94795aSAndroid Build Coastguard Worker check_cmd = re.search(r'if ! applypatch --check (\w+:.+:\w+:\w+);', 191*9e94795aSAndroid Build Coastguard Worker lines[1].strip()) 192*9e94795aSAndroid Build Coastguard Worker check_partition = check_cmd.group(1) 193*9e94795aSAndroid Build Coastguard Worker assert len(check_partition.split(':')) == 4 194*9e94795aSAndroid Build Coastguard Worker 195*9e94795aSAndroid Build Coastguard Worker full_recovery_image = info_dict.get("full_recovery_image") == "true" 196*9e94795aSAndroid Build Coastguard Worker if full_recovery_image: 197*9e94795aSAndroid Build Coastguard Worker assert len(lines) == 10, "Invalid line count: {}".format(lines) 198*9e94795aSAndroid Build Coastguard Worker 199*9e94795aSAndroid Build Coastguard Worker # Expect something like "EMMC:/dev/block/recovery:28:5f9c..62e3". 200*9e94795aSAndroid Build Coastguard Worker target = re.search(r'--target (.+) &&', lines[4].strip()) 201*9e94795aSAndroid Build Coastguard Worker assert target is not None, \ 202*9e94795aSAndroid Build Coastguard Worker "Failed to parse target line \"{}\"".format(lines[4]) 203*9e94795aSAndroid Build Coastguard Worker flash_partition = target.group(1) 204*9e94795aSAndroid Build Coastguard Worker 205*9e94795aSAndroid Build Coastguard Worker # Check we have the same recovery target in the check and flash commands. 206*9e94795aSAndroid Build Coastguard Worker assert check_partition == flash_partition, \ 207*9e94795aSAndroid Build Coastguard Worker "Mismatching targets: {} vs {}".format( 208*9e94795aSAndroid Build Coastguard Worker check_partition, flash_partition) 209*9e94795aSAndroid Build Coastguard Worker 210*9e94795aSAndroid Build Coastguard Worker # Validate the SHA-1 of the recovery image. 211*9e94795aSAndroid Build Coastguard Worker recovery_sha1 = flash_partition.split(':')[3] 212*9e94795aSAndroid Build Coastguard Worker ValidateFileAgainstSha1( 213*9e94795aSAndroid Build Coastguard Worker input_tmp, 'recovery.img', recovery_img, recovery_sha1) 214*9e94795aSAndroid Build Coastguard Worker else: 215*9e94795aSAndroid Build Coastguard Worker assert len(lines) == 11, "Invalid line count: {}".format(lines) 216*9e94795aSAndroid Build Coastguard Worker 217*9e94795aSAndroid Build Coastguard Worker # --source boot_type:boot_device:boot_size:boot_sha1 218*9e94795aSAndroid Build Coastguard Worker source = re.search(r'--source (\w+:.+:\w+:\w+) \\', lines[4].strip()) 219*9e94795aSAndroid Build Coastguard Worker assert source is not None, \ 220*9e94795aSAndroid Build Coastguard Worker "Failed to parse source line \"{}\"".format(lines[4]) 221*9e94795aSAndroid Build Coastguard Worker 222*9e94795aSAndroid Build Coastguard Worker source_partition = source.group(1) 223*9e94795aSAndroid Build Coastguard Worker source_info = source_partition.split(':') 224*9e94795aSAndroid Build Coastguard Worker assert len(source_info) == 4, \ 225*9e94795aSAndroid Build Coastguard Worker "Invalid source partition: {}".format(source_partition) 226*9e94795aSAndroid Build Coastguard Worker ValidateFileAgainstSha1(input_tmp, file_name='boot.img', 227*9e94795aSAndroid Build Coastguard Worker file_path='IMAGES/boot.img', 228*9e94795aSAndroid Build Coastguard Worker expected_sha1=source_info[3]) 229*9e94795aSAndroid Build Coastguard Worker 230*9e94795aSAndroid Build Coastguard Worker # --target recovery_type:recovery_device:recovery_size:recovery_sha1 231*9e94795aSAndroid Build Coastguard Worker target = re.search(r'--target (\w+:.+:\w+:\w+) && \\', lines[5].strip()) 232*9e94795aSAndroid Build Coastguard Worker assert target is not None, \ 233*9e94795aSAndroid Build Coastguard Worker "Failed to parse target line \"{}\"".format(lines[5]) 234*9e94795aSAndroid Build Coastguard Worker target_partition = target.group(1) 235*9e94795aSAndroid Build Coastguard Worker 236*9e94795aSAndroid Build Coastguard Worker # Check we have the same recovery target in the check and patch commands. 237*9e94795aSAndroid Build Coastguard Worker assert check_partition == target_partition, \ 238*9e94795aSAndroid Build Coastguard Worker "Mismatching targets: {} vs {}".format( 239*9e94795aSAndroid Build Coastguard Worker check_partition, target_partition) 240*9e94795aSAndroid Build Coastguard Worker 241*9e94795aSAndroid Build Coastguard Worker recovery_info = target_partition.split(':') 242*9e94795aSAndroid Build Coastguard Worker assert len(recovery_info) == 4, \ 243*9e94795aSAndroid Build Coastguard Worker "Invalid target partition: {}".format(target_partition) 244*9e94795aSAndroid Build Coastguard Worker ValidateFileAgainstSha1(input_tmp, file_name='recovery.img', 245*9e94795aSAndroid Build Coastguard Worker file_path='IMAGES/recovery.img', 246*9e94795aSAndroid Build Coastguard Worker expected_sha1=recovery_info[3]) 247*9e94795aSAndroid Build Coastguard Worker 248*9e94795aSAndroid Build Coastguard Worker logging.info('Done checking %s', script_path) 249*9e94795aSAndroid Build Coastguard Worker 250*9e94795aSAndroid Build Coastguard Worker 251*9e94795aSAndroid Build Coastguard Worker# Symlink files in `src` to `dst`, if the files do not 252*9e94795aSAndroid Build Coastguard Worker# already exists in `dst` directory. 253*9e94795aSAndroid Build Coastguard Workerdef symlinkIfNotExists(src, dst): 254*9e94795aSAndroid Build Coastguard Worker if not os.path.isdir(src): 255*9e94795aSAndroid Build Coastguard Worker return 256*9e94795aSAndroid Build Coastguard Worker for filename in os.listdir(src): 257*9e94795aSAndroid Build Coastguard Worker if os.path.exists(os.path.join(dst, filename)): 258*9e94795aSAndroid Build Coastguard Worker continue 259*9e94795aSAndroid Build Coastguard Worker os.symlink(os.path.join(src, filename), os.path.join(dst, filename)) 260*9e94795aSAndroid Build Coastguard Worker 261*9e94795aSAndroid Build Coastguard Worker 262*9e94795aSAndroid Build Coastguard Workerdef ValidatePartitionFingerprints(input_tmp, info_dict): 263*9e94795aSAndroid Build Coastguard Worker build_info = common.BuildInfo(info_dict) 264*9e94795aSAndroid Build Coastguard Worker # Expected format: 265*9e94795aSAndroid Build Coastguard Worker # Prop: com.android.build.vendor.fingerprint -> 'generic/aosp_cf_x86_64_phone/vsoc_x86_64:S/AOSP.MASTER/7335886:userdebug/test-keys' 266*9e94795aSAndroid Build Coastguard Worker # Prop: com.android.build.vendor_boot.fingerprint -> 'generic/aosp_cf_x86_64_phone/vsoc_x86_64:S/AOSP.MASTER/7335886:userdebug/test-keys' 267*9e94795aSAndroid Build Coastguard Worker p = re.compile( 268*9e94795aSAndroid Build Coastguard Worker r"Prop: com.android.build.(?P<partition>\w+).fingerprint -> '(?P<fingerprint>[\w\/:\.-]+)'") 269*9e94795aSAndroid Build Coastguard Worker for vbmeta_partition in ["vbmeta", "vbmeta_system"]: 270*9e94795aSAndroid Build Coastguard Worker image = os.path.join(input_tmp, "IMAGES", vbmeta_partition + ".img") 271*9e94795aSAndroid Build Coastguard Worker if not os.path.exists(image): 272*9e94795aSAndroid Build Coastguard Worker assert vbmeta_partition != "vbmeta",\ 273*9e94795aSAndroid Build Coastguard Worker "{} is a required partition for AVB.".format( 274*9e94795aSAndroid Build Coastguard Worker vbmeta_partition) 275*9e94795aSAndroid Build Coastguard Worker logging.info("vb partition %s not present, skipping", vbmeta_partition) 276*9e94795aSAndroid Build Coastguard Worker continue 277*9e94795aSAndroid Build Coastguard Worker 278*9e94795aSAndroid Build Coastguard Worker output = common.RunAndCheckOutput( 279*9e94795aSAndroid Build Coastguard Worker [info_dict["avb_avbtool"], "info_image", "--image", image]) 280*9e94795aSAndroid Build Coastguard Worker matches = p.findall(output) 281*9e94795aSAndroid Build Coastguard Worker for (partition, fingerprint) in matches: 282*9e94795aSAndroid Build Coastguard Worker actual_fingerprint = build_info.GetPartitionFingerprint( 283*9e94795aSAndroid Build Coastguard Worker partition) 284*9e94795aSAndroid Build Coastguard Worker if actual_fingerprint is None: 285*9e94795aSAndroid Build Coastguard Worker logging.warning( 286*9e94795aSAndroid Build Coastguard Worker "Failed to get fingerprint for partition %s", partition) 287*9e94795aSAndroid Build Coastguard Worker continue 288*9e94795aSAndroid Build Coastguard Worker assert fingerprint == actual_fingerprint, "Fingerprint mismatch for partition {}, expected: {} actual: {}".format( 289*9e94795aSAndroid Build Coastguard Worker partition, fingerprint, actual_fingerprint) 290*9e94795aSAndroid Build Coastguard Worker 291*9e94795aSAndroid Build Coastguard Worker 292*9e94795aSAndroid Build Coastguard Workerdef ValidateVerifiedBootImages(input_tmp, info_dict, options): 293*9e94795aSAndroid Build Coastguard Worker """Validates the Verified Boot related images. 294*9e94795aSAndroid Build Coastguard Worker 295*9e94795aSAndroid Build Coastguard Worker For Verified Boot 1.0, it verifies the signatures of the bootable images 296*9e94795aSAndroid Build Coastguard Worker (boot/recovery etc), as well as the dm-verity metadata in system images 297*9e94795aSAndroid Build Coastguard Worker (system/vendor/product). For Verified Boot 2.0, it calls avbtool to verify 298*9e94795aSAndroid Build Coastguard Worker vbmeta.img, which in turn verifies all the descriptors listed in vbmeta. 299*9e94795aSAndroid Build Coastguard Worker 300*9e94795aSAndroid Build Coastguard Worker Args: 301*9e94795aSAndroid Build Coastguard Worker input_tmp: The top-level directory of unpacked target-files.zip. 302*9e94795aSAndroid Build Coastguard Worker info_dict: The loaded info dict. 303*9e94795aSAndroid Build Coastguard Worker options: A dict that contains the user-supplied public keys to be used for 304*9e94795aSAndroid Build Coastguard Worker image verification. In particular, 'verity_key' is used to verify the 305*9e94795aSAndroid Build Coastguard Worker bootable images in VB 1.0, and the vbmeta image in VB 2.0, where 306*9e94795aSAndroid Build Coastguard Worker applicable. 'verity_key_mincrypt' will be used to verify the system 307*9e94795aSAndroid Build Coastguard Worker images in VB 1.0. 308*9e94795aSAndroid Build Coastguard Worker 309*9e94795aSAndroid Build Coastguard Worker Raises: 310*9e94795aSAndroid Build Coastguard Worker AssertionError: On any verification failure. 311*9e94795aSAndroid Build Coastguard Worker """ 312*9e94795aSAndroid Build Coastguard Worker # See bug 159299583 313*9e94795aSAndroid Build Coastguard Worker # After commit 5277d1015, some images (e.g. acpio.img and tos.img) are no 314*9e94795aSAndroid Build Coastguard Worker # longer copied from RADIO to the IMAGES folder. But avbtool assumes that 315*9e94795aSAndroid Build Coastguard Worker # images are in IMAGES folder. So we symlink them. 316*9e94795aSAndroid Build Coastguard Worker symlinkIfNotExists(os.path.join(input_tmp, "RADIO"), 317*9e94795aSAndroid Build Coastguard Worker os.path.join(input_tmp, "IMAGES")) 318*9e94795aSAndroid Build Coastguard Worker # Verified boot 1.0 (images signed with boot_signer and verity_signer). 319*9e94795aSAndroid Build Coastguard Worker if info_dict.get('boot_signer') == 'true': 320*9e94795aSAndroid Build Coastguard Worker logging.info('Verifying Verified Boot images...') 321*9e94795aSAndroid Build Coastguard Worker 322*9e94795aSAndroid Build Coastguard Worker # Verify the boot/recovery images (signed with boot_signer), against the 323*9e94795aSAndroid Build Coastguard Worker # given X.509 encoded pubkey (or falling back to the one in the info_dict if 324*9e94795aSAndroid Build Coastguard Worker # none given). 325*9e94795aSAndroid Build Coastguard Worker verity_key = options['verity_key'] 326*9e94795aSAndroid Build Coastguard Worker if verity_key is None: 327*9e94795aSAndroid Build Coastguard Worker verity_key = info_dict['verity_key'] + '.x509.pem' 328*9e94795aSAndroid Build Coastguard Worker for image in ('boot.img', 'recovery.img', 'recovery-two-step.img'): 329*9e94795aSAndroid Build Coastguard Worker if image == 'recovery-two-step.img': 330*9e94795aSAndroid Build Coastguard Worker image_path = os.path.join(input_tmp, 'OTA', image) 331*9e94795aSAndroid Build Coastguard Worker else: 332*9e94795aSAndroid Build Coastguard Worker image_path = os.path.join(input_tmp, 'IMAGES', image) 333*9e94795aSAndroid Build Coastguard Worker if not os.path.exists(image_path): 334*9e94795aSAndroid Build Coastguard Worker continue 335*9e94795aSAndroid Build Coastguard Worker 336*9e94795aSAndroid Build Coastguard Worker cmd = ['boot_signer', '-verify', image_path, '-certificate', verity_key] 337*9e94795aSAndroid Build Coastguard Worker proc = common.Run(cmd) 338*9e94795aSAndroid Build Coastguard Worker stdoutdata, _ = proc.communicate() 339*9e94795aSAndroid Build Coastguard Worker assert proc.returncode == 0, \ 340*9e94795aSAndroid Build Coastguard Worker 'Failed to verify {} with boot_signer:\n{}'.format(image, stdoutdata) 341*9e94795aSAndroid Build Coastguard Worker logging.info( 342*9e94795aSAndroid Build Coastguard Worker 'Verified %s with boot_signer (key: %s):\n%s', image, verity_key, 343*9e94795aSAndroid Build Coastguard Worker stdoutdata.rstrip()) 344*9e94795aSAndroid Build Coastguard Worker 345*9e94795aSAndroid Build Coastguard Worker # Verify verity signed system images in Verified Boot 1.0. Note that not using 346*9e94795aSAndroid Build Coastguard Worker # 'elif' here, since 'boot_signer' and 'verity' are not bundled in VB 1.0. 347*9e94795aSAndroid Build Coastguard Worker if info_dict.get('verity') == 'true': 348*9e94795aSAndroid Build Coastguard Worker # First verify that the verity key is built into the root image (regardless 349*9e94795aSAndroid Build Coastguard Worker # of system-as-root). 350*9e94795aSAndroid Build Coastguard Worker verity_key_mincrypt = os.path.join(input_tmp, 'ROOT', 'verity_key') 351*9e94795aSAndroid Build Coastguard Worker assert os.path.exists(verity_key_mincrypt), 'Missing verity_key' 352*9e94795aSAndroid Build Coastguard Worker 353*9e94795aSAndroid Build Coastguard Worker # Verify /verity_key matches the one given via command line, if any. 354*9e94795aSAndroid Build Coastguard Worker if options['verity_key_mincrypt'] is None: 355*9e94795aSAndroid Build Coastguard Worker logging.warn( 356*9e94795aSAndroid Build Coastguard Worker 'Skipped checking the content of /verity_key, as the key file not ' 357*9e94795aSAndroid Build Coastguard Worker 'provided. Use --verity_key_mincrypt to specify.') 358*9e94795aSAndroid Build Coastguard Worker else: 359*9e94795aSAndroid Build Coastguard Worker expected_key = options['verity_key_mincrypt'] 360*9e94795aSAndroid Build Coastguard Worker assert filecmp.cmp(expected_key, verity_key_mincrypt, shallow=False), \ 361*9e94795aSAndroid Build Coastguard Worker "Mismatching mincrypt verity key files" 362*9e94795aSAndroid Build Coastguard Worker logging.info('Verified the content of /verity_key') 363*9e94795aSAndroid Build Coastguard Worker 364*9e94795aSAndroid Build Coastguard Worker verity_key_ramdisk = os.path.join( 365*9e94795aSAndroid Build Coastguard Worker input_tmp, 'BOOT', 'RAMDISK', 'verity_key') 366*9e94795aSAndroid Build Coastguard Worker assert os.path.exists( 367*9e94795aSAndroid Build Coastguard Worker verity_key_ramdisk), 'Missing verity_key in ramdisk' 368*9e94795aSAndroid Build Coastguard Worker 369*9e94795aSAndroid Build Coastguard Worker assert filecmp.cmp( 370*9e94795aSAndroid Build Coastguard Worker verity_key_mincrypt, verity_key_ramdisk, shallow=False), \ 371*9e94795aSAndroid Build Coastguard Worker 'Mismatching verity_key files in root and ramdisk' 372*9e94795aSAndroid Build Coastguard Worker logging.info('Verified the content of /verity_key in ramdisk') 373*9e94795aSAndroid Build Coastguard Worker 374*9e94795aSAndroid Build Coastguard Worker # Then verify the verity signed system/vendor/product images, against the 375*9e94795aSAndroid Build Coastguard Worker # verity pubkey in mincrypt format. 376*9e94795aSAndroid Build Coastguard Worker for image in ('system.img', 'vendor.img', 'product.img'): 377*9e94795aSAndroid Build Coastguard Worker image_path = os.path.join(input_tmp, 'IMAGES', image) 378*9e94795aSAndroid Build Coastguard Worker 379*9e94795aSAndroid Build Coastguard Worker # We are not checking if the image is actually enabled via info_dict (e.g. 380*9e94795aSAndroid Build Coastguard Worker # 'system_verity_block_device=...'). Because it's most likely a bug that 381*9e94795aSAndroid Build Coastguard Worker # skips signing some of the images in signed target-files.zip, while 382*9e94795aSAndroid Build Coastguard Worker # having the top-level verity flag enabled. 383*9e94795aSAndroid Build Coastguard Worker if not os.path.exists(image_path): 384*9e94795aSAndroid Build Coastguard Worker continue 385*9e94795aSAndroid Build Coastguard Worker 386*9e94795aSAndroid Build Coastguard Worker cmd = ['verity_verifier', image_path, '-mincrypt', verity_key_mincrypt] 387*9e94795aSAndroid Build Coastguard Worker proc = common.Run(cmd) 388*9e94795aSAndroid Build Coastguard Worker stdoutdata, _ = proc.communicate() 389*9e94795aSAndroid Build Coastguard Worker assert proc.returncode == 0, \ 390*9e94795aSAndroid Build Coastguard Worker 'Failed to verify {} with verity_verifier (key: {}):\n{}'.format( 391*9e94795aSAndroid Build Coastguard Worker image, verity_key_mincrypt, stdoutdata) 392*9e94795aSAndroid Build Coastguard Worker logging.info( 393*9e94795aSAndroid Build Coastguard Worker 'Verified %s with verity_verifier (key: %s):\n%s', image, 394*9e94795aSAndroid Build Coastguard Worker verity_key_mincrypt, stdoutdata.rstrip()) 395*9e94795aSAndroid Build Coastguard Worker 396*9e94795aSAndroid Build Coastguard Worker # Handle the case of Verified Boot 2.0 (AVB). 397*9e94795aSAndroid Build Coastguard Worker if info_dict.get("avb_building_vbmeta_image") == "true": 398*9e94795aSAndroid Build Coastguard Worker logging.info('Verifying Verified Boot 2.0 (AVB) images...') 399*9e94795aSAndroid Build Coastguard Worker 400*9e94795aSAndroid Build Coastguard Worker key = options['verity_key'] 401*9e94795aSAndroid Build Coastguard Worker if key is None: 402*9e94795aSAndroid Build Coastguard Worker key = info_dict['avb_vbmeta_key_path'] 403*9e94795aSAndroid Build Coastguard Worker 404*9e94795aSAndroid Build Coastguard Worker ValidatePartitionFingerprints(input_tmp, info_dict) 405*9e94795aSAndroid Build Coastguard Worker 406*9e94795aSAndroid Build Coastguard Worker # avbtool verifies all the images that have descriptors listed in vbmeta. 407*9e94795aSAndroid Build Coastguard Worker # Using `--follow_chain_partitions` so it would additionally verify chained 408*9e94795aSAndroid Build Coastguard Worker # vbmeta partitions (e.g. vbmeta_system). 409*9e94795aSAndroid Build Coastguard Worker image = os.path.join(input_tmp, 'IMAGES', 'vbmeta.img') 410*9e94795aSAndroid Build Coastguard Worker cmd = [info_dict['avb_avbtool'], 'verify_image', '--image', image, 411*9e94795aSAndroid Build Coastguard Worker '--follow_chain_partitions'] 412*9e94795aSAndroid Build Coastguard Worker 413*9e94795aSAndroid Build Coastguard Worker # Custom images. 414*9e94795aSAndroid Build Coastguard Worker custom_partitions = info_dict.get( 415*9e94795aSAndroid Build Coastguard Worker "avb_custom_images_partition_list", "").strip().split() 416*9e94795aSAndroid Build Coastguard Worker 417*9e94795aSAndroid Build Coastguard Worker # Append the args for chained partitions if any. 418*9e94795aSAndroid Build Coastguard Worker for partition in (common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS + 419*9e94795aSAndroid Build Coastguard Worker tuple(custom_partitions)): 420*9e94795aSAndroid Build Coastguard Worker key_name = 'avb_' + partition + '_key_path' 421*9e94795aSAndroid Build Coastguard Worker if info_dict.get(key_name) is not None: 422*9e94795aSAndroid Build Coastguard Worker if info_dict.get('ab_update') != 'true' and partition == 'recovery': 423*9e94795aSAndroid Build Coastguard Worker continue 424*9e94795aSAndroid Build Coastguard Worker 425*9e94795aSAndroid Build Coastguard Worker # Use the key file from command line if specified; otherwise fall back 426*9e94795aSAndroid Build Coastguard Worker # to the one in info dict. 427*9e94795aSAndroid Build Coastguard Worker key_file = options.get(key_name, info_dict[key_name]) 428*9e94795aSAndroid Build Coastguard Worker chained_partition_arg = common.GetAvbChainedPartitionArg( 429*9e94795aSAndroid Build Coastguard Worker partition, info_dict, key_file) 430*9e94795aSAndroid Build Coastguard Worker cmd.extend(['--expected_chain_partition', 431*9e94795aSAndroid Build Coastguard Worker chained_partition_arg.to_string()]) 432*9e94795aSAndroid Build Coastguard Worker 433*9e94795aSAndroid Build Coastguard Worker # Handle the boot image with a non-default name, e.g. boot-5.4.img 434*9e94795aSAndroid Build Coastguard Worker boot_images = info_dict.get("boot_images") 435*9e94795aSAndroid Build Coastguard Worker if boot_images: 436*9e94795aSAndroid Build Coastguard Worker # we used the 1st boot image to generate the vbmeta. Rename the filename 437*9e94795aSAndroid Build Coastguard Worker # to boot.img so that avbtool can find it correctly. 438*9e94795aSAndroid Build Coastguard Worker first_image_name = boot_images.split()[0] 439*9e94795aSAndroid Build Coastguard Worker first_image_path = os.path.join(input_tmp, 'IMAGES', first_image_name) 440*9e94795aSAndroid Build Coastguard Worker assert os.path.isfile(first_image_path) 441*9e94795aSAndroid Build Coastguard Worker renamed_boot_image_path = os.path.join(input_tmp, 'IMAGES', 'boot.img') 442*9e94795aSAndroid Build Coastguard Worker os.rename(first_image_path, renamed_boot_image_path) 443*9e94795aSAndroid Build Coastguard Worker 444*9e94795aSAndroid Build Coastguard Worker proc = common.Run(cmd) 445*9e94795aSAndroid Build Coastguard Worker stdoutdata, _ = proc.communicate() 446*9e94795aSAndroid Build Coastguard Worker assert proc.returncode == 0, \ 447*9e94795aSAndroid Build Coastguard Worker 'Failed to verify {} with avbtool (key: {}):\n{}'.format( 448*9e94795aSAndroid Build Coastguard Worker image, key, stdoutdata) 449*9e94795aSAndroid Build Coastguard Worker 450*9e94795aSAndroid Build Coastguard Worker logging.info( 451*9e94795aSAndroid Build Coastguard Worker 'Verified %s with avbtool (key: %s):\n%s', image, key, 452*9e94795aSAndroid Build Coastguard Worker stdoutdata.rstrip()) 453*9e94795aSAndroid Build Coastguard Worker 454*9e94795aSAndroid Build Coastguard Worker # avbtool verifies recovery image for non-A/B devices. 455*9e94795aSAndroid Build Coastguard Worker if (info_dict.get('ab_update') != 'true' and 456*9e94795aSAndroid Build Coastguard Worker info_dict.get('no_recovery') != 'true'): 457*9e94795aSAndroid Build Coastguard Worker image = os.path.join(input_tmp, 'IMAGES', 'recovery.img') 458*9e94795aSAndroid Build Coastguard Worker key = info_dict['avb_recovery_key_path'] 459*9e94795aSAndroid Build Coastguard Worker cmd = [info_dict['avb_avbtool'], 'verify_image', '--image', image, 460*9e94795aSAndroid Build Coastguard Worker '--key', key] 461*9e94795aSAndroid Build Coastguard Worker proc = common.Run(cmd) 462*9e94795aSAndroid Build Coastguard Worker stdoutdata, _ = proc.communicate() 463*9e94795aSAndroid Build Coastguard Worker assert proc.returncode == 0, \ 464*9e94795aSAndroid Build Coastguard Worker 'Failed to verify {} with avbtool (key: {}):\n{}'.format( 465*9e94795aSAndroid Build Coastguard Worker image, key, stdoutdata) 466*9e94795aSAndroid Build Coastguard Worker logging.info( 467*9e94795aSAndroid Build Coastguard Worker 'Verified %s with avbtool (key: %s):\n%s', image, key, 468*9e94795aSAndroid Build Coastguard Worker stdoutdata.rstrip()) 469*9e94795aSAndroid Build Coastguard Worker 470*9e94795aSAndroid Build Coastguard Worker 471*9e94795aSAndroid Build Coastguard Workerdef CheckDataInconsistency(lines): 472*9e94795aSAndroid Build Coastguard Worker build_prop = {} 473*9e94795aSAndroid Build Coastguard Worker for line in lines: 474*9e94795aSAndroid Build Coastguard Worker if line.startswith("import") or line.startswith("#"): 475*9e94795aSAndroid Build Coastguard Worker continue 476*9e94795aSAndroid Build Coastguard Worker if "=" not in line: 477*9e94795aSAndroid Build Coastguard Worker continue 478*9e94795aSAndroid Build Coastguard Worker 479*9e94795aSAndroid Build Coastguard Worker key, value = line.rstrip().split("=", 1) 480*9e94795aSAndroid Build Coastguard Worker if key in build_prop: 481*9e94795aSAndroid Build Coastguard Worker logging.info("Duplicated key found for {}".format(key)) 482*9e94795aSAndroid Build Coastguard Worker if value != build_prop[key]: 483*9e94795aSAndroid Build Coastguard Worker logging.error("Key {} is defined twice with different values {} vs {}" 484*9e94795aSAndroid Build Coastguard Worker .format(key, value, build_prop[key])) 485*9e94795aSAndroid Build Coastguard Worker return key 486*9e94795aSAndroid Build Coastguard Worker build_prop[key] = value 487*9e94795aSAndroid Build Coastguard Worker 488*9e94795aSAndroid Build Coastguard Worker 489*9e94795aSAndroid Build Coastguard Workerdef CheckBuildPropDuplicity(input_tmp): 490*9e94795aSAndroid Build Coastguard Worker """Check all buld.prop files inside directory input_tmp, raise error 491*9e94795aSAndroid Build Coastguard Worker if they contain duplicates""" 492*9e94795aSAndroid Build Coastguard Worker 493*9e94795aSAndroid Build Coastguard Worker if not os.path.isdir(input_tmp): 494*9e94795aSAndroid Build Coastguard Worker raise ValueError("Expect {} to be a directory".format(input_tmp)) 495*9e94795aSAndroid Build Coastguard Worker for name in os.listdir(input_tmp): 496*9e94795aSAndroid Build Coastguard Worker if not name.isupper(): 497*9e94795aSAndroid Build Coastguard Worker continue 498*9e94795aSAndroid Build Coastguard Worker for prop_file in ['build.prop', 'etc/build.prop']: 499*9e94795aSAndroid Build Coastguard Worker path = os.path.join(input_tmp, name, prop_file) 500*9e94795aSAndroid Build Coastguard Worker if not os.path.exists(path): 501*9e94795aSAndroid Build Coastguard Worker continue 502*9e94795aSAndroid Build Coastguard Worker logging.info("Checking {}".format(path)) 503*9e94795aSAndroid Build Coastguard Worker with open(path, 'r') as fp: 504*9e94795aSAndroid Build Coastguard Worker dupKey = CheckDataInconsistency(fp.readlines()) 505*9e94795aSAndroid Build Coastguard Worker if dupKey: 506*9e94795aSAndroid Build Coastguard Worker raise ValueError("{} contains duplicate keys for {}".format( 507*9e94795aSAndroid Build Coastguard Worker path, dupKey)) 508*9e94795aSAndroid Build Coastguard Worker 509*9e94795aSAndroid Build Coastguard Worker 510*9e94795aSAndroid Build Coastguard Workerdef main(): 511*9e94795aSAndroid Build Coastguard Worker parser = argparse.ArgumentParser( 512*9e94795aSAndroid Build Coastguard Worker description=__doc__, 513*9e94795aSAndroid Build Coastguard Worker formatter_class=argparse.RawDescriptionHelpFormatter) 514*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 515*9e94795aSAndroid Build Coastguard Worker 'target_files', 516*9e94795aSAndroid Build Coastguard Worker help='the input target_files.zip to be validated') 517*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 518*9e94795aSAndroid Build Coastguard Worker '--verity_key', 519*9e94795aSAndroid Build Coastguard Worker help='the verity public key to verify the bootable images (Verified ' 520*9e94795aSAndroid Build Coastguard Worker 'Boot 1.0), or the vbmeta image (Verified Boot 2.0, aka AVB), where ' 521*9e94795aSAndroid Build Coastguard Worker 'applicable') 522*9e94795aSAndroid Build Coastguard Worker for partition in common.AVB_PARTITIONS + common.AVB_VBMETA_PARTITIONS: 523*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 524*9e94795aSAndroid Build Coastguard Worker '--avb_' + partition + '_key_path', 525*9e94795aSAndroid Build Coastguard Worker help='the public or private key in PEM format to verify AVB chained ' 526*9e94795aSAndroid Build Coastguard Worker 'partition of {}'.format(partition)) 527*9e94795aSAndroid Build Coastguard Worker parser.add_argument( 528*9e94795aSAndroid Build Coastguard Worker '--verity_key_mincrypt', 529*9e94795aSAndroid Build Coastguard Worker help='the verity public key in mincrypt format to verify the system ' 530*9e94795aSAndroid Build Coastguard Worker 'images, if target using Verified Boot 1.0') 531*9e94795aSAndroid Build Coastguard Worker args = parser.parse_args() 532*9e94795aSAndroid Build Coastguard Worker 533*9e94795aSAndroid Build Coastguard Worker # Unprovided args will have 'None' as the value. 534*9e94795aSAndroid Build Coastguard Worker options = vars(args) 535*9e94795aSAndroid Build Coastguard Worker 536*9e94795aSAndroid Build Coastguard Worker logging_format = '%(asctime)s - %(filename)s - %(levelname)-8s: %(message)s' 537*9e94795aSAndroid Build Coastguard Worker date_format = '%Y/%m/%d %H:%M:%S' 538*9e94795aSAndroid Build Coastguard Worker logging.basicConfig(level=logging.INFO, format=logging_format, 539*9e94795aSAndroid Build Coastguard Worker datefmt=date_format) 540*9e94795aSAndroid Build Coastguard Worker 541*9e94795aSAndroid Build Coastguard Worker logging.info("Unzipping the input target_files.zip: %s", args.target_files) 542*9e94795aSAndroid Build Coastguard Worker input_tmp = common.UnzipTemp(args.target_files) 543*9e94795aSAndroid Build Coastguard Worker 544*9e94795aSAndroid Build Coastguard Worker info_dict = common.LoadInfoDict(input_tmp) 545*9e94795aSAndroid Build Coastguard Worker with zipfile.ZipFile(args.target_files, 'r', allowZip64=True) as input_zip: 546*9e94795aSAndroid Build Coastguard Worker ValidateFileConsistency(input_zip, input_tmp, info_dict) 547*9e94795aSAndroid Build Coastguard Worker 548*9e94795aSAndroid Build Coastguard Worker CheckBuildPropDuplicity(input_tmp) 549*9e94795aSAndroid Build Coastguard Worker 550*9e94795aSAndroid Build Coastguard Worker ValidateInstallRecoveryScript(input_tmp, info_dict) 551*9e94795aSAndroid Build Coastguard Worker 552*9e94795aSAndroid Build Coastguard Worker ValidateVerifiedBootImages(input_tmp, info_dict, options) 553*9e94795aSAndroid Build Coastguard Worker 554*9e94795aSAndroid Build Coastguard Worker # TODO: Check if the OTA keys have been properly updated (the ones on /system, 555*9e94795aSAndroid Build Coastguard Worker # in recovery image). 556*9e94795aSAndroid Build Coastguard Worker 557*9e94795aSAndroid Build Coastguard Worker logging.info("Done.") 558*9e94795aSAndroid Build Coastguard Worker 559*9e94795aSAndroid Build Coastguard Worker 560*9e94795aSAndroid Build Coastguard Workerif __name__ == '__main__': 561*9e94795aSAndroid Build Coastguard Worker try: 562*9e94795aSAndroid Build Coastguard Worker main() 563*9e94795aSAndroid Build Coastguard Worker finally: 564*9e94795aSAndroid Build Coastguard Worker common.Cleanup() 565