def run_checks(self): sources = self.dcp._list_pkl + self.dcp._list_cpl for source in sources: asset_stack = [source['FileName']] if 'PackingList' in source['Info']: source_xml = source['Info']['PackingList'] else: source_xml = source['Info']['CompositionPlaylist'] if not all_keys_in_dict(source_xml, ['Signer', 'Signature']): continue self.cert_list = [] self.cert_store = crypto.X509Store() self.cert_chains = source_xml['Signature']['KeyInfo']['X509Data'] for index, cert in reversed(list(enumerate(self.cert_chains))): cert_x509 = self.run_check(self.certif_der_decoding, cert) if not cert_x509: continue self.cert_store.add_cert(cert_x509) self.cert_list.append(cert_x509) stack = asset_stack + [ "Certificate {}".format(cert_x509.get_serial_number()) ] [ self.run_check(check, cert_x509, index, stack=stack) for check in self.find_check('certif') ] [ self.run_check(check, cert_x509, cert, stack=stack) for check in self.find_check('xml_certif') ] if not self.cert_list: return self.checks checks = self.find_check('sign') [ self.run_check(check, source_xml, stack=asset_stack) for check in checks ] checks = self.find_check('document') [ self.run_check(check, source_xml, source['FilePath'], stack=asset_stack) for check in checks ] return self.checks
def check_assets_cpl_cut(self, playlist, asset): """ CPL assets cut coherence check. """ _, asset = asset cut_keys = ['EntryPoint', 'OutPoint', 'IntrinsicDuration'] if all_keys_in_dict(asset, cut_keys): start = asset['EntryPoint'] end = asset['OutPoint'] dur = asset['IntrinsicDuration'] if start >= dur: raise CheckException("Invalid EntryPoint") if end > dur: raise CheckException("Invalid Duration")
def cpl_asset_parse_cut(asset, position): """ Parse an asset Cut """ edit_r = 0 # Format Editrate if 'EditRate' in asset: edit_r = format_ratio(asset['EditRate']) asset['EditRate'] = edit_r # Format Cut if all_keys_in_dict(asset, ["EditRate", "Duration", "EntryPoint"]): asset['OutPoint'] = asset['Duration'] + asset['EntryPoint'] asset['CPLEntryPoint'] = position asset['CPLOutPoint'] = position + asset['Duration'] asset['TimeCodeIn'] = frame_to_tc(asset['CPLEntryPoint'], edit_r) asset['TimeCodeOut'] = frame_to_tc(asset['CPLOutPoint'], edit_r) asset['TimeCodeDuration'] = frame_to_tc(asset['Duration'], edit_r)
def check_dcp_signed(self): """ DCP with encrypted content must be digitally signed. """ if self.dcp.schema != "SMPTE": return for cpl in self.dcp._list_cpl: cpl_node = cpl['Info']['CompositionPlaylist'] docs = [ pkl['Info']['PackingList'] for pkl in self.dcp._list_pkl if pkl['Info']['PackingList']['Id'] == cpl_node.get('PKLId') ] docs.append(cpl_node) for doc in docs: signed = all_keys_in_dict(doc, ['Signer', 'Signature']) if not signed and cpl_node['Encrypted'] is True: raise CheckException("Encrypted DCP must be signed")
def check_assets_cpl_cut(self, playlist, asset): """ CPL assets cut coherence check. References: SMPTE ST 429-7:2006 8.1.4, 8.1.5, 8.1.6 """ _, asset = asset cut_keys = ['EntryPoint', 'OutPoint', 'IntrinsicDuration'] if all_keys_in_dict(asset, cut_keys): start = asset['EntryPoint'] end = asset['OutPoint'] dur = asset['IntrinsicDuration'] if start >= dur: self.error("Invalid EntryPoint", "entrypoint") if end > dur: self.error("Invalid Duration", "duration")
def check_dcp_signed(self): """ DCP with encrypted content must be digitally signed. Reference : DCI Spec 1.3 5.4.3.7. DCI Spec 1.3 5.5.2.3. """ for cpl in self.dcp._list_cpl: cpl_node = cpl['Info']['CompositionPlaylist'] xmls = [ pkl['Info']['PackingList'] for pkl in self.dcp._list_pkl if pkl['Info']['PackingList']['Id'] == cpl_node.get('PKLId')] xmls.append(cpl_node) for xml in xmls: signed = all_keys_in_dict(xml, ['Signer', 'Signature']) if not signed and cpl_node['Encrypted'] is True: raise CheckException("Encrypted DCP must be signed")