More encryption fixes.
authorCarl Hetherington <cth@carlh.net>
Fri, 20 Sep 2013 19:20:36 +0000 (20:20 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 20 Sep 2013 19:20:36 +0000 (20:20 +0100)
src/cpl.cc
src/cpl.h
src/dcp.cc
src/dcp.h
src/mxf_asset.h
src/picture_asset.cc
src/picture_asset_writer.cc
src/sound_asset.cc
test/encryption_test.cc

index 2c0bf6c4d1f5841290983a309894fc93a2031eb0..a3d2ecfa9fbbaa831f5597ce3a0cd1f5d9b618db 100644 (file)
@@ -44,7 +44,7 @@ using boost::lexical_cast;
 using boost::optional;
 using namespace libdcp;
 
-CPL::CPL (string directory, string name, ContentKind content_kind, int length, int frames_per_second)
+CPL::CPL (boost::filesystem::path directory, string name, ContentKind content_kind, int length, int frames_per_second)
        : _directory (directory)
        , _name (name)
        , _content_kind (content_kind)
@@ -60,7 +60,7 @@ CPL::CPL (string directory, string name, ContentKind content_kind, int length, i
  *  @param asset_maps AssetMaps to look for assets in.
  *  @param require_mxfs true to throw an exception if a required MXF file does not exist.
  */
-CPL::CPL (string directory, string file, list<PathAssetMap> asset_maps, bool require_mxfs)
+CPL::CPL (boost::filesystem::path directory, string file, list<PathAssetMap> asset_maps, bool require_mxfs)
        : _directory (directory)
        , _content_kind (FEATURE)
        , _length (0)
@@ -348,6 +348,7 @@ shared_ptr<xmlpp::Document>
 CPL::make_kdm (
        shared_ptr<const Signer> signer,
        shared_ptr<const Certificate> recipient_cert,
+       Key key,
        boost::posix_time::ptime from,
        boost::posix_time::ptime until,
        bool interop,
@@ -445,26 +446,12 @@ CPL::make_kdm (
                authenticated_private->set_attribute ("Id", "ID_AuthenticatedPrivate");
                xmlAddID (0, doc->cobj(), (const xmlChar *) "ID_AuthenticatedPrivate", authenticated_private->get_attribute("Id")->cobj());
 
-               /* Hex keys that we have already written into the node */
-               list<Key> written_keys;
-
-               list<shared_ptr<const Asset> > a = assets();
-               for (list<shared_ptr<const Asset> >::iterator i = a.begin(); i != a.end(); ++i) {
-                       /* XXX: non-MXF assets? */
-                       shared_ptr<const MXFAsset> mxf = boost::dynamic_pointer_cast<const MXFAsset> (*i);
-                       if (!mxf || find (written_keys.begin(), written_keys.end(), mxf->key ()) != written_keys.end ()) {
-                               continue;
-                       }
-                       
-                       xmlpp::Element* encrypted_key = authenticated_private->add_child ("EncryptedKey", "enc");
-                       xmlpp::Element* encryption_method = encrypted_key->add_child ("EncryptionMethod", "enc");
-                       encryption_method->set_attribute ("Algorithm", "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
-                       encryption_method->add_child("DigestMethod", "ds")->set_attribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
-                       xmlpp::Element* cipher_data = authenticated_private->add_child ("CipherData", "enc");
-                       cipher_data->add_child("CipherValue", "enc")->add_child_text(mxf->key()->hex());
-
-                       written_keys.push_back (mxf->key().get());
-               }
+               xmlpp::Element* encrypted_key = authenticated_private->add_child ("EncryptedKey", "enc");
+               xmlpp::Element* encryption_method = encrypted_key->add_child ("EncryptionMethod", "enc");
+               encryption_method->set_attribute ("Algorithm", "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
+               encryption_method->add_child("DigestMethod", "ds")->set_attribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
+               xmlpp::Element* cipher_data = authenticated_private->add_child ("CipherData", "enc");
+               cipher_data->add_child("CipherValue", "enc")->add_child_text(key.hex());
        }
        
        {
index 91756d3a81abf573b75795a8f1c172f41aed2ded..da30fdbb8e2c009aa4d4e8f4ea6c3d0ed63933ad 100644 (file)
--- a/src/cpl.h
+++ b/src/cpl.h
@@ -29,6 +29,7 @@
 #include <libxml++/libxml++.h>
 #include "types.h"
 #include "certificates.h"
+#include "key.h"
 
 namespace libdcp {
 
@@ -48,8 +49,8 @@ class KDM;
 class CPL
 {
 public:
-       CPL (std::string directory, std::string name, ContentKind content_kind, int length, int frames_per_second);
-       CPL (std::string directory, std::string file, std::list<PathAssetMap> asset_maps, bool require_mxfs = true);
+       CPL (boost::filesystem::path directory, std::string name, ContentKind content_kind, int length, int frames_per_second);
+       CPL (boost::filesystem::path, std::string file, std::list<PathAssetMap> asset_maps, bool require_mxfs = true);
 
        void add_reel (boost::shared_ptr<Reel> reel);
        
@@ -99,6 +100,7 @@ public:
         *  @param signer Details of the certificates and private key to sign the KDM with.
         *  @param recipient_cert The certificate of the projector that this KDM is targeted at.  This will contain the
         *  projector's public key which is used to encrypt the content keys.
+        *  @param key Private key used to encrypt the MXFs referenced by this CPL.
         *  @param from Time that the KDM should be valid from.
         *  @param until Time that the KDM should be valid until.
         *  @param interop true to generate an interop KDM, false for SMPTE.
@@ -106,6 +108,7 @@ public:
        boost::shared_ptr<xmlpp::Document> make_kdm (
                boost::shared_ptr<const Signer> signer,
                boost::shared_ptr<const Certificate> recipient_cert,
+               Key key,
                boost::posix_time::ptime from,
                boost::posix_time::ptime until,
                bool interop,
@@ -118,7 +121,7 @@ public:
 private:
        std::pair<std::string, boost::shared_ptr<const parse::AssetMapAsset> > asset_from_id (std::list<PathAssetMap>, std::string id) const;
        
-       std::string _directory;
+       boost::filesystem::path _directory;
        /** the name of the DCP */
        std::string _name;
        /** the content kind of the CPL */
index d21b3b4ec1ed6104c43c8745495ca489793fd493..03d1598d6dc8d396269d17ec3b91d9da931be869 100644 (file)
@@ -60,7 +60,7 @@ using boost::shared_ptr;
 using boost::lexical_cast;
 using namespace libdcp;
 
-DCP::DCP (string directory)
+DCP::DCP (boost::filesystem::path directory)
        : _directory (directory)
 {
        boost::filesystem::create_directories (directory);
index 8b7b19c1e84a10eaaca21112c482c2ffcb9d5d04..f2a261cd875c1dbb8c78fa00a9a1d2824007cd83 100644 (file)
--- a/src/dcp.h
+++ b/src/dcp.h
@@ -67,7 +67,7 @@ public:
         *
         *  @param directory Directory containing the DCP's files.
         */
-       DCP (std::string directory);
+       DCP (boost::filesystem::path directory);
 
        void read (bool require_mxfs = true);
 
@@ -149,7 +149,7 @@ private:
        Files _files;
 
        /** the directory that we are writing to */
-       std::string _directory;
+       boost::filesystem::path _directory;
        /** our CPLs */
        std::list<boost::shared_ptr<CPL> > _cpls;
 
index d681970eb24291281c22944753ead1c577127792..97ce44b291247d2c9e37f7db3df44e58a3862e76 100644 (file)
@@ -95,6 +95,10 @@ public:
        boost::optional<Key> key () const {
                return _key;
        }
+
+       ASDCP::AESEncContext* encryption_context () const {
+               return _encryption_context;
+       }
        
 protected:
        virtual std::string key_type () const = 0;
index 5903b394304b0baf4fdd70ca2c6473f5b651cc1b..bc38a3f93d07587c490f5bd307e9af1b4162028b 100644 (file)
@@ -479,7 +479,6 @@ StereoPictureAsset::StereoPictureAsset (string directory, string mxf_name, int f
 shared_ptr<PictureAssetWriter>
 StereoPictureAsset::start_write (bool overwrite, bool interop, MXFMetadata const & metadata)
 {
-       /* XXX: can't we use shared_ptr here? */
        return shared_ptr<StereoPictureAssetWriter> (new StereoPictureAssetWriter (this, overwrite, interop, metadata));
 }
 
index e16dac7211efdaf5b6f60dd303b34d07a3b1b57e..f5767e3d4c02d83aca338741d17fb9909ee3933b 100644 (file)
@@ -61,7 +61,7 @@ PictureAssetWriter::PictureAssetWriter (PictureAsset* asset, bool overwrite, boo
        , _interop (interop)
        , _metadata (metadata)
 {
-       
+
 }
 
 struct ASDCPStateBase
@@ -74,6 +74,7 @@ struct ASDCPStateBase
        ASDCP::JP2K::FrameBuffer frame_buffer;
        ASDCP::WriterInfo writer_info;
        ASDCP::JP2K::PictureDescriptor picture_descriptor;
+       ASDCP::AESEncContext* encryption_context;
 };
 
 struct MonoPictureAssetWriter::ASDCPState : public ASDCPStateBase
@@ -93,7 +94,7 @@ MonoPictureAssetWriter::MonoPictureAssetWriter (PictureAsset* asset, bool overwr
        : PictureAssetWriter (asset, overwrite, interop, metadata)
        , _state (new MonoPictureAssetWriter::ASDCPState)
 {
-
+       _state->encryption_context = asset->encryption_context ();
 }
 
 StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* asset, bool overwrite, bool interop, MXFMetadata const & metadata)
@@ -101,7 +102,7 @@ StereoPictureAssetWriter::StereoPictureAssetWriter (PictureAsset* asset, bool ov
        , _state (new StereoPictureAssetWriter::ASDCPState)
        , _next_eye (EYE_LEFT)
 {
-
+       _state->encryption_context = asset->encryption_context ();
 }
 
 template <class P, class Q>
@@ -158,7 +159,7 @@ MonoPictureAssetWriter::write (uint8_t* data, int size)
        uint64_t const before_offset = _state->mxf_writer.Tell ();
 
        string hash;
-       if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, 0, 0, &hash))) {
+       if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0, &hash))) {
                boost::throw_exception (MXFFileError ("error in writing video MXF", _asset->path().string()));
        }
 
@@ -190,7 +191,7 @@ StereoPictureAssetWriter::write (uint8_t* data, int size)
                    _state->mxf_writer.WriteFrame (
                            _state->frame_buffer,
                            _next_eye == EYE_LEFT ? ASDCP::JP2K::SP_LEFT : ASDCP::JP2K::SP_RIGHT,
-                           0,
+                           _state->encryption_context,
                            0,
                            &hash)
                    )) {
index 6f74e54a9c461c23fb428f36cdfc76eaf5faf87f..026c44ef2bc46783276aeca4871b12d72ecfaa30 100644 (file)
@@ -316,6 +316,7 @@ struct SoundAssetWriter::ASDCPState
        ASDCP::PCM::FrameBuffer frame_buffer;
        ASDCP::WriterInfo writer_info;
        ASDCP::PCM::AudioDescriptor audio_desc;
+       ASDCP::AESEncContext* encryption_context;
 };
 
 SoundAssetWriter::SoundAssetWriter (SoundAsset* a, bool interop, MXFMetadata const & m)
@@ -326,6 +327,8 @@ SoundAssetWriter::SoundAssetWriter (SoundAsset* a, bool interop, MXFMetadata con
        , _frame_buffer_offset (0)
        , _metadata (m)
 {
+       _state->encryption_context = a->encryption_context ();
+       
        /* Derived from ASDCP::Wav::SimpleWaveHeader::FillADesc */
        _state->audio_desc.EditRate = ASDCP::Rational (_asset->edit_rate(), 1);
        _state->audio_desc.AudioSamplingRate = ASDCP::Rational (_asset->sampling_rate(), 1);
@@ -378,7 +381,7 @@ SoundAssetWriter::write (float const * const * data, int frames)
 void
 SoundAssetWriter::write_current_frame ()
 {
-       if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, 0, 0))) {
+       if (ASDCP_FAILURE (_state->mxf_writer.WriteFrame (_state->frame_buffer, _state->encryption_context, 0))) {
                boost::throw_exception (MiscError ("could not write audio MXF frame"));
        }
 
index 3501befce283ca90b0d24c94fdb994eb96f84572..888011aa22f3eabc67cfadad19abcf6b57024dab 100644 (file)
@@ -64,7 +64,9 @@ BOOST_AUTO_TEST_CASE (encryption)
                                                         mxf_metadata
                                                         ));
 
-       mp->set_key (libdcp::Key ());
+       libdcp::Key key;
+
+       mp->set_key (key);
 
        shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset (
                                                   wav,
@@ -78,7 +80,7 @@ BOOST_AUTO_TEST_CASE (encryption)
                                                   mxf_metadata
                                                   ));
 
-       ms->set_key (libdcp::Key ());
+       ms->set_key (key);
        
        cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
        d.add_cpl (cpl);
@@ -88,6 +90,7 @@ BOOST_AUTO_TEST_CASE (encryption)
        shared_ptr<xmlpp::Document> kdm = cpl->make_kdm (
                signer,
                signer->certificates().leaf(),
+               key,
                boost::posix_time::time_from_string ("2013-01-01 00:00:00"),
                boost::posix_time::time_from_string ("2013-01-08 00:00:00"),
                false,