Prompt to recreate > ~10 year old certificates on startup. v2.14.x-10-year-validity v2.14.58
authorCarl Hetherington <cth@carlh.net>
Sat, 12 Feb 2022 19:15:05 +0000 (20:15 +0100)
committerCarl Hetherington <cth@carlh.net>
Sat, 12 Feb 2022 19:15:05 +0000 (20:15 +0100)
cscript
src/lib/config.cc
src/lib/config.h
src/tools/dcpomatic.cc
src/wx/recreate_chain_dialog.cc
src/wx/recreate_chain_dialog.h

diff --git a/cscript b/cscript
index 5c17de099c7b70280224dfcb4b25f059c2028a5e..31bb8a19b278f891379f0aa2d74ac9ea011cb6c4 100644 (file)
--- a/cscript
+++ b/cscript
@@ -391,8 +391,8 @@ def dependencies(target):
         # Use distro-provided FFmpeg on Arch
         deps = []
 
-    deps.append(('libdcp', 'v1.6.19'))
-    deps.append(('libsub', 'v1.4.26'))
+    deps.append(('libdcp', 'v1.6.20'))
+    deps.append(('libsub', 'v1.4.27'))
     deps.append(('rtaudio-cdist', 'bf0fc23'))
 
     return deps
index 9b0cc5f97e512c85161b47a35df9750df580dfda..9754e1695d4b5ee19211fa4c7350a38abf025d02 100644 (file)
@@ -69,7 +69,7 @@ Config* Config::_instance = 0;
 int const Config::_current_version = 3;
 boost::signals2::signal<void ()> Config::FailedToLoad;
 boost::signals2::signal<void (string)> Config::Warning;
-boost::signals2::signal<bool (void)> Config::BadSignerChain;
+boost::signals2::signal<bool (Config::BadSignerChainReason)> Config::BadSignerChain;
 
 /** Construct default configuration */
 Config::Config ()
@@ -452,15 +452,23 @@ try
                }
        }
 
-       bool bad_signer_chain = false;
+       BadSignerChainReason reason = BAD_SIGNER_CHAIN_NONE;
        BOOST_FOREACH (dcp::Certificate const & i, _signer_chain->unordered()) {
                if (i.has_utf8_strings()) {
-                       bad_signer_chain = true;
+                       reason = static_cast<BadSignerChainReason>(reason | BAD_SIGNER_CHAIN_HAS_UTF8_STRINGS);
+               }
+               struct tm not_before = i.not_before();
+               struct tm not_after = i.not_after();
+               if ((not_after.tm_year - not_before.tm_year) > 15) {
+                       /* We don't know why (or precise details) but it seems like certificate validity of >10
+                        * years causes problems with some projection systems (#2174 and others).
+                        */
+                       reason = static_cast<BadSignerChainReason>(reason | BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG);
                }
        }
 
-       if (bad_signer_chain) {
-               optional<bool> const remake = BadSignerChain();
+       if (reason) {
+               optional<bool> const remake = BadSignerChain(reason);
                if (remake && *remake) {
                        _signer_chain = create_certificate_chain ();
                }
index 8cc25d7377d6d132e6a8e3934260111e93215083..f9d669371c0370b9cc8352041ea7556059411ce8 100644 (file)
@@ -372,10 +372,11 @@ public:
                NAG_DKDM_CONFIG,
                NAG_ENCRYPTED_METADATA,
                NAG_ALTER_DECRYPTION_CHAIN,
-               NAG_BAD_SIGNER_CHAIN,
+               NAG_BAD_SIGNER_CHAIN_UTF8_STRINGS,
                /* Not really a nag but it's the same idea */
                NAG_INITIAL_SETUP,
                NAG_IMPORT_DECRYPTION_CHAIN,
+               NAG_BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG,
                NAG_COUNT
        };
 
@@ -1074,7 +1075,12 @@ public:
        /** Emitted if there is a bad certificate in the signer chain.  Handler can call
         *  true to ask Config to re-create the chain.
         */
-       static boost::signals2::signal<bool (void)> BadSignerChain;
+       enum BadSignerChainReason {
+               BAD_SIGNER_CHAIN_NONE = 0x0,
+               BAD_SIGNER_CHAIN_HAS_UTF8_STRINGS = 0x1,
+               BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG = 0x2,
+       };
+       static boost::signals2::signal<bool (BadSignerChainReason)> BadSignerChain;
 
        void write () const;
        void write_config () const;
index d0d8320083517fabe80a9b1344e1f5d1128066e5..816686eea7bb6b8ac750b47f1a1b7d148065b9a1 100644 (file)
@@ -1524,7 +1524,7 @@ private:
                        */
                        Config::drop ();
 
-                       Config::BadSignerChain.connect (boost::bind (&App::config_bad_signer_chain, this));
+                       Config::BadSignerChain.connect (boost::bind (&App::config_bad_signer_chain, this, _1));
 
                        _frame = new DOMFrame (_("DCP-o-matic"));
                        SetTopWindow (_frame);
@@ -1693,9 +1693,12 @@ private:
                message_dialog (_frame, std_to_wx (m));
        }
 
