Merge branch '1.0' of ssh://main.carlh.net/home/carl/git/libdcp into 1.0
[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 #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                         throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0), cipher_value_len, rsa->n->dmax);
157                 }
158
159                 unsigned char* p = decrypted;
160                 switch (decrypted_len) {
161                 case 134:
162                 {
163                         /* Inter-op */
164                         /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
165                         p += 16;
166                         /* 16 is is signer thumbprint [20 bytes] */
167                         p += 20;
168                         /* 36 is CPL id [16 bytes] */
169                         string const cpl_id = get_uuid (&p);
170                         /* 52 is key id [16 bytes] */
171                         string const key_id = get_uuid (&p);
172                         /* 68 is not-valid-before (a string) [25 bytes] */
173                         p += 25;
174                         /* 93 is not-valid-after (a string) [25 bytes] */
175                         p += 25;
176                         /* 118 is the key [ASDCP::KeyLen bytes] */
177                         add_key (optional<string>(), key_id, Key (p), cpl_id, INTEROP);
178                         break;
179                 }
180                 case 138:
181                 {
182                         /* SMPTE */
183                         /* 0 is structure id (fixed sequence specified by standard) [16 bytes] */
184                         DCP_ASSERT (memcmp (p, smpte_structure_id, 16) == 0);
185                         p += 16;
186                         /* 16 is is signer thumbprint [20 bytes] */
187                         p += 20;
188                         /* 36 is CPL id [16 bytes] */
189                         string const cpl_id = get_uuid (&p);
190                         /* 52 is key type [4 bytes] */
191                         string const key_type = get (&p, 4);
192                         /* 56 is key id [16 bytes] */
193                         string const key_id = get_uuid (&p);
194                         /* 72 is not-valid-before (a string) [25 bytes] */
195                         p += 25;
196                         /* 97 is not-valid-after (a string) [25 bytes] */
197                         p += 25;
198                         /* 112 is the key [ASDCP::KeyLen bytes] */
199                         add_key (key_type, key_id, Key (p), cpl_id, SMPTE);
200                         break;
201                 }
202                 default:
203                         DCP_ASSERT (false);
204                 }
205
206                 delete[] decrypted;
207         }
208
209         RSA_free (rsa);
210         BIO_free (bio);
211
212         _annotation_text = kdm.annotation_text ();
213         _content_title_text = kdm.content_title_text ();
214         _issue_date = kdm.issue_date ();
215 }
216
217 DecryptedKDM::DecryptedKDM (
218         LocalTime not_valid_before,
219         LocalTime not_valid_after,
220         string annotation_text,
221         string content_title_text,
222         string issue_date
223         )
224         : _not_valid_before (not_valid_before)
225         , _not_valid_after (not_valid_after)
226         , _annotation_text (annotation_text)
227         , _content_title_text (content_title_text)
228         , _issue_date (issue_date)
229 {
230
231 }
232
233 DecryptedKDM::DecryptedKDM (
234         string cpl_id,
235         map<shared_ptr<const ReelMXF>, Key> keys,
236         LocalTime not_valid_before,
237         LocalTime not_valid_after,
238         string annotation_text,
239         string content_title_text,
240         string issue_date
241         )
242         : _not_valid_before (not_valid_before)
243         , _not_valid_after (not_valid_after)
244         , _annotation_text (annotation_text)
245         , _content_title_text (content_title_text)
246         , _issue_date (issue_date)
247 {
248         for (map<shared_ptr<const ReelMXF>, Key>::const_iterator i = keys.begin(); i != keys.end(); ++i) {
249                 add_key (i->first->key_type(), i->first->key_id().get(), i->second, cpl_id, SMPTE);
250         }
251 }
252
253 DecryptedKDM::DecryptedKDM (
254         shared_ptr<const CPL> cpl,
255         Key key,
256         LocalTime not_valid_before,
257         LocalTime not_valid_after,
258         string annotation_text,
259         string content_title_text,
260         string issue_date
261         )
262         : _not_valid_before (not_valid_before)
263         , _not_valid_after (not_valid_after)
264         , _annotation_text (annotation_text)
265         , _content_title_text (content_title_text)
266         , _issue_date (issue_date)
267 {
268         /* Create DecryptedKDMKey objects for each encryptable asset */
269         bool did_one = false;
270         BOOST_FOREACH(shared_ptr<const ReelAsset> i, cpl->reel_assets ()) {
271                 shared_ptr<const ReelMXF> mxf = boost::dynamic_pointer_cast<const ReelMXF> (i);
272                 if (mxf && mxf->key_id ()) {
273                         add_key (mxf->key_type(), mxf->key_id().get(), key, cpl->id(), SMPTE);
274                         did_one = true;
275                 }
276         }
277
278         if (!did_one) {
279                 throw NotEncryptedError (cpl->id ());
280         }
281 }
282
283 /** @param type (MDIK, MDAK etc.)
284  *  @param key_id Key ID.
285  *  @param key The actual symmetric key.
286  *  @param cpl_id ID of CPL that the key is for.
287  */
288 void
289 DecryptedKDM::add_key (optional<string> type, string key_id, Key key, string cpl_id, Standard standard)
290 {
291         _keys.push_back (DecryptedKDMKey (type, key_id, key, cpl_id, standard));
292 }
293
294 void
295 DecryptedKDM::add_key (DecryptedKDMKey key)
296 {
297         _keys.push_back (key);
298 }
299
300 EncryptedKDM
301 DecryptedKDM::encrypt (
302         shared_ptr<const CertificateChain> signer, Certificate recipient, vector<Certificate> trusted_devices, Formulation formulation
303         ) const
304 {
305         list<pair<string, string> > key_ids;
306         list<string> keys;
307         BOOST_FOREACH (DecryptedKDMKey const & i, _keys) {
308                 /* We're making SMPTE keys so we must have a type for each one */
309                 DCP_ASSERT (i.type());
310                 key_ids.push_back (make_pair (i.type().get(), i.id ()));
311
312                 /* XXX: SMPTE only */
313                 uint8_t block[138];
314                 uint8_t* p = block;
315
316                 put (&p, smpte_structure_id, 16);
317
318                 base64_decode (signer->leaf().thumbprint (), p, 20);
319                 p += 20;
320
321                 put_uuid (&p, i.cpl_id ());
322                 put (&p, i.type().get());
323                 put_uuid (&p, i.id ());
324                 put (&p, _not_valid_before.as_string ());
325                 put (&p, _not_valid_after.as_string ());
326                 put (&p, i.key().value(), ASDCP::KeyLen);
327
328                 /* Encrypt using the projector's public key */
329                 RSA* rsa = recipient.public_key ();
330                 unsigned char encrypted[RSA_size(rsa)];
331                 int const encrypted_len = RSA_public_encrypt (p - block, block, encrypted, rsa, RSA_PKCS1_OAEP_PADDING);
332                 if (encrypted_len == -1) {
333                         throw MiscError (String::compose ("Could not encrypt KDM (%1)", ERR_error_string (ERR_get_error(), 0)));
334                 }
335
336                 /* Lazy overallocation */
337                 char out[encrypted_len * 2];
338                 Kumu::base64encode (encrypted, encrypted_len, out, encrypted_len * 2);
339                 int const N = strlen (out);
340                 string lines;
341                 for (int i = 0; i < N; ++i) {
342                         if (i > 0 && (i % 64) == 0) {
343                                 lines += "\n";
344                         }
345                         lines += out[i];
346                 }
347
348                 keys.push_back (lines);
349         }
350
351         string device_list_description = recipient.subject_common_name ();
352         if (device_list_description.find (".") != string::npos) {
353                 device_list_description = device_list_description.substr (device_list_description.find (".") + 1);
354         }
355
356         return EncryptedKDM (
357                 signer,
358                 recipient,
359                 trusted_devices,
360                 _keys.front().cpl_id (),
361                 _content_title_text,
362                 _annotation_text,
363                 _not_valid_before,
364                 _not_valid_after,
365                 formulation,
366                 key_ids,
367                 keys
368                 );
369 }