diff options
| author | Carl Hetherington <cth@carlh.net> | 2018-12-23 21:04:38 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2018-12-23 21:04:49 +0000 |
| commit | 3526252ff2fd80a459c72ab1c55ea5a6ee61aa2f (patch) | |
| tree | c9e9774de4acfa562f83db39a900fe4d0b241945 /src/lib | |
| parent | a65efe6bd00fbba4f075c4c666dafafb8a5eed4d (diff) | |
swaroop: encrypt decryption private key with motherboard UUID.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/config.cc | 47 | ||||
| -rw-r--r-- | src/lib/config.h | 3 | ||||
| -rw-r--r-- | src/lib/cross.cc | 27 | ||||
| -rw-r--r-- | src/lib/cross.h | 1 | ||||
| -rw-r--r-- | src/lib/crypto.cc | 16 | ||||
| -rw-r--r-- | src/lib/crypto.h | 6 |
6 files changed, 77 insertions, 23 deletions
diff --git a/src/lib/config.cc b/src/lib/config.cc index e61eea3a6..172890dcf 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -32,6 +32,7 @@ #include "film.h" #include "dkdm_wrapper.h" #include "compose.hpp" +#include "crypto.h" #include <dcp/raw_convert.h> #include <dcp/name_format.h> #include <dcp/certificate_chain.h> @@ -61,6 +62,7 @@ using boost::shared_ptr; using boost::optional; using boost::dynamic_pointer_cast; using boost::algorithm::trim; +using boost::shared_array; using dcp::raw_convert; Config* Config::_instance = 0; @@ -435,7 +437,19 @@ try BOOST_FOREACH (cxml::NodePtr i, decryption->node_children ("Certificate")) { c->add (dcp::Certificate (i->content ())); } - c->set_key (decryption->string_child ("PrivateKey")); + optional<string> key = decryption->optional_string_child ("PrivateKey"); +#ifdef DCPOMATIC_VARIANT_SWAROOP + if (key) { + c->set_key (*key); + } else { + dcp::Data encrypted_key (path("private")); + dcp::Data iv (path("iv")); + c->set_key (dcpomatic::decrypt (encrypted_key, key_from_uuid(), iv)); + } +#else + DCPOMATIC_ASSERT (key); + c->set_key (*key); +#endif _decryption_chain = c; } else { _decryption_chain = create_certificate_chain (); @@ -599,6 +613,19 @@ Config::write () const write_cinemas (); } +#ifdef DCPOMATIC_VARIANT_SWAROOP +/* Make up a key from the machine UUID */ +dcp::Data +Config::key_from_uuid () const +{ + dcp::Data key (dcpomatic::crypto_key_length()); + memset (key.data().get(), 0, key.size()); + string const magic = command_and_read ("dcpomatic2_uuid"); + strncpy ((char *) key.data().get(), magic.c_str(), dcpomatic::crypto_key_length()); + return key; +} +#endif + void Config::write_config () const { @@ -771,18 +798,7 @@ Config::write_config () const BOOST_FOREACH (dcp::Certificate const & i, _signer_chain->unordered()) { signer->add_child("Certificate")->add_child_text (i.certificate (true)); } -#ifdef DCPOMATIC_SWAROOP - FILE* f = fopen_boost (path("private"), "wb"); - if (!f) { - throw FileError ("Could not open file for writing", path("private")); - } - shared_array<uint8_t> iv = dcpomatic::random_iv (); - dcp::Data encrypted_key = dcpomatic::encrypt (_signer_chain->key().get(), key, iv); - fwrite (encrypted_key.data().get(), encrypted_key.data().size(), 1, f); - fclose (f); -#else signer->add_child("PrivateKey")->add_child_text (_signer_chain->key().get ()); -#endif /* [XML] Decryption Certificate chain and private key to use when decrypting KDMs */ xmlpp::Element* decryption = root->add_child ("Decryption"); @@ -790,7 +806,14 @@ Config::write_config () const BOOST_FOREACH (dcp::Certificate const & i, _decryption_chain->unordered()) { decryption->add_child("Certificate")->add_child_text (i.certificate (true)); } +#ifdef DCPOMATIC_VARIANT_SWAROOP + dcp::Data iv = dcpomatic::random_iv (); + dcp::Data encrypted_key = dcpomatic::encrypt (_decryption_chain->key().get(), key_from_uuid(), iv); + encrypted_key.write (path("private")); + iv.write (path("iv")); +#else decryption->add_child("PrivateKey")->add_child_text (_decryption_chain->key().get ()); +#endif /* [XML] History Filename of DCP to present in the <guilabel>File</guilabel> menu of the GUI; there can be more than one of these tags. diff --git a/src/lib/config.h b/src/lib/config.h index 0e5f9dfd1..e28928226 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -1083,6 +1083,9 @@ private: boost::filesystem::path directory_or (boost::optional<boost::filesystem::path> dir, boost::filesystem::path a) const; void add_to_history_internal (std::vector<boost::filesystem::path>& h, boost::filesystem::path p); void backup (); +#ifdef DCPOMATIC_VARIANT_SWAROOP + dcp::Data key_from_uuid () const; +#endif template <class T> void maybe_set (T& member, T new_value, Property prop = OTHER) { diff --git a/src/lib/cross.cc b/src/lib/cross.cc index e3fb22f39..171bf2c81 100644 --- a/src/lib/cross.cc +++ b/src/lib/cross.cc @@ -474,3 +474,30 @@ home_directory () return boost::filesystem::path(getenv("HOMEDRIVE")) / boost::filesystem::path(getenv("HOMEPATH")); #endif } + +string +command_and_read (string cmd) +{ +#ifdef DCPOMATIC_LINUX + FILE* pipe = popen (cmd.c_str(), "r"); + if (!pipe) { + throw runtime_error ("popen failed"); + } + + string result; + char buffer[128]; + try { + while (fgets(buffer, sizeof(buffer), pipe)) { + result += buffer; + } + } catch (...) { + pclose (pipe); + throw; + } + + pclose (pipe); + return result; +#endif + + return ""; +} diff --git a/src/lib/cross.h b/src/lib/cross.h index ee5e7919a..06e198e99 100644 --- a/src/lib/cross.h +++ b/src/lib/cross.h @@ -56,6 +56,7 @@ extern void start_player (boost::filesystem::path dcpomatic); extern uint64_t thread_id (); extern int avio_open_boost (AVIOContext** s, boost::filesystem::path file, int flags); extern boost::filesystem::path home_directory (); +extern std::string command_and_read (std::string cmd); /** @class Waker * @brief A class which tries to keep the computer awake on various operating systems. diff --git a/src/lib/crypto.cc b/src/lib/crypto.cc index 69e041cb2..b02a3d34c 100644 --- a/src/lib/crypto.cc +++ b/src/lib/crypto.cc @@ -35,24 +35,24 @@ using namespace dcpomatic; /** The cipher that this code uses */ #define CIPHER EVP_aes_256_cbc() -shared_array<unsigned char> +dcp::Data dcpomatic::random_iv () { EVP_CIPHER const * cipher = CIPHER; - shared_array<unsigned char> iv (new unsigned char[EVP_CIPHER_iv_length(cipher)]); - RAND_bytes (iv.get(), EVP_CIPHER_iv_length(cipher)); + dcp::Data iv (EVP_CIPHER_iv_length(cipher)); + RAND_bytes (iv.data().get(), iv.size()); return iv; } dcp::Data -dcpomatic::encrypt (string plaintext, shared_array<unsigned char const> key, shared_array<unsigned char const> iv) +dcpomatic::encrypt (string plaintext, dcp::Data key, dcp::Data iv) { EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new (); if (!ctx) { throw CryptoError ("could not create cipher context"); } - int r = EVP_EncryptInit_ex (ctx, CIPHER, 0, key.get(), iv.get()); + int r = EVP_EncryptInit_ex (ctx, CIPHER, 0, key.data().get(), iv.data().get()); if (r != 1) { throw CryptoError ("could not initialise cipher context for encryption"); } @@ -60,7 +60,7 @@ dcpomatic::encrypt (string plaintext, shared_array<unsigned char const> key, sha dcp::Data ciphertext (plaintext.size() * 2); int len; - r = EVP_EncryptUpdate (ctx, ciphertext.data().get(), &len, (unsigned char const *) plaintext.c_str(), plaintext.size()); + r = EVP_EncryptUpdate (ctx, ciphertext.data().get(), &len, (uint8_t const *) plaintext.c_str(), plaintext.size()); if (r != 1) { throw CryptoError ("could not encrypt data"); } @@ -80,14 +80,14 @@ dcpomatic::encrypt (string plaintext, shared_array<unsigned char const> key, sha } string -dcpomatic::decrypt (dcp::Data ciphertext, shared_array<unsigned char const> key, shared_array<unsigned char const> iv) +dcpomatic::decrypt (dcp::Data ciphertext, dcp::Data key, dcp::Data iv) { EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new (); if (!ctx) { throw CryptoError ("could not create cipher context"); } - int r = EVP_DecryptInit_ex (ctx, CIPHER, 0, key.get(), iv.get()); + int r = EVP_DecryptInit_ex (ctx, CIPHER, 0, key.data().get(), iv.data().get()); if (r != 1) { throw CryptoError ("could not initialise cipher context for decryption"); } diff --git a/src/lib/crypto.h b/src/lib/crypto.h index ea46162a4..e450d4db1 100644 --- a/src/lib/crypto.h +++ b/src/lib/crypto.h @@ -22,9 +22,9 @@ namespace dcpomatic { -boost::shared_array<unsigned char> random_iv (); -dcp::Data encrypt (std::string plaintext, boost::shared_array<unsigned char const> key, boost::shared_array<unsigned char const> iv); -std::string decrypt (dcp::Data ciphertext, boost::shared_array<unsigned char const> key, boost::shared_array<unsigned char const> iv); +dcp::Data random_iv (); +dcp::Data encrypt (std::string plaintext, dcp::Data key, dcp::Data iv); +std::string decrypt (dcp::Data ciphertext, dcp::Data key, dcp::Data iv); int crypto_key_length (); } |
