2 Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
4 This file is part of libdcp.
6 libdcp is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 libdcp is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with libdcp. If not, see <http://www.gnu.org/licenses/>.
19 In addition, as a special exception, the copyright holders give
20 permission to link the code of portions of this program with the
21 OpenSSL library under certain conditions as described in each
22 individual source file, and distribute linked combinations
25 You must obey the GNU General Public License in all respects
26 for all of the code used other than OpenSSL. If you modify
27 file(s) with this exception, you may extend this exception to your
28 version of the file(s), but you are not obligated to do so. If you
29 do not wish to do so, delete this exception statement from your
30 version. If you delete this exception statement from all source
31 files in the program, then also delete it here.
34 #include "decrypted_kdm.h"
35 #include "decrypted_kdm_key.h"
36 #include "encrypted_kdm.h"
38 #include "reel_asset.h"
40 #include "exceptions.h"
42 #include "certificate_chain.h"
43 #include "dcp_assert.h"
44 #include "compose.hpp"
45 #include <asdcp/AS_DCP.h>
46 #include <asdcp/KM_util.h>
47 #include <openssl/rsa.h>
48 #include <openssl/pem.h>
49 #include <openssl/err.h>
59 using std::shared_ptr;
60 using boost::optional;
63 /* Magic value specified by SMPTE S430-1-2006 */
64 static uint8_t smpte_structure_id[] = { 0xf1, 0xdc, 0x12, 0x44, 0x60, 0x16, 0x9a, 0x0e, 0x85, 0xbc, 0x30, 0x06, 0x42, 0xf8, 0x66, 0xab };
67 put (uint8_t ** d, string s)
69 memcpy (*d, s.c_str(), s.length());
74 put (uint8_t ** d, uint8_t const * s, int N)
81 DecryptedKDM::put_uuid (uint8_t ** d, string id)
83 /* 32 hex digits plus some hyphens */
84 DCP_ASSERT (id.length() == 36);
91 "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
92 *d + 0, *d + 1, *d + 2, *d + 3, *d + 4, *d + 5, *d + 6, *d + 7,
93 *d + 8, *d + 9, *d + 10, *d + 11, *d + 12, *d + 13, *d + 14, *d + 15
100 DecryptedKDM::get_uuid (unsigned char ** p)
103 #ifdef LIBDCP_WINDOWS
108 buffer, sizeof(buffer), "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
109 (*p)[0], (*p)[1], (*p)[2], (*p)[3], (*p)[4], (*p)[5], (*p)[6], (*p)[7],
110 (*p)[8], (*p)[9], (*p)[10], (*p)[11], (*p)[12], (*p)[13], (*p)[14], (*p)[15]
118 get (uint8_t ** p, int N)
121 for (int i = 0; i < N; ++i) {
129 DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key)
131 /* Read the private key */
133 BIO* bio = BIO_new_mem_buf (const_cast<char *> (private_key.c_str ()), -1);
135 throw MiscError ("could not create memory BIO");
138 RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
140 throw FileError ("could not read RSA private key file", private_key, errno);
143 /* Use the private key to decrypt the keys */
145 for (auto const& i: kdm.keys()) {
146 /* Decode the base-64-encoded cipher value from the KDM */
147 unsigned char cipher_value[256];
148 int const cipher_value_len = base64_decode (i, cipher_value, sizeof (cipher_value));
151 unsigned char * decrypted = new unsigned char[RSA_size(rsa)];
152 int const decrypted_len = RSA_private_decrypt (cipher_value_len, cipher_value, decrypted, rsa, RSA_PKCS1_OAEP_PADDING);
153 if (decrypted_len == -1) {
155 #if OPENSSL_VERSION_NUMBER > 0x10100000L
156 throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0), cipher_value_len, RSA_bits(rsa));
158 throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0), cipher_value_len, rsa->n->dmax);
162 unsigned char* p = decrypted;
163 switch (decrypted_len) {
167 /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
169 /* 16 is is signer thumbprint [20 bytes] */
171 /* 36 is CPL id [16 bytes] */
172 string const cpl_id = get_uuid (&p);
173 /* 52 is key id [16 bytes] */
174 string const key_id = get_uuid (&p);
175 /* 68 is not-valid-before (a string) [25 bytes] */
177 /* 93 is not-valid-after (a string) [25 bytes] */
179 /* 118 is the key [ASDCP::KeyLen bytes] */
180 add_key (optional<string>(), key_id, Key(p), cpl_id, Standard::INTEROP);
186 /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
187 DCP_ASSERT (memcmp (p, smpte_structure_id, 16) == 0);
189 /* 16 is is signer thumbprint [20 bytes] */
191 /* 36 is CPL id [16 bytes] */
192 string const cpl_id = get_uuid (&p);
193 /* 52 is key type [4 bytes] */
194 string const key_type = get (&p, 4);
195 /* 56 is key id [16 bytes] */
196 string const key_id = get_uuid (&p);
197 /* 72 is not-valid-before (a string) [25 bytes] */
199 /* 97 is not-valid-after (a string) [25 bytes] */
201 /* 112 is the key [ASDCP::KeyLen bytes] */
202 add_key (key_type, key_id, Key(p), cpl_id, Standard::SMPTE);
215 _annotation_text = kdm.annotation_text ();
216 _content_title_text = kdm.content_title_text ();
217 _issue_date = kdm.issue_date ();
220 DecryptedKDM::DecryptedKDM (
221 LocalTime not_valid_before,
222 LocalTime not_valid_after,
223 string annotation_text,
224 string content_title_text,
227 : _not_valid_before (not_valid_before)
228 , _not_valid_after (not_valid_after)
229 , _annotation_text (annotation_text)
230 , _content_title_text (content_title_text)
231 , _issue_date (issue_date)
236 DecryptedKDM::DecryptedKDM (
238 map<shared_ptr<const ReelMXF>, Key> keys,
239 LocalTime not_valid_before,
240 LocalTime not_valid_after,
241 string annotation_text,
242 string content_title_text,
245 : _not_valid_before (not_valid_before)
246 , _not_valid_after (not_valid_after)
247 , _annotation_text (annotation_text)
248 , _content_title_text (content_title_text)
249 , _issue_date (issue_date)
251 for (map<shared_ptr<const ReelMXF>, Key>::const_iterator i = keys.begin(); i != keys.end(); ++i) {
252 add_key (i->first->key_type(), i->first->key_id().get(), i->second, cpl_id, Standard::SMPTE);
256 DecryptedKDM::DecryptedKDM (
257 shared_ptr<const CPL> cpl,
259 LocalTime not_valid_before,
260 LocalTime not_valid_after,
261 string annotation_text,
262 string content_title_text,
265 : _not_valid_before (not_valid_before)
266 , _not_valid_after (not_valid_after)
267 , _annotation_text (annotation_text)
268 , _content_title_text (content_title_text)
269 , _issue_date (issue_date)
271 /* Create DecryptedKDMKey objects for each encryptable asset */
272 bool did_one = false;
273 for (auto i: cpl->reel_mxfs()) {
275 add_key (i->key_type(), i->key_id().get(), key, cpl->id(), Standard::SMPTE);
281 throw NotEncryptedError (cpl->id ());
285 /** @param type (MDIK, MDAK etc.)
286 * @param key_id Key ID.
287 * @param key The actual symmetric key.
288 * @param cpl_id ID of CPL that the key is for.
291 DecryptedKDM::add_key (optional<string> type, string key_id, Key key, string cpl_id, Standard standard)
293 _keys.push_back (DecryptedKDMKey (type, key_id, key, cpl_id, standard));
297 DecryptedKDM::add_key (DecryptedKDMKey key)
299 _keys.push_back (key);
303 DecryptedKDM::encrypt (
304 shared_ptr<const CertificateChain> signer,
305 Certificate recipient,
306 vector<string> trusted_devices,
307 Formulation formulation,
308 bool disable_forensic_marking_picture,
309 optional<int> disable_forensic_marking_audio
312 DCP_ASSERT (!_keys.empty ());
314 for (auto i: signer->leaf_to_root()) {
315 if (day_greater_than_or_equal(dcp::LocalTime(i.not_before()), _not_valid_before)) {
316 throw BadKDMDateError (true);
317 } else if (day_less_than_or_equal(dcp::LocalTime(i.not_after()), _not_valid_after)) {
318 throw BadKDMDateError (false);
322 vector<pair<string, string>> key_ids;
324 for (auto const& i: _keys) {
325 /* We're making SMPTE keys so we must have a type for each one */
326 DCP_ASSERT (i.type());
327 key_ids.push_back (make_pair (i.type().get(), i.id ()));
329 /* XXX: SMPTE only */
333 put (&p, smpte_structure_id, 16);
335 base64_decode (signer->leaf().thumbprint (), p, 20);
338 put_uuid (&p, i.cpl_id ());
339 put (&p, i.type().get());
340 put_uuid (&p, i.id ());
341 put (&p, _not_valid_before.as_string ());
342 put (&p, _not_valid_after.as_string ());
343 put (&p, i.key().value(), ASDCP::KeyLen);
345 /* Encrypt using the projector's public key */
346 RSA* rsa = recipient.public_key ();
347 unsigned char encrypted[RSA_size(rsa)];
348 int const encrypted_len = RSA_public_encrypt (p - block, block, encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
349 if (encrypted_len == -1) {
350 throw MiscError (String::compose ("Could not encrypt KDM (%1)", ERR_error_string (ERR_get_error(), 0)));
353 /* Lazy overallocation */
354 char out[encrypted_len * 2];
355 Kumu::base64encode (encrypted, encrypted_len, out, encrypted_len * 2);
356 int const N = strlen (out);
358 for (int i = 0; i < N; ++i) {
359 if (i > 0 && (i % 64) == 0) {
365 keys.push_back (lines);
368 string device_list_description = recipient.subject_common_name ();
369 if (device_list_description.find (".") != string::npos) {
370 device_list_description = device_list_description.substr (device_list_description.find (".") + 1);
373 return EncryptedKDM (
377 _keys.front().cpl_id (),
383 disable_forensic_marking_picture,
384 disable_forensic_marking_audio,