From 37631b4d5e07eddbf052c1cff315d6a98b3bcb73 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 19 Jan 2021 00:05:44 +0100 Subject: Bv2.1 9.2: PKL must be signed if it contains encrypted assets. --- src/verify.cc | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/verify.cc') diff --git a/src/verify.cc b/src/verify.cc index 901f44bc..26173a5b 100644 --- a/src/verify.cc +++ b/src/verify.cc @@ -1061,6 +1061,36 @@ check_extension_metadata (shared_ptr cpl, vector& no } +bool +pkl_has_encrypted_assets (shared_ptr dcp, shared_ptr pkl) +{ + vector encrypted; + for (auto i: dcp->cpls()) { + for (auto j: i->reel_mxfs()) { + if (j->asset_ref().resolved()) { + /* It's a bit surprising / broken but Interop subtitle assets are represented + * in reels by ReelSubtitleAsset which inherits ReelMXF, so it's possible for + * ReelMXFs to have assets which are not MXFs. + */ + if (auto asset = dynamic_pointer_cast(j->asset_ref().asset())) { + if (asset->encrypted()) { + encrypted.push_back(j->asset_ref().id()); + } + } + } + } + } + + for (auto i: pkl->asset_list()) { + if (find(encrypted.begin(), encrypted.end(), i->id()) != encrypted.end()) { + return true; + } + } + + return false; +} + + vector dcp::verify ( vector directories, @@ -1336,6 +1366,13 @@ dcp::verify ( for (auto pkl: dcp->pkls()) { stage ("Checking PKL", pkl->file()); validate_xml (pkl->file().get(), xsd_dtd_directory, notes); + if (pkl_has_encrypted_assets(dcp, pkl)) { + cxml::Document doc ("PackingList"); + doc.read_file (pkl->file().get()); + if (!doc.optional_node_child("Signature")) { + notes.push_back ({VerificationNote::VERIFY_BV21_ERROR, VerificationNote::PKL_WITH_ENCRYPTED_CONTENT_NOT_SIGNED, pkl->file().get()}); + } + } } if (dcp->asset_map_path()) { @@ -1473,6 +1510,8 @@ dcp::note_to_string (dcp::VerificationNote note) return String::compose("The is malformed in some way: %1", note.note().get()); case dcp::VerificationNote::CPL_WITH_ENCRYPTED_CONTENT_NOT_SIGNED: return String::compose("The CPL %1, which has encrypted content, is not signed", note.file()->filename()); + case dcp::VerificationNote::PKL_WITH_ENCRYPTED_CONTENT_NOT_SIGNED: + return String::compose("The PKL %1, which has encrypted content, is not signed", note.file()->filename()); case dcp::VerificationNote::PKL_ANNOTATION_TEXT_DOES_NOT_MATCH_CPL_CONTENT_TITLE_TEXT: return String::compose("The PKL %1 has only one CPL but its does not match the CPL's ", note.file()->filename()); } -- cgit v1.2.3