Bv2.1 10.1: if any asset is encrypted they all must be.
authorCarl Hetherington <cth@carlh.net>
Mon, 18 Jan 2021 23:33:14 +0000 (00:33 +0100)
committerCarl Hetherington <cth@carlh.net>
Mon, 18 Jan 2021 23:33:14 +0000 (00:33 +0100)
src/verify.cc
src/verify.h
test/verify_test.cc

index 3b0fb7c9c34d7cd864cdc30b0edbbf58473b7d28..5644d36998c69d2eb5acbe7f6367dee08d49e764 100644 (file)
@@ -1131,6 +1131,10 @@ dcp::verify (
                        stage ("Checking CPL", cpl->file());
                        validate_xml (cpl->file().get(), xsd_dtd_directory, notes);
 
+                       if (cpl->any_encrypted() && !cpl->all_encrypted()) {
+                               notes.push_back ({VerificationNote::VERIFY_BV21_ERROR, VerificationNote::PARTIALLY_ENCRYPTED});
+                       }
+
                        for (auto const& i: cpl->additional_subtitle_languages()) {
                                verify_language_tag (i, notes);
                        }
@@ -1514,6 +1518,8 @@ dcp::note_to_string (dcp::VerificationNote note)
                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());
+       case dcp::VerificationNote::PARTIALLY_ENCRYPTED:
+               return "Some assets are encrypted but some are not";
        }
 
        return "";
index a48b65f3d11bde048055fcd9c7d1c8b975506d82..32a369d06b78cec15266519801dda6d21d4d41bf 100644 (file)
@@ -178,7 +178,9 @@ public:
                /** 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
+               PKL_ANNOTATION_TEXT_DOES_NOT_MATCH_CPL_CONTENT_TITLE_TEXT,
+               /** If any content is encrypted, everything must be encrypted */
+               PARTIALLY_ENCRYPTED,
        };
 
        VerificationNote (Type type, Code code)
index f0c6b644e6bf3285e6f84060ad8c943c650cbe51..7aad7a42d950b560450f7b88fd60b80833021f1e 100644 (file)
@@ -2622,3 +2622,62 @@ BOOST_AUTO_TEST_CASE (verify_unencrypted_pkl_can_be_unsigned)
        check_verify_result ({dir}, {});
 }
 
+
+BOOST_AUTO_TEST_CASE (verify_must_not_be_partially_encrypted)
+{
+       boost::filesystem::path dir ("build/test/verify_must_not_be_partially_encrypted");
+       prepare_directory (dir);
+
+       dcp::DCP d (dir);
+
+       auto signer = make_shared<dcp::CertificateChain>();
+       signer->add (dcp::Certificate(dcp::file_to_string("test/ref/crypt/ca.self-signed.pem")));
+       signer->add (dcp::Certificate(dcp::file_to_string("test/ref/crypt/intermediate.signed.pem")));
+       signer->add (dcp::Certificate(dcp::file_to_string("test/ref/crypt/leaf.signed.pem")));
+       signer->set_key (dcp::file_to_string("test/ref/crypt/leaf.key"));
+
+       auto cpl = make_shared<dcp::CPL>("A Test DCP", dcp::TRAILER);
+
+       dcp::Key key;
+
+       auto mp = make_shared<dcp::MonoPictureAsset>(dcp::Fraction (24, 1), dcp::SMPTE);
+       mp->set_key (key);
+
+       auto writer = mp->start_write (dir / "video.mxf", false);
+       dcp::ArrayData j2c ("test/data/flat_red.j2c");
+       for (int i = 0; i < 24; ++i) {
+               writer->write (j2c.data(), j2c.size());
+       }
+       writer->finalize ();
+
+       auto ms = simple_sound (dir, "", dcp::MXFMetadata(), "de-DE");
+
+       auto reel = make_shared<dcp::Reel>(
+               make_shared<dcp::ReelMonoPictureAsset>(mp, 0),
+               make_shared<dcp::ReelSoundAsset>(ms, 0)
+               );
+
+       reel->add (simple_markers());
+
+       cpl->add (reel);
+
+       cpl->set_content_version (
+               {"urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00", "81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00"}
+               );
+       cpl->set_annotation_text ("A Test DCP");
+       cpl->set_issuer ("OpenDCP 0.0.25");
+       cpl->set_creator ("OpenDCP 0.0.25");
+       cpl->set_issue_date ("2012-07-17T04:45:18+00:00");
+       cpl->set_main_sound_configuration ("L,C,R,Lfe,-,-");
+       cpl->set_main_sound_sample_rate (48000);
+       cpl->set_main_picture_stored_area (dcp::Size(1998, 1080));
+       cpl->set_main_picture_active_area (dcp::Size(1440, 1080));
+       cpl->set_version_number (1);
+
+       d.add (cpl);
+
+       d.write_xml (dcp::SMPTE, "OpenDCP 0.0.25", "OpenDCP 0.0.25", "2012-07-17T04:45:18+00:00", "A Test DCP", signer);
+
+       check_verify_result ({dir}, {{dcp::VerificationNote::VERIFY_BV21_ERROR, dcp::VerificationNote::PARTIALLY_ENCRYPTED}});
+}
+