043eac4715186845316f69a59e98996f9b1ddf71
[libdcp.git] / src / decrypted_kdm.cc
1 /*
2     Copyright (C) 2013-2017 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
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.
10
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.
15
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/>.
18
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
23     including the two.
24
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.
32 */
33
34 #include "decrypted_kdm.h"
35 #include "decrypted_kdm_key.h"
36 #include "encrypted_kdm.h"
37 #include "reel_mxf.h"
38 #include "reel_asset.h"
39 #include "util.h"
40 #include "exceptions.h"
41 #include "cpl.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>
50 #include <boost/foreach.hpp>
51
52 using std::list;
53 using std::vector;
54 using std::string;
55 using std::setw;
56 using std::setfill;
57 using std::hex;
58 using std::pair;
59 using std::map;
60 using std::shared_ptr;
61 using boost::optional;
62 using namespace dcp;
63
64 /* Magic value specified by SMPTE S430-1-2006 */
65 static uint8_t smpte_structure_id[] = { 0xf1, 0xdc, 0x12, 0x44, 0x60, 0x16, 0x9a, 0x0e, 0x85, 0xbc, 0x30, 0x06, 0x42, 0xf8, 0x66, 0xab };
66
67 static void
68 put (uint8_t ** d, string s)
69 {
70         memcpy (*d, s.c_str(), s.length());
71         (*d) += s.length();
72 }
73
74 static void
75 put (uint8_t ** d, uint8_t const * s, int N)
76 {
77         memcpy (*d, s, N);
78         (*d) += N;
79 }
80
81 void
82 DecryptedKDM::put_uuid (uint8_t ** d, string id)
83 {
84         /* 32 hex digits plus some hyphens */
85         DCP_ASSERT (id.length() == 36);
86 #ifdef LIBDCP_WINDOWS
87         __mingw_sscanf (
88 #else
89         sscanf (
90 #endif
91                 id.c_str(),
92                 "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
93                 *d + 0, *d + 1, *d + 2, *d + 3, *d + 4, *d + 5, *d + 6, *d + 7,
94                 *d + 8, *d + 9, *d + 10, *d + 11, *d + 12, *d + 13, *d + 14, *d + 15
95                 );
96
97         *d += 16;
98 }
99
100 string
101 DecryptedKDM::get_uuid (unsigned char ** p)
102 {
103         char buffer[37];
104 #ifdef LIBDCP_WINDOWS
105         __mingw_snprintf (
106 #else
107         snprintf (
108 #endif
109                 buffer, sizeof(buffer), "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
110                 (*p)[0], (*p)[1], (*p)[2], (*p)[3], (*p)[4], (*p)[5], (*p)[6], (*p)[7],
111                 (*p)[8], (*p)[9], (*p)[10], (*p)[11], (*p)[12], (*p)[13], (*p)[14], (*p)[15]
112                 );
113
114         *p += 16;
115         return buffer;
116 }
117
118 static string
119 get (uint8_t ** p, int N)
120 {
121         string g;
122         for (int i = 0; i < N; ++i) {
123                 g += **p;
124                 (*p)++;
125         }
126
127         return g;
128 }
129
130 DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key)
131 {
132         /* Read the private key */
133
134         BIO* bio = BIO_new_mem_buf (const_cast<char *> (private_key.c_str ()), -1);
135         if (!bio) {
136                 throw MiscError ("could not create memory BIO");
137         }
138
139         RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
140         if (!rsa) {
141                 throw FileError ("could not read RSA private key file", private_key, errno);
142         }
143
144         /* Use the private key to decrypt the keys */
145
146         BOOST_FOREACH (string const & i, kdm.keys ()) {
147                 /* Decode the base-64-encoded cipher value from the KDM */
148                 unsigned char cipher_value[256];
149                 int const cipher_value_len = base64_decode (i, cipher_value, sizeof (cipher_value));
150
151                 /* Decrypt it */
152                 unsigned char * decrypted = new unsigned char[RSA_size(rsa)];
153                 int const decrypted_len = RSA_private_decrypt (cipher_value_len, cipher_value, decrypted, rsa, RSA_PKCS1_OAEP_PADDING);
154                 if (decrypted_len == -1) {
155                         delete[] decrypted;
156 #if OPENSSL_VERSION_NUMBER > 0x10100000L
157                         throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0), cipher_value_len, RSA_bits(rsa));
158 #else
159                         throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0), cipher_value_len, rsa->n->dmax);
160 #endif
161                 }
162
163                 unsigned char* p = decrypted;
164                 switch (decrypted_len) {
165                 case 134:
166                 {
167                         /* Inter-op */
168                         /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
169                         p += 16;
170                         /* 16 is is signer thumbprint [20 bytes] */
171                         p += 20;
172                         /* 36 is CPL id [16 bytes] */
173                         string const cpl_id = get_uuid (&p);
174                         /* 52 is key id [16 bytes] */
175                         string const key_id = get_uuid (&p);
176                         /* 68 is not-valid-before (a string) [25 bytes] */
177                         p += 25;
178                         /* 93 is not-valid-after (a string) [25 bytes] */
179                         p += 25;
180                         /* 118 is the key [ASDCP::KeyLen bytes] */
181                         add_key (optional<string>(), key_id, Key (p), cpl_id, INTEROP);
182                         break;
183                 }
184                 case 138:
185                 {
186                         /* SMPTE */
187                         /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
188                         DCP_ASSERT (memcmp (p, smpte_structure_id, 16) == 0);
189                         p += 16;
190                         /* 16 is is signer thumbprint [20 bytes] */
191                         p += 20;
192                         /* 36 is CPL id [16 bytes] */
193                         string const cpl_id = get_uuid (&p);
194                         /* 52 is key type [4 bytes] */
195                         string const key_type = get (&p, 4);
196                         /* 56 is key id [16 bytes] */
197                         string const key_id = get_uuid (&p);
198                         /* 72 is not-valid-before (a string) [25 bytes] */
199                         p += 25;
200                         /* 97 is not-valid-after (a string) [25 bytes] */
201                         p += 25;
202                         /* 112 is the key [ASDCP::KeyLen bytes] */
203                         add_key (key_type, key_id, Key (p), cpl_id, SMPTE);
204                         break;
205                 }
206                 default:
207                         DCP_ASSERT (false);
208                 }
209
210                 delete[] decrypted;
211         }
212
213         RSA_free (rsa);
214         BIO_free (bio);
215
216         _annotation_text = kdm.annotation_text ();
217         _content_title_text = kdm.content_title_text ();
218         _issue_date = kdm.issue_date ();
219 }
220
221 DecryptedKDM::DecryptedKDM (
222         LocalTime not_valid_before,
223         LocalTime not_valid_after,
224         string annotation_text,
225         string content_title_text,
226         string issue_date
227         )
228         : _not_valid_before (not_valid_before)
229         , _not_valid_after (not_valid_after)
230         , _annotation_text (annotation_text)
231         , _content_title_text (content_title_text)
232         , _issue_date (issue_date)
233 {
234
235 }
236
237 DecryptedKDM::DecryptedKDM (
238         string cpl_id,
239         map<shared_ptr<const ReelMXF>, Key> keys,
240         LocalTime not_valid_before,
241         LocalTime not_valid_after,
242         string annotation_text,
243         string content_title_text,
244         string issue_date
245         )
246         : _not_valid_before (not_valid_before)
247         , _not_valid_after (not_valid_after)
248         , _annotation_text (annotation_text)
249         , _content_title_text (content_title_text)
250         , _issue_date (issue_date)
251 {
252         for (map<shared_ptr<const ReelMXF>, Key>::const_iterator i = keys.begin(); i != keys.end(); ++i) {
253                 add_key (i->first->key_type(), i->first->key_id().get(), i->second, cpl_id, SMPTE);
254         }
255 }
256
257 DecryptedKDM::DecryptedKDM (
258         shared_ptr<const CPL> cpl,
259         Key key,
260         LocalTime not_valid_before,
261         LocalTime not_valid_after,
262         string annotation_text,
263         string content_title_text,
264         string issue_date
265         )
266         : _not_valid_before (not_valid_before)
267         , _not_valid_after (not_valid_after)
268         , _annotation_text (annotation_text)
269         , _content_title_text (content_title_text)
270         , _issue_date (issue_date)
271 {
272         /* Create DecryptedKDMKey objects for each encryptable asset */
273         bool did_one = false;
274         BOOST_FOREACH(shared_ptr<const ReelMXF> i, cpl->reel_mxfs()) {
275                 if (i->key_id()) {
276                         add_key (i->key_type(), i->key_id().get(), key, cpl->id(), SMPTE);
277                         did_one = true;
278                 }
279         }
280
281         if (!did_one) {
282                 throw NotEncryptedError (cpl->id ());
283         }
284 }
285
286 /** @param type (MDIK, MDAK etc.)
287  *  @param key_id Key ID.
288  *  @param key The actual symmetric key.
289  *  @param cpl_id ID of CPL that the key is for.
290  */
291 void
292 DecryptedKDM::add_key (optional<string> type, string key_id, Key key, string cpl_id, Standard standard)
293 {
294         _keys.push_back (DecryptedKDMKey (type, key_id, key, cpl_id, standard));
295 }
296
297 void
298 DecryptedKDM::add_key (DecryptedKDMKey key)
299 {
300         _keys.push_back (key);
301 }
302
303 EncryptedKDM
304 DecryptedKDM::encrypt (
305         shared_ptr<const CertificateChain> signer,
306         Certificate recipient,
307         vector<string> trusted_devices,
308         Formulation formulation,
309         bool disable_forensic_marking_picture,
310         optional<int> disable_forensic_marking_audio
311         ) const
312 {
313         DCP_ASSERT (!_keys.empty ());
314
315         BOOST_FOREACH (dcp::Certificate i, signer->leaf_to_root()) {
316                 if (day_greater_than_or_equal(dcp::LocalTime(i.not_before()), _not_valid_before)) {
317                         throw BadKDMDateError (true);
318                 } else if (day_less_than_or_equal(dcp::LocalTime(i.not_after()), _not_valid_after)) {
319                         throw BadKDMDateError (false);
320                 }
321         }
322
323         list<pair<string, string> > key_ids;
324         list<string> keys;
325         BOOST_FOREACH (DecryptedKDMKey const & i, _keys) {
326                 /* We're making SMPTE keys so we must have a type for each one */
327                 DCP_ASSERT (i.type());
328                 key_ids.push_back (make_pair (i.type().get(), i.id ()));
329
330                 /* XXX: SMPTE only */
331                 uint8_t block[138];
332                 uint8_t* p = block;
333
334                 put (&p, smpte_structure_id, 16);
335
336                 base64_decode (signer->leaf().thumbprint (), p, 20);
337                 p += 20;
338
339                 put_uuid (&p, i.cpl_id ());
340                 put (&p, i.type().get());
341                 put_uuid (&p, i.id ());
342                 put (&p, _not_valid_before.as_string ());
343                 put (&p, _not_valid_after.as_string ());
344                 put (&p, i.key().value(), ASDCP::KeyLen);
345
346                 /* Encrypt using the projector's public key */
347                 RSA* rsa = recipient.public_key ();
348                 unsigned char encrypted[RSA_size(rsa)];
349                 int const encrypted_len = RSA_public_encrypt (p - block, block, encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
350                 if (encrypted_len == -1) {
351                         throw MiscError (String::compose ("Could not encrypt KDM (%1)", ERR_error_string (ERR_get_error(), 0)));
352                 }
353
354                 /* Lazy overallocation */
355                 char out[encrypted_len * 2];
356                 Kumu::base64encode (encrypted, encrypted_len, out, encrypted_len * 2);
357                 int const N = strlen (out);
358                 string lines;
359                 for (int i = 0; i < N; ++i) {
360                         if (i > 0 && (i % 64) == 0) {
361                                 lines += "\n";
362                         }
363                         lines += out[i];
364                 }
365
366                 keys.push_back (lines);
367         }
368
369         string device_list_description = recipient.subject_common_name ();
370         if (device_list_description.find (".") != string::npos) {
371                 device_list_description = device_list_description.substr (device_list_description.find (".") + 1);
372         }
373
374         return EncryptedKDM (
375                 signer,
376                 recipient,
377                 trusted_devices,
378                 _keys.front().cpl_id (),
379                 _content_title_text,
380                 _annotation_text,
381                 _not_valid_before,
382                 _not_valid_after,
383                 formulation,
384                 disable_forensic_marking_picture,
385                 disable_forensic_marking_audio,
386                 key_ids,
387                 keys
388                 );
389 }