summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2021-01-19 00:05:44 +0100
committerCarl Hetherington <cth@carlh.net>2021-01-19 00:10:24 +0100
commit37631b4d5e07eddbf052c1cff315d6a98b3bcb73 (patch)
tree546879f1ee943523ad6bce3cb79ede2e274baf60 /src
parent49b30838def07c225481def5e54458c22f6ceece (diff)
Bv2.1 9.2: PKL must be signed if it contains encrypted assets.
Diffstat (limited to 'src')
-rw-r--r--src/verify.cc39
-rw-r--r--src/verify.h2
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
};