diff options
| author | Carl Hetherington <cth@carlh.net> | 2021-01-19 00:05:44 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2021-01-19 00:10:24 +0100 |
| commit | 37631b4d5e07eddbf052c1cff315d6a98b3bcb73 (patch) | |
| tree | 546879f1ee943523ad6bce3cb79ede2e274baf60 /src | |
| parent | 49b30838def07c225481def5e54458c22f6ceece (diff) | |
Bv2.1 9.2: PKL must be signed if it contains encrypted assets.
Diffstat (limited to 'src')
| -rw-r--r-- | src/verify.cc | 39 | ||||
| -rw-r--r-- | src/verify.h | 2 |
2 files changed, 41 insertions, 0 deletions
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<dcp::CPL> cpl, vector<VerificationNote>& no } +bool +pkl_has_encrypted_assets (shared_ptr<DCP> dcp, shared_ptr<PKL> pkl) +{ + vector<string> 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<MXF>(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<VerificationNote> dcp::verify ( vector<boost::filesystem::path> 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 <ExtensionMetadata> 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 <AnnotationText> does not match the CPL's <ContentTitleText>", note.file()->filename()); } diff --git a/src/verify.h b/src/verify.h index 46c7b2e3..a48b65f3 100644 --- a/src/verify.h +++ b/src/verify.h @@ -175,6 +175,8 @@ public: INVALID_EXTENSION_METADATA, /** CPLs containing encrypted content must be signed Bv2.1_8.7 */ CPL_WITH_ENCRYPTED_CONTENT_NOT_SIGNED, + /** PKLs containing encrypted content must be signed Bv2.1_8.7 */ + PKL_WITH_ENCRYPTED_CONTENT_NOT_SIGNED, /** If a PKL has one CPL its <ContentTitleText> must be the same as the PKL's <AnnotationText> */ PKL_ANNOTATION_TEXT_DOES_NOT_MATCH_CPL_CONTENT_TITLE_TEXT }; |
