From 2199f765aca8727da11dd0f33f7dfc59e39bf455 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Mon, 13 May 2019 23:45:05 +0100 Subject: [PATCH] swaroop: basics of ECinema support in KDM creator. --- src/tools/dcpomatic_kdm.cc | 155 +++++++++++++++++++++++++++---------- 1 file changed, 113 insertions(+), 42 deletions(-) diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index fc4282535..9f1c28c99 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -46,6 +46,9 @@ #include "lib/cinema.h" #include "lib/dkdm_wrapper.h" #include "lib/cross.h" +#ifdef DCPOMATIC_VARIANT_SWAROOP +#include "lib/decrypted_ecinema_kdm.h" +#endif #include #include #include @@ -299,57 +302,88 @@ private: if (!dkdm_base) { return; } - shared_ptr dkdm = boost::dynamic_pointer_cast (dkdm_base); - if (!dkdm) { - return; - } - /* Decrypt the DKDM */ - dcp::DecryptedKDM decrypted (dkdm->dkdm(), Config::instance()->decryption_chain()->key().get()); + list > screen_kdms; + string title; + +#ifdef DCPOMATIC_VARIANT_SWAROOP + shared_ptr ecinema_dkdm = boost::dynamic_pointer_cast (dkdm_base); + if (ecinema_dkdm) { + DecryptedECinemaKDM decrypted (ecinema_dkdm->dkdm(), Config::instance()->decryption_chain()->key().get()); + title = decrypted.name (); - /* This is the signer for our new KDMs */ - shared_ptr signer = Config::instance()->signer_chain (); - if (!signer->valid ()) { - throw InvalidSignerError (); - } + BOOST_FOREACH (shared_ptr i, _screens->screens()) { - list > screen_kdms; - BOOST_FOREACH (shared_ptr i, _screens->screens()) { + if (!i->recipient) { + continue; + } - if (!i->recipient) { - continue; + DecryptedECinemaKDM kdm (decrypted.id(), decrypted.name(), decrypted.key()); + + /* Encrypt */ + screen_kdms.push_back ( + shared_ptr( + new ECinemaScreenKDM(i, kdm.encrypt(i->recipient.get())) + ) + ); } + } +#endif - /* Make an empty KDM */ - dcp::DecryptedKDM kdm ( - dcp::LocalTime (_timing->from(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()), - dcp::LocalTime (_timing->until(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()), - decrypted.annotation_text().get_value_or (""), - decrypted.content_title_text(), - dcp::LocalTime().as_string() - ); + shared_ptr dkdm = boost::dynamic_pointer_cast (dkdm_base); + if (dkdm) { + + /* Decrypt the DKDM */ + dcp::DecryptedKDM decrypted (dkdm->dkdm(), Config::instance()->decryption_chain()->key().get()); + title = decrypted.content_title_text (); - /* Add keys from the DKDM */ - BOOST_FOREACH (dcp::DecryptedKDMKey const & j, decrypted.keys()) { - kdm.add_key (j); + /* This is the signer for our new KDMs */ + shared_ptr signer = Config::instance()->signer_chain (); + if (!signer->valid ()) { + throw InvalidSignerError (); } - /* Encrypt */ - screen_kdms.push_back ( - shared_ptr( - new DCPScreenKDM( - i, - kdm.encrypt( - signer, i->recipient.get(), i->trusted_device_thumbprints(), _output->formulation(), - !_output->forensic_mark_video(), _output->forensic_mark_audio() ? boost::optional() : 0 + BOOST_FOREACH (shared_ptr i, _screens->screens()) { + + if (!i->recipient) { + continue; + } + + /* Make an empty KDM */ + dcp::DecryptedKDM kdm ( + dcp::LocalTime (_timing->from(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()), + dcp::LocalTime (_timing->until(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()), + decrypted.annotation_text().get_value_or (""), + decrypted.content_title_text(), + dcp::LocalTime().as_string() + ); + + /* Add keys from the DKDM */ + BOOST_FOREACH (dcp::DecryptedKDMKey const & j, decrypted.keys()) { + kdm.add_key (j); + } + + /* Encrypt */ + screen_kdms.push_back ( + shared_ptr( + new DCPScreenKDM( + i, + kdm.encrypt( + signer, i->recipient.get(), i->trusted_device_thumbprints(), _output->formulation(), + !_output->forensic_mark_video(), _output->forensic_mark_audio() ? boost::optional() : 0 + ) ) ) - ) - ); + ); + } + } + + if (screen_kdms.empty()) { + return; } pair, int> result = _output->make ( - screen_kdms, decrypted.content_title_text(), _timing, bind (&DOMFrame::confirm_overwrite, this, _1) + screen_kdms, title, _timing, bind (&DOMFrame::confirm_overwrite, this, _1) ); if (result.first) { @@ -425,16 +459,53 @@ private: { wxFileDialog* d = new wxFileDialog (this, _("Select DKDM file")); if (d->ShowModal() == wxID_OK) { - shared_ptr new_dkdm; + shared_ptr chain = Config::instance()->decryption_chain(); + DCPOMATIC_ASSERT (chain->key()); + +#ifdef DCPOMATIC_VARIANT_SWAROOP try { - dcp::EncryptedKDM ekdm(dcp::file_to_string (wx_to_std (d->GetPath ()), MAX_KDM_SIZE)); + cxml::Document test_doc; + string const xml_string = dcp::file_to_string (wx_to_std(d->GetPath()), MAX_KDM_SIZE); + test_doc.read_string (xml_string); + if (test_doc.root_name() == "ECinemaSecurityMessage") { + EncryptedECinemaKDM ekdm(xml_string); + /* Decrypt the DKDM to make sure that we can */ + DecryptedECinemaKDM dkdm(ekdm, chain->key().get()); + + shared_ptr new_dkdm(new ECinemaDKDM(ekdm)); + shared_ptr group = dynamic_pointer_cast (selected_dkdm()); + if (!group) { + group = Config::instance()->dkdms(); + } + add_dkdm_model (new_dkdm, group); + add_dkdm_view (new_dkdm); + d->Destroy (); + return; + } + } catch (KDMError& e) { + error_dialog ( + this, "Could not read file as a KDM. Perhaps it is badly formatted, created with the wrong certificate, or not a KDM at all.", + std_to_wx(e.what()) + ); + d->Destroy (); + return; + } catch (dcp::MiscError& e) { + error_dialog ( + this, + _("Could not read file as a KDM. It is much too large. Make sure you are loading a DKDM (XML) file."), + std_to_wx(e.what()) + ); + d->Destroy (); + return; + } +#endif + try { + dcp::EncryptedKDM ekdm(dcp::file_to_string (wx_to_std (d->GetPath ()), MAX_KDM_SIZE)); /* Decrypt the DKDM to make sure that we can */ - shared_ptr chain = Config::instance()->decryption_chain(); - DCPOMATIC_ASSERT (chain->key()); dcp::DecryptedKDM dkdm(ekdm, chain->key().get()); - new_dkdm.reset(new DKDM(ekdm)); + shared_ptr new_dkdm(new DKDM(ekdm)); shared_ptr group = dynamic_pointer_cast (selected_dkdm ()); if (!group) { group = Config::instance()->dkdms (); -- 2.30.2