Check SMPTE structure ID when reading KDMs.
[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 boost::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         snprintf (
105                 buffer, sizeof(buffer), "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
106                 (*p)[0], (*p)[1], (*p)[2], (*p)[3], (*p)[4], (*p)[5], (*p)[6], (*p)[7],
107                 (*p)[8], (*p)[9], (*p)[10], (*p)[11], (*p)[12], (*p)[13], (*p)[14], (*p)[15]
108                 );
109
110         *p += 16;
111         return buffer;
112 }
113
114 static string
115 get (uint8_t ** p, int N)
116 {
117         string g;
118         for (int i = 0; i < N; ++i) {
119                 g += **p;
120                 (*p)++;
121         }
122
123         return g;
124 }
125
126 DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key)
127 {
128         /* Read the private key */
129
130         BIO* bio = BIO_new_mem_buf (const_cast<char *> (private_key.c_str ()), -1);
131         if (!bio) {
132                 throw MiscError ("could not create memory BIO");
133         }
134
135         RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
136         if (!rsa) {
137                 throw FileError ("could not read RSA private key file", private_key, errno);
138         }
139
140         /* Use the private key to decrypt the keys */
141
142         BOOST_FOREACH (string const & i, kdm.keys ()) {
143                 /* Decode the base-64-encoded cipher value from the KDM */
144                 unsigned char cipher_value[256];
145                 int const cipher_value_len = base64_decode (i, cipher_value, sizeof (cipher_value));
146
147                 /* Decrypt it */
148                 unsigned char * decrypted = new unsigned char[RSA_size(rsa)];
149                 int const decrypted_len = RSA_private_decrypt (cipher_value_len, cipher_value, decrypted, rsa, RSA_PKCS1_OAEP_PADDING);
150                 if (decrypted_len == -1) {
151                         delete[] decrypted;
152                         throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0));
153                 }
154
155                 unsigned char* p = decrypted;
156                 switch (decrypted_len) {
157                 case 134:
158                 {
159                         /* Inter-op */
160                         /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
161                         p += 16;
162                         /* 16 is is signer thumbprint [20 bytes] */
163                         p += 20;
164                         /* 36 is CPL id [16 bytes] */
165                         string const cpl_id = get_uuid (&p);
166                         /* 52 is key id [16 bytes] */
167                         string const key_id = get_uuid (&p);
168                         /* 68 is not-valid-before (a string) [25 bytes] */
169                         p += 25;
170                         /* 93 is not-valid-after (a string) [25 bytes] */
171                         p += 25;
172                         /* 118 is the key [ASDCP::KeyLen bytes] */
173                         add_key (optional<string>(), key_id, Key (p), cpl_id);
174                         break;
175                 }
176                 case 138:
177                 {
178                         /* SMPTE */
179                         /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
180                         DCP_ASSERT (memcmp (p, smpte_structure_id, 16) == 0);
181                         p += 16;
182                         /* 16 is is signer thumbprint [20 bytes] */
183                         p += 20;
184                         /* 36 is CPL id [16 bytes] */
185                         string const cpl_id = get_uuid (&p);
186                         /* 52 is key type [4 bytes] */
187                         string const key_type = get (&p, 4);
188                         /* 56 is key id [16 bytes] */
189                         string const key_id = get_uuid (&p);
190                         /* 72 is not-valid-before (a string) [25 bytes] */
191                         p += 25;
192                         /* 97 is not-valid-after (a string) [25 bytes] */
193                         p += 25;
194                         /* 112 is the key [ASDCP::KeyLen bytes] */
195                         add_key (key_type, key_id, Key (p), cpl_id);
196                         break;
197                 }
198                 default:
199                         DCP_ASSERT (false);
200                 }
201
202                 delete[] decrypted;
203         }
204
205         RSA_free (rsa);
206         BIO_free (bio);
207
208         _annotation_text = kdm.annotation_text ();
209         _content_title_text = kdm.content_title_text ();
210         _issue_date = kdm.issue_date ();
211 }
212
213 DecryptedKDM::DecryptedKDM (
214         LocalTime not_valid_before,
215         LocalTime not_valid_after,
216         string annotation_text,
217         string content_title_text,
218         string issue_date
219         )
220         : _not_valid_before (not_valid_before)
221         , _not_valid_after (not_valid_after)
222         , _annotation_text (annotation_text)
223         , _content_title_text (content_title_text)
224         , _issue_date (issue_date)
225 {
226
227 }
228
229 DecryptedKDM::DecryptedKDM (
230         string cpl_id,
231         map<shared_ptr<const ReelMXF>, Key> keys,
232         LocalTime not_valid_before,
233         LocalTime not_valid_after,
234         string annotation_text,
235         string content_title_text,
236         string issue_date
237         )
238         : _not_valid_before (not_valid_before)
239         , _not_valid_after (not_valid_after)
240         , _annotation_text (annotation_text)
241         , _content_title_text (content_title_text)
242         , _issue_date (issue_date)
243 {
244         for (map<shared_ptr<const ReelMXF>, Key>::const_iterator i = keys.begin(); i != keys.end(); ++i) {
245                 add_key (i->first->key_type(), i->first->key_id().get(), i->second, cpl_id);
246         }
247 }
248
249 DecryptedKDM::DecryptedKDM (
250         shared_ptr<const CPL> cpl,
251         Key key,
252         LocalTime not_valid_before,
253         LocalTime not_valid_after,
254         string annotation_text,
255         string content_title_text,
256         string issue_date
257         )
258         : _not_valid_before (not_valid_before)
259         , _not_valid_after (not_valid_after)
260         , _annotation_text (annotation_text)
261         , _content_title_text (content_title_text)
262         , _issue_date (issue_date)
263 {
264         /* Create DecryptedKDMKey objects for each encryptable asset */
265         bool did_one = false;
266         BOOST_FOREACH(shared_ptr<const ReelAsset> i, cpl->reel_assets ()) {
267                 shared_ptr<const ReelMXF> mxf = boost::dynamic_pointer_cast<const ReelMXF> (i);
268                 if (mxf && mxf->key_id ()) {
269                         add_key (mxf->key_type(), mxf->key_id().get(), key, cpl->id ());
270                         did_one = true;
271                 }
272         }
273
274         if (!did_one) {
275                 throw NotEncryptedError (cpl->id ());
276         }
277 }
278
279 /** @param type (MDIK, MDAK etc.)
280  *  @param key_id Key ID.
281  *  @param key The actual symmetric key.
282  *  @param cpl_id ID of CPL that the key is for.
283  */
284 void
285 DecryptedKDM::add_key (optional<string> type, string key_id, Key key, string cpl_id)
286 {
287         _keys.push_back (DecryptedKDMKey (type, key_id, key, cpl_id));
288 }
289
290 void
291 DecryptedKDM::add_key (DecryptedKDMKey key)
292 {
293         _keys.push_back (key);
294 }
295
296 EncryptedKDM
297 DecryptedKDM::encrypt (shared_ptr<const CertificateChain> signer, Certificate recipient, vector<Certificate> trusted_devices, Formulation formulation) const
298 {
299         list<pair<string, string> > key_ids;
300         list<string> keys;
301         BOOST_FOREACH (DecryptedKDMKey const & i, _keys) {
302                 /* We're making SMPTE keys so we must have a type for each one */
303                 DCP_ASSERT (i.type());
304                 key_ids.push_back (make_pair (i.type().get(), i.id ()));
305
306                 /* XXX: SMPTE only */
307                 uint8_t block[138];
308                 uint8_t* p = block;
309
310                 put (&p, smpte_structure_id, 16);
311
312                 base64_decode (signer->leaf().thumbprint (), p, 20);
313                 p += 20;
314
315                 put_uuid (&p, i.cpl_id ());
316                 put (&p, i.type().get());
317                 put_uuid (&p, i.id ());
318                 put (&p, _not_valid_before.as_string ());
319                 put (&p, _not_valid_after.as_string ());
320                 put (&p, i.key().value(), ASDCP::KeyLen);
321
322                 /* Encrypt using the projector's public key */
323                 RSA* rsa = recipient.public_key ();
324                 unsigned char encrypted[RSA_size(rsa)];
325                 int const encrypted_len = RSA_public_encrypt (p - block, block, encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
326                 if (encrypted_len == -1) {
327                         throw MiscError (String::compose ("Could not encrypt KDM (%1)", ERR_error_string (ERR_get_error(), 0)));
328                 }
329
330                 /* Lazy overallocation */
331                 char out[encrypted_len * 2];
332                 Kumu::base64encode (encrypted, encrypted_len, out, encrypted_len * 2);
333                 int const N = strlen (out);
334                 string lines;
335                 for (int i = 0; i < N; ++i) {
336                         if (i > 0 && (i % 64) == 0) {
337                                 lines += "\n";
338                         }
339                         lines += out[i];
340                 }
341
342                 keys.push_back (lines);
343         }
344
345         string device_list_description = recipient.subject_common_name ();
346         if (device_list_description.find (".") != string::npos) {
347                 device_list_description = device_list_description.substr (device_list_description.find (".") + 1);
348         }
349
350         return EncryptedKDM (
351                 signer,
352                 recipient,
353                 trusted_devices,
354                 _keys.front().cpl_id (),
355                 _content_title_text,
356                 _annotation_text,
357                 _not_valid_before,
358                 _not_valid_after,
359                 formulation,
360                 key_ids,
361                 keys
362                 );
363 }