diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-01-17 01:31:38 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-01-22 14:34:25 +0100 |
| commit | 5e10a6f047d12f1e2e3d0e2f8ee30f93897a2227 (patch) | |
| tree | c3daccbbf2291d6330df2c2f6d99bf34fcb2e288 | |
| parent | c29ba2526337b486d4a3b1a1468513a22293bc87 (diff) | |
Allow KDMRecipient and hence Screen to convert certs to dcp::Certificate lazily.
This is pretty slow (as it runs the certificate through OpenSSL) and we
don't need to do it for every certificate in a database when we load the
database.
| -rw-r--r-- | src/lib/cinema_list.cc | 6 | ||||
| -rw-r--r-- | src/lib/dkdm_recipient.cc | 4 | ||||
| -rw-r--r-- | src/lib/dkdm_recipient_list.cc | 4 | ||||
| -rw-r--r-- | src/lib/kdm_cli.cc | 4 | ||||
| -rw-r--r-- | src/lib/kdm_recipient.cc | 34 | ||||
| -rw-r--r-- | src/lib/kdm_recipient.h | 22 | ||||
| -rw-r--r-- | src/lib/screen.cc | 6 | ||||
| -rw-r--r-- | src/lib/screen.h | 11 | ||||
| -rw-r--r-- | src/wx/recipients_panel.cc | 4 | ||||
| -rw-r--r-- | src/wx/screens_panel.cc | 4 | ||||
| -rw-r--r-- | test/cinema_list_test.cc | 12 | ||||
| -rw-r--r-- | test/dkdm_recipient_list_test.cc | 4 |
12 files changed, 84 insertions, 31 deletions
diff --git a/src/lib/cinema_list.cc b/src/lib/cinema_list.cc index f59a8f4f8..01824ca54 100644 --- a/src/lib/cinema_list.cc +++ b/src/lib/cinema_list.cc @@ -309,7 +309,7 @@ CinemaList::add_screen(CinemaID cinema_id, dcpomatic::Screen const& screen) add_screen.bind_int64(1, cinema_id.get()); add_screen.bind_text(2, screen.name); add_screen.bind_text(3, screen.notes); - add_screen.bind_text(4, screen.recipient->certificate(true)); + add_screen.bind_text(4, screen.recipient()->certificate(true)); add_screen.bind_text(5, screen.recipient_file.get_value_or("")); add_screen.execute(); @@ -332,7 +332,7 @@ dcpomatic::Screen CinemaList::screen_from_result(SQLiteStatement& statement, ScreenID screen_id) const { auto certificate_string = statement.column_text(4); - optional<dcp::Certificate> certificate = certificate_string.empty() ? optional<dcp::Certificate>() : dcp::Certificate(certificate_string); + optional<string> certificate = certificate_string.empty() ? optional<string>() : certificate_string; auto recipient_file_string = statement.column_text(5); optional<string> recipient_file = recipient_file_string.empty() ? optional<string>() : recipient_file_string; @@ -429,7 +429,7 @@ CinemaList::update_screen(CinemaID cinema_id, ScreenID screen_id, dcpomatic::Scr statement.bind_int64(1, cinema_id.get()); statement.bind_text(2, screen.name); statement.bind_text(3, screen.notes); - statement.bind_text(4, screen.recipient->certificate(true)); + statement.bind_text(4, screen.recipient()->certificate(true)); statement.bind_text(5, screen.recipient_file.get_value_or("")); statement.bind_int64(6, screen_id.get()); diff --git a/src/lib/dkdm_recipient.cc b/src/lib/dkdm_recipient.cc index 4ab532f3d..bd14aedea 100644 --- a/src/lib/dkdm_recipient.cc +++ b/src/lib/dkdm_recipient.cc @@ -41,7 +41,7 @@ kdm_for_dkdm_recipient ( dcp::LocalTime valid_to ) { - if (!recipient.recipient) { + if (!recipient.recipient()) { return {}; } @@ -51,7 +51,7 @@ kdm_for_dkdm_recipient ( } auto const decrypted_kdm = film->make_kdm(cpl, valid_from, valid_to); - auto const kdm = decrypted_kdm.encrypt(signer, recipient.recipient.get(), {}, dcp::Formulation::MODIFIED_TRANSITIONAL_1, true, 0); + auto const kdm = decrypted_kdm.encrypt(signer, recipient.recipient().get(), {}, dcp::Formulation::MODIFIED_TRANSITIONAL_1, true, 0); dcp::NameFormat::Map name_values; name_values['f'] = kdm.content_title_text(); diff --git a/src/lib/dkdm_recipient_list.cc b/src/lib/dkdm_recipient_list.cc index 34179337e..f67379122 100644 --- a/src/lib/dkdm_recipient_list.cc +++ b/src/lib/dkdm_recipient_list.cc @@ -154,7 +154,7 @@ DKDMRecipientList::add_dkdm_recipient(DKDMRecipient const& dkdm_recipient) add_dkdm_recipient.bind_text(1, dkdm_recipient.name); add_dkdm_recipient.bind_text(2, dkdm_recipient.notes); - add_dkdm_recipient.bind_text(3, dkdm_recipient.recipient ? dkdm_recipient.recipient->certificate(true) : ""); + add_dkdm_recipient.bind_text(3, dkdm_recipient.recipient() ? dkdm_recipient.recipient()->certificate(true) : ""); add_dkdm_recipient.bind_text(4, join_strings(dkdm_recipient.emails)); add_dkdm_recipient.execute(); @@ -170,7 +170,7 @@ DKDMRecipientList::update_dkdm_recipient(DKDMRecipientID id, DKDMRecipient const add_dkdm_recipient.bind_text(1, dkdm_recipient.name); add_dkdm_recipient.bind_text(2, dkdm_recipient.notes); - add_dkdm_recipient.bind_text(3, dkdm_recipient.recipient ? dkdm_recipient.recipient->certificate(true) : ""); + add_dkdm_recipient.bind_text(3, dkdm_recipient.recipient() ? dkdm_recipient.recipient()->certificate(true) : ""); add_dkdm_recipient.bind_text(4, join_strings(dkdm_recipient.emails)); add_dkdm_recipient.bind_int64(5, id.get()); diff --git a/src/lib/kdm_cli.cc b/src/lib/kdm_cli.cc index 686d2b4a1..c820fb22a 100644 --- a/src/lib/kdm_cli.cc +++ b/src/lib/kdm_cli.cc @@ -380,13 +380,13 @@ from_dkdm ( try { list<KDMWithMetadataPtr> kdms; for (auto const& screen_details: screens) { - if (!screen_details.screen.recipient) { + if (!screen_details.screen.recipient()) { continue; } auto const kdm = kdm_from_dkdm( dkdm, - screen_details.screen.recipient.get(), + screen_details.screen.recipient().get(), screen_details.screen.trusted_device_thumbprints(), valid_from, valid_to, diff --git a/src/lib/kdm_recipient.cc b/src/lib/kdm_recipient.cc index c33eb1b9f..7e7e14324 100644 --- a/src/lib/kdm_recipient.cc +++ b/src/lib/kdm_recipient.cc @@ -22,14 +22,17 @@ #include "kdm_recipient.h" +using boost::optional; + + KDMRecipient::KDMRecipient (cxml::ConstNodePtr node) : name (node->string_child("Name")) , notes (node->optional_string_child("Notes").get_value_or("")) { if (node->optional_string_child("Certificate")) { - recipient = dcp::Certificate (node->string_child("Certificate")); + _recipient = dcp::Certificate(node->string_child("Certificate")); } else if (node->optional_string_child("Recipient")) { - recipient = dcp::Certificate (node->string_child("Recipient")); + _recipient = dcp::Certificate(node->string_child("Recipient")); } recipient_file = node->optional_string_child("RecipientFile"); @@ -40,8 +43,8 @@ void KDMRecipient::as_xml (xmlpp::Element* parent) const { cxml::add_text_child(parent, "Name", name); - if (recipient) { - cxml::add_text_child(parent, "Recipient", recipient->certificate(true)); + if (auto const r = recipient()) { + cxml::add_text_child(parent, "Recipient", r->certificate(true)); } if (recipient_file) { cxml::add_text_child(parent, "RecipientFile", *recipient_file); @@ -50,3 +53,26 @@ KDMRecipient::as_xml (xmlpp::Element* parent) const cxml::add_text_child(parent, "Notes", notes); } + +boost::optional<dcp::Certificate> +KDMRecipient::recipient() const +{ + if (_recipient) { + return _recipient; + } + + if (_recipient_string) { + return dcp::Certificate(*_recipient_string); + } + + return {}; +} + + +void +KDMRecipient::set_recipient(optional<dcp::Certificate> certificate) +{ + _recipient = certificate; + _recipient_string = {}; +} + diff --git a/src/lib/kdm_recipient.h b/src/lib/kdm_recipient.h index f18e71429..9fe75874d 100644 --- a/src/lib/kdm_recipient.h +++ b/src/lib/kdm_recipient.h @@ -36,11 +36,18 @@ LIBDCP_ENABLE_WARNINGS class KDMRecipient { public: - KDMRecipient (std::string const& name_, std::string const& notes_, boost::optional<dcp::Certificate> recipient_, boost::optional<std::string> recipient_file_) + KDMRecipient (std::string const& name_, std::string const& notes_, boost::optional<dcp::Certificate> recipient, boost::optional<std::string> recipient_file_) : name (name_) , notes (notes_) - , recipient (recipient_) , recipient_file (recipient_file_) + , _recipient(recipient) + {} + + KDMRecipient(std::string const& name_, std::string const& notes_, boost::optional<std::string> recipient, boost::optional<std::string> recipient_file_) + : name(name_) + , notes(notes_) + , recipient_file(recipient_file_) + , _recipient_string(recipient) {} explicit KDMRecipient (cxml::ConstNodePtr); @@ -49,13 +56,22 @@ public: virtual void as_xml (xmlpp::Element *) const; + boost::optional<dcp::Certificate> recipient() const; + void set_recipient(boost::optional<dcp::Certificate> certificate); + std::string name; std::string notes; - boost::optional<dcp::Certificate> recipient; /** The pathname or URL that the recipient certificate was obtained from; purely * to inform the user. */ boost::optional<std::string> recipient_file; + +private: + /* The recipient certificate may be stored as either a string or a dcp::Certificate; + * the string is useful if we want to be lazy about constructing the dcp::Certificate. + */ + boost::optional<dcp::Certificate> _recipient; + boost::optional<std::string> _recipient_string; }; diff --git a/src/lib/screen.cc b/src/lib/screen.cc index b77eb6b52..304fb52f3 100644 --- a/src/lib/screen.cc +++ b/src/lib/screen.cc @@ -65,11 +65,11 @@ kdm_for_screen ( vector<KDMCertificatePeriod>& period_checks ) { - if (!screen.recipient) { + if (!screen.recipient()) { return {}; } - period_checks.push_back(check_kdm_and_certificate_validity_periods(cinema.name, screen.name, screen.recipient.get(), valid_from, valid_to)); + period_checks.push_back(check_kdm_and_certificate_validity_periods(cinema.name, screen.name, screen.recipient().get(), valid_from, valid_to)); auto signer = Config::instance()->signer_chain(); if (!signer->valid()) { @@ -77,7 +77,7 @@ kdm_for_screen ( } auto kdm = make_kdm(valid_from, valid_to).encrypt( - signer, screen.recipient.get(), screen.trusted_device_thumbprints(), formulation, disable_forensic_marking_picture, disable_forensic_marking_audio + signer, screen.recipient().get(), screen.trusted_device_thumbprints(), formulation, disable_forensic_marking_picture, disable_forensic_marking_audio ); dcp::NameFormat::Map name_values; diff --git a/src/lib/screen.h b/src/lib/screen.h index 89ebc3ab4..326bc9403 100644 --- a/src/lib/screen.h +++ b/src/lib/screen.h @@ -64,6 +64,17 @@ public: , trusted_devices (trusted_devices_) {} + Screen( + std::string const & name_, + std::string const & notes_, + boost::optional<std::string> recipient_, + boost::optional<std::string> recipient_file_, + std::vector<TrustedDevice> trusted_devices_ + ) + : KDMRecipient(name_, notes_, recipient_, recipient_file_) + , trusted_devices(trusted_devices_) + {} + std::vector<std::string> trusted_device_thumbprints () const; std::vector<TrustedDevice> trusted_devices; }; diff --git a/src/wx/recipients_panel.cc b/src/wx/recipients_panel.cc index 33b715260..ff19c0227 100644 --- a/src/wx/recipients_panel.cc +++ b/src/wx/recipients_panel.cc @@ -149,14 +149,14 @@ RecipientsPanel::edit_recipient_clicked () recipient->name, recipient->notes, recipient->emails, - recipient->recipient + recipient->recipient() ); if (dialog.ShowModal() == wxID_OK) { recipient->name = dialog.name(); recipient->emails = dialog.emails(); recipient->notes = dialog.notes(); - recipient->recipient = dialog.recipient(); + recipient->set_recipient(dialog.recipient()); recipients.update_dkdm_recipient(recipient_id, *recipient); _targets->SetItemText(selection.first, std_to_wx(dialog.name())); } diff --git a/src/wx/screens_panel.cc b/src/wx/screens_panel.cc index 221af30b7..6de1d86f0 100644 --- a/src/wx/screens_panel.cc +++ b/src/wx/screens_panel.cc @@ -415,7 +415,7 @@ ScreensPanel::edit_screen(CinemaID cinema_id, ScreenID screen_id) GetParent(), _("Edit screen"), screen->name, screen->notes, - screen->recipient, + screen->recipient(), screen->recipient_file, screen->trusted_devices ); @@ -439,7 +439,7 @@ ScreensPanel::edit_screen(CinemaID cinema_id, ScreenID screen_id) screen->name = dialog.name(); screen->notes = dialog.notes(); - screen->recipient = dialog.recipient(); + screen->set_recipient(dialog.recipient()); screen->recipient_file = dialog.recipient_file(); screen->trusted_devices = dialog.trusted_devices(); _cinema_list.update_screen(cinema_id, screen_id, *screen); diff --git a/test/cinema_list_test.cc b/test/cinema_list_test.cc index c19b88315..58af7839a 100644 --- a/test/cinema_list_test.cc +++ b/test/cinema_list_test.cc @@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE(add_screen_test) BOOST_CHECK(check[0].first == screen_id); BOOST_CHECK_EQUAL(check[0].second.name, "Screen 1"); BOOST_CHECK_EQUAL(check[0].second.notes, "Smells of popcorn"); - BOOST_CHECK(check[0].second.recipient == dcp::Certificate(dcp::file_to_string("test/data/cert.pem"))); + BOOST_CHECK(check[0].second.recipient() == dcp::Certificate(dcp::file_to_string("test/data/cert.pem"))); BOOST_CHECK(check[0].second.recipient_file == string("test/data/cert.pem")); } @@ -208,7 +208,7 @@ BOOST_AUTO_TEST_CASE(update_screen_test) BOOST_CHECK(check[0].first == screen_id); BOOST_CHECK_EQUAL(check[0].second.name, "Screen 1 updated"); BOOST_CHECK_EQUAL(check[0].second.notes, "Smells of popcorn and hope"); - BOOST_CHECK(check[0].second.recipient == dcp::Certificate(dcp::file_to_string("test/data/cert.pem"))); + BOOST_CHECK(check[0].second.recipient() == dcp::Certificate(dcp::file_to_string("test/data/cert.pem"))); BOOST_CHECK(check[0].second.recipient_file == string("test/data/cert.pem")); } @@ -247,11 +247,11 @@ BOOST_AUTO_TEST_CASE(cinemas_list_copy_from_xml_test) BOOST_CHECK_EQUAL(screens.size(), 2U); auto screen_iter = screens.begin(); BOOST_CHECK_EQUAL(screen_iter->second.name, "1"); - BOOST_CHECK(screen_iter->second.recipient); - BOOST_CHECK_EQUAL(screen_iter->second.recipient->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI="); + BOOST_CHECK(screen_iter->second.recipient()); + BOOST_CHECK_EQUAL(screen_iter->second.recipient()->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI="); ++screen_iter; BOOST_CHECK_EQUAL(screen_iter->second.name, "2"); - BOOST_CHECK(screen_iter->second.recipient); - BOOST_CHECK_EQUAL(screen_iter->second.recipient->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI="); + BOOST_CHECK(screen_iter->second.recipient()); + BOOST_CHECK_EQUAL(screen_iter->second.recipient()->subject_dn_qualifier(), "CVsuuv9eYsQZSl8U4fDpvOmzZhI="); } diff --git a/test/dkdm_recipient_list_test.cc b/test/dkdm_recipient_list_test.cc index 406d181a1..9d4486595 100644 --- a/test/dkdm_recipient_list_test.cc +++ b/test/dkdm_recipient_list_test.cc @@ -45,12 +45,12 @@ BOOST_AUTO_TEST_CASE(dkdm_receipient_list_copy_from_xml_test) BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails.size(), 2U); BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails[0], "epicbob@gmail.com"); BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.emails[1], "boblikesemlong@cinema-bob.com"); - BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient->subject_dn_qualifier(), "r5/Q5f3UTm7qzoF5QzNZP6aEuvI="); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient()->subject_dn_qualifier(), "r5/Q5f3UTm7qzoF5QzNZP6aEuvI="); ++dkdm_recipient_iter; BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.name, "Sharon's Shorts"); BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.notes, "Even if it sucks, at least it's over quickly"); - BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient->subject_dn_qualifier(), "FHerM3Us/DWuqD1MnztStSlFJO0="); + BOOST_CHECK_EQUAL(dkdm_recipient_iter->second.recipient()->subject_dn_qualifier(), "FHerM3Us/DWuqD1MnztStSlFJO0="); ++dkdm_recipient_iter; } |
