def repr_fuse_entries(fuse_entries): retval = TablePrinter() COLUMN_SNO = 0 COLUMN_ADDR = 1 COLUMN_OP = 2 COLUMN_MSB = 3 COLUMN_LSB = 4 COLUMN_REGION = 5 retval.insert_data(0, COLUMN_SNO, 'S.No') retval.insert_data(0, COLUMN_ADDR, 'Address') retval.insert_data(0, COLUMN_OP, 'Operation') retval.insert_data(0, COLUMN_MSB, 'MSB') retval.insert_data(0, COLUMN_LSB, 'LSB') retval.insert_data(0, COLUMN_REGION, 'Region Type') for idx, fuse in enumerate(sorted(fuse_entries.values(), key=lambda x: x.address)): retval.insert_data(idx + 1, COLUMN_SNO, str(idx + 1)) retval.insert_data(idx + 1, COLUMN_ADDR, hex(fuse.address)[2:].rstrip('L').rjust(8,'0')) retval.insert_data(idx + 1, COLUMN_OP, FUSEPROV_OPERATION_ETYPE_DICT.get(fuse.operation)) retval.insert_data(idx + 1, COLUMN_MSB, hex(fuse.msb)[2:].rstrip('L').rjust(8,'0')) retval.insert_data(idx + 1, COLUMN_LSB, hex(fuse.lsb)[2:].rstrip('L').rjust(8,'0')) retval.insert_data(idx + 1, COLUMN_REGION, FUSEPROV_REGION_ETYPE_DICT[fuse.region]) return retval.get_data()
def repr_shdrs(shdrs, sno_range=None): retval = TablePrinter() COLUMN_SNO = 0 COLUMN_NAME = 1 COLUMN_TYPE = 2 COLUMN_ADDR = 3 COLUMN_OFF = 4 COLUMN_SIZE = 5 COLUMN_ENTSIZE = 6 COLUMN_FLAGS = 7 COLUMN_LINK = 8 COLUMN_INFO = 9 COLUMN_ALIGN = 10 retval.insert_data(0, COLUMN_SNO, 'Num') retval.insert_data(0, COLUMN_NAME, 'Name') retval.insert_data(0, COLUMN_TYPE, 'Type') retval.insert_data(0, COLUMN_ADDR, 'Addr') retval.insert_data(0, COLUMN_OFF, 'Offset') retval.insert_data(0, COLUMN_SIZE, 'Size') retval.insert_data(0, COLUMN_ENTSIZE, 'EntSize') retval.insert_data(0, COLUMN_FLAGS, 'Flags') retval.insert_data(0, COLUMN_LINK, 'Link') retval.insert_data(0, COLUMN_INFO, 'Info') retval.insert_data(0, COLUMN_ALIGN, 'Align') stats = [0] * (COLUMN_ALIGN + 1) for idx, shdr in enumerate(shdrs): stats[COLUMN_ADDR] = shdr.sh_addr if shdr.sh_addr > stats[COLUMN_ADDR] else stats[COLUMN_ADDR] stats[COLUMN_OFF] = shdr.sh_offset if shdr.sh_offset > stats[COLUMN_OFF] else stats[COLUMN_OFF] stats[COLUMN_SIZE] = shdr.sh_size if shdr.sh_size > stats[COLUMN_SIZE] else stats[COLUMN_SIZE] stats[COLUMN_ENTSIZE] = shdr.sh_entsize if shdr.sh_entsize > stats[COLUMN_ENTSIZE] else stats[COLUMN_ENTSIZE] for idx in range(COLUMN_ALIGN + 1): stats[idx] = len(hex(stats[idx]).rstrip('L'))-2 if sno_range is None: sno_range = range(1, len(shdrs)+1) for idx, shdr in enumerate(shdrs): retval.insert_data(idx+1, COLUMN_SNO, str(sno_range[idx])) retval.insert_data(idx+1, COLUMN_NAME, shdr.sh_name_str, justify=retval.LEFT) retval.insert_data(idx+1, COLUMN_TYPE, str(ST_DESCRIPTION.get(shdr.sh_type, shdr.sh_type)), justify=retval.LEFT) retval.insert_data(idx+1, COLUMN_ADDR, hex_addr(shdr.sh_addr, stats[COLUMN_ADDR])) retval.insert_data(idx+1, COLUMN_OFF, hex_addr(shdr.sh_offset, stats[COLUMN_OFF])) retval.insert_data(idx+1, COLUMN_SIZE, hex_addr(shdr.sh_size, stats[COLUMN_SIZE])) retval.insert_data(idx+1, COLUMN_ENTSIZE, hex_addr(shdr.sh_entsize, stats[COLUMN_ENTSIZE])) retval.insert_data(idx+1, COLUMN_FLAGS, PERM_DESCRIPTION.get(shdr.flags, "")) retval.insert_data(idx+1, COLUMN_LINK, shdr.sh_link) retval.insert_data(idx+1, COLUMN_INFO, shdr.sh_info) retval.insert_data(idx+1, COLUMN_ALIGN, shdr.sh_addralign) return retval.get_data()
def validate_addresses(self, addr_dict): seg_ranges = [] # Collect all the addr ranges for phdr in self.parsegen.phdrs: if self.segment_to_put(phdr): if addr_dict['isPhy']: seg_ranges.append( (phdr.p_paddr, phdr.p_paddr + phdr.p_memsz, phdr.p_memsz)) else: seg_ranges.append( (phdr.p_vaddr, phdr.p_vaddr + phdr.p_memsz, phdr.p_memsz)) # Sort ranges by start address seg_ranges.sort(key=lambda x: x[0]) # Check for overlaps overlapping = [] for idx in range(len(seg_ranges) - 1): if seg_ranges[idx + 1][0] < seg_ranges[idx][1]: overlapping.append((seg_ranges[idx], seg_ranges[idx + 1])) if overlapping: # Create table header table = TablePrinter([1]) table.insert_data(0, 0, 'S.No.') table.insert_data(0, 1, 'Segment A', column_end=2) table.insert_data(0, 3, 'Segment B', column_end=4) # Create sub header table.insert_data(1, 1, addr_dict['tString']) table.insert_data(1, 2, 'Size') table.insert_data(1, 3, addr_dict['tString']) table.insert_data(1, 4, 'Size') # Add all the overlapping segments for idx, overlap in enumerate(overlapping): table.insert_data(idx + 2, 1, hex(overlap[0][0])) table.insert_data(idx + 2, 2, hex(overlap[0][2])) table.insert_data(idx + 2, 3, hex(overlap[1][0])) table.insert_data(idx + 2, 4, hex(overlap[1][2])) # Create the error string addr_dict['policy']().run( addr_dict['eString'] + '\n'.join([' ' + l for l in table.get_data().split('\n')]))
def repr_phdrs(phdrs): retval = TablePrinter() COLUMN_SNO = 0 COLUMN_TYPE = 1 COLUMN_OFF = 2 COLUMN_VADDR = 3 COLUMN_PADDR = 4 COLUMN_FSIZE = 5 COLUMN_MSIZE = 6 COLUMN_FLAGS = 7 COLUMN_ALIGN = 8 retval.insert_data(0, COLUMN_SNO, 'S.No') retval.insert_data(0, COLUMN_TYPE, 'Type') retval.insert_data(0, COLUMN_OFF, 'Offset') retval.insert_data(0, COLUMN_VADDR, 'VirtAddr') retval.insert_data(0, COLUMN_PADDR, 'PhysAddr') retval.insert_data(0, COLUMN_FSIZE, 'FileSize') retval.insert_data(0, COLUMN_MSIZE, 'MemSize') retval.insert_data(0, COLUMN_FLAGS, 'Flags') retval.insert_data(0, COLUMN_ALIGN, 'Align') stats = [0] * (COLUMN_ALIGN + 1) for idx, phdr in enumerate(phdrs): stats[COLUMN_OFF] = phdr.p_offset if phdr.p_offset > stats[COLUMN_OFF] else stats[COLUMN_OFF] stats[COLUMN_VADDR] = phdr.p_vaddr if phdr.p_vaddr > stats[COLUMN_VADDR] else stats[COLUMN_VADDR] stats[COLUMN_PADDR] = phdr.p_paddr if phdr.p_paddr > stats[COLUMN_PADDR] else stats[COLUMN_PADDR] stats[COLUMN_FSIZE] = phdr.p_filesz if phdr.p_filesz > stats[COLUMN_FSIZE] else stats[COLUMN_FSIZE] stats[COLUMN_MSIZE] = phdr.p_memsz if phdr.p_memsz > stats[COLUMN_MSIZE] else stats[COLUMN_MSIZE] stats[COLUMN_FLAGS] = phdr.p_flags if phdr.p_flags > stats[COLUMN_FLAGS] else stats[COLUMN_FLAGS] for idx in range(COLUMN_ALIGN + 1): stats[idx] = len(hex(stats[idx]).rstrip('L'))-2 for idx, phdr in enumerate(phdrs): retval.insert_data(idx+1, COLUMN_SNO, str(idx+1)) retval.insert_data(idx+1, COLUMN_TYPE, PT_DESCRIPTION.get(phdr.p_type, phdr.p_type)) retval.insert_data(idx+1, COLUMN_OFF, hex_addr(phdr.p_offset, stats[COLUMN_OFF])) retval.insert_data(idx+1, COLUMN_VADDR, hex_addr(phdr.p_vaddr, stats[COLUMN_VADDR])) retval.insert_data(idx+1, COLUMN_PADDR, hex_addr(phdr.p_paddr, stats[COLUMN_PADDR])) retval.insert_data(idx+1, COLUMN_FSIZE, hex_addr(phdr.p_filesz, stats[COLUMN_FSIZE])) retval.insert_data(idx+1, COLUMN_MSIZE, hex_addr(phdr.p_memsz, stats[COLUMN_MSIZE])) retval.insert_data(idx+1, COLUMN_FLAGS, hex_addr(phdr.p_flags, stats[COLUMN_FLAGS])) retval.insert_data(idx+1, COLUMN_ALIGN, hex(phdr.p_align), justify=retval.LEFT) return retval.get_data()
def repr_seghdrs(segments): retval = TablePrinter() COLUMN_SNO = 0 COLUMN_OFF = 1 COLUMN_TYPE = 2 COLUMN_ATTR = 3 retval.insert_data(0, COLUMN_SNO, 'S.No') retval.insert_data(0, COLUMN_OFF, 'Offset') retval.insert_data(0, COLUMN_TYPE, 'Type') retval.insert_data(0, COLUMN_ATTR, 'Attribute') for idx, segment in enumerate(segments): retval.insert_data(idx + 1, COLUMN_SNO, str(idx + 1)) retval.insert_data(idx + 1, COLUMN_OFF, hex(segment.offset)) retval.insert_data(idx + 1, COLUMN_TYPE, df.SEG_TYPE_DESCRIPTION.get(segment.type)) retval.insert_data(idx + 1, COLUMN_ATTR, hex(segment.attribute)) return retval.get_data()
def _validate_segments(self): if not POLICY_OVERLAPPING_SEGMENTS.is_ignore(): # Collect all the phys addr ranges seg_ranges = [] for phdr in self._elf_parsegen.phdrs: if self._elf_parsegen._segment_to_put(phdr): seg_ranges.append((phdr.p_paddr, phdr.p_paddr + phdr.p_memsz, phdr.p_memsz)) # Sort ranges by start address seg_ranges.sort(key=lambda x: x[0]) # Check for overlaps overlapping = [] for idx in range(len(seg_ranges)-1): if seg_ranges[idx+1][0] < seg_ranges[idx][1]: overlapping.append((seg_ranges[idx], seg_ranges[idx+1])) if overlapping: # Create table header table = TablePrinter([1]) table.insert_data(0, 0, 'S.No.') table.insert_data(0, 1, 'Segment A', column_end=2) table.insert_data(0, 3, 'Segment B', column_end=4) # Create sub header table.insert_data(1, 1, 'Phys') table.insert_data(1, 2, 'Size') table.insert_data(1, 3, 'Phys') table.insert_data(1, 4, 'Size') # Add all the overlapping segments for idx, overlap in enumerate(overlapping): table.insert_data(idx + 2, 1, hex(overlap[0][0])) table.insert_data(idx + 2, 2, hex(overlap[0][2])) table.insert_data(idx + 2, 3, hex(overlap[1][0])) table.insert_data(idx + 2, 4, hex(overlap[1][2])) # Create the error string POLICY_OVERLAPPING_SEGMENTS.run('Following overlapping segments were found: ' + '\n' + '\n'.join([' ' + l for l in table.get_data().split('\n')]))
def print_summary(args, image_info_list): """Prints the summary of the actions performed by SecImage""" actions = [] # Check which actions were performed if args.integrity_check: actions.append('integrity_check') if args.sign: actions.append('sign') if args.encrypt: actions.append('encrypt') if args.validate: actions.append('validate') if not actions: return # Figure out the output directory output_print = (('Output is saved at: ' + args.output_dir + '\n') if args.output_dir else ('Minimized build was updated at: ' + args.mini_build + '\n') if args.mini_build else '\n') # Log the actions and output directory logger.info('SUMMARY:' + '\n' + 'Following actions were performed: "' + ', '.join(actions) + '"' + '\n' + output_print) # Table information summary_table = TablePrinter([1]) # summary_table = TablePrinter([0]) COLUMN_IDX = 0 COLUMN_SIGN_ID = 1 COLUMN_PARSE = 2 COLUMN_INTEGRITY_CHECK = 3 COLUMN_SIGN = 4 COLUMN_ENCRYPT = 5 COLUMN_VAL_PARSE = 6 COLUMN_VAL_INTEGRITY_CHECK = 7 COLUMN_VAL_SIGN = 8 COLUMN_VAL_ENCRYPT = 9 # First row summary_table.insert_data(0, COLUMN_IDX, 'Idx') summary_table.insert_data(0, COLUMN_SIGN_ID, 'SignId') summary_table.insert_data(0, COLUMN_PARSE, 'Parse') summary_table.insert_data(0, COLUMN_INTEGRITY_CHECK, 'Integrity') summary_table.insert_data(0, COLUMN_SIGN, 'Sign') summary_table.insert_data(0, COLUMN_ENCRYPT, 'Encrypt') summary_table.insert_data(0, COLUMN_VAL_PARSE, 'Validate', column_end=COLUMN_VAL_ENCRYPT) # Second row summary_table.insert_data(1, COLUMN_VAL_PARSE, 'Parse') summary_table.insert_data(1, COLUMN_VAL_INTEGRITY_CHECK, 'Integrity') summary_table.insert_data(1, COLUMN_VAL_SIGN, 'Sign') summary_table.insert_data(1, COLUMN_VAL_ENCRYPT, 'Encrypt') # Data rows for idx, image in enumerate(image_info_list): idx += 2 summary_table.insert_data(idx, COLUMN_IDX, str(idx - 1) + '.') summary_table.insert_data(idx, COLUMN_SIGN_ID, image.sign_id) summary_table.insert_data(idx, COLUMN_PARSE, image.status.parsegen.state) summary_table.insert_data(idx, COLUMN_INTEGRITY_CHECK, image.status.integrity_check.state) summary_table.insert_data(idx, COLUMN_SIGN, image.status.sign.state) summary_table.insert_data(idx, COLUMN_ENCRYPT, image.status.encrypt.state) summary_table.insert_data(idx, COLUMN_VAL_PARSE, image.status.validate_parsegen.state) summary_table.insert_data(idx, COLUMN_VAL_INTEGRITY_CHECK, image.status.validate_integrity_check.state) summary_table.insert_data(idx, COLUMN_VAL_SIGN, image.status.validate_sign.state) summary_table.insert_data(idx, COLUMN_VAL_ENCRYPT, image.status.validate_encrypt.state) # TODO: put the error and image paths logger.info(summary_table.get_data())
def print_summary(args, image_info_list): """Prints the summary of the actions performed by SecImage""" if not image_info_list: return # Check which actions were performed actions = [] if args.sign: actions.append('sign') if args.validate: actions.append('validate') if args.integrity_check: actions.append('integrity_check') if not actions: return # Figure out the output directory if args.output_dir: output_print = 'Output is saved at: %s\n' % args.output_dir else: output_print = '\n' # Log the actions and output directory actions_str = 'Following actions were performed: "%s"\n' % ', '.join( actions) logger.info('SUMMARY:' + '\n' + actions_str + output_print) # Table information summary_table = TablePrinter([1]) (COLUMN_PARSE, COLUMN_INTEGRITY_CHECK, COLUMN_SIGN, COLUMN_VAL_PARSE, COLUMN_VAL_INTEGRITY_CHECK, COLUMN_VAL_SIGN) = range(6) # First row row = 0 summary_table.insert_data(row, COLUMN_PARSE, 'Parse') summary_table.insert_data(row, COLUMN_INTEGRITY_CHECK, 'Integrity') summary_table.insert_data(row, COLUMN_SIGN, 'Sign') summary_table.insert_data(row, COLUMN_VAL_PARSE, 'Validate', column_end=COLUMN_VAL_SIGN) # Second row row += 1 summary_table.insert_data(row, COLUMN_VAL_PARSE, 'Parse') summary_table.insert_data(row, COLUMN_VAL_INTEGRITY_CHECK, 'Integrity') summary_table.insert_data(row, COLUMN_VAL_SIGN, 'Sign') # Data rows for image in image_info_list: row += 1 summary_table.insert_data(row, COLUMN_PARSE, image.status.parsegen.state) summary_table.insert_data(row, COLUMN_INTEGRITY_CHECK, image.status.integrity_check.state) summary_table.insert_data(row, COLUMN_SIGN, image.status.sign.state) summary_table.insert_data(row, COLUMN_VAL_PARSE, image.status.validate_parsegen.state) summary_table.insert_data(row, COLUMN_VAL_INTEGRITY_CHECK, image.status.validate_integrity_check.state) summary_table.insert_data(row, COLUMN_VAL_SIGN, image.status.validate_sign.state) logger.info(summary_table.get_data())
def print_summary(args, image_info_list): """Prints the summary of the actions performed by SecImage""" actions = [] # Check which actions were performed if args.sign: actions.append('sign') if args.encrypt: actions.append('encrypt') if args.validate: actions.append('validate') if not actions: return # Figure out the output directory output_print = (('Output is saved at: ' + args.output_dir + '\n') if args.output_dir else ('Minimized build was updated at: ' + args.mini_build + '\n') if args.mini_build else '\n') # Log the actions and output directory logger.info('SUMMARY:' + '\n' + 'Following actions were performed: "' + ', '.join(actions) + '"' + '\n' + output_print) # Table information summary_table = TablePrinter() COLUMN_IDX = 0 COLUMN_SIGN_ID = 1 COLUMN_PARSE = 2 COLUMN_SIGN = 3 COLUMN_ENCRYPT = 4 #COLUMN_VAL_PARSE = 5 #COLUMN_VAL_SIGN = 6 #COLUMN_VAL_ENCRYPT = 7 COLUMN_ERROR = 5 COLUMN_IMAGE = 6 # First row summary_table.insert_data(0, COLUMN_IDX, 'Idx') summary_table.insert_data(0, COLUMN_SIGN_ID, 'SignId') summary_table.insert_data(0, COLUMN_PARSE, 'Parse') summary_table.insert_data(0, COLUMN_SIGN, 'Sign') summary_table.insert_data(0, COLUMN_ENCRYPT, 'Encrypt') #summary_table.insert_data(0, COLUMN_VAL_PARSE, 'Validate', column_end=COLUMN_VAL_ENCRYPT) summary_table.insert_data(0, COLUMN_ERROR, 'Error') summary_table.insert_data(0, COLUMN_IMAGE, 'Image Path') # Second row #summary_table.insert_data(1, COLUMN_VAL_PARSE, 'Parse') #summary_table.insert_data(1, COLUMN_VAL_SIGN, 'Sign') #summary_table.insert_data(1, COLUMN_VAL_ENCRYPT, 'Encrypt') # Data rows for idx, image in enumerate(image_info_list): idx += 1 summary_table.insert_data(idx, COLUMN_IDX, str(idx - 1) + '.') summary_table.insert_data(idx, COLUMN_SIGN_ID, image.sign_id) summary_table.insert_data(idx, COLUMN_PARSE, image.status.parsegen.state) summary_table.insert_data(idx, COLUMN_SIGN, image.status.sign.state) summary_table.insert_data(idx, COLUMN_ENCRYPT, image.status.encrypt.state) #summary_table.insert_data(idx, COLUMN_VAL_PARSE, image.status.validate_secimage.state) #summary_table.insert_data(idx, COLUMN_VAL_SIGN, image.status.validate_sign.state) #summary_table.insert_data(idx, COLUMN_VAL_ENCRYPT, image.status.validate_encrypt.state) summary_table.insert_data(idx, COLUMN_ERROR, (('' if image.status.parsegen.error is None else image.status.parsegen.error) + ('' if image.status.sign.error is None else image.status.sign.error) + ('' if image.status.encrypt.error is None else image.status.encrypt.error))) summary_table.insert_data(idx, COLUMN_IMAGE, image.image_under_operation) logger.info(summary_table.get_data())
def _validate_segments(self): if not POLICY_OVERLAPPING_SEGMENTS.is_ignore(): # Collect all the phys addr ranges seg_ranges = [] for phdr in self._elf_parsegen.phdrs: if self._elf_parsegen._segment_to_put(phdr): seg_ranges.append( (phdr.p_paddr, phdr.p_paddr + phdr.p_memsz, phdr.p_memsz)) # Sort ranges by start address seg_ranges.sort(key=lambda x: x[0]) # Check for overlaps overlapping = [] for idx in range(len(seg_ranges) - 1): if seg_ranges[idx + 1][0] < seg_ranges[idx][1]: overlapping.append((seg_ranges[idx], seg_ranges[idx + 1])) if overlapping: # Create table header table = TablePrinter([1]) table.insert_data(0, 0, 'S.No.') table.insert_data(0, 1, 'Segment A', column_end=2) table.insert_data(0, 3, 'Segment B', column_end=4) # Create sub header table.insert_data(1, 1, 'Phys') table.insert_data(1, 2, 'Size') table.insert_data(1, 3, 'Phys') table.insert_data(1, 4, 'Size') # Add all the overlapping segments for idx, overlap in enumerate(overlapping): table.insert_data(idx + 2, 1, hex(overlap[0][0])) table.insert_data(idx + 2, 2, hex(overlap[0][2])) table.insert_data(idx + 2, 3, hex(overlap[1][0])) table.insert_data(idx + 2, 4, hex(overlap[1][2])) # Create the error string POLICY_OVERLAPPING_SEGMENTS.run( 'Following overlapping segments were found: ' + '\n' + '\n'.join([' ' + l for l in table.get_data().split('\n')])) if not POLICY_NON_LOAD_OUTSIDE_LOAD.is_ignore(): load_ranges = [] non_load_ranges = [] # Collect address ranges for idx, phdr in enumerate(self._elf_parsegen.phdrs): if self._elf_parsegen._segment_to_put(phdr): load_ranges.append( (phdr.p_offset, phdr.p_offset + phdr.p_filesz)) elif phdr.p_type != PT_NULL and phdr.p_filesz != 0: non_load_ranges.append( (phdr.p_offset, phdr.p_offset + phdr.p_filesz, phdr, idx + 3)) # Sort ranges by start address load_ranges.sort(key=lambda x: x[0]) non_load_ranges.sort(key=lambda x: x[0]) # Check for non-encapsulated segments non_encap = [] non_encap_sno = [] for d in range(len(non_load_ranges)): in_seg = False for s in range(len(load_ranges)): in_rng = load_ranges[s][0] <= non_load_ranges[d][ 0], non_load_ranges[d][1] <= load_ranges[s][1] if in_rng[0] and in_rng[1]: in_seg = True # if non load segment not encapsulated in any segment, add to non_encapsulated list if not in_seg: non_encap.append(non_load_ranges[d][2]) non_encap_sno.append(non_load_ranges[d][3]) if non_encap: # Create the error string POLICY_NON_LOAD_OUTSIDE_LOAD.run( "Following non-loadable segments found outside load segments: " + '\n' + repr_phdrs(non_encap, non_encap_sno))
def validate(self, image, root_cert_hash=None, imageinfo=None): if image.is_signed(): # Create error string errstr = [] for i, data_to_sign, data_signature, cert_chain in image.get_signing_assets( ): # Check if empty if not data_signature and not cert_chain: if i != image.authority: logger.warning(i + ' signature is not present') else: raise RuntimeError(i + ' signature is not present') continue # Extract the cert chain list cert_chain_der = crypto_functions.split_certificate_blob_into_certs( cert_chain) # Signature verification if not self.validate_sig(data_to_sign, data_signature, cert_chain_der): errstr.append(i + ' signature is invalid') # OID Validation if len(cert_chain_der) == 3: if not self.validate_oid_from_certs( cert_chain_der[1], cert_chain_der[0]): errstr.append( 'OID values in the certificate are invalid') # Extract the cert chain list cert_chain_blob = image.cert_chain cert_chain_der = crypto_functions.split_certificate_blob_into_certs( cert_chain_blob) # Root cert hash validation if root_cert_hash: if not cert_chain_der: errstr.append( 'Root certificate for ' + image.authority + ' is not present in image for root cert hash verification' ) elif not self.validate_root_cert_hash(cert_chain_der, root_cert_hash): errstr.append( 'Root certificate from image does not match the given root cert hash value' ) # Signing attributes vaidation if imageinfo is not None: if not cert_chain_der: errstr.append( 'Certificate chain for ' + image.authority + ' is not present in image signing attributes verification' ) else: mismatch = self.validate_signing_attributes( cert_chain_der, imageinfo) if mismatch: tp = TablePrinter() tp.insert_data(0, 0, 'Attribute') tp.insert_data(0, 1, 'Attestation Cert') tp.insert_data(0, 2, 'Config File') i = 0 for m in mismatch: # Handle formatting of items that are lists if isinstance(m[1], list) and isinstance( m[2], list): num_rows = max(len(m[1]), len(m[2])) tp.insert_data(i + 1, 0, m[0]) for n in range(num_rows): if n < len(m[1]): tp.insert_data(i + n + 1, 1, m[1][n]) else: tp.insert_data(i + n + 1, 1, "") if n < len(m[2]): tp.insert_data(i + n + 1, 2, m[2][n]) else: tp.insert_data(i + n + 1, 2, "") i += num_rows continue tp.insert_data(i + 1, 0, m[0]) tp.insert_data(i + 1, 1, m[1]) tp.insert_data(i + 1, 2, m[2]) i += 1 errstr.append( 'Following signing attributes do not match: \n ' + '\n '.join(tp.get_data().split('\n'))) if errstr: raise RuntimeError( 'Following validations failed for the image:\n ' + '\n '.join([(str(i + 1) + '. ' + e) for i, e in enumerate(errstr)])) return True else: raise RuntimeError("Image supplied is not signed.")