Correctly include keys for referenced encrypted DCPs in KDMs (#975).
authorCarl Hetherington <cth@carlh.net>
Sun, 12 Feb 2017 20:20:18 +0000 (20:20 +0000)
committerCarl Hetherington <cth@carlh.net>
Sun, 12 Feb 2017 20:20:18 +0000 (20:20 +0000)
ChangeLog
src/lib/film.cc
test/data

index 3c7af48e9d74c41b8505203ca1c9a01127269af5..84524fc23b18326d10f951921bb2400a7323778b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-02-12  Carl Hetherington  <cth@carlh.net>
+
+       * Fix missing keys in VF KDMs (#975).
+
 2017-02-10  Carl Hetherington  <cth@carlh.net>
 
        * Version 2.10.7 released.
index 9ffe09f6b811953e36e3fb6ea6b7a4e1fca38968..79eb313ce44de451e37184094e92454e2b492085 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -57,6 +57,8 @@
 #include <dcp/local_time.h>
 #include <dcp/decrypted_kdm.h>
 #include <dcp/raw_convert.h>
+#include <dcp/reel_mxf.h>
+#include <dcp/reel_asset.h>
 #include <libxml++/libxml++.h>
 #include <boost/filesystem.hpp>
 #include <boost/algorithm/string.hpp>
@@ -83,6 +85,9 @@ using std::cout;
 using std::list;
 using std::set;
 using std::runtime_error;
+using std::copy;
+using std::back_inserter;
+using std::map;
 using boost::shared_ptr;
 using boost::weak_ptr;
 using boost::dynamic_pointer_cast;
@@ -1232,8 +1237,42 @@ Film::make_kdm (
                throw InvalidSignerError ();
        }
 
+       /* Find keys that have been added to imported, encrypted DCP content */
+       list<dcp::DecryptedKDMKey> imported_keys;
+       BOOST_FOREACH (shared_ptr<Content> i, content()) {
+               shared_ptr<DCPContent> d = dynamic_pointer_cast<DCPContent> (i);
+               if (d && d->kdm()) {
+                       dcp::DecryptedKDM kdm (d->kdm().get(), Config::instance()->decryption_chain()->key().get());
+                       list<dcp::DecryptedKDMKey> keys = kdm.keys ();
+                       copy (keys.begin(), keys.end(), back_inserter (imported_keys));
+               }
+       }
+
+       map<shared_ptr<const dcp::ReelMXF>, dcp::Key> keys;
+
+       BOOST_FOREACH(shared_ptr<const dcp::ReelAsset> i, cpl->reel_assets ()) {
+               shared_ptr<const dcp::ReelMXF> mxf = boost::dynamic_pointer_cast<const dcp::ReelMXF> (i);
+               if (!mxf || !mxf->key_id()) {
+                       continue;
+               }
+
+               /* Get any imported key for this ID */
+               bool done = false;
+               BOOST_FOREACH (dcp::DecryptedKDMKey j, imported_keys) {
+                       if (j.id() == mxf->key_id().get()) {
+                               keys[mxf] = j.key();
+                               done = true;
+                       }
+               }
+
+               if (!done) {
+                       /* No imported key; it must be an asset that we encrypted */
+                       keys[mxf] = key();
+               }
+       }
+
        return dcp::DecryptedKDM (
-               cpl, key(), from, until, cpl->content_title_text(), cpl->content_title_text(), dcp::LocalTime().as_string()
+               cpl->id(), keys, from, until, cpl->content_title_text(), cpl->content_title_text(), dcp::LocalTime().as_string()
                ).encrypt (signer, recipient, trusted_devices, formulation);
 }
 
index b0c5a330fcb42082ff4f22c245721f3f88f9d74f..2e0db02e882f18d9a0923c19350eb0bac2abfefa 160000 (submodule)
--- a/test/data
+++ b/test/data
@@ -1 +1 @@
-Subproject commit b0c5a330fcb42082ff4f22c245721f3f88f9d74f
+Subproject commit 2e0db02e882f18d9a0923c19350eb0bac2abfefa