def main(args, return_isc=False): """Parses the command line arguments, performs any basic operations based on the parsed arguments and starts processing using the isc module. """ # Log to file flids = logger.log_to_file(IoT_SECIMAGE_TOOL_NAME, args.output_dir) try: # Print the tool's launch command # logged_args = sys.argv logger.info('\n\n IoT launched as: "' + ' '.join(sys.argv) + '"\n') # Initialize SecImageIotCore # The parsegen_config is set to None for now. It will be initialized # later before set_image_path. isc = SecImageIotCore(config_dir=IoT_CONFIG_DIR, parsegen_config=None, cfgparser=iot_cfgparser, debug=args.debug) # Configure image signer if args.image_file: isc.set_chipset(args.chipset, args.overrides) crypto_params = {} if args.sign: crypto_params.update(root_certificate_properties=dict( certificate_path=args.root_cert, private_key_path=args.root_key)) # Set the input, it must be done after isc.set_chipset(...) # # All actual IDs are passed to the back-end, along with root cert # and root private key as crypto_params. isc.set_image_path(args.image_file, args.sign_id, crypto_params=crypto_params) # Set the output if args.output_dir: isc.output_dir = args.output_dir # Process the images isc.process(sign=args.sign, integrity_check=args.integrity_check, val_sign=args.validate, val_image=args.validate, val_integrity_check=args.validate) # Print the summary print_summary(args, isc.image_info_list) if return_isc: return isc else: return isc.image_info_list finally: # Clear all log handlers logger.removeFileLogger(flids)
def main(args, return_isc=False): """Parses the command line arguments, performs any basic operations based on the parsed arguments and starts processing using the isc module. """ # Log to file flids = logger.log_to_file(SECIMAGE_TOOL_NAME, args.output_dir) # Print the tool's launch command logger.debug('\n\n SecImage launched as: "' + ' '.join(sys.argv) + '"\n') # Initialize SecImageCore isc = SecImageCore(debug=args.debug) # Configure image signer if args.image_file or ( args.meta_build and not SecImageCore.meta_supports_sign_id(args.meta_build)): if args.chipset: isc.set_chipset(args.chipset, args._c_overrides) elif args.config_path: isc.set_config_path(args.config_path, args._c_overrides) # Set the input if args.image_file: isc.set_image_path(args.image_file, args.sign_id) elif args.meta_build: isc.set_meta_build_path(args.meta_build, [] if args.sign_id is None else [args.sign_id]) # Set the output if args.mini_build: isc.mini_build_path = args.mini_build elif args.output_dir: isc.output_dir = args.output_dir # Process the images isc.process(verify_setup=args.verify_inputs, integrity_check=args.integrity_check, sign=args.sign, encrypt=args.encrypt, decrypt=args.decrypt, val_image=args.validate, val_integrity_check=args.validate, val_sign=args.validate, val_encrypt=args.validate, root_cert_hash=args.rch) # Print the summary print_summary(args, isc.image_info_list) # Clear all log handlers logger.removeFileLogger(flids) if return_isc: return isc else: return isc.image_info_list
def _process(idx, image, integrity_check, sign, val_image, val_integrity_check, val_sign): assert isinstance(image, ImageInfoIot) logger.info('------------------------------------------------------') status_string = ('Processing: ' + 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 file_logger_id = None image.authority = self.authority 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) # Set the root cert hash image.validation_root_cert_hash = root_cert_hash # Enable file logging to the directory file_logger_id = logger.add_file_logger(c_path.join(image_output_dir, 'IoT_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign: parsegen = self._process_secure_operation( image, progress, security_policy_list, integrity_check, sign, parsegens=parsegens.get(image.chipset, list())) # For validation if val_image or val_integrity_check or val_sign: parsegen = self._process_validation( image, progress, security_policy_list, val_image, val_integrity_check, val_sign) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.error(traceback.format_exc()) logger.error(sys.exc_info()[1]) finally: if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info('------------------------------------------------------\n')
def _process(idx, image, sign_attr, integrity_check, sign, encrypt, decrypt, val_image, val_integrity_check, val_sign, val_encrypt): assert isinstance(image, ImageInfo) logger.info( '------------------------------------------------------') status_string = ('Processing ' + str(idx + 1) + '/' + str(total_image_count) + ': ' + 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 file_logger_id = None image.authority = self.authority 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) # Set the root cert hash image.validation_root_cert_hash = root_cert_hash # Enable file logging to the directory file_logger_id = logger.add_file_logger( c_path.join(image_output_dir, 'SecImage_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign or encrypt or decrypt: parsegen = self._process_secure_operation( image, progress, security_policy_list, sign_attr, integrity_check, sign, encrypt, decrypt) # For validation if val_image or val_integrity_check or val_sign or val_encrypt: # Bypass validation when encrypted key provide is configured as UIE server because decryption will always fail if parsegen is not None and parsegen.is_encrypted( ) and encrypted_key_provider_id_supported( image.general_properties.UIE_key): logger.warning( "Skipping validation because encrypted key provider is configured as UIE server" ) else: parsegen = self._process_validation( image, progress, security_policy_list, val_image, val_integrity_check, val_sign, val_encrypt) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR) or (val_encrypt and image.status.validate_encrypt.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except RemoteSignerNote as e: logger.info('NOTE: ' + str(e), color=logger.YELLOW) except Exception: logger.error(traceback.format_exc()) logger.error(sys.exc_info()[1]) finally: if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info( '------------------------------------------------------\n')
def process(self, verify_setup=False, integrity_check=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_integrity_check=False, val_sign=False, val_encrypt=False, root_cert_hash=None, 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 integrity_check: Add integrity check to the image. :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_integrity_check: Validate the integrity check in the image. :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) \""" ... """ from imageinfo import ImageInfo, StatusInfo from sectools.features.isc.signer.remote import RemoteSignerNote # 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 integrity_check or sign or encrypt or decrypt or val_image or val_integrity_check or val_sign or val_encrypt): raise RuntimeError( 'Please specify one or more operations to perform.') # Print the openssl path version = '' path_info = 'is unavailable. Please run "which openssl" and "openssl version" to check openssl version info, and upgrade to required version' try: from sectools.common import crypto from sectools.common.crypto import crypto_functions version = 'v' + crypto.discovery.openssl.OPENSSL_VERSION_MIN + ' or greater ' crypto_functions.are_available([crypto_functions.MOD_OPENSSL]) path_info = 'is available at: "' + crypto.openssl_binary_implementation.openssl_binary_path + '"' except Exception as e: pass logger.info('Openssl ' + version + path_info) 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 file_logger_id = None 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) # Set the root cert hash image.validation_root_cert_hash = root_cert_hash # Enable file logging to the directory file_logger_id = logger.add_file_logger( c_path.join(image_output_dir, 'SecImage_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign or encrypt or decrypt: parsegen = self._process_secure_operation( image, progress, security_policy_list, integrity_check, sign, encrypt, decrypt) # For validation if val_image or val_integrity_check or val_sign or val_encrypt: parsegen = self._process_validation( image, progress, security_policy_list, val_image, val_integrity_check, val_sign, val_encrypt) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR) or (val_encrypt and image.status.validate_encrypt.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except RemoteSignerNote as e: logger.info('NOTE: ' + str(e), color=logger.YELLOW) except Exception: logger.error(traceback.format_exc()) logger.error(sys.exc_info()[1]) if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info( '------------------------------------------------------\n') progress.complete()
def process(self, verify_setup=False, integrity_check=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_integrity_check=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 integrity_check: Add integrity check to the image. :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_integrity_check: Validate the integrity check in the image. :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 integrity_check or sign or encrypt or decrypt or val_image or val_integrity_check or val_sign or val_encrypt): 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 file_logger_id = None 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) # Enable file logging to the directory file_logger_id = logger.add_file_logger(c_path.join(image_output_dir, 'SecImage_log.txt'), logger.verbosity) # For secure operations if integrity_check or sign or encrypt or decrypt: self._process_secure_operation(image, progress, integrity_check, sign, encrypt, decrypt) # For validation if val_image or val_integrity_check or val_sign or val_encrypt: self._process_validation(image, progress, val_image, val_integrity_check, val_sign, val_encrypt) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR) or (val_encrypt and image.status.validate_encrypt.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.debug(traceback.format_exc()) logger.error(sys.exc_info()[1]) if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info('------------------------------------------------------\n') progress.complete()
def main(args, return_isc=False): """Parses the command line arguments, performs any basic operations based on the parsed arguments and starts processing using the isc module. """ # Log to file flids = logger.log_to_file(SECIMAGE_TOOL_NAME, args.output_dir) try: # Print the tool's launch command logged_args = CoreOptionParser.mask_private_args( sys.argv, args._c_spec_override_prefix) logger.info('\n\n SecImage launched as: "' + ' '.join(logged_args) + '"\n') # Initialize SecImageCore isc = SecImageCore(debug=args.debug) # Configure image signer if args.image_file or ( args.meta_build and not SecImageCore.meta_supports_sign_id(args.meta_build)): if args.chipset: isc.set_chipset(args.chipset, args._c_overrides, args._c_spec_overrides) elif args.config_path: isc.set_config_path(args.config_path, args._c_overrides, args._c_spec_overrides) if args.qti_signing: isc.authority = AUTHORITY_QTI # Set the input if args.image_file: isc.set_image_path(args.image_file, args.sign_id, args.m_gen, args.m_image_file) elif args.meta_build: isc.set_meta_build_path( args.meta_build, [] if args.sign_id is None else [args.sign_id], args.m_gen) # Set the output if args.mini_build: isc.mini_build_path = args.mini_build elif args.output_dir: isc.output_dir = args.output_dir # Process the images isc.process(verify_setup=args.verify_inputs, sign_attr=args.sign_attr, integrity_check=args.integrity_check, sign=args.sign, encrypt=args.encrypt, decrypt=args.decrypt, no_op=args.no_op, val_image=args.validate, val_integrity_check=args.validate, val_sign=args.validate, val_encrypt=args.validate, m_sign_attr=args.m_sign_attr, m_integrity_check=args.m_integrity_check, m_sign=args.m_sign, m_encrypt=args.m_encrypt, m_decrypt=args.m_decrypt, m_val_image=args.m_validate, m_val_integrity_check=args.m_validate, m_val_sign=args.m_validate, m_val_encrypt=args.m_validate, gen_multi_image=args.m_gen, root_cert_hash=args.rch) # Print the summary print_summary(args, isc.image_info_list, isc.multi_image_imageinfo_dict.values()) if return_isc: return isc else: return isc.image_info_list finally: # Clear all log handlers logger.removeFileLogger(flids)
def process(self, verify_setup=False, integrity_check=False, sign=False, encrypt=False, decrypt=False, val_image=False, val_integrity_check=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 integrity_check: Add integrity check to the image. :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_integrity_check: Validate the integrity check in the image. :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 integrity_check or sign or encrypt or decrypt or val_image or val_integrity_check or val_sign or val_encrypt): 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 file_logger_id = None 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) # Enable file logging to the directory file_logger_id = logger.add_file_logger(c_path.join(image_output_dir, 'SecImage_log.txt'), logger.verbosity) # Create the security policies list for this image security_policy_list = create_security_policy_list(image) # Parsegen object parsegen = None # For secure operations if integrity_check or sign or encrypt or decrypt: parsegen = self._process_secure_operation(image, progress, security_policy_list, integrity_check, sign, encrypt, decrypt) # For validation if val_image or val_integrity_check or val_sign or val_encrypt: parsegen = self._process_validation(image, progress, security_policy_list, val_image, val_integrity_check, val_sign, val_encrypt) # Print the image data if parsegen is not None: logger.info('\n' + str(parsegen)) # Set overall processing to true if not ((val_image and image.status.validate_parsegen.state == StatusInfo.ERROR) or (val_integrity_check and image.status.validate_integrity_check.state == StatusInfo.ERROR) or (val_sign and image.status.validate_sign.state == StatusInfo.ERROR) or (val_encrypt and image.status.validate_encrypt.state == StatusInfo.ERROR)): image.status.overall.state = StatusInfo.SUCCESS except Exception: logger.debug(traceback.format_exc()) logger.error(sys.exc_info()[1]) if file_logger_id is not None: logger.removeFileLogger(file_logger_id) logger.info('------------------------------------------------------\n') progress.complete()
def main(args, return_isc=False): """Parses the command line arguments, performs any basic operations based on the parsed arguments and starts processing using the isc module. """ # Log to file flids = logger.log_to_file(SECIMAGE_TOOL_NAME, args.output_dir) try: # Print the tool's launch command logged_args = CoreOptionParser.mask_private_args( sys.argv, args._c_spec_override_prefix) logger.info('\n\n SecImage v' + SECIMAGE_TOOL_VERSION + ' launched as: "' + ' '.join(logged_args) + '"\n') # Initialize SecImageCore # When args.serial_numbers is ALL, disable all serial-binding. isc = SecImageCore(debug=args.debug, verbatim_config=args.verbatim_config, disable_serial_binding=args.serial_numbers == DISABLE_SERIAL_BINDING, platform_binding=args.platform_binding) # Configure image signer if args.image_file or ( args.meta_build and not SecImageCore.meta_supports_sign_id(args.meta_build)): if args.chipset: isc.set_chipset(args.chipset, args._c_overrides, args._c_spec_overrides) elif args.config_path: isc.set_config_path(args.config_path, args._c_overrides, args._c_spec_overrides) if args.qti_signing: isc.authority = AUTHORITY_QTI # Set the input if args.image_file: isc.set_image_path(args.image_file, args.sign_id, args.m_gen, args.m_image_file) elif args.meta_build: isc.set_meta_build_path( args.meta_build, [] if args.sign_id is None else [args.sign_id], args.m_gen) # Set the output if args.mini_build: isc.mini_build_path = args.mini_build elif args.output_dir: isc.output_dir = args.output_dir # Process the images isc.process(verify_setup=args.verify_inputs, sign_attr=args.sign_attr, integrity_check=args.integrity_check, sign=args.sign, encrypt=args.encrypt, decrypt=args.decrypt, no_op=args.no_op, val_image=args.validate, val_integrity_check=args.validate, val_sign=args.validate, val_encrypt=args.validate, m_sign_attr=args.m_sign_attr, m_integrity_check=args.m_integrity_check, m_sign=args.m_sign, m_encrypt=args.m_encrypt, m_decrypt=args.m_decrypt, m_val_image=args.m_validate, m_val_integrity_check=args.m_validate, m_val_sign=args.m_validate, m_val_encrypt=args.m_validate, gen_multi_image=args.m_gen, root_cert_hash=args.rch, enforce_signed=args.enforce_signed, enforce_encrypted=args.enforce_encrypted) # Print the summary print_summary(args, isc.image_info_list, isc.multi_image_imageinfo_dict.values()) overall_status = [ image.status.overall.state == StatusInfo.SUCCESS for image in isc.image_info_list ] multi_image_status = [ m.status.overall.state == StatusInfo.SUCCESS for m in isc.multi_image_imageinfo_dict.values() ] return_code = RETURN_CODE_SUCCESS if all(overall_status + multi_image_status) else\ RETURN_CODE_FAILURE if return_isc: return return_code, isc return return_code, isc.image_info_list finally: # Clear all log handlers logger.removeFileLogger(flids)