def _process_secure_operation(self, image, progress, integrity_check, sign, encrypt, decrypt): # Create the encryptor object encdec = None if encrypt or decrypt: c_path.create_debug_dir(image.dest_image.debug_dir_encdec) encdec = get_encdec(image) # Create the parsegen object image.encdec = encdec parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, progress, True, image) # Set the security mechanisms parsegen.integrity_check = parsegen.contains_integrity_check() or integrity_check parsegen.sign = parsegen.is_signed() or sign parsegen.encrypt = parsegen.is_encrypted() or encrypt # If encrypt: if encrypt: parsegen.encryption_params = encdec.get_encryption_parameters_blob() # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # Sign the image if sign: self._status_updater(self._sign_image, image.status.sign, progress, True, image, parsegen) # Package and generate the output image file if integrity_check or sign or encrypt: store_data_to_file(image.dest_image.image_path, parsegen.get_data()) if integrity_check: image.status.integrity_check.state = StatusInfo.SUCCESS if encrypt: image.status.encrypt.state = StatusInfo.SUCCESS logger.info(('Signed ' if sign else '') + ('& ' if sign and encrypt else '') + ('Encrypted ' if encrypt else '') + 'image is stored at ' + image.dest_image.image_path) image.image_under_operation = image.dest_image.image_path # Do any post processing self._status_updater(self._post_process, image.status.postprocess, progress, True, image, image.config.post_process.pil_splitter, getattr(self._stager, '_meta_build_path', None)) # Print the image data logger.info('\n' + str(parsegen)) # Decrypt the image if decrypt: store_data_to_file(image.dest_image.decrypted_file, parsegen.get_data(encrypt=False))
def _sign(self, binary_to_sign, image_tosign_filename, cert_folder): c_path.create_dir(cert_folder) c_misc.store_data_to_file(image_tosign_filename, binary_to_sign) sig_package = signerutils.getSigPackage(cert_folder) if sig_package is not None: [signature, cert_chain_list] = signerutils.\ readSigFromZip(sig_package) if self.validate_sig(binary_to_sign, signature, cert_chain_list) is False: raise ExternalSignerError( self.MESG_INVALID_SIG.format(image_tosign_filename, sig_package)) else: raise ExternalSignerError( self.MESG_ASKUSERTOSIGN.format(image_tosign_filename, cert_folder)) signer_output = self._get_signer_output(signature, cert_chain_list) self._cleanup(cert_folder) return signer_output
def dump_parsegen_debug_data(self, image, parsegen): if image.dest_image.debug_dir_parsegen is None: return so = parsegen fp = image.dest_image from imageinfo import DestImagePath assert isinstance(fp, DestImagePath) debug_logs = [] try: debug_logs.append((so.get_data(False, False, False), fp.debug_file_parsegen_unsigned)) except Exception: pass try: debug_logs.append((so.data_to_sign, fp.debug_file_parsegen_tosign)) except Exception: pass try: debug_logs.append((so.cert_chain, fp.debug_file_parsegen_cert_chain)) except Exception: pass try: debug_logs.append((so.data_signature, fp.debug_file_parsegen_signature)) except Exception: pass try: debug_logs.append((so.get_data(True, False, False), fp.debug_file_parsegen_integrity_check)) except Exception: pass try: debug_logs.append((so.get_data(True, True, False), fp.debug_file_parsegen_signed)) except Exception: pass try: debug_logs.append((so.get_data(True, True, True), fp.debug_file_parsegen_encrypted)) except Exception: pass for data, debug_file in debug_logs: try: store_data_to_file(debug_file, data) except Exception: logger.debug2('Failed to save debug file ' + debug_file + '\n' ' ' + str(sys.exc_info()[1]))
def _sign(self, binary_to_sign, image_tosign_filename, cert_folder): c_path.create_dir(cert_folder) c_misc.store_data_to_file(image_tosign_filename, binary_to_sign) sig_package = signerutils.getSigPackage(cert_folder) if sig_package is not None: [signature, cert_chain_list] = signerutils.\ readSigFromZip(sig_package) if self.validate_sig(binary_to_sign, signature, cert_chain_list) is False: raise ExternalSignerError( self.MESG_INVALID_SIG. format(image_tosign_filename, sig_package)) else: raise ExternalSignerError( self.MESG_ASKUSERTOSIGN. format(image_tosign_filename, cert_folder)) signer_output = self._get_signer_output(signature, cert_chain_list) self._cleanup(cert_folder) return signer_output
def dump_signer_debug_data(self, image, sign_assets): if image.dest_image.debug_dir_signer is None: return c_path.create_debug_dir(image.dest_image.debug_dir_signer) sa = sign_assets fp = image.dest_image from imageinfo import DestImagePath assert isinstance(fp, DestImagePath) debug_logs = [ (sa.root_cert, fp.debug_file_signer_root_cert), (sa.attestation_ca_cert, fp.debug_file_signer_attestation_ca_cert), (sa.attestation_cert, fp.debug_file_signer_attestation_cert), (sa.signature, fp.debug_file_signer_signature), (sa.cert_chain, fp.debug_file_signer_cert_chain) ] # Save the private attributes too debug_logs += [ (sa.root_key, fp.debug_file_signer_root_key), (sa.attestation_ca_key, fp.debug_file_signer_attestation_ca_key), (sa.attestation_key, fp.debug_file_signer_attestation_key) ] for data, debug_file in debug_logs: try: store_data_to_file(debug_file, data) except Exception: logger.debug2('Failed to save debug file ' + debug_file + '\n' ' ' + str(sys.exc_info()[1]))
def dump_parsegen_debug_data(self, image, parsegen): if image.dest_image.debug_dir_parsegen is None: return so = parsegen fp = image.dest_image from imageinfo import DestImagePath assert isinstance(fp, DestImagePath) debug_logs = [] try: debug_logs.append((so.get_data(False, False, False), fp.debug_file_parsegen_unsigned)) except Exception: pass try: debug_logs.append((so.data_to_sign, fp.debug_file_parsegen_tosign)) except Exception: pass try: debug_logs.append((so.cert_chain, fp.debug_file_parsegen_cert_chain)) except Exception: pass try: debug_logs.append((so.data_signature, fp.debug_file_parsegen_signature)) except Exception: pass try: debug_logs.append((so.get_data(True, False, False), fp.debug_file_parsegen_integrity_check)) except Exception: pass try: debug_logs.append((so.get_data(True, True, False), fp.debug_file_parsegen_signed)) except Exception: pass try: debug_logs.append((so.get_data(True, True, True), fp.debug_file_parsegen_encrypted)) except Exception: pass for data, debug_file in debug_logs: try: store_data_to_file(debug_file, data) except Exception: logger.debug2('Failed to save debug file ' + debug_file + '\n' ' ' + str(sys.exc_info()[1]))
def _pil_split(self, src, prefix): from sectools.common.parsegen.elf.format import ParseGenElf, pack_phdrs, PF_OS_SEGMENT_HASH # Load the data p_obj = ParseGenElf(load_data_from_file(src)) # File names elfhdr = prefix + '.mdt' # Cleanup for eachpattern in [elfhdr, (prefix + '.b*')]: import glob for eachfile in glob.glob(eachpattern): try: os.remove(eachfile) except Exception: pass # Create the mdt data elfdata = p_obj.ehdr.pack() + pack_phdrs(p_obj.phdrs) # Dump the segments for idx, phdr in enumerate(p_obj.phdrs): path = prefix + ('.b%02d' % idx) store_data_to_file(path, p_obj.segments[phdr]) if phdr.f_os_segment_type == PF_OS_SEGMENT_HASH: elfdata += p_obj.segments[phdr] # Dump the final elfhdr mdt store_data_to_file(elfhdr, elfdata)
def pil_split(src, prefix): from sectools.common.parsegen.elf.format import ParseGenElf, pack_phdrs, PF_OS_SEGMENT_HASH # Load the data p_obj = ParseGenElf(load_data_from_file(src)) # File names elfhdr = prefix + '.mdt' # Cleanup for eachpattern in [elfhdr, (prefix + '.b*')]: import glob for eachfile in glob.glob(eachpattern): try: os.remove(eachfile) except Exception: pass # Create the mdt data elfdata = p_obj.ehdr.pack() + pack_phdrs(p_obj.phdrs) # Dump the segments for idx, phdr in enumerate(p_obj.phdrs): path = prefix + ('.b%02d' % idx) store_data_to_file(path, p_obj.segments[phdr]) if phdr.f_os_segment_type == PF_OS_SEGMENT_HASH: elfdata += p_obj.segments[phdr] # Dump the final elfhdr mdt store_data_to_file(elfhdr, elfdata)
def _saveResultToFile(self, filename): result = self.getResult() path, file = os.path.split(filename) if not os.path.exists(path): os.makedirs(path) c_misc.store_data_to_file(filename, result)
def _saveResultToFile(self, filename): result = self.getResult() path, file = os.path.split(filename) if not os.path.exists(path): os.makedirs(path) c_misc.store_data_to_file(filename, result)
def save(self): if self.status_code != "1": raise ExternalSignerError( "Error returned from signature response:\n{0}".format( self._get_tag("Error").text)) result = self._get_result() path, f = os.path.split(self.signature_result_file) if not os.path.exists(path): os.makedirs(path) c_misc.store_data_to_file(self.signature_result_file, result)
def dump_signer_debug_data(self, image, sign_assets, parsegen): if image.dest_image.debug_dir_signer is None: return c_path.create_debug_dir(image.dest_image.debug_dir_signer) sa = sign_assets fp = image.dest_image from imageinfo import DestImagePath assert isinstance(fp, DestImagePath) # Backup parsegen authority authority = parsegen.authority # QTI Signature and Cert Chain parsegen.authority = defines.AUTHORITY_QTI data_signature_qti = parsegen.data_signature cert_chain_qti = parsegen.cert_chain # OEM Signature and Cert Chain parsegen.authority = defines.AUTHORITY_OEM data_signature = parsegen.data_signature cert_chain = parsegen.cert_chain # Restore authority parsegen.authority = authority debug_logs = [ (sa.root_cert, fp.debug_file_signer_root_cert), (sa.attestation_ca_cert, fp.debug_file_signer_attestation_ca_cert), (sa.attestation_cert, fp.debug_file_signer_attestation_cert), (data_signature, fp.debug_file_signer_signature), (cert_chain, fp.debug_file_signer_cert_chain), (data_signature_qti, fp.debug_file_signer_qti_signature), (cert_chain_qti, fp.debug_file_signer_qti_cert_chain) ] # Save the private attributes too debug_logs += [ (sa.root_key, fp.debug_file_signer_root_key), (sa.attestation_ca_key, fp.debug_file_signer_attestation_ca_key), (sa.attestation_key, fp.debug_file_signer_attestation_key) ] for data, debug_file in debug_logs: try: store_data_to_file(debug_file, data) except Exception: logger.debug2('Failed to save debug file ' + debug_file + '\n' ' ' + str(sys.exc_info()[1]))
def dump_debug_secdat(self, secdat_parser, path): """Dumps the secdat related debug data into the output directory. :param obj secdat_parser: Parser to dump debug info for """ if not self.debug: return try: debug_dir = c_path.join(path, defines.DEST_DEBUG_DIR) c_path.create_dir(debug_dir) secdat_repr_log = c_path.join(debug_dir, defines.DEST_DEBUG_FILE_SECDAT_REPR) store_data_to_file(secdat_repr_log, repr(secdat_parser)) logger.info('Dumped debug secdat repr at: ' + secdat_repr_log + ', date & time: ' + datetime.datetime.now().strftime('%c')) except Exception as e: logger.warning('Failed to store debug logs: ' + str(e))
def dump_debug_data_model(self, data_model, path): """Dumps the data model related debug data into the output directory. :param obj data_model: Data model to dump debug info for """ if not self.debug: return try: debug_dir = c_path.join(path, defines.DEST_DEBUG_DIR) c_path.create_dir(debug_dir) debug_file = c_path.join(debug_dir, defines.DEST_DEBUG_FILE_DATA_MODEL_REPR.format(self.TOOL_NAME)) store_data_to_file(debug_file, repr(data_model)) logger.info('Dumped debug data model repr at: ' + debug_file + ', date & time: ' + datetime.datetime.now().strftime('%c')) except Exception as e: logger.warning('Failed to store debug logs: ' + str(e))
def get_metabuild_log(self): data = [] logdir = os.path.dirname(self.log) ufc_log = c_path.join(logdir, UFC_LOG) regenerate_log = c_path.join(logdir, REGENERATE_BUID_LOG) buildloading_log = c_path.join(logdir, FASTBOOT_COMPLETE_LOG) metabuild_log = c_path.join(logdir, META_BUILD_LOG) # remove meta build log from previous session if c_path.validate_file(metabuild_log): os.remove(metabuild_log) data.append('Meta build log:\n') if c_path.validate_file(ufc_log): data.append(SECTION_BREAK) data.append('Step 1: UltraFastCopy meta build') data.append('Meta Build: ' + self.meta_build_path) data.append(SECTION_BREAK) data.append(load_data_from_file(ufc_log)) else: data.append('meta build copy skipped') data.append(SECTION_BREAK) if c_path.validate_file(regenerate_log): data.append(SECTION_BREAK) data.append('Step 2: Meta build regeneration') data.append('Meta Build: ' + logdir) data.append('Image Build:' + self.image_build_path) data.append(SECTION_BREAK) data.append(load_data_from_file(regenerate_log)) else: data.append('meta build regeneration skipped') data.append(SECTION_BREAK) if c_path.validate_file(buildloading_log): data.append(SECTION_BREAK) data.append('Step 3: Meta build loading') data.append('Meta Build: ' + logdir) data.append(SECTION_BREAK) data.append(load_data_from_file(buildloading_log)) store_data_to_file(metabuild_log, "\n".join(data)) return metabuild_log
def dump_signer_debug_data(self, image, sign_assets): if image.dest_image.debug_dir_signer is None: return sa = sign_assets fp = image.dest_image from imageinfo import DestImagePath assert isinstance(fp, DestImagePath) debug_logs = [(sa.root_cert, fp.debug_file_signer_root_cert), (sa.attestation_ca_cert, fp.debug_file_signer_attestation_ca_cert), (sa.attestation_cert, fp.debug_file_signer_attestation_cert), (sa.attestation_key, fp.debug_file_signer_attestation_key), (sa.signature, fp.debug_file_signer_signature), (sa.cert_chain, fp.debug_file_signer_cert_chain)] for data, debug_file in debug_logs: try: store_data_to_file(debug_file, data) except Exception: logger.debug2('Failed to save debug file ' + debug_file + '\n' ' ' + str(sys.exc_info()[1]))
def dump_signer_debug_data(self, image, sign_assets, parsegen, more_debug_logs=[]): if image.dest_image.debug_dir_signer is None: return c_path.create_debug_dir(image.dest_image.debug_dir_signer) sa = sign_assets fp = image.dest_image assert isinstance(fp, self.dest_image_path_class) # Backup parsegen authority authority = parsegen.authority # OEM Signature and Cert Chain parsegen.authority = AUTHORITY_OEM data_signature = parsegen.data_signature cert_chain = parsegen.cert_chain # Restore authority parsegen.authority = authority debug_logs = [(sa.root_cert, fp.debug_file_signer_root_cert), (sa.attestation_ca_cert, fp.debug_file_signer_attestation_ca_cert), (sa.attestation_cert, fp.debug_file_signer_attestation_cert), (data_signature, fp.debug_file_signer_signature), (cert_chain, fp.debug_file_signer_cert_chain)] for dbg_log in more_debug_logs: debug_logs.append((dbg_log[0], getattr(fp, dbg_log[1]))) # Save the private attributes too debug_logs += [(sa.root_key, fp.debug_file_signer_root_key), (sa.attestation_ca_key, fp.debug_file_signer_attestation_ca_key), (sa.attestation_key, fp.debug_file_signer_attestation_key)] for data, debug_file in debug_logs: try: store_data_to_file(debug_file, data) except Exception: logger.debug2('Failed to save debug file ' + debug_file + '\n' ' ' + str(sys.exc_info()[1]))
def process(self, verify_setup=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_sign=False, val_encrypt=False, progress_cb=PROGRESS_CB_PYPASS): """Performs the secure-image related operations specified from the params. :param bool verify_setup: Verify that the configuration of the object is correct and return. This will ignore any other params. :param bool sign: Sign the images. (Re-sign if image is already signed) :param bool encrypt: Encrypt the images. (Re-encrypt if image is already encrypted) :param bool val_image: Validate the integrity of the image against the config file. :param bool val_sign: Validate that the image is signed and validate the integrity of the signing related data. :param bool val_encrypt: Validate that the image is encrypted and validate the integrity of the encryption related data. :param cb progress_cb: Callback method to get a status update during processing. Callback method should have this format: :: def progress_cb(status_string, progress_percent): \""" :param str status_string: the current status. :param int progress_percent: the progress (in percent) \""" ... """ # Ensure that one or more image files is provided for processing if self._stager is None or not self.image_path_list: raise RuntimeError( 'Please specify one or more images for processing') # Ensure the correct set of operations is provided if not (verify_setup or sign or encrypt or val_image or val_sign or val_encrypt or decrypt): raise RuntimeError( 'Please specify one or more operations to perform.') if verify_setup: logger.note('The inputs provided (config, cmd args) are valid.') return # Start processing images total_images = len(self.image_info_list) progress = ProgressNotifier(total_images, progress_cb, PROGRESS_TOTAL_STAGES) for idx, image in enumerate(self.image_info_list): assert isinstance(image, ImageInfo) logger.info( '------------------------------------------------------') status_string = ('Processing ' + str(idx + 1) + '/' + str(total_images) + ': ' + image.image_under_operation) logger.info(status_string + '\n') # Send a progress notification to the toplevel progress.status = status_string progress.cur = idx progress.cur_stage = 0 try: # Create the required directory structure for this image image_output_dir = image.dest_image.image_dir try: c_path.create_dir(image_output_dir) except Exception as e: raise RuntimeError('Could not create output directory: ' + image_output_dir + '\n' ' ' + 'Error: ' + str(e)) # Enable/Disable debug image.dest_image.debug_enable = self.debug c_path.create_debug_dir(image.dest_image.debug_dir) # Create the encryptor object if encrypt or decrypt or val_encrypt: try: c_path.create_debug_dir( image.dest_image.debug_dir_encdec) encdec = get_encdec(image) except Exception: if not val_encrypt: raise else: encdec = None # Create the parsegen object image.encdec = encdec parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, image) progress.push() # Set the security mechanisms parsegen.sign = parsegen.is_signed() or sign parsegen.encrypt = parsegen.is_encrypted() or encrypt # If encrypt: if encrypt: parsegen.encryption_params = encdec.get_encryption_parameters_blob( ) # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # Sign the image if sign: self._status_updater(self._sign_image, image.status.sign, image, parsegen) progress.push() # Package and generate the output file if sign or encrypt: store_data_to_file(image.dest_image.image_path, parsegen.get_data()) if encrypt: image.status.encrypt.state = StatusInfo.SUCCESS logger.info(('Signed ' if sign else '') + ('& ' if sign and encrypt else '') + ('Encrypted ' if encrypt else '') + 'image is stored at ' + image.dest_image.image_path) image.image_under_operation = image.dest_image.image_path # Do any post processing self._status_updater( self._post_process, image.status.postprocess, image, image.config.post_process.pil_splitter, getattr(self._stager, '_meta_build_path', None)) progress.push() # Print the image data logger.info('\n' + str(parsegen)) # Decrypt the image if decrypt: store_data_to_file(image.dest_image.decrypted_file, parsegen.get_data(encrypt=False)) # Validate parsegen if val_image: self._validate_parsegen(image, parsegen) progress.push() # Validate sign if val_sign: self._validate_sign(image, parsegen) progress.push() # Validate encrypt if val_encrypt: self._validate_encrypt(image, parsegen) progress.push() # Set overall processing to true image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.debug(traceback.format_exc()) logger.error(sys.exc_info()[1]) logger.info( '------------------------------------------------------\n') progress.complete()
def generate(self, sign_id=None): """Generate the debugpolicy elf file based on the configs which have been setup. """ # Set the debug params if self.debug: debug_dir = c_path.join(self.output_dir, defines.DEST_DEBUG_DIR) debug_prefix, debug_suffix = os.path.splitext( os.path.basename(c_path.join(self.output_dir, 'dp.dat'))) else: debug_dir, debug_prefix, debug_suffix = None, None, None dbgpelfparser = ParseGenDbgpElf( version=self._config_parser.root.file_properties.revision, debug_dir=debug_dir, debug_prefix=debug_prefix, debug_suffix=debug_suffix, elf_class=self._config_parser.root.file_properties.elf.elf_class) # Set version number to be revision number dbgpelfparser.dbgpparser.header.version = self._config_parser.root.file_properties.revision # Set serial number start and end values if not (self._config_parser.root.file_properties.serial_number_start is None or \ self._config_parser.root.file_properties.serial_number_end is None): self.versionAttrCheck(dbgpelfparser.dbgpparser.header, "set_sernum", ["serial_number_start", "serial_number_end"]) dbgpelfparser.dbgpparser.header.set_sernum( self._config_parser.root.file_properties.serial_number_start, self._config_parser.root.file_properties.serial_number_end) # Validate flag bits and set flags self.flagBitsCheck(dbgpelfparser.dbgpparser.header.INVALID_FLAG_BITS, self._config_parser.root.file_properties.flags) dbgpelfparser.dbgpparser.header.flags = self._config_parser.root.file_properties.flags # Set imagebit_map if self._config_parser.root.file_properties.image_bit_map is not None: self.versionAttrCheck(dbgpelfparser.dbgpparser.header, "imagebit_map", "image_bit_map") dbgpelfparser.dbgpparser.header.imagebit_map = self._config_parser.root.file_properties.image_bit_map # Set Image ID Info if self._config_parser.root.file_properties.image_id_list is not None: self.versionAttrCheck(dbgpelfparser.dbgpparser.header, "imgid_array", "image_id_list") dbgpelfparser.dbgpparser.header.imgid_array = self._config_parser.root.file_properties.image_id_list.image_id # Initialize rootcerthash array dbgpelfparser.dbgpparser.header.rootcerthash_array = self._config_parser.root.file_properties.root_cert_hash_list.root_cert_hash # Set Serial Num List if self._config_parser.root.file_properties.serial_num_list is not None: self.versionAttrCheck(dbgpelfparser.dbgpparser.header, "serial_num_array", "serial_num_list") dbgpelfparser.dbgpparser.header.serial_num_array = self._config_parser.root.file_properties.serial_num_list.serial_num # Initialize rootcerthash_qc array if self._config_parser.root.file_properties.root_cert_hash_qc_list is not None: self.versionAttrCheck(dbgpelfparser.dbgpparser.header, "rootcerthash_qc_array", "root_cert_hash_qc_list") dbgpelfparser.dbgpparser.header.rootcerthash_qc_array = self._config_parser.root.file_properties.root_cert_hash_qc_list.root_cert_hash_qc # Set physical address dbgpelfparser.phys_addr = self._config_parser.root.file_properties.elf.phys_addr # Validate header version contents dbgpelfparser.dbgpparser.header.validate_ranges() dbgpelf_data = dbgpelfparser.get_data() dp_unsigned = c_path.join(self.output_dir, 'dp_unsigned.mbn') store_data_to_file(dp_unsigned, dbgpelf_data) logger.info('Generated unsigned debugpolicy elf file at: ' + dp_unsigned + ', date & time: ' + datetime.datetime.now().strftime('%c')) dp_unsigned_repr = c_path.join(self.output_dir, 'dbgpelf_repr.txt') store_data_to_file(dp_unsigned_repr, repr(dbgpelfparser)) logger.info('Dumped debugpolicy elf repr at: ' + dp_unsigned_repr + ', date & time: ' + datetime.datetime.now().strftime('%c')) self.sign(dp_unsigned, sign_id)
def _process_secure_operation(self, image, progress, security_policy_list, i_integrity_check, i_sign, idx=0, parsegens=None): # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError('Security policy list length must be more than index.') # Get the current security policy file_type = security_policy_list[idx].file_type integrity_check = security_policy_list[idx].integrity_check and i_integrity_check sign = security_policy_list[idx].sign and i_sign # Create the parsegen object file_type_backup = image.image_type.file_type image.image_type.file_type = file_type try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, progress, True, image, validating=False, signing=sign, parsegens=parsegens) finally: image.image_type.file_type = file_type_backup # Set the security mechanisms parsegen.integrity_check = security_policy_list[idx].integrity_check and (parsegen.contains_integrity_check() or integrity_check) parsegen.sign = security_policy_list[idx].sign and (parsegen.is_signed() or sign) # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: tmp_file_path = c_path.create_tmp_file(data=parsegen.get_wrapped_data()) # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name image.src_image.image_dir_base = os.path.dirname(tmp_file_path) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename(tmp_file_path) try: data = self._process_secure_operation(image, progress, security_policy_list, i_integrity_check, i_sign, idx=idx + 1) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name os.remove(tmp_file_path) parsegen.set_wrapped_data(data) # Sign the image if sign: self._status_updater(self._sign_image, image.status.sign, progress, True, image, parsegen) # Package and generate the output image file data = parsegen.get_data() if integrity_check: image.status.integrity_check.state = StatusInfo.SUCCESS if idx != 0: return data store_data_to_file(image.dest_image.image_path, data) logger.info(('Signed ' if parsegen.sign else '') + 'image is stored at ' + image.dest_image.image_path, color=logger.GREEN) image.image_under_operation = image.dest_image.image_path return parsegen
def write_to_file(self, file_path, version, hdr_info=None): store_data_to_file(file_path, self.get_data(version, hdr_info))
def _process_validation(self, image, progress, security_policy_list, i_val_image, i_val_integrity_check, i_val_sign, i_val_encrypt, idx=0): # TODO: Need to figure how to do this #image.dest_image._mid = 'validation' # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError( 'Security policy list length must be more than index.') # Get the current security policy file_type = security_policy_list[idx].file_type val_image = i_val_image val_integrity_check = security_policy_list[ idx].integrity_check and i_val_integrity_check val_sign = security_policy_list[idx].sign and i_val_sign val_encrypt = security_policy_list[idx].encrypt and i_val_encrypt # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name # Update the souce image path image.src_image.image_dir_base = os.path.dirname( image.image_under_operation) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename( image.image_under_operation) try: # Create the encryptor object encdec = None if val_encrypt and image.general_properties.selected_encryptor: c_path.create_debug_dir(image.dest_image.debug_dir_encdec) encdec = get_encdec(image) # Create the parsegen object file_type_backup = image.image_type.file_type encdec_backup = image.encdec image.image_type.file_type = file_type image.encdec = encdec try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.validate_parsegen, progress, True, image) finally: image.image_type.file_type = file_type_backup image.encdec = encdec_backup # Set the security mechanisms parsegen.integrity_check = parsegen.contains_integrity_check() parsegen.sign = parsegen.is_signed() parsegen.encrypt = parsegen.is_encrypted() # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # Validate parsegen if val_image: self._status_updater(self._validate_parsegen, image.status.validate_parsegen, progress, False, image, parsegen) # Validate integrity check if val_integrity_check: self._status_updater(self._validate_integrity_check, image.status.validate_integrity_check, progress, False, image, parsegen) # Validate sign if val_sign: self._status_updater(self._validate_sign, image.status.validate_sign, progress, False, image, parsegen) # Validate encrypt if val_encrypt: self._status_updater(self._validate_encrypt, image.status.validate_encrypt, progress, False, image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: data = parsegen.get_wrapped_data() import tempfile tmp_fd = tempfile.NamedTemporaryFile(delete=False) tmp_fd.close() store_data_to_file(tmp_fd.name, data) # Backup the image_under_operation here image_under_operation_int = image.image_under_operation image.image_under_operation = tmp_fd.name try: self._process_validation(image, progress, security_policy_list, i_val_image, i_val_integrity_check, i_val_sign, i_val_encrypt, idx + 1) finally: image.image_under_operation = image_under_operation_int os.remove(tmp_fd.name) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name return parsegen
def _process_validation(self, image, progress, security_policy_list, i_val_image, i_val_integrity_check, i_val_sign, i_val_encrypt, idx=0): # TODO: Need to figure how to do this #image.dest_image._mid = 'validation' # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError('Security policy list length must be more than index.') # Get the current security policy file_type = security_policy_list[idx].file_type val_image = i_val_image val_integrity_check = security_policy_list[idx].integrity_check and i_val_integrity_check val_sign = security_policy_list[idx].sign and i_val_sign val_encrypt = security_policy_list[idx].encrypt and i_val_encrypt # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name # Update the souce image path image.src_image.image_dir_base = os.path.dirname(image.image_under_operation) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename(image.image_under_operation) try: # Create the encryptor object encdec = None if val_encrypt: c_path.create_debug_dir(image.dest_image.debug_dir_encdec) encdec = get_encdec(image) # Create the parsegen object file_type_backup = image.image_type.file_type encdec_backup = image.encdec image.image_type.file_type = file_type image.encdec = encdec try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.validate_parsegen, progress, True, image) finally: image.image_type.file_type = file_type_backup image.encdec = encdec_backup # Set the security mechanisms parsegen.integrity_check = parsegen.contains_integrity_check() parsegen.sign = parsegen.is_signed() parsegen.encrypt = parsegen.is_encrypted() # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # Validate parsegen if val_image: self._status_updater(self._validate_parsegen, image.status.validate_parsegen, progress, False, image, parsegen) # Validate integrity check if val_integrity_check: self._status_updater(self._validate_integrity_check, image.status.validate_integrity_check, progress, False, image, parsegen) # Validate sign if val_sign: self._status_updater(self._validate_sign, image.status.validate_sign, progress, False, image, parsegen) # Validate encrypt if val_encrypt: self._status_updater(self._validate_encrypt, image.status.validate_encrypt, progress, False, image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: data = parsegen.get_wrapped_data() import tempfile tmp_fd = tempfile.NamedTemporaryFile(delete=False) tmp_fd.close() store_data_to_file(tmp_fd.name, data) # Backup the image_under_operation here image_under_operation_int = image.image_under_operation image.image_under_operation = tmp_fd.name try: self._process_validation(image, progress, security_policy_list, i_val_image, i_val_integrity_check, i_val_sign, i_val_encrypt, idx + 1) finally: image.image_under_operation = image_under_operation_int os.remove(tmp_fd.name) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name return parsegen
def _process_secure_operation(self, image, progress, security_policy_list, sign_attr, i_integrity_check, i_sign, i_encrypt, i_decrypt, idx=0, prefix_override=None): from imageinfo import ImageInfo, StatusInfo # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError( 'Security policy list length must be more than index.') # Get the current security policy file_type = security_policy_list[idx].file_type integrity_check = security_policy_list[ idx].integrity_check and i_integrity_check sign = security_policy_list[idx].sign and i_sign encrypt = security_policy_list[idx].encrypt and i_encrypt decrypt = security_policy_list[idx].encrypt and i_decrypt # Create the encryptor object encdec = None if image.general_properties.selected_encryptor: c_path.create_debug_dir(image.dest_image.debug_dir_encdec) encdec = get_encdec(image, False) # Create the parsegen object file_type_backup = image.image_type.file_type encdec_backup = image.encdec image.image_type.file_type = file_type image.encdec = encdec try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, progress, True, image, False, sign, prefix_override, sign_attr) finally: image.image_type.file_type = file_type_backup image.encdec = encdec_backup # Validate the authority settings self.validate_authority_settings( self.authority, image.general_properties.secboot_version, image.general_properties.qti_sign, image.general_properties.oem_sign, image.general_properties.num_root_certs, encrypt) # Do not allow signed unencrypted elf images to be encrypted as the # Sign will not longer match the encrypted image's tosign if parsegen.file_type() == 'elf' and parsegen.is_signed( ) and not sign and not parsegen.is_encrypted() and encrypt: raise RuntimeError( 'Cannot encrypt a signed unencrypted image without resigning ' 'as the sign no longer matches the format change.') # Set the security mechanisms parsegen.integrity_check = security_policy_list[ idx].integrity_check and (parsegen.contains_integrity_check() or integrity_check) parsegen.sign = security_policy_list[idx].sign and ( parsegen.is_signed() or sign) parsegen.encrypt = security_policy_list[idx].encrypt and ( False if decrypt else (parsegen.is_encrypted() or encrypt)) # Get blob if populating encryption parameters: if encrypt: if encdec is None: raise RuntimeError('Encryptor is not set') parsegen.encryption_params = encdec.get_encryption_parameters_blob( ) # check if input image is a TA, if yes re-initialize encdec object with updated bitmap for manifest segment if is_TA(image.signing_attributes.sw_id): non_encrypt_segment_found, encrypted_segments_indices = self._get_encrypted_segments_index_list( parsegen._elf_parsegen.phdrs) if non_encrypt_segment_found and len( encrypted_segments_indices) > 0: logger.info( "Re-initializing encdec object for updated segment bitmap" ) encdec = get_encdec(image, False, encrypted_segments_indices) parsegen.encryption_params = encdec.get_encryption_parameters_blob( ) parsegen.encdec = encdec elif parsegen.encryption_params and parsegen.encdec is not None: parsegen.encdec.update_encryption_parameters( parsegen.encryption_params) # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: data = parsegen.get_wrapped_data() import tempfile tmp_fd = tempfile.NamedTemporaryFile(delete=False) tmp_fd.close() store_data_to_file(tmp_fd.name, data) # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name image.src_image.image_dir_base = os.path.dirname(tmp_fd.name) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename(tmp_fd.name) # Override debug dumped file prefix prefix_override = SecImageCore._get_prefix_override( prefix_override, file_type) try: data = self._process_secure_operation( image, progress, security_policy_list, sign_attr, i_integrity_check, i_sign, i_encrypt, i_decrypt, idx + 1, prefix_override) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name os.remove(tmp_fd.name) parsegen.set_wrapped_data(data) # Sign the image if sign: self._status_updater(self._sign_image, image.status.sign, progress, True, image, parsegen) # Package and generate the output image file data = parsegen.get_data() if integrity_check: image.status.integrity_check.state = StatusInfo.SUCCESS if encrypt: image.status.encrypt.state = StatusInfo.SUCCESS if idx != 0: return data if decrypt: encryption_params_backup = parsegen.encryption_params parsegen.encryption_params = '' try: store_data_to_file(image.dest_image.decrypted_file, parsegen.get_data()) finally: parsegen.encryption_params = encryption_params_backup else: store_data_to_file(image.dest_image.image_path, data) logger.info(('Signed ' if sign else '') + ('& ' if sign and encrypt else '') + ('Encrypted ' if encrypt else '') + 'image is stored at ' + image.dest_image.image_path) image.image_under_operation = image.dest_image.image_path # Do any post processing self._status_updater(self._post_process, image.status.postprocess, progress, True, image, image.config.post_process.pil_splitter, getattr(self._stager, '_meta_build_path', None)) return parsegen
def _process_validation(self, image, progress, security_policy_list, i_val_image, i_val_integrity_check, i_val_sign, i_val_encrypt, idx=0, prefix_override=None): # TODO: Need to figure how to do this #image.dest_image._mid = 'validation' # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError( 'Security policy list length must be more than index.') # Get the current security policy file_type = security_policy_list[idx].file_type val_image = i_val_image val_integrity_check = security_policy_list[ idx].integrity_check and i_val_integrity_check val_sign = security_policy_list[idx].sign and i_val_sign val_encrypt = security_policy_list[idx].encrypt and i_val_encrypt # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name # Update the souce image path image.src_image.image_dir_base = os.path.dirname( image.image_under_operation) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename( image.image_under_operation) try: # Create the encryptor object encdec = None if image.general_properties.selected_encryptor: c_path.create_debug_dir(image.dest_image.debug_dir_encdec) encdec = get_encdec(image, True) # Create the parsegen object file_type_backup = image.image_type.file_type encdec_backup = image.encdec image.image_type.file_type = file_type image.encdec = encdec try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.validate_parsegen, progress, True, image, True, False, prefix_override) finally: image.image_type.file_type = file_type_backup image.encdec = encdec_backup # Validate the authority settings self.validate_authority_settings( self.authority, image.general_properties.secboot_version, image.general_properties.qti_sign, image.general_properties.oem_sign, image.general_properties.num_root_certs, parsegen.is_encrypted()) # Prevent validation when using an encrypted key provider from sectools.features.isc.encryption_service.unified import encrypted_key_provider_id_supported encrypted_key_provider_id = image.signing_attributes.UIE_key if parsegen.is_encrypted() and encrypted_key_provider_id_supported( encrypted_key_provider_id): raise RuntimeError( "The image is encrypted. Validation is not supported when using an encrypted key provider.\n" "Try again with validation disabled.") # Set the security mechanisms parsegen.integrity_check = parsegen.contains_integrity_check() parsegen.sign = parsegen.is_signed() parsegen.encrypt = parsegen.is_encrypted() # Validate parsegen if val_image: self._status_updater(self._validate_parsegen, image.status.validate_parsegen, progress, False, image, parsegen) # Validate integrity check if val_integrity_check: self._status_updater(self._validate_integrity_check, image.status.validate_integrity_check, progress, False, image, parsegen) # Validate sign if val_sign: self._status_updater(self._validate_sign, image.status.validate_sign, progress, False, image, parsegen) # Validate encrypt if val_encrypt: self._status_updater(self._validate_encrypt, image.status.validate_encrypt, progress, False, image, parsegen) # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: data = parsegen.get_wrapped_data() import tempfile tmp_fd = tempfile.NamedTemporaryFile( prefix=security_policy_list[idx + 1].file_type, delete=False) tmp_fd.close() store_data_to_file(tmp_fd.name, data) # Backup the image_under_operation here image_under_operation_int = image.image_under_operation image.image_under_operation = tmp_fd.name # Override debug dumped file prefix prefix_override = SecImageCore._get_prefix_override( prefix_override, file_type) try: self._process_validation(image, progress, security_policy_list, i_val_image, i_val_integrity_check, i_val_sign, i_val_encrypt, idx + 1, prefix_override) finally: image.image_under_operation = image_under_operation_int os.remove(tmp_fd.name) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name return parsegen
def _process_secure_operation(self, image, progress, security_policy_list, i_integrity_check, i_sign, i_encrypt, i_decrypt, idx=0): from imageinfo import ImageInfo, StatusInfo # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError( 'Security policy list length must be more than index.') # Get the current security policy file_type = security_policy_list[idx].file_type integrity_check = security_policy_list[ idx].integrity_check and i_integrity_check sign = security_policy_list[idx].sign and i_sign encrypt = security_policy_list[idx].encrypt and i_encrypt decrypt = security_policy_list[idx].encrypt and i_decrypt # Create the encryptor object encdec = None if encrypt or decrypt: c_path.create_debug_dir(image.dest_image.debug_dir_encdec) encdec = get_encdec(image) # Create the parsegen object file_type_backup = image.image_type.file_type encdec_backup = image.encdec image.image_type.file_type = file_type image.encdec = encdec try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, progress, True, image) finally: image.image_type.file_type = file_type_backup image.encdec = encdec_backup # Do not allow signed unencrypted elf images to be encrypted as the # Sign will not longer match the encrypted image's tosign if parsegen.file_type() == 'elf' and parsegen.is_signed( ) and not sign and not parsegen.is_encrypted() and encrypt: raise RuntimeError( 'Cannot encrypt a signed unencrypted image without resigning ' 'as the sign no longer matches the format change.') # Set the security mechanisms parsegen.integrity_check = security_policy_list[ idx].integrity_check and (parsegen.contains_integrity_check() or integrity_check) parsegen.sign = security_policy_list[idx].sign and ( parsegen.is_signed() or sign) parsegen.encrypt = security_policy_list[idx].encrypt and ( False if decrypt else (parsegen.is_encrypted() or encrypt)) # If encrypt: if encrypt: parsegen.encryption_params = encdec.get_encryption_parameters_blob( ) # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: data = parsegen.get_wrapped_data() import tempfile tmp_fd = tempfile.NamedTemporaryFile(delete=False) tmp_fd.close() store_data_to_file(tmp_fd.name, data) # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name image.src_image.image_dir_base = os.path.dirname(tmp_fd.name) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename(tmp_fd.name) try: data = self._process_secure_operation(image, progress, security_policy_list, i_integrity_check, i_sign, i_encrypt, i_decrypt, idx + 1) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name os.remove(tmp_fd.name) parsegen.set_wrapped_data(data) # Sign the image if sign: self._status_updater(self._sign_image, image.status.sign, progress, True, image, parsegen) # Package and generate the output image file data = parsegen.get_data() if integrity_check: image.status.integrity_check.state = StatusInfo.SUCCESS if encrypt: image.status.encrypt.state = StatusInfo.SUCCESS if idx != 0: return data if decrypt: ecryption_params_backup = parsegen.encryption_params parsegen.encryption_params = '' try: store_data_to_file(image.dest_image.decrypted_file, parsegen.get_data()) finally: parsegen.encryption_params = ecryption_params_backup else: store_data_to_file(image.dest_image.image_path, data) logger.info(('Signed ' if sign else '') + ('& ' if sign and encrypt else '') + ('Encrypted ' if encrypt else '') + 'image is stored at ' + image.dest_image.image_path) image.image_under_operation = image.dest_image.image_path # Do any post processing self._status_updater(self._post_process, image.status.postprocess, progress, True, image, image.config.post_process.pil_splitter, getattr(self._stager, '_meta_build_path', None)) return parsegen
def _create_parsegen(self, image, progress, security_policy_list, idx=0): # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError('Security policy list length must be more than index.') file_type = security_policy_list[idx].file_type # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name # Update the souce image path image.src_image.image_dir_base = os.path.dirname(image.image_under_operation) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename(image.image_under_operation) try: # Create the parsegen object file_type_backup = image.image_type.file_type image.image_type.file_type = file_type try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, progress, True, image, validating=False, signing=False) finally: image.image_type.file_type = file_type_backup # Set the security mechanisms parsegen.integrity_check = parsegen.contains_integrity_check() parsegen.sign = parsegen.is_signed() # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: data = parsegen.get_wrapped_data() tmp_fd = tempfile.NamedTemporaryFile(prefix=security_policy_list[idx + 1].file_type, delete=False) tmp_fd.close() store_data_to_file(tmp_fd.name, data) # Backup the image_under_operation here image_under_operation_int = image.image_under_operation image.image_under_operation = tmp_fd.name try: self._create_parsegen(image, progress, security_policy_list, idx + 1) finally: image.image_under_operation = image_under_operation_int os.remove(tmp_fd.name) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name return parsegen
def _process_secure_operation(self, image, progress, security_policy_list, i_integrity_check, i_sign, i_encrypt, i_decrypt, idx=0): # Check bounds if len(security_policy_list) == 0: raise RuntimeError('Security policy list must not be empty.') elif len(security_policy_list) <= idx: raise RuntimeError('Security policy list length must be more than index.') # Get the current security policy file_type = security_policy_list[idx].file_type integrity_check = security_policy_list[idx].integrity_check and i_integrity_check sign = security_policy_list[idx].sign and i_sign encrypt = security_policy_list[idx].encrypt and i_encrypt decrypt = security_policy_list[idx].encrypt and i_decrypt # Create the encryptor object encdec = None if encrypt or decrypt: c_path.create_debug_dir(image.dest_image.debug_dir_encdec) encdec = get_encdec(image) # Create the parsegen object file_type_backup = image.image_type.file_type encdec_backup = image.encdec image.image_type.file_type = file_type image.encdec = encdec try: parsegen = self._status_updater(self._create_parsegen_obj, image.status.parsegen, progress, True, image) finally: image.image_type.file_type = file_type_backup image.encdec = encdec_backup # Do not allow signed unencrypted elf images to be encrypted as the # Sign will not longer match the encrypted image's tosign if parsegen.file_type() == 'elf' and parsegen.is_signed() and not sign and not parsegen.is_encrypted() and encrypt: raise RuntimeError('Cannot encrypt a signed unencrypted image without resigning ' 'as the sign no longer matches the format change.') # Set the security mechanisms parsegen.integrity_check = security_policy_list[idx].integrity_check and (parsegen.contains_integrity_check() or integrity_check) parsegen.sign = security_policy_list[idx].sign and (parsegen.is_signed() or sign) parsegen.encrypt = security_policy_list[idx].encrypt and (False if decrypt else (parsegen.is_encrypted() or encrypt)) # If encrypt: if encrypt: parsegen.encryption_params = encdec.get_encryption_parameters_blob() # Dump any debug data self.dump_parsegen_debug_data(image, parsegen) # If the security policy list contains more formats, call them if idx < len(security_policy_list) - 1: data = parsegen.get_wrapped_data() import tempfile tmp_fd = tempfile.NamedTemporaryFile(delete=False) tmp_fd.close() store_data_to_file(tmp_fd.name, data) # Backup the source path here src_image_dir_base = image.src_image.image_dir_base src_image_dir_ext = image.src_image.image_dir_ext src_image_name = image.src_image.image_name image.src_image.image_dir_base = os.path.dirname(tmp_fd.name) image.src_image.image_dir_ext = '' image.src_image.image_name = os.path.basename(tmp_fd.name) try: data = self._process_secure_operation(image, progress, security_policy_list, i_integrity_check, i_sign, i_encrypt, i_decrypt, idx + 1) finally: image.src_image.image_dir_base = src_image_dir_base image.src_image.image_dir_ext = src_image_dir_ext image.src_image.image_name = src_image_name os.remove(tmp_fd.name) parsegen.set_wrapped_data(data) # Sign the image if sign: self._status_updater(self._sign_image, image.status.sign, progress, True, image, parsegen) # Package and generate the output image file data = parsegen.get_data() if integrity_check: image.status.integrity_check.state = StatusInfo.SUCCESS if encrypt: image.status.encrypt.state = StatusInfo.SUCCESS if idx != 0: return data if decrypt: store_data_to_file(image.dest_image.decrypted_file, data) else: store_data_to_file(image.dest_image.image_path, data) logger.info(('Signed ' if sign else '') + ('& ' if sign and encrypt else '') + ('Encrypted ' if encrypt else '') + 'image is stored at ' + image.dest_image.image_path) image.image_under_operation = image.dest_image.image_path # Do any post processing self._status_updater(self._post_process, image.status.postprocess, progress, True, image, image.config.post_process.pil_splitter, getattr(self._stager, '_meta_build_path', None)) return parsegen