Allow specification of trusted devices by thumbprint rather than v2.13.68
authorCarl Hetherington <cth@carlh.net>
Fri, 9 Nov 2018 00:04:23 +0000 (00:04 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 9 Nov 2018 00:04:23 +0000 (00:04 +0000)
by full certificate.

14 files changed:
ChangeLog
cscript
src/lib/film.cc
src/lib/film.h
src/lib/screen.cc
src/lib/screen.h
src/tools/dcpomatic.cc
src/tools/dcpomatic_kdm.cc
src/tools/dcpomatic_kdm_cli.cc
src/wx/screen_dialog.cc
src/wx/screen_dialog.h
test/import_dcp_test.cc
test/remake_id_test.cc
test/vf_kdm_test.cc

index a9d6d8b..02bb1e7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+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.
diff --git a/cscript b/cscript
index 9f0460b..9f12046 100644 (file)
--- a/cscript
+++ b/cscript
@@ -341,8 +341,8 @@ def dependencies(target):
         # 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
index 2ff02d7..426c7f8 100644 (file)
@@ -1259,7 +1259,7 @@ Film::frame_size () const
 }
 
 /** @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.
@@ -1271,7 +1271,7 @@ Film::frame_size () const
 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,
@@ -1357,7 +1357,7 @@ Film::make_kdms (
                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()),
index d251c7f..4656da9 100644 (file)
@@ -130,7 +130,7 @@ public:
 
        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,
index fe8369c..5ec00f9 100644 (file)
 #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"))
@@ -33,7 +37,11 @@ Screen::Screen (cxml::ConstNodePtr node)
        }
 
        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()));
+               }
        }
 }
 
@@ -47,7 +55,49 @@ Screen::as_xml (xmlpp::Element* parent) const
 
        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;
 }
index 5e8f1f9..eff2e5f 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    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.
 
@@ -18,6 +18,9 @@
 
 */
 
+#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)
@@ -43,10 +65,13 @@ public:
        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
index 4d6a289..3d74859 100644 (file)
@@ -55,6 +55,7 @@
 #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"
@@ -823,7 +824,7 @@ private:
                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"),
index 184319a..e901d2d 100644 (file)
@@ -332,7 +332,7 @@ private:
                                        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
                                                        )
                                                )
index f1849ad..3dc3f21 100644 (file)
@@ -273,7 +273,7 @@ dcp::EncryptedKDM
 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,
@@ -337,7 +337,7 @@ from_dkdm (
                                        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,
@@ -500,7 +500,7 @@ int main (int argc, char* argv[])
                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);
                        }
@@ -510,7 +510,7 @@ int main (int argc, char* argv[])
                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':
index 8f00861..f5d4b04 100644 (file)
@@ -22,6 +22,7 @@
 #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>
@@ -37,23 +38,64 @@ using boost::optional;
 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)
@@ -100,7 +142,7 @@ ScreenDialog::ScreenDialog (
 
        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),
index 9bb7d86..913480d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    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
 {
@@ -36,13 +37,13 @@ public:
                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;
        }
 
@@ -53,7 +54,7 @@ private:
        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;
        }
 
@@ -63,8 +64,8 @@ private:
        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;
 };
index 1f52473..9bec453 100644 (file)
@@ -25,6 +25,7 @@
 
 #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"
@@ -38,6 +39,7 @@
 #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 */
@@ -64,7 +66,7 @@ BOOST_AUTO_TEST_CASE (import_dcp_test)
 
        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"),
index e7e9c67..ac1bfbe 100644 (file)
@@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE (remake_id_test2)
        /* 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"),
index 8b6e215..bbaa3d6 100644 (file)
 #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)
@@ -62,7 +64,7 @@ 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"),
@@ -92,7 +94,7 @@ BOOST_AUTO_TEST_CASE (vf_kdm_test)
 
        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"),