for 2K projectors.
*/
boost::shared_ptr<libdcp::MonoPictureAsset> picture_asset (
- new libdcp::MonoPictureAsset (video_frame, "My Film DCP", "video.mxf", 0, 24, 48, false, libdcp::Size (1998, 1080), false)
+ new libdcp::MonoPictureAsset (video_frame, "My Film DCP", "video.mxf", 0, 24, 48, libdcp::Size (1998, 1080), false)
);
/* Now we will create a `sound asset', which is made up of a WAV file for each channel of audio. Here we're using
/* Now we can create the sound asset using these files */
boost::shared_ptr<libdcp::SoundAsset> sound_asset (
- new libdcp::SoundAsset (sound_files, "My Film DCP", "audio.mxf", 0, 24, 48, false, false)
+ new libdcp::SoundAsset (sound_files, "My Film DCP", "audio.mxf", 0, 24, 48, false)
);
/* Now that we have the assets, we can create a Reel to put them in and add it to the CPL */
}
-Certificate::Certificate (string const & filename)
+Certificate::Certificate (boost::filesystem::path filename)
: _certificate (0)
{
FILE* f = fopen (filename.c_str(), "r");
}
}
+Certificate::Certificate (string cert)
+{
+ read_string (cert);
+}
+
+Certificate::Certificate (Certificate const & other)
+{
+ read_string (other.certificate (true));
+}
+
+void
+Certificate::read_string (string cert)
+{
+ BIO* bio = BIO_new_mem_buf (const_cast<char *> (cert.c_str ()), -1);
+ if (!bio) {
+ throw MiscError ("could not create memory BIO");
+ }
+
+ _certificate = PEM_read_bio_X509 (bio, 0, 0, 0);
+ if (!_certificate) {
+ throw MiscError ("could not read X509 certificate from memory BIO");
+ }
+
+ BIO_free (bio);
+}
+
Certificate::~Certificate ()
{
X509_free (_certificate);
}
+Certificate &
+Certificate::operator= (Certificate const & other)
+{
+ if (this == &other) {
+ return *this;
+ }
+
+ X509_free (_certificate);
+ read_string (other.certificate ());
+
+ return *this;
+}
+
string
-Certificate::certificate () const
+Certificate::certificate (bool with_begin_end) const
{
assert (_certificate);
BIO_free (bio);
- boost::replace_all (s, "-----BEGIN CERTIFICATE-----\n", "");
- boost::replace_all (s, "\n-----END CERTIFICATE-----\n", "");
+ if (!with_begin_end) {
+ boost::replace_all (s, "-----BEGIN CERTIFICATE-----\n", "");
+ boost::replace_all (s, "\n-----END CERTIFICATE-----\n", "");
+ }
+
return s;
}
#include <list>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>
+#include <boost/filesystem.hpp>
#undef X509_NAME
#include <openssl/x509.h>
namespace libdcp {
-class Certificate : public boost::noncopyable
+class Certificate
{
public:
Certificate ()
: _certificate (0)
{}
- Certificate (std::string const &);
+ Certificate (boost::filesystem::path);
+ Certificate (std::string);
Certificate (X509 *);
+ Certificate (Certificate const &);
~Certificate ();
- std::string certificate () const;
+ Certificate& operator= (Certificate const &);
+
+ /** @param with_begin_end true to include BEGIN CERTIFICATE / END CERTIFICATE markers
+ * @return the whole certificate as a string.
+ */
+ std::string certificate (bool with_begin_end = false) const;
std::string issuer () const;
std::string serial () const;
std::string subject () const;
std::string thumbprint () const;
private:
+ void read_string (std::string);
+
static std::string name_for_xml (X509_NAME *);
static std::string asn_to_utf8 (ASN1_STRING *);
static std::string get_name_part (X509_NAME *, int);
xmlpp::Element* authenticated_private = root->add_child("AuthenticatedPrivate");
authenticated_private->set_attribute ("Id", "ID_AuthenticatedPrivate");
xmlAddID (0, doc->cobj(), (const xmlChar *) "ID_AuthenticatedPrivate", authenticated_private->get_attribute("Id")->cobj());
- {
- 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");
- }
+ /* 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("XXX");
+ cipher_data->add_child("CipherValue", "enc")->add_child_text(mxf->key()->hex());
+
+ written_keys.push_back (mxf->key().get());
}
}
- /* XXX: x2 one for each mxf? */
-
{
xmlpp::Element* signature = root->add_child("Signature", "ds");
void
DCP::add_kdm (KDM const & kdm)
{
- list<KDMCipher> ciphers = kdm.ciphers ();
+ list<KDMKey> keys = kdm.keys ();
for (list<shared_ptr<CPL> >::iterator i = _cpls.begin(); i != _cpls.end(); ++i) {
- for (list<KDMCipher>::iterator j = ciphers.begin(); j != ciphers.end(); ++j) {
+ for (list<KDMKey>::iterator j = keys.begin(); j != keys.end(); ++j) {
if (j->cpl_id() == (*i)->id()) {
(*i)->add_kdm (kdm);
}
throw MiscError (String::compose ("Could not decrypt KDM (%1)", ERR_error_string (ERR_get_error(), 0)));
}
- _ciphers.push_back (KDMCipher (decrypted, decrypted_len));
+ _keys.push_back (KDMKey (decrypted, decrypted_len));
delete[] decrypted;
}
}
-KDMCipher::KDMCipher (unsigned char const * raw, int len)
+KDMKey::KDMKey (unsigned char const * raw, int len)
{
switch (len) {
case 134:
_key_id = get_uuid (&raw, 16);
_not_valid_before = get (&raw, 25);
_not_valid_after = get (&raw, 25);
- memcpy (_key_raw, raw, 16);
- _key_string = get_hex (&raw, 16);
+ _key = Key (raw);
break;
case 138:
/* SMPTE */
_key_id = get_uuid (&raw, 16);
_not_valid_before = get (&raw, 25);
_not_valid_after = get (&raw, 25);
- memcpy (_key_raw, raw, 16);
- _key_string = get_hex (&raw, 16);
+ _key = Key (raw);
break;
default:
assert (false);
}
string
-KDMCipher::get (unsigned char const ** p, int N) const
+KDMKey::get (unsigned char const ** p, int N) const
{
string g;
for (int i = 0; i < N; ++i) {
}
string
-KDMCipher::get_uuid (unsigned char const ** p, int N) const
+KDMKey::get_uuid (unsigned char const ** p, int N) const
{
stringstream g;
return g.str ();
}
-
-string
-KDMCipher::get_hex (unsigned char const ** p, int N) const
-{
- stringstream g;
-
- for (int i = 0; i < N; ++i) {
- g << setw(2) << setfill('0') << hex << static_cast<int> (**p);
- (*p)++;
- }
-
- return g.str ();
-}
#define LIBDCP_KDM_H
#include <boost/filesystem.hpp>
+#include "key.h"
namespace libdcp {
-/** A single cipher for encrypting or decrypting an MXF. One or more of these
+/** A single key for encrypting or decrypting an MXF. One or more of these
* are delivered in a KDM.
*/
-class KDMCipher
+class KDMKey
{
public:
- KDMCipher (unsigned char const *, int);
+ KDMKey (unsigned char const *, int);
std::string structure_id () const {
return _structure_id;
std::string key_type () const {
return _key_type;
}
-
+
std::string key_id () const {
return _key_id;
}
-
+
std::string not_valid_before () const {
return _not_valid_before;
}
return _not_valid_after;
}
- /** The key as a hex string */
- std::string key_string () const {
- return _key_string;
- }
-
- /** The key as 16 raw bytes */
- unsigned char const * key_raw () const {
- return _key_raw;
+ Key key () const {
+ return _key;
}
private:
std::string get (unsigned char const **, int) const;
std::string get_uuid (unsigned char const **, int) const;
- std::string get_hex (unsigned char const **, int) const;
std::string _structure_id;
std::string _signer_thumbprint;
std::string _cpl_id;
- std::string _key_type;
- std::string _key_id;
std::string _not_valid_before;
std::string _not_valid_after;
- std::string _key_string;
- unsigned char _key_raw[16];
+ std::string _key_type;
+ std::string _key_id;
+ Key _key;
};
class KDM
public:
KDM (boost::filesystem::path, boost::filesystem::path);
- std::list<KDMCipher> ciphers () const {
- return _ciphers;
+ std::list<KDMKey> keys () const {
+ return _keys;
}
private:
- std::list<KDMCipher> _ciphers;
+ std::list<KDMKey> _keys;
};
--- /dev/null
+/*
+ Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <sstream>
+#include <string>
+#include <iomanip>
+#include "AS_DCP.h"
+#include "KM_prng.h"
+#include "KM_util.h"
+#include "key.h"
+
+using std::string;
+using std::stringstream;
+using std::setw;
+using std::setfill;
+using namespace libdcp;
+
+Key::Key ()
+ : _value (new uint8_t[ASDCP::KeyLen])
+{
+ Kumu::FortunaRNG rng;
+ rng.FillRandom (_value, ASDCP::KeyLen);
+}
+
+Key::Key (uint8_t const * value)
+ : _value (new uint8_t[ASDCP::KeyLen])
+{
+ memcpy (_value, value, ASDCP::KeyLen);
+}
+
+Key::Key (string value)
+ : _value (new uint8_t[ASDCP::KeyLen])
+{
+ unsigned int length;
+ Kumu::hex2bin (value.c_str(), _value, ASDCP::KeyLen, &length);
+}
+
+Key::Key (Key const & other)
+ : _value (new uint8_t[ASDCP::KeyLen])
+{
+ memcpy (_value, other._value, ASDCP::KeyLen);
+}
+
+Key::~Key ()
+{
+ delete[] _value;
+}
+
+Key &
+Key::operator= (Key const & other)
+{
+ if (this == &other) {
+ return *this;
+ }
+
+ memcpy (_value, other._value, ASDCP::KeyLen);
+ return *this;
+}
+
+string
+Key::hex () const
+{
+ stringstream g;
+
+ for (unsigned int i = 0; i < ASDCP::KeyLen; ++i) {
+ g << setw(2) << setfill('0') << std::hex << static_cast<int> (_value[i]);
+ }
+
+ return g.str ();
+}
+
+bool
+libdcp::operator== (Key const & a, Key const & b)
+{
+ return memcmp (a.value(), b.value(), ASDCP::KeyLen) == 0;
+}
+
+bool
+libdcp::operator!= (Key const & a, Key const & b)
+{
+ return !(a == b);
+}
+
--- /dev/null
+/*
+ Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef LIBDCP_KEY_H
+#define LIBDCP_KEY_H
+
+#include <stdint.h>
+
+namespace libdcp {
+
+/** A key for encrypting MXFs */
+class Key
+{
+public:
+ /** Create a new, random key */
+ Key ();
+
+ /** Create a Key from a raw key value */
+ Key (uint8_t const *);
+
+ /** Create a Key from a hex key value */
+ Key (std::string);
+
+ Key (Key const &);
+ ~Key ();
+
+ Key& operator= (Key const &);
+
+ uint8_t* value () const {
+ return _value;
+ }
+
+ std::string hex () const;
+
+private:
+ /** Raw key value */
+ uint8_t* _value;
+};
+
+extern bool operator== (Key const & a, Key const & b);
+extern bool operator!= (Key const & a, Key const & b);
+
+}
+
+#endif
MXFAsset::MXFAsset (string directory, string file_name)
: Asset (directory, file_name)
, _progress (0)
- , _encrypted (false)
, _encryption_context (0)
, _decryption_context (0)
{
}
-MXFAsset::MXFAsset (string directory, string file_name, boost::signals2::signal<void (float)>* progress, int edit_rate, int intrinsic_duration, bool encrypted)
+MXFAsset::MXFAsset (string directory, string file_name, boost::signals2::signal<void (float)>* progress, int edit_rate, int intrinsic_duration)
: Asset (directory, file_name, edit_rate, intrinsic_duration)
, _progress (progress)
- , _encrypted (encrypted)
, _encryption_context (0)
, _decryption_context (0)
{
- if (_encrypted) {
- /* Generate an encryption key and a UUID for it */
- _key_id = make_uuid ();
- uint8_t key_buffer[ASDCP::KeyLen];
- Kumu::FortunaRNG rng;
- rng.FillRandom (key_buffer, ASDCP::KeyLen);
- char key_string[ASDCP::KeyLen * 4];
- Kumu::bin2hex (key_buffer, ASDCP::KeyLen, key_string, ASDCP::KeyLen * 4);
- _key_value = key_string;
-
- _encryption_context = new ASDCP::AESEncContext;
- if (ASDCP_FAILURE (_encryption_context->InitKey (key_buffer))) {
- throw MiscError ("could not set up encryption context");
- }
-
- uint8_t cbc_buffer[ASDCP::CBC_BLOCK_SIZE];
-
- if (ASDCP_FAILURE (_encryption_context->SetIVec (rng.FillRandom (cbc_buffer, ASDCP::CBC_BLOCK_SIZE)))) {
- throw MiscError ("could not set up CBC initialization vector");
- }
- }
+
}
MXFAsset::~MXFAsset ()
{
delete _encryption_context;
+ delete _decryption_context;
}
void
Kumu::hex2bin (uuid.c_str(), writer_info->AssetUUID, Kumu::UUID_Length, &c);
assert (c == Kumu::UUID_Length);
- if (_encrypted) {
+ if (_key) {
Kumu::GenRandomUUID (writer_info->ContextID);
writer_info->EncryptedEssence = true;
a->add_child ("IntrinsicDuration")->add_child_text (lexical_cast<string> (_intrinsic_duration));
a->add_child ("EntryPoint")->add_child_text (lexical_cast<string> (_entry_point));
a->add_child ("Duration")->add_child_text (lexical_cast<string> (_duration));
- if (_encrypted) {
+ if (!_key_id.empty ()) {
a->add_child("KeyId")->add_child_text ("urn:uuid:" + _key_id);
}
}
void
-MXFAsset::set_kdm_cipher (KDMCipher cipher)
+MXFAsset::set_key (Key key)
{
+ _key = key;
+
+ if (_key_id.empty ()) {
+ /* No key ID so far; we now need one */
+ _key_id = make_uuid ();
+ }
+
_decryption_context = new ASDCP::AESDecContext;
- if (ASDCP_FAILURE (_decryption_context->InitKey (cipher.key_raw ()))) {
+ if (ASDCP_FAILURE (_decryption_context->InitKey (_key->value ()))) {
throw MiscError ("could not set up decryption context");
}
+
+ _encryption_context = new ASDCP::AESEncContext;
+ if (ASDCP_FAILURE (_encryption_context->InitKey (_key->value ()))) {
+ throw MiscError ("could not set up encryption context");
+ }
+
+ uint8_t cbc_buffer[ASDCP::CBC_BLOCK_SIZE];
+
+ Kumu::FortunaRNG rng;
+ if (ASDCP_FAILURE (_encryption_context->SetIVec (rng.FillRandom (cbc_buffer, ASDCP::CBC_BLOCK_SIZE)))) {
+ throw MiscError ("could not set up CBC initialization vector");
+ }
}
#include <boost/signals2.hpp>
#include "asset.h"
+#include "key.h"
namespace ASDCP {
class AESEncContext;
{
class MXFMetadata;
-class KDMCipher;
/** @brief Parent class for assets which have MXF files */
class MXFAsset : public Asset
* @param edit_rate Edit rate in frames per second (usually equal to the video frame rate).
* @param intrinsic_duration Duration of the whole asset in frames.
*/
- MXFAsset (std::string directory, std::string file_name, boost::signals2::signal<void (float)>* progress, int edit_rate, int intrinsic_duration, bool encrypted);
+ MXFAsset (
+ std::string directory,
+ std::string file_name,
+ boost::signals2::signal<void (float)>* progress,
+ int edit_rate,
+ int intrinsic_duration
+ );
~MXFAsset ();
void add_typed_key_id (xmlpp::Element *) const;
- std::string key_id () const {
- return _key_id;
+ bool encrypted () const {
+ return !_key_id.empty ();
}
- void set_key_id (std::string k) {
- _key_id = k;
+ void set_key_id (std::string i) {
+ _key_id = i;
}
- bool encrypted () const {
- return !_key_id.empty ();
+ std::string key_id () const {
+ return _key_id;
}
+
+ void set_key (Key);
- void set_kdm_cipher (KDMCipher);
+ boost::optional<Key> key () const {
+ return _key;
+ }
protected:
virtual std::string key_type () const = 0;
/** Signal to emit to report progress, or 0 */
boost::signals2::signal<void (float)>* _progress;
- bool _encrypted;
ASDCP::AESEncContext* _encryption_context;
- /** Key used to encrypt, or empty if _encryption is false */
- std::string _key_value;
- /** UUID of encryption key */
- std::string _key_id;
ASDCP::AESDecContext* _decryption_context;
+ std::string _key_id;
+ boost::optional<Key> _key;
};
}
using boost::lexical_cast;
using namespace libdcp;
-PictureAsset::PictureAsset (string directory, string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration, bool encrypted, Size size)
- : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration, encrypted)
+PictureAsset::PictureAsset (string directory, string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration, Size size)
+ : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration)
, _size (size)
{
boost::signals2::signal<void (float)>* progress,
int fps,
int intrinsic_duration,
- bool encrypted,
Size size,
bool interop,
MXFMetadata const & metadata
)
- : PictureAsset (directory, mxf_name, progress, fps, intrinsic_duration, encrypted, size)
+ : PictureAsset (directory, mxf_name, progress, fps, intrinsic_duration, size)
{
construct (get_path, interop, metadata);
}
boost::signals2::signal<void (float)>* progress,
int fps,
int intrinsic_duration,
- bool encrypted,
Size size,
bool interop,
MXFMetadata const & metadata
)
- : PictureAsset (directory, mxf_name, progress, fps, intrinsic_duration, encrypted, size)
+ : PictureAsset (directory, mxf_name, progress, fps, intrinsic_duration, size)
{
construct (boost::bind (&MonoPictureAsset::path_from_list, this, _1, files), interop, metadata);
}
-MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name, int fps, Size size, bool encrypted)
- : PictureAsset (directory, mxf_name, 0, fps, 0, encrypted, size)
+MonoPictureAsset::MonoPictureAsset (string directory, string mxf_name, int fps, Size size)
+ : PictureAsset (directory, mxf_name, 0, fps, 0, size)
{
}
StereoPictureAsset::StereoPictureAsset (string directory, string mxf_name, int fps, int intrinsic_duration)
- : PictureAsset (directory, mxf_name, 0, fps, intrinsic_duration, false, Size (0, 0))
+ : PictureAsset (directory, mxf_name, 0, fps, intrinsic_duration, Size (0, 0))
{
ASDCP::JP2K::MXFSReader reader;
if (ASDCP_FAILURE (reader.OpenRead (path().string().c_str()))) {
return "MDIK";
}
-StereoPictureAsset::StereoPictureAsset (string directory, string mxf_name, int fps, Size size, bool encrypted)
- : PictureAsset (directory, mxf_name, 0, fps, 0, encrypted, size)
+StereoPictureAsset::StereoPictureAsset (string directory, string mxf_name, int fps, Size size)
+ : PictureAsset (directory, mxf_name, 0, fps, 0, size)
{
}
boost::signals2::signal<void (float)>* progress,
int fps,
int intrinsic_duration,
- bool encrypted,
Size
);
* @param fps Video frames per second.
* @param intrinsic_duration Total number of frames in the asset.
* @param size Size of images in pixels.
- * @param encrypted true if asset should be encrypted.
*/
MonoPictureAsset (
std::vector<std::string> const & files,
boost::signals2::signal<void (float)>* progress,
int fps,
int intrinsic_duration,
- bool encrypted,
Size size,
bool interop,
MXFMetadata const & metadata = MXFMetadata ()
* @param fps Video frames per second.
* @param intrinsic_duration Total number of frames in the asset.
* @param size Size of images in pixels.
- * @param encrypted true if asset should be encrypted.
*/
MonoPictureAsset (
boost::function<std::string (int)> get_path,
boost::signals2::signal<void (float)>* progress,
int fps,
int intrinsic_duration,
- bool encrypted,
Size size,
bool interop,
MXFMetadata const & metadata = MXFMetadata ()
* @param fps Video frames per second.
* @param size Size in pixels that the picture frames will be.
*/
- MonoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size, bool encrypted);
+ MonoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size);
/** Start a progressive write to a MonoPictureAsset */
boost::shared_ptr<PictureAssetWriter> start_write (bool, bool, MXFMetadata const & metadata = MXFMetadata ());
* @param fps Video frames per second.
* @param size Size in pixels that the picture frames will be.
*/
- StereoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size, bool encrypted);
+ StereoPictureAsset (std::string directory, std::string mxf_name, int fps, Size size);
/** Start a progressive write to a StereoPictureAsset */
boost::shared_ptr<PictureAssetWriter> start_write (bool, bool, MXFMetadata const & metadata = MXFMetadata ());
void
Reel::add_kdm (KDM const & kdm)
{
- list<KDMCipher> ciphers = kdm.ciphers ();
+ list<KDMKey> keys = kdm.keys ();
- for (list<KDMCipher>::iterator i = ciphers.begin(); i != ciphers.end(); ++i) {
+ for (list<KDMKey>::iterator i = keys.begin(); i != keys.end(); ++i) {
if (i->key_id() == _main_picture->key_id()) {
- _main_picture->set_kdm_cipher (*i);
+ _main_picture->set_key (i->key ());
}
if (i->key_id() == _main_sound->key_id()) {
- _main_sound->set_kdm_cipher (*i);
+ _main_sound->set_key (i->key ());
}
}
}
boost::signals2::signal<void (float)>* progress,
int fps,
int intrinsic_duration,
- bool encrypted,
bool interop,
MXFMetadata const & metadata
)
- : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration, encrypted)
+ : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration)
, _channels (files.size ())
, _sampling_rate (0)
{
int fps,
int intrinsic_duration,
int channels,
- bool encrypted,
bool interop,
MXFMetadata const & metadata
)
- : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration, encrypted)
+ : MXFAsset (directory, mxf_name, progress, fps, intrinsic_duration)
, _channels (channels)
, _sampling_rate (0)
{
_intrinsic_duration = desc.ContainerDuration;
}
-SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int channels, int sampling_rate, bool encrypted)
- : MXFAsset (directory, mxf_name, 0, fps, 0, encrypted)
+SoundAsset::SoundAsset (string directory, string mxf_name, int fps, int channels, int sampling_rate)
+ : MXFAsset (directory, mxf_name, 0, fps, 0)
, _channels (channels)
, _sampling_rate (sampling_rate)
{
* @param length Length in frames.
* @param start_frame Frame in the source to start writing from.
* @param intrinsic_duration Length of the whole asset in frames.
- * @param encrypted true if asset should be encrypted.
* Note that this is different to entry_point in that the asset will contain no data before start_frame.
*/
SoundAsset (
boost::signals2::signal<void (float)>* progress,
int fps,
int intrinsic_duration,
- bool encrypted,
bool interop,
MXFMetadata const & metadata = MXFMetadata ()
);
* @param fps Frames per second.
* @param intrinsic_duration Length of the whole asset in frames.
* @param channels Number of audio channels.
- * @param encrypted true if asset should be encrypted.
*/
SoundAsset (
boost::function<std::string (Channel)> get_path,
int fps,
int intrinsic_duration,
int channels,
- bool encrypted,
bool interop,
MXFMetadata const & metadata = MXFMetadata ()
);
std::string mxf_name,
int fps,
int channels,
- int sampling_rate,
- bool encrypted
+ int sampling_rate
);
boost::shared_ptr<SoundAssetWriter> start_write (bool, MXFMetadata const & metadata = MXFMetadata ());
gamma_lut.cc
image.cc
kdm.cc
+ key.cc
metadata.cc
mxf_asset.cc
picture_asset.cc
gamma_lut.h
image.h
kdm.h
+ key.h
lut.h
lut_cache.h
metadata.h
{
libdcp::CertificateChain c;
- c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("test/ref/crypt/ca.self-signed.pem")));
- c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("test/ref/crypt/intermediate.signed.pem")));
- c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("test/ref/crypt/leaf.signed.pem")));
+ c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
+ c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
+ c.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
list<shared_ptr<libdcp::Certificate> > leaf_to_root = c.leaf_to_root ();
"dnQualifier=ndND9A/cODo2rTdrbLVmfQnoaSc=,CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION,OU=example.org,O=example.org"
);
+ /* Check that reconstruction from a string works */
+ libdcp::Certificate test (c.root()->certificate (true));
+ BOOST_CHECK_EQUAL (test.certificate(), c.root()->certificate());
}
&d.Progress,
24,
24,
- false,
libdcp::Size (32, 32),
false,
mxf_meta
24,
2,
false,
- false,
mxf_meta
));
libdcp::DCP d ("build/test/DCP/bar");
libdcp::CertificateChain chain;
- chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/signer/ca.self-signed.pem")));
- chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/signer/intermediate.signed.pem")));
- chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/signer/leaf.signed.pem")));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("build/test/signer/ca.self-signed.pem"))));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("build/test/signer/intermediate.signed.pem"))));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (boost::filesystem::path ("build/test/signer/leaf.signed.pem"))));
shared_ptr<libdcp::Signer> signer (
new libdcp::Signer (
&d.Progress,
24,
24,
- true,
libdcp::Size (32, 32),
false,
mxf_metadata
));
+ mp->set_key (libdcp::Key ());
+
shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset (
wav,
"build/test/bar",
24,
24,
2,
- true,
false,
mxf_metadata
));
+
+ ms->set_key (libdcp::Key ());
cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
d.add_cpl (cpl);
/* Trying to create video/audio MXFs using a non-existant file should throw an exception */
BOOST_CHECK_THROW (
- new libdcp::MonoPictureAsset (p, "build/test/fred", "video.mxf", &d.Progress, 24, 24, false, libdcp::Size (32, 32), false),
+ new libdcp::MonoPictureAsset (p, "build/test/fred", "video.mxf", &d.Progress, 24, 24, libdcp::Size (32, 32), false),
libdcp::FileError
);
BOOST_CHECK_THROW (
- new libdcp::SoundAsset (p, "build/test/fred", "audio.mxf", &d.Progress, 24, 24, false, false),
+ new libdcp::SoundAsset (p, "build/test/fred", "audio.mxf", &d.Progress, 24, 24, false),
libdcp::FileError
);
}
"test/data/private.key"
);
- list<libdcp::KDMCipher> ciphers = kdm.ciphers ();
+ list<libdcp::KDMKey> keys = kdm.keys ();
- BOOST_CHECK_EQUAL (ciphers.size(), 2);
-
- BOOST_CHECK_EQUAL (ciphers.front().cpl_id(), "eece17de-77e8-4a55-9347-b6bab5724b9f");
- BOOST_CHECK_EQUAL (ciphers.front().key_id(), "4ac4f922-8239-4831-b23b-31426d0542c4");
- BOOST_CHECK_EQUAL (ciphers.front().not_valid_before(), "2013-07-06T20:04:58+00:00");
- BOOST_CHECK_EQUAL (ciphers.front().not_valid_after(), "2023-07-02T20:04:56+00:00");
- BOOST_CHECK_EQUAL (ciphers.front().key_string(), "8a2729c3e5b65c45d78305462104c3fb");
-
- BOOST_CHECK_EQUAL (ciphers.back().cpl_id(), "eece17de-77e8-4a55-9347-b6bab5724b9f");
- BOOST_CHECK_EQUAL (ciphers.back().key_id(), "73baf5de-e195-4542-ab28-8a465f7d4079");
- BOOST_CHECK_EQUAL (ciphers.back().not_valid_before(), "2013-07-06T20:04:58+00:00");
- BOOST_CHECK_EQUAL (ciphers.back().not_valid_after(), "2023-07-02T20:04:56+00:00");
- BOOST_CHECK_EQUAL (ciphers.back().key_string(), "5327fb7ec2e807bd57059615bf8a169d");
+ BOOST_CHECK_EQUAL (keys.size(), 2);
+
+ BOOST_CHECK_EQUAL (keys.front().cpl_id(), "eece17de-77e8-4a55-9347-b6bab5724b9f");
+ BOOST_CHECK_EQUAL (keys.front().key_id(), "4ac4f922-8239-4831-b23b-31426d0542c4");
+ BOOST_CHECK_EQUAL (keys.front().not_valid_before(), "2013-07-06T20:04:58+00:00");
+ BOOST_CHECK_EQUAL (keys.front().not_valid_after(), "2023-07-02T20:04:56+00:00");
+ BOOST_CHECK_EQUAL (keys.front().key().hex(), "8a2729c3e5b65c45d78305462104c3fb");
+
+ BOOST_CHECK_EQUAL (keys.back().cpl_id(), "eece17de-77e8-4a55-9347-b6bab5724b9f");
+ BOOST_CHECK_EQUAL (keys.back().key_id(), "73baf5de-e195-4542-ab28-8a465f7d4079");
+ BOOST_CHECK_EQUAL (keys.back().not_valid_before(), "2013-07-06T20:04:58+00:00");
+ BOOST_CHECK_EQUAL (keys.back().not_valid_after(), "2023-07-02T20:04:56+00:00");
+ BOOST_CHECK_EQUAL (keys.back().key().hex(), "5327fb7ec2e807bd57059615bf8a169d");
}
boost::filesystem::remove_all ("build/test/baz");
boost::filesystem::create_directories ("build/test/baz");
- shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/baz", "video1.mxf", 24, libdcp::Size (32, 32), false));
+ shared_ptr<libdcp::MonoPictureAsset> mp (new libdcp::MonoPictureAsset ("build/test/baz", "video1.mxf", 24, libdcp::Size (32, 32)));
shared_ptr<libdcp::PictureAssetWriter> writer = mp->start_write (false, false);
int written_size = 0;
Kumu::ResetTestRNG ();
#endif
- mp.reset (new libdcp::MonoPictureAsset ("build/test/baz", "video2.mxf", 24, libdcp::Size (32, 32), false));
+ mp.reset (new libdcp::MonoPictureAsset ("build/test/baz", "video2.mxf", 24, libdcp::Size (32, 32)));
writer = mp->start_write (true, false);
writer->write (data, size);