summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-09-21 20:16:11 +0100
committerCarl Hetherington <cth@carlh.net>2013-09-21 20:16:11 +0100
commit66ef19cdb8ab4e4613762acee98a2bcb999ab65c (patch)
tree10cc30f8f0758e12fe7a7119d3b898dbdca7dcfa /src
parent864bbcc3f293bf60c05fda02b0d15c3f604eacc8 (diff)
Unbuilt KDM changes.
Diffstat (limited to 'src')
-rw-r--r--src/cpl.cc24
-rw-r--r--src/cpl.h2
-rw-r--r--src/kdm.cc91
-rw-r--r--src/kdm.h42
4 files changed, 102 insertions, 57 deletions
diff --git a/src/cpl.cc b/src/cpl.cc
index a3d2ecfa..072304b8 100644
--- a/src/cpl.cc
+++ b/src/cpl.cc
@@ -348,7 +348,6 @@ 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,
@@ -446,12 +445,23 @@ CPL::make_kdm (
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");
- xmlpp::Element* cipher_data = authenticated_private->add_child ("CipherData", "enc");
- cipher_data->add_child("CipherValue", "enc")->add_child_text(key.hex());
+ 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) {
+ 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 = encrypted_key->add_child ("CipherData", "enc");
+
+ KDMKey kkey (signer, _id, mxf->key_id (), from, until, mxf->key ());
+ cipher_data->add_child("CipherValue", "enc")->add_child_text (kkey.base64 ());
+ }
}
{
diff --git a/src/cpl.h b/src/cpl.h
index da30fdbb..726fdda2 100644
--- a/src/cpl.h
+++ b/src/cpl.h
@@ -100,7 +100,6 @@ 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.
@@ -108,7 +107,6 @@ 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,
diff --git a/src/kdm.cc b/src/kdm.cc
index bbfd3832..b35c34b5 100644
--- a/src/kdm.cc
+++ b/src/kdm.cc
@@ -44,13 +44,13 @@ KDM::KDM (boost::filesystem::path kdm, boost::filesystem::path private_key)
FILE* private_key_file = fopen (private_key.string().c_str(), "r");
if (!private_key_file) {
- throw FileError ("could not find RSA private key file", private_key.string ());
+ throw FileError ("could not find RSA private key file", private_key);
}
RSA* rsa = PEM_read_RSAPrivateKey (private_key_file, 0, 0, 0);
fclose (private_key_file);
if (!rsa) {
- throw FileError ("could not read RSA private key file", private_key.string ());
+ throw FileError ("could not read RSA private key file", private_key);
}
@@ -87,27 +87,41 @@ KDM::KDM (boost::filesystem::path kdm, boost::filesystem::path private_key)
RSA_free (rsa);
}
+KDMKey::KDMKey (shared_ptr<const Signer> signer, string cpl_id, string key_id, boost::posix_time::ptime from, boost::posix_time::ptime until, Key key)
+ : _cpl_id (cpl_id)
+ , _key_id (key_id),
+ , _not_valid_before (ptime_to_string (from))
+ , _not_valid_after (ptime_to_string (until))
+ , _key (key)
+{
+ /* Magic value specified by SMPTE S430-1-2006 */
+ _structure_id[] = { 0xf1, 0xdc, 0x12, 0x44, 0x60, 0x16, 0x9a, 0x0e, 0x85, 0xbc, 0x30, 0x06, 0x42, 0xf8, 0x66, 0xab };
+
+ base64_decode (signer->certificates()->leaf()->thumbprint (), _signer_thumbprint, 20);
+}
-KDMKey::KDMKey (unsigned char const * raw, int len)
+KDMKey::KDMKey (uint8_t const * raw, int len)
{
switch (len) {
case 134:
/* interop */
- _structure_id = get (&raw, 16);
- _signer_thumbprint = get (&raw, 20);
- _cpl_id = get_uuid (&raw, 16);
- _key_id = get_uuid (&raw, 16);
+ /* [0-15] is structure id (fixed sequence specified by standard) */
+ raw += 16;
+ get (_signer_thumbprint, &raw, 20);
+ _cpl_id = get_uuid (&raw);
+ _key_id = get_uuid (&raw);
_not_valid_before = get (&raw, 25);
_not_valid_after = get (&raw, 25);
_key = Key (raw);
break;
case 138:
/* SMPTE */
- _structure_id = get (&raw, 16);
- _signer_thumbprint = get (&raw, 20);
- _cpl_id = get_uuid (&raw, 16);
+ /* [0-15] is structure id (fixed sequence specified by standard) */
+ raw += 16;
+ get (_signer_thumbprint, &raw, 20);
+ _cpl_id = get_uuid (&raw);
_key_type = get (&raw, 4);
- _key_id = get_uuid (&raw, 16);
+ _key_id = get_uuid (&raw);
_not_valid_before = get (&raw, 25);
_not_valid_after = get (&raw, 25);
_key = Key (raw);
@@ -117,8 +131,32 @@ KDMKey::KDMKey (unsigned char const * raw, int len)
}
}
+
+string
+KDMKey::base64 () const
+{
+ /* XXX: SMPTE only */
+ uint8_t block[138];
+ uint8_t* p = block;
+
+ /* Magic value specified by SMPTE S430-1-2006 */
+ uint8_t structure_id[] = { 0xf1, 0xdc, 0x12, 0x44, 0x60, 0x16, 0x9a, 0x0e, 0x85, 0xbc, 0x30, 0x06, 0x42, 0xf8, 0x66, 0xab };
+ put (&p, structure_id, 16);
+ put (&p, _signer_thumbprint, 20);
+ put_uuid (&p, _cpl_id);
+ put (&p, _key_type, 4);
+ put_uuid (&p, _key_id);
+ put (&p, _not_valid_before.c_str(), 25);
+ put (&p, _not_valid_after.c_str(), 25);
+ put (&p, _key.value(), ASDCP::KeyLen);
+
+ /* Lazy overallocation */
+ char string[138 * 2];
+ return Kumu::base64encode (block, 138, string, 138 * 2);
+}
+
string
-KDMKey::get (unsigned char const ** p, int N) const
+KDMKey::get (uint8_t const ** p, int N) const
{
string g;
for (int i = 0; i < N; ++i) {
@@ -129,12 +167,19 @@ KDMKey::get (unsigned char const ** p, int N) const
return g;
}
+void
+KDMKey::get (uint8_t const * o, uint8_t const ** p, int N) const
+{
+ memcpy (o, *p, N);
+ *p += N;
+}
+
string
-KDMKey::get_uuid (unsigned char const ** p, int N) const
+KDMKey::get_uuid (unsigned char const ** p) const
{
stringstream g;
- for (int i = 0; i < N; ++i) {
+ for (int i = 0; i < 16; ++i) {
g << setw(2) << setfill('0') << hex << static_cast<int> (**p);
(*p)++;
if (i == 3 || i == 5 || i == 7 || i == 9) {
@@ -144,3 +189,21 @@ KDMKey::get_uuid (unsigned char const ** p, int N) const
return g.str ();
}
+
+void
+KDMKey::put (uint8_t ** d, uint8_t const * s, int N) const
+{
+ memcpy (*d, s, N);
+ (*d) += N;
+}
+
+void
+KDMKey::put_uuid (uint8_t ** d, string id) const
+{
+ id.erase (id.remove (id.begin(), id.end(), "-"));
+ for (int i = 0; i < 32; i += 2) {
+ stringstream s;
+ s << id[i] << id[i + 1];
+ s >> *d++;
+ }
+}
diff --git a/src/kdm.h b/src/kdm.h
index c012c101..253589fe 100644
--- a/src/kdm.h
+++ b/src/kdm.h
@@ -28,49 +28,23 @@ namespace libdcp {
/** A single key for encrypting or decrypting an MXF. One or more of these
* are delivered in a KDM.
*/
-class KDMKey
+class KDMKey : public boost::noncopyable
{
public:
- KDMKey (unsigned char const *, int);
-
- std::string structure_id () const {
- return _structure_id;
- }
-
- std::string signer_thumbprint () const {
- return _signer_thumbprint;
- }
-
- std::string cpl_id () const {
- return _cpl_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;
- }
-
- std::string not_valid_after () const {
- return _not_valid_after;
- }
+ KDMKey (uint8_t const *, int);
Key key () const {
return _key;
}
private:
- std::string get (unsigned char const **, int) const;
- std::string get_uuid (unsigned char const **, int) const;
+ void get (uint8_t *, uint8_t const **, int) const;
+ std::string get (uint8_t const **, int) const;
+ std::string get_uuid (uint8_t const **) const;
+ void put (uint8_t **, uint8_t const *, int) const;
+ void put_uuid (uint8_t **, std::string) const;
- std::string _structure_id;
- std::string _signer_thumbprint;
+ uint8_t _signer_thumbprint[20];
std::string _cpl_id;
std::string _not_valid_before;
std::string _not_valid_after;