summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2025-01-17 01:31:38 +0100
committerCarl Hetherington <cth@carlh.net>2025-01-22 14:34:25 +0100
commit5e10a6f047d12f1e2e3d0e2f8ee30f93897a2227 (patch)
treec3daccbbf2291d6330df2c2f6d99bf34fcb2e288
parentc29ba2526337b486d4a3b1a1468513a22293bc87 (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.cc6
-rw-r--r--src/lib/dkdm_recipient.cc4
-rw-r--r--src/lib/dkdm_recipient_list.cc4
-rw-r--r--src/lib/kdm_cli.cc4
-rw-r--r--src/lib/kdm_recipient.cc34
-rw-r--r--src/lib/kdm_recipient.h22
-rw-r--r--src/lib/screen.cc6
-rw-r--r--src/lib/screen.h11
-rw-r--r--src/wx/recipients_panel.cc4
-rw-r--r--src/wx/screens_panel.cc4
-rw-r--r--test/cinema_list_test.cc12
-rw-r--r--test/dkdm_recipient_list_test.cc4
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;
}