-       bool config_bad_signer_chain ()
+       bool config_bad_signer_chain (Config::BadSignerChainReason reason)
        {
-               if (Config::instance()->nagged(Config::NAG_BAD_SIGNER_CHAIN)) {
+               bool const need_nag_utf8_strings = (reason & Config::BAD_SIGNER_CHAIN_HAS_UTF8_STRINGS) && !Config::instance()->nagged(Config::NAG_BAD_SIGNER_CHAIN_UTF8_STRINGS);
+               bool const need_nag_validity_too_long = (reason & Config::BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG) && !Config::instance()->nagged(Config::NAG_BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG);
+
+               if (!need_nag_utf8_strings && !need_nag_validity_too_long) {
                        return false;
                }
 
@@ -1704,7 +1707,7 @@ private:
                        _splash = 0;
                }
 
-               RecreateChainDialog* d = new RecreateChainDialog (_frame);
+               RecreateChainDialog* d = new RecreateChainDialog (_frame, reason);
                int const r = d->ShowModal ();
                d->Destroy ();
                return r == wxID_OK;
index 9350169390e760f3cbbbe26bf5101ac8d3f31777..d4dc7431546b1b9fe2f6fe10fbc182ee08dc7912 100644 (file)
@@ -32,12 +32,20 @@ using std::string;
 using namespace boost::placeholders;
 #endif
 
-RecreateChainDialog::RecreateChainDialog (wxWindow* parent)
+RecreateChainDialog::RecreateChainDialog (wxWindow* parent, Config::BadSignerChainReason reason)
        : QuestionDialog (parent, _("Certificate chain"), _("Recreate signing certificates"), _("Do nothing"))
+       , _reason (reason)
 {
-       wxString const message = _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs contains a small error\n"
-                                  "which will prevent DCPs from being validated correctly on some systems.  Do you want to re-create\n"
-                                  "the certificate chain for signing DCPs and KDMs?");
+       wxString message;
+       if (_reason & Config::BadSignerChainReason::BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG) {
+               message = _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs has a validity period\n"
+                           "that is too long.  This will cause problems playing back DCPs on some systems.\n"
+                           "Do you want to re-create the certificate chain for signing DCPs and KDMs?");
+       } else {
+               message = _("The certificate chain that DCP-o-matic uses for signing DCPs and KDMs contains a small error\n"
+                           "which will prevent DCPs from being validated correctly on some systems.  Do you want to re-create\n"
+                           "the certificate chain for signing DCPs and KDMs?");
+       }
 
        _sizer->Add (new StaticText (this, message), 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
 
@@ -52,5 +60,10 @@ RecreateChainDialog::RecreateChainDialog (wxWindow* parent)
 void
 RecreateChainDialog::shut_up (wxCommandEvent& ev)
 {
-       Config::instance()->set_nagged (Config::NAG_BAD_SIGNER_CHAIN, ev.IsChecked());
+       if (_reason & Config::BadSignerChainReason::BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG) {
+               Config::instance()->set_nagged (Config::NAG_BAD_SIGNER_CHAIN_VALIDITY_TOO_LONG, ev.IsChecked());
+       } else {
+               Config::instance()->set_nagged (Config::NAG_BAD_SIGNER_CHAIN_UTF8_STRINGS, ev.IsChecked());
+       }
 }
+
index 287e657670408a14fbc52540218ceb320652a046..5973bb49b5b1df9aebaec24b5f490529f9360937 100644 (file)
 */
 
 #include "question_dialog.h"
+#include "lib/config.h"
 #include <wx/wx.h>
 #include <list>
 
 class RecreateChainDialog : public QuestionDialog
 {
 public:
-       RecreateChainDialog (wxWindow* parent);
+       RecreateChainDialog (wxWindow* parent, Config::BadSignerChainReason reason);
 
 private:
        void shut_up (wxCommandEvent& ev);
+
+       Config::BadSignerChainReason _reason;
 };