/*
- Copyright (C) 2012-2017 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
This file is part of DCP-o-matic.
#include "config_dialog.h"
#include "nag_dialog.h"
+using std::string;
using boost::bind;
+using boost::optional;
+using boost::shared_ptr;
static
void
boost::function<boost::shared_ptr<const dcp::CertificateChain> (void)> get,
boost::function<void (void)> nag_remake
)
- : wxPanel (parent)
+ : wxDialog (parent, wxID_ANY, title)
, _set (set)
, _get (get)
, _nag_remake (nag_remake)
font.SetFamily (wxFONTFAMILY_TELETYPE);
_private_key->SetFont (font);
table->Add (_private_key, wxGBPosition (r, 1), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
- _load_private_key = new wxButton (this, wxID_ANY, _("Load..."));
- table->Add (_load_private_key, wxGBPosition (r, 2));
+ _import_private_key = new wxButton (this, wxID_ANY, _("Import..."));
+ table->Add (_import_private_key, wxGBPosition (r, 2));
_export_private_key = new wxButton (this, wxID_ANY, _("Export..."));
table->Add (_export_private_key, wxGBPosition (r, 3));
++r;
_button_sizer = new wxBoxSizer (wxHORIZONTAL);
- _remake_certificates = new wxButton (this, wxID_ANY, _("Re-make certificates\nand key..."));
+ _remake_certificates = new wxButton (this, wxID_ANY, _("Re-make certificates and key..."));
_button_sizer->Add (_remake_certificates, 1, wxRIGHT, border);
table->Add (_button_sizer, wxGBPosition (r, 0), wxGBSpan (1, 4));
++r;
_certificates->Bind (wxEVT_LIST_ITEM_SELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
_certificates->Bind (wxEVT_LIST_ITEM_DESELECTED, boost::bind (&CertificateChainEditor::update_sensitivity, this));
_remake_certificates->Bind (wxEVT_BUTTON, boost::bind (&CertificateChainEditor::remake_certificates, this));
- _load_private_key->Bind (wxEVT_BUTTON, boost::bind (&CertificateChainEditor::load_private_key, this));
+ _import_private_key->Bind (wxEVT_BUTTON, boost::bind (&CertificateChainEditor::import_private_key, this));
_export_private_key->Bind (wxEVT_BUTTON, boost::bind (&CertificateChainEditor::export_private_key, this));
- SetSizerAndFit (_sizer);
-}
-
+ wxSizer* buttons = CreateSeparatedButtonSizer (wxCLOSE);
+ if (buttons) {
+ _sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
+ }
-void
-CertificateChainEditor::config_changed ()
-{
- _chain.reset (new dcp::CertificateChain (*_get().get ()));
+ SetSizerAndFit (_sizer);
update_certificate_list ();
update_private_key ();
try {
extra = c.read_string (dcp::file_to_string (wx_to_std (d->GetPath ())));
} catch (boost::filesystem::filesystem_error& e) {
- error_dialog (this, wxString::Format (_("Could not load certificate (%s)"), d->GetPath().data()));
+ error_dialog (this, wxString::Format (_("Could not import certificate (%s)"), d->GetPath().data()));
d->Destroy ();
return;
}
"Only the first certificate will be used.")
);
}
- _chain->add (c);
- if (!_chain->chain_valid ()) {
+ shared_ptr<dcp::CertificateChain> chain(new dcp::CertificateChain(*_get().get()));
+ chain->add (c);
+ if (!chain->chain_valid ()) {
error_dialog (
this,
_("Adding this certificate would make the chain inconsistent, so it will not be added. "
"Add certificates in order from root to intermediate to leaf.")
);
- _chain->remove (c);
+ chain->remove (c);
} else {
- _set (_chain);
+ _set (chain);
update_certificate_list ();
}
} catch (dcp::MiscError& e) {
}
_certificates->DeleteItem (i);
- _chain->remove (i);
- _set (_chain);
+ shared_ptr<dcp::CertificateChain> chain(new dcp::CertificateChain(*_get().get()));
+ chain->remove (i);
+ _set (chain);
update_sensitivity ();
}
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
);
- dcp::CertificateChain::List all = _chain->root_to_leaf ();
+ dcp::CertificateChain::List all = _get()->root_to_leaf ();
dcp::CertificateChain::List::iterator j = all.begin ();
for (int k = 0; k < i; ++k) {
++j;
}
if (d->ShowModal () == wxID_OK) {
- FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
+ FILE* f = fopen_boost (path_from_file_dialog (d, "pem"), "w");
if (!f) {
throw OpenFileError (wx_to_std (d->GetPath ()), errno, false);
}
{
_certificates->DeleteAllItems ();
size_t n = 0;
- dcp::CertificateChain::List certs = _chain->root_to_leaf ();
+ dcp::CertificateChain::List certs = _get()->root_to_leaf ();
BOOST_FOREACH (dcp::Certificate const & i, certs) {
wxListItem item;
item.SetId (n);
static wxColour normal = _private_key_bad->GetForegroundColour ();
- if (_chain->private_key_valid ()) {
+ if (_get()->private_key_valid()) {
_private_key_bad->Hide ();
_private_key_bad->SetForegroundColour (normal);
} else {
void
CertificateChainEditor::remake_certificates ()
{
- boost::shared_ptr<const dcp::CertificateChain> chain = _get ();
+ boost::shared_ptr<const dcp::CertificateChain> chain = _get();
std::string subject_organization_name;
std::string subject_organizational_unit_name;
);
if (d->ShowModal () == wxID_OK) {
- _chain.reset (
- new dcp::CertificateChain (
- openssl_path (),
- d->organisation (),
- d->organisational_unit (),
- d->root_common_name (),
- d->intermediate_common_name (),
- d->leaf_common_name ()
+ _set (
+ shared_ptr<dcp::CertificateChain> (
+ new dcp::CertificateChain (
+ openssl_path (),
+ d->organisation (),
+ d->organisational_unit (),
+ d->root_common_name (),
+ d->intermediate_common_name (),
+ d->leaf_common_name ()
+ )
)
);
- _set (_chain);
update_certificate_list ();
update_private_key ();
}
void
CertificateChainEditor::update_private_key ()
{
- checked_set (_private_key, dcp::private_key_fingerprint (_chain->key().get ()));
+ checked_set (_private_key, dcp::private_key_fingerprint (_get()->key().get()));
_sizer->Layout ();
}
void
-CertificateChainEditor::load_private_key ()
+CertificateChainEditor::import_private_key ()
{
wxFileDialog* d = new wxFileDialog (this, _("Select Key File"));
return;
}
- _chain->set_key (dcp::file_to_string (p));
- _set (_chain);
+ shared_ptr<dcp::CertificateChain> chain(new dcp::CertificateChain(*_get().get()));
+ chain->set_key (dcp::file_to_string (p));
+ _set (chain);
update_private_key ();
} catch (dcp::MiscError& e) {
error_dialog (this, wxString::Format (_("Could not read certificate file (%s)"), e.what ()));
void
CertificateChainEditor::export_private_key ()
{
- boost::optional<std::string> key = _chain->key ();
+ boost::optional<std::string> key = _get()->key();
if (!key) {
return;
}
);
if (d->ShowModal () == wxID_OK) {
- FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
+ FILE* f = fopen_boost (path_from_file_dialog (d, "pem"), "w");
if (!f) {
throw OpenFileError (wx_to_std (d->GetPath ()), errno, false);
}
- std::string const s = _chain->key().get ();
+ std::string const s = _get()->key().get ();
fwrite (s.c_str(), 1, s.length(), f);
fclose (f);
}
void
KeysPage::setup ()
{
- if (_sign) {
- _signer = new CertificateChainEditor (
- _panel, _("Signing DCPs and KDMs"), _border,
- bind (&Config::set_signer_chain, Config::instance (), _1),
- bind (&Config::signer_chain, Config::instance ()),
- bind (&do_nothing)
- );
+ wxFont subheading_font (*wxNORMAL_FONT);
+ subheading_font.SetWeight (wxFONTWEIGHT_BOLD);
- _panel->GetSizer()->Add (_signer);
+ wxSizer* sizer = _panel->GetSizer();
+
+ {
+ wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Decrypting KDMs"));
+ m->SetFont (subheading_font);
+ sizer->Add (m, 0, wxALL, _border);
}
- _decryption = new CertificateChainEditor (
+ wxButton* export_decryption_certificate = new wxButton (_panel, wxID_ANY, _("Export KDM decryption certificate..."));
+ sizer->Add (export_decryption_certificate, 0, wxLEFT, _border);
+ wxButton* export_decryption_chain = new wxButton (_panel, wxID_ANY, _("Export KDM decryption chain..."));
+ sizer->Add (export_decryption_chain, 0, wxLEFT, _border);
+ wxButton* export_settings = new wxButton (_panel, wxID_ANY, _("Export all KDM decryption settings..."));
+ sizer->Add (export_settings, 0, wxLEFT, _border);
+ wxButton* import_settings = new wxButton (_panel, wxID_ANY, _("Import all KDM decryption settings..."));
+ sizer->Add (import_settings, 0, wxLEFT, _border);
+ wxButton* decryption_advanced = new wxButton (_panel, wxID_ANY, _("Advanced..."));
+ sizer->Add (decryption_advanced, 0, wxALL, _border);
+
+ export_decryption_certificate->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_certificate, this));
+ export_decryption_chain->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_chain, this));
+ export_settings->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_chain_and_key, this));
+ import_settings->Bind (wxEVT_BUTTON, bind (&KeysPage::import_decryption_chain_and_key, this));
+ decryption_advanced->Bind (wxEVT_BUTTON, bind (&KeysPage::decryption_advanced, this));
+
+ {
+ wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Signing DCPs and KDMs"));
+ m->SetFont (subheading_font);
+ sizer->Add (m, 0, wxALL, _border);
+ }
+
+ wxButton* signing_advanced = new wxButton (_panel, wxID_ANY, _("Advanced..."));
+ sizer->Add (signing_advanced, 0, wxLEFT, _border);
+ signing_advanced->Bind (wxEVT_BUTTON, bind (&KeysPage::signing_advanced, this));
+}
+
+void
+KeysPage::decryption_advanced ()
+{
+ CertificateChainEditor* c = new CertificateChainEditor (
_panel, _("Decrypting KDMs"), _border,
bind (&Config::set_decryption_chain, Config::instance (), _1),
bind (&Config::decryption_chain, Config::instance ()),
bind (&KeysPage::nag_remake_decryption_chain, this)
);
- _panel->GetSizer()->Add (_decryption);
+ c->ShowModal();
+}
- _export_decryption_certificate = new wxButton (_decryption, wxID_ANY, _("Export KDM decryption\ncertificate..."));
- _decryption->add_button (_export_decryption_certificate);
- _export_decryption_chain = new wxButton (_decryption, wxID_ANY, _("Export KDM decryption\nchain..."));
- _decryption->add_button (_export_decryption_chain);
+void
+KeysPage::signing_advanced ()
+{
+ CertificateChainEditor* c = new CertificateChainEditor (
+ _panel, _("Signing DCPs and KDMs"), _border,
+ bind (&Config::set_signer_chain, Config::instance (), _1),
+ bind (&Config::signer_chain, Config::instance ()),
+ bind (&do_nothing)
+ );
- _export_decryption_certificate->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_certificate, this));
- _export_decryption_chain->Bind (wxEVT_BUTTON, bind (&KeysPage::export_decryption_chain, this));
+ c->ShowModal();
}
void
-KeysPage::config_changed ()
+KeysPage::export_decryption_chain_and_key ()
{
- if (_sign) {
- _signer->config_changed ();
+ wxFileDialog* d = new wxFileDialog (
+ _panel, _("Select Export File"), wxEmptyString, wxEmptyString, wxT ("DOM files (*.dom)|*.dom"),
+ wxFD_SAVE | wxFD_OVERWRITE_PROMPT
+ );
+
+ if (d->ShowModal () == wxID_OK) {
+ FILE* f = fopen_boost (path_from_file_dialog (d, "dom"), "w");
+ if (!f) {
+ throw OpenFileError (wx_to_std (d->GetPath ()), errno, false);
+ }
+
+ string const chain = Config::instance()->decryption_chain()->chain();
+ fwrite (chain.c_str(), 1, chain.length(), f);
+ optional<string> const key = Config::instance()->decryption_chain()->key();
+ DCPOMATIC_ASSERT (key);
+ fwrite (key->c_str(), 1, key->length(), f);
+ fclose (f);
+ }
+ d->Destroy ();
+
+}
+
+void
+KeysPage::import_decryption_chain_and_key ()
+{
+ wxFileDialog* d = new wxFileDialog (
+ _panel, _("Select File To Import"), wxEmptyString, wxEmptyString, wxT ("DOM files (*.dom)|*.dom")
+ );
+
+ if (d->ShowModal () == wxID_OK) {
+ shared_ptr<dcp::CertificateChain> new_chain(new dcp::CertificateChain());
+
+ FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "r");
+ if (!f) {
+ throw OpenFileError (wx_to_std (d->GetPath ()), errno, false);
+ }
+
+ string current;
+ while (!feof (f)) {
+ char buffer[128];
+ if (fgets (buffer, 128, f) == 0) {
+ break;
+ }
+ current += buffer;
+ if (strncmp (buffer, "-----END CERTIFICATE-----", 25) == 0) {
+ new_chain->add (dcp::Certificate (current));
+ current = "";
+ } else if (strncmp (buffer, "-----END RSA PRIVATE KEY-----", 29) == 0) {
+ std::cout << "the key is " << current << "\n";
+ new_chain->set_key (current);
+ current = "";
+ }
+ }
+ fclose (f);
+
+ if (new_chain->chain_valid() && new_chain->private_key_valid()) {
+ Config::instance()->set_decryption_chain (new_chain);
+ } else {
+ error_dialog (_panel, _("Invalid DCP-o-matic export file"));
+ }
}
- _decryption->config_changed ();
+ d->Destroy ();
}
void
);
if (d->ShowModal () == wxID_OK) {
- FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
+ FILE* f = fopen_boost (path_from_file_dialog (d, "pem"), "w");
if (!f) {
throw OpenFileError (wx_to_std (d->GetPath ()), errno, false);
}
);
if (d->ShowModal () == wxID_OK) {
- FILE* f = fopen_boost (wx_to_std (d->GetPath ()), "w");
+ FILE* f = fopen_boost (path_from_file_dialog (d, "pem"), "w");
if (!f) {
throw OpenFileError (wx_to_std (d->GetPath ()), errno, false);
}