by full certificate.
+2018-11-09 Carl Hetherington <cth@carlh.net>
+
+ * Allow specification of trusted devices by thumbprint rather than full certificate.
+
2018-11-07 Carl Hetherington <cth@carlh.net>
* Add button to force re-encode of JPEG2000 content.
# Use distro-provided FFmpeg on Arch
deps = []
- deps.append(('libdcp', '7930f76'))
- deps.append(('libsub', '7bf99dc'))
+ deps.append(('libdcp', '27e1378'))
+ deps.append(('libsub', '2728525'))
deps.append(('rtaudio-cdist', '739969e'))
return deps
}
/** @param recipient KDM recipient certificate.
- * @param trusted_devices Certificates of other trusted devices (can be empty).
+ * @param trusted_devices Certificate thumbprints of other trusted devices (can be empty).
* @param cpl_file CPL filename.
* @param from KDM from time expressed as a local time with an offset from UTC.
* @param until KDM to time expressed as a local time with an offset from UTC.
dcp::EncryptedKDM
Film::make_kdm (
dcp::Certificate recipient,
- vector<dcp::Certificate> trusted_devices,
+ vector<string> trusted_devices,
boost::filesystem::path cpl_file,
dcp::LocalTime from,
dcp::LocalTime until,
if (i->recipient) {
dcp::EncryptedKDM const kdm = make_kdm (
i->recipient.get(),
- i->trusted_devices,
+ i->trusted_device_thumbprints(),
cpl_file,
dcp::LocalTime (from, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
dcp::LocalTime (until, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
dcp::EncryptedKDM make_kdm (
dcp::Certificate recipient,
- std::vector<dcp::Certificate> trusted_devices,
+ std::vector<std::string> trusted_devices,
boost::filesystem::path cpl_file,
dcp::LocalTime from,
dcp::LocalTime until,
#include "screen.h"
#include <libxml++/libxml++.h>
#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
+
+using std::string;
+using std::vector;
Screen::Screen (cxml::ConstNodePtr node)
: name (node->string_child("Name"))
}
BOOST_FOREACH (cxml::ConstNodePtr i, node->node_children ("TrustedDevice")) {
- trusted_devices.push_back (dcp::Certificate (i->content ()));
+ if (boost::algorithm::starts_with(i->content(), "-----BEGIN CERTIFICATE-----")) {
+ trusted_devices.push_back (TrustedDevice(dcp::Certificate(i->content())));
+ } else {
+ trusted_devices.push_back (TrustedDevice(i->content()));
+ }
}
}
parent->add_child("Notes")->add_child_text (notes);
- BOOST_FOREACH (dcp::Certificate const & i, trusted_devices) {
- parent->add_child("TrustedDevice")->add_child_text (i.certificate (true));
+ BOOST_FOREACH (TrustedDevice i, trusted_devices) {
+ parent->add_child("TrustedDevice")->add_child_text(i.as_string());
+ }
+}
+
+vector<string>
+Screen::trusted_device_thumbprints () const
+{
+ vector<string> t;
+ BOOST_FOREACH (TrustedDevice i, trusted_devices) {
+ t.push_back (i.thumbprint());
}
+ return t;
+}
+
+TrustedDevice::TrustedDevice (string thumbprint)
+ : _thumbprint (thumbprint)
+{
+
+}
+
+TrustedDevice::TrustedDevice (dcp::Certificate certificate)
+ : _certificate (certificate)
+{
+
+}
+
+string
+TrustedDevice::as_string () const
+{
+ if (_certificate) {
+ return _certificate->certificate(true);
+ }
+
+ return *_thumbprint;
+}
+
+string
+TrustedDevice::thumbprint () const
+{
+ if (_certificate) {
+ return _certificate->thumbprint ();
+ }
+
+ return *_thumbprint;
}
/*
- Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
+#ifndef DCPOMATIC_SCREEN_H
+#define DCPOMATIC_SCREEN_H
+
#include <dcp/certificate.h>
#include <libcxml/cxml.h>
#include <boost/optional.hpp>
class Cinema;
+class TrustedDevice
+{
+public:
+ explicit TrustedDevice (std::string);
+ explicit TrustedDevice (dcp::Certificate);
+
+ boost::optional<dcp::Certificate> certificate () const {
+ return _certificate;
+ }
+
+ std::string thumbprint () const;
+ std::string as_string () const;
+
+private:
+ boost::optional<dcp::Certificate> _certificate;
+ boost::optional<std::string> _thumbprint;
+};
+
/** @class Screen
* @brief A representation of a Screen for KDM generation.
*
- * This is the name of the screen and the certificate of its
- * `recipient' (i.e. the servers).
+ * This is the name of the screen, the certificate of its
+ * `recipient' (i.e. the mediablock) and the certificates/thumbprints
+ * of any trusted devices.
*/
class Screen
{
public:
- Screen (std::string const & n, boost::optional<dcp::Certificate> rec, std::vector<dcp::Certificate> td)
+ Screen (std::string const & n, boost::optional<dcp::Certificate> rec, std::vector<TrustedDevice> td)
: name (n)
, recipient (rec)
, trusted_devices (td)
explicit Screen (cxml::ConstNodePtr);
void as_xml (xmlpp::Element *) const;
+ std::vector<std::string> trusted_device_thumbprints () const;
boost::shared_ptr<Cinema> cinema;
std::string name;
std::string notes;
boost::optional<dcp::Certificate> recipient;
- std::vector<dcp::Certificate> trusted_devices;
+ std::vector<TrustedDevice> trusted_devices;
};
+
+#endif
#include "lib/version.h"
#include "lib/signal_manager.h"
#include "lib/log.h"
+#include "lib/screen.h"
#include "lib/job_manager.h"
#include "lib/exceptions.h"
#include "lib/cinema.h"
try {
kdm = _film->make_kdm (
Config::instance()->decryption_chain()->leaf(),
- vector<dcp::Certificate> (),
+ vector<string>(),
d->cpl (),
dcp::LocalTime ("2012-01-01T01:00:00+00:00"),
dcp::LocalTime ("2112-01-01T01:00:00+00:00"),
ScreenKDM (
i,
kdm.encrypt (
- signer, i->recipient.get(), i->trusted_devices, _output->formulation(),
+ signer, i->recipient.get(), i->trusted_device_thumbprints(), _output->formulation(),
!_output->forensic_mark_video(), _output->forensic_mark_audio() ? boost::optional<int>() : 0
)
)
kdm_from_dkdm (
dcp::DecryptedKDM dkdm,
dcp::Certificate target,
- vector<dcp::Certificate> trusted_devices,
+ vector<string> trusted_devices,
dcp::LocalTime valid_from,
dcp::LocalTime valid_to,
dcp::Formulation formulation,
kdm_from_dkdm (
dkdm,
i->recipient.get(),
- i->trusted_devices,
+ i->trusted_device_thumbprints(),
dcp::LocalTime(valid_from, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
dcp::LocalTime(valid_to, i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()),
formulation,
case 'C':
{
/* Make a new screen and add it to the current cinema */
- shared_ptr<Screen> screen (new Screen (screen_description, dcp::Certificate (dcp::file_to_string (optarg)), vector<dcp::Certificate>()));
+ shared_ptr<Screen> screen (new Screen (screen_description, dcp::Certificate (dcp::file_to_string (optarg)), vector<TrustedDevice>()));
if (cinema) {
cinema->add_screen (screen);
}
case 'T':
/* A trusted device ends up in the last screen we made */
if (!screens.empty ()) {
- screens.back()->trusted_devices.push_back (dcp::Certificate (dcp::file_to_string (optarg)));
+ screens.back()->trusted_devices.push_back(TrustedDevice(dcp::Certificate(dcp::file_to_string(optarg))));
}
break;
case 'B':
#include "wx_util.h"
#include "file_dialog_wrapper.h"
#include "download_certificate_dialog.h"
+#include "table_dialog.h"
#include "lib/compose.hpp"
#include "lib/util.h"
#include <dcp/exceptions.h>
using boost::bind;
static string
-column (dcp::Certificate c)
+column (TrustedDevice d)
{
- return c.thumbprint ();
+ return d.thumbprint ();
}
-class CertificateFileDialogWrapper : public FileDialogWrapper<dcp::Certificate>
+class TrustedDeviceDialog : public TableDialog
{
public:
- explicit CertificateFileDialogWrapper (wxWindow* parent)
- : FileDialogWrapper<dcp::Certificate> (parent, _("Select certificate file"))
+ explicit TrustedDeviceDialog (wxWindow* parent)
+ : TableDialog (parent, _("Trusted Device"), 3, 1, true)
{
+ add (_("Thumbprint"), true);
+ _thumbprint = add (new wxTextCtrl(this, wxID_ANY, wxT(""), wxDefaultPosition, wxSize(300, -1)));
+ _file = add (new wxButton(this, wxID_ANY, _("Load certificate...")));
+ layout ();
+
+ _file->Bind (wxEVT_BUTTON, bind(&TrustedDeviceDialog::load_certificate, this));
+ }
+
+ void load_certificate ()
+ {
+ wxFileDialog* d = new wxFileDialog (this, _("Trusted Device certificate"));
+ d->ShowModal ();
+ try {
+ _certificate = dcp::Certificate(dcp::file_to_string(wx_to_std(d->GetPath())));
+ _thumbprint->SetValue (std_to_wx(_certificate->thumbprint()));
+ } catch (dcp::MiscError& e) {
+ error_dialog (this, wxString::Format(_("Could not load certficate (%s)"), std_to_wx(e.what())));
+ }
+ }
+
+ void set (TrustedDevice t)
+ {
+ _certificate = t.certificate ();
+ _thumbprint->SetValue (std_to_wx(t.thumbprint()));
}
+
+ optional<TrustedDevice> get ()
+ {
+ string const t = wx_to_std (_thumbprint->GetValue ());
+ if (_certificate && _certificate->thumbprint() == t) {
+ return TrustedDevice (*_certificate);
+ } else if (t.length() == 28) {
+ return TrustedDevice (t);
+ }
+
+ return optional<TrustedDevice> ();
+ }
+
+private:
+ wxTextCtrl* _thumbprint;
+ wxButton* _file;
+ boost::optional<dcp::Certificate> _certificate;
};
ScreenDialog::ScreenDialog (
- wxWindow* parent, wxString title, string name, string notes, optional<dcp::Certificate> recipient, vector<dcp::Certificate> trusted_devices
+ wxWindow* parent, wxString title, string name, string notes, optional<dcp::Certificate> recipient, vector<TrustedDevice> trusted_devices
)
: wxDialog (parent, wxID_ANY, title)
, _recipient (recipient)
vector<string> columns;
columns.push_back (wx_to_std (_("Thumbprint")));
- _trusted_device_list = new EditableList<dcp::Certificate, CertificateFileDialogWrapper> (
+ _trusted_device_list = new EditableList<TrustedDevice, TrustedDeviceDialog> (
this,
columns,
bind (&ScreenDialog::trusted_devices, this),
/*
- Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
*/
#include "editable_list.h"
+#include "lib/screen.h"
#include <dcp/certificate.h>
#include <wx/wx.h>
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
class Progress;
-class CertificateFileDialogWrapper;
+class TrustedDeviceDialog;
class ScreenDialog : public wxDialog
{
std::string name = "",
std::string notes = "",
boost::optional<dcp::Certificate> c = boost::optional<dcp::Certificate> (),
- std::vector<dcp::Certificate> d = std::vector<dcp::Certificate> ()
+ std::vector<TrustedDevice> d = std::vector<TrustedDevice>()
);
std::string name () const;
std::string notes () const;
boost::optional<dcp::Certificate> recipient () const;
- std::vector<dcp::Certificate> trusted_devices () {
+ std::vector<TrustedDevice> trusted_devices () {
return _trusted_devices;
}
void setup_sensitivity ();
void set_recipient (boost::optional<dcp::Certificate>);
- void set_trusted_devices (std::vector<dcp::Certificate> d) {
+ void set_trusted_devices (std::vector<TrustedDevice> d) {
_trusted_devices = d;
}
wxStaticText* _recipient_thumbprint;
wxButton* _get_recipient_from_file;
wxButton* _download_recipient;
- EditableList<dcp::Certificate, CertificateFileDialogWrapper>* _trusted_device_list;
+ EditableList<TrustedDevice, TrustedDeviceDialog>* _trusted_device_list;
boost::optional<dcp::Certificate> _recipient;
- std::vector<dcp::Certificate> _trusted_devices;
+ std::vector<TrustedDevice> _trusted_devices;
};
#include "test.h"
#include "lib/film.h"
+#include "lib/screen.h"
#include "lib/dcp_subtitle_content.h"
#include "lib/ratio.h"
#include "lib/dcp_content_type.h"
#include <boost/test/unit_test.hpp>
using std::vector;
+using std::string;
using boost::shared_ptr;
/** Make an encrypted DCP, import it and make a new unencrypted DCP */
dcp::EncryptedKDM kdm = A->make_kdm (
Config::instance()->decryption_chain()->leaf (),
- vector<dcp::Certificate> (),
+ vector<string>(),
A_dcp.cpls().front()->file().get(),
dcp::LocalTime ("2014-07-21T00:00:00+00:00"),
dcp::LocalTime ("2024-07-21T00:00:00+00:00"),
/* Make a DKDM */
dcp::EncryptedKDM kdm = film->make_kdm (
Config::instance()->decryption_chain()->leaf(),
- vector<dcp::Certificate>(),
+ vector<string>(),
*cpl,
dcp::LocalTime ("2012-01-01T01:00:00+00:00"),
dcp::LocalTime ("2112-01-01T01:00:00+00:00"),
#include "lib/ffmpeg_content.h"
#include "lib/config.h"
#include "lib/cross.h"
+#include "lib/screen.h"
#include <dcp/cpl.h>
#include <boost/test/unit_test.hpp>
using std::vector;
+using std::string;
using boost::shared_ptr;
BOOST_AUTO_TEST_CASE (vf_kdm_test)
dcp::EncryptedKDM A_kdm = A->make_kdm (
Config::instance()->decryption_chain()->leaf (),
- vector<dcp::Certificate> (),
+ vector<string>(),
A_dcp.cpls().front()->file().get(),
dcp::LocalTime ("2014-07-21T00:00:00+00:00"),
dcp::LocalTime ("2024-07-21T00:00:00+00:00"),
dcp::EncryptedKDM B_kdm = B->make_kdm (
Config::instance()->decryption_chain()->leaf (),
- vector<dcp::Certificate> (),
+ vector<string>(),
B_dcp.cpls().front()->file().get(),
dcp::LocalTime ("2014-07-21T00:00:00+00:00"),
dcp::LocalTime ("2024-07-21T00:00:00+00:00"),