/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2015 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
#include "decrypted_kdm.h"
#include "decrypted_kdm_key.h"
#include "encrypted_kdm.h"
-#include "reel_mxf_asset.h"
+#include "reel_mxf.h"
+#include "reel_asset.h"
#include "util.h"
#include "exceptions.h"
#include "cpl.h"
-#include "mxf.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include "dcp_assert.h"
#include "AS_DCP.h"
#include "KM_util.h"
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
+#include <boost/foreach.hpp>
using std::list;
using std::string;
get_uuid (unsigned char ** p)
{
stringstream g;
-
+
for (int i = 0; i < 16; ++i) {
g << setw(2) << setfill('0') << hex << static_cast<int> (**p);
(*p)++;
if (!bio) {
throw MiscError ("could not create memory BIO");
}
-
+
RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
if (!rsa) {
throw FileError ("could not read RSA private key file", private_key, errno);
/* Use the private key to decrypt the keys */
- list<string> const encrypted_keys = kdm.keys ();
- for (list<string>::const_iterator i = encrypted_keys.begin(); i != encrypted_keys.end(); ++i) {
-
+ BOOST_FOREACH (string const & i, kdm.keys ()) {
/* Decode the base-64-encoded cipher value from the KDM */
unsigned char cipher_value[256];
- int const cipher_value_len = base64_decode (*i, cipher_value, sizeof (cipher_value));
+ int const cipher_value_len = base64_decode (i, cipher_value, sizeof (cipher_value));
/* Decrypt it */
unsigned char * decrypted = new unsigned char[RSA_size(rsa)];
}
default:
DCP_ASSERT (false);
- }
-
+ }
+
delete[] decrypted;
}
, _content_title_text (content_title_text)
, _issue_date (issue_date)
{
- /* Create DecryptedKDMKey objects for each MXF asset */
- list<shared_ptr<const ReelAsset> > assets = cpl->reel_assets ();
- for (list<shared_ptr<const ReelAsset> >::iterator i = assets.begin(); i != assets.end(); ++i) {
- /* XXX: do non-MXF assets need keys? */
- shared_ptr<const ReelMXFAsset> mxf = boost::dynamic_pointer_cast<const ReelMXFAsset> (*i);
- if (mxf) {
- if (mxf->key_id().empty ()) {
- throw NotEncryptedError (mxf->id());
+ /* Create DecryptedKDMKey objects for each encryptable asset */
+ BOOST_FOREACH(shared_ptr<const ReelAsset> i, cpl->reel_assets ()) {
+ shared_ptr<const ReelMXF> mxf = boost::dynamic_pointer_cast<const ReelMXF> (i);
+ shared_ptr<const ReelAsset> asset = boost::dynamic_pointer_cast<const ReelAsset> (i);
+ if (asset && mxf) {
+ if (!mxf->key_id ()) {
+ throw NotEncryptedError (asset->id ());
}
- _keys.push_back (DecryptedKDMKey (mxf->key_type(), mxf->key_id(), key, cpl->id ()));
+ _keys.push_back (DecryptedKDMKey (mxf->key_type(), mxf->key_id().get(), key, cpl->id ()));
}
}
}
EncryptedKDM
-DecryptedKDM::encrypt (shared_ptr<const Signer> signer, Certificate recipient, Formulation formulation) const
+DecryptedKDM::encrypt (shared_ptr<const CertificateChain> signer, Certificate recipient, Formulation formulation) const
{
list<pair<string, string> > key_ids;
list<string> keys;
- for (list<DecryptedKDMKey>::const_iterator i = _keys.begin(); i != _keys.end(); ++i) {
-
- key_ids.push_back (make_pair (i->type(), i->id ()));
+ BOOST_FOREACH (DecryptedKDMKey const & i, _keys) {
+ key_ids.push_back (make_pair (i.type(), i.id ()));
/* XXX: SMPTE only */
uint8_t block[138];
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);
- base64_decode (signer->certificates().leaf().thumbprint (), p, 20);
+ base64_decode (signer->leaf().thumbprint (), p, 20);
p += 20;
-
- put_uuid (&p, i->cpl_id ());
- put (&p, i->type ());
- put_uuid (&p, i->id ());
+
+ put_uuid (&p, i.cpl_id ());
+ put (&p, i.type ());
+ put_uuid (&p, i.id ());
put (&p, _not_valid_before.as_string ());
put (&p, _not_valid_after.as_string ());
- put (&p, i->key().value(), ASDCP::KeyLen);
-
+ put (&p, i.key().value(), ASDCP::KeyLen);
+
/* Encrypt using the projector's public key */
RSA* rsa = recipient.public_key ();
unsigned char encrypted[RSA_size(rsa)];
if (encrypted_len == -1) {
throw MiscError (String::compose ("Could not encrypt KDM (%1)", ERR_error_string (ERR_get_error(), 0)));
}
-
+
/* Lazy overallocation */
char out[encrypted_len * 2];
Kumu::base64encode (encrypted, encrypted_len, out, encrypted_len * 2);
}
lines << out[i];
}
-
+
keys.push_back (lines.str ());
}
- string device_list_description = recipient.common_name ();
+ string device_list_description = recipient.subject_common_name ();
if (device_list_description.find (".") != string::npos) {
device_list_description = device_list_description.substr (device_list_description.find (".") + 1);
}