No-op: whitespace.
[libdcp.git] / src / kdm.h
1 /*
2     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 /** @file  src/kdm.h
21  *  @brief Handling of Key Delivery Messages (KDMs).
22  */
23
24 #ifndef LIBDCP_KDM_H
25 #define LIBDCP_KDM_H
26
27 #include <boost/filesystem.hpp>
28 #include <boost/scoped_ptr.hpp>
29 #include <boost/date_time/posix_time/posix_time.hpp>
30 #include "key.h"
31 #include "metadata.h"
32
33 class kdm_key_test;
34
35 namespace libdcp {
36
37 namespace xml {
38         class DCinemaSecurityMessage;
39 };
40
41 class Signer;
42 class Certificate;
43 class CPL;
44
45 /** @class KDMKey
46  *  @brief A single key (and associated metadata) for encrypting or decrypting an MXF.
47  *
48  *  One or more of these are delivered (themselves encrypted) in a KDM.  The following
49  *  data is collected into a block:
50  *
51  *  A structure ID (a magic value specified by the standard)
52  *  The thumbprint of the KDM signer's certificate.
53  *  The CPL ID.
54  *  The key ID.
55  *  Validity start and end times.
56  *  The key itself
57  *
58  *  This data block is then encrypted using the projector's public key, so that
59  *  only the target projector can decrypt block.
60  */
61 class KDMKey
62 {
63 public:
64         /** Create a KDMKey from the raw block that is encrypted in the KDM's CipherData.
65          *  @param raw Pointer to data block (134 bytes for interop, 138 bytes for SMPTE).
66          *  @param len Length of the data block in bytes.
67          */
68         KDMKey (uint8_t const * raw, int len);
69
70         /** Create a KDMKey from its constituent parts.
71          *  @param signer Signer for the KDM.
72          *  @param cpl_id ID of the CPL that the KDM is for.
73          *  @param key_type Type of data that this key is for (MDIK for image, MDAK for audio, ...)
74          *  @param key_id ID of this key.
75          *  @param from Valid-from time.
76          *  @param until Valid-until time.
77          *  @param key The key itself.
78          */
79         KDMKey (
80                 boost::shared_ptr<const Signer> signer,
81                 std::string cpl_id,
82                 std::string key_type,
83                 std::string key_id,
84                 boost::posix_time::ptime from,
85                 boost::posix_time::ptime until,
86                 Key key
87                 );
88
89         KDMKey (KDMKey const &);
90
91         KDMKey& operator= (KDMKey const &);
92
93         /** @return ID of the CPL that the KDM is for */
94         std::string cpl_id () const {
95                 return _cpl_id;
96         }
97
98         /** @return ID of the key */
99         std::string key_id () const {
100                 return _key_id;
101         }
102
103         /** @return start of the validity period as a string */
104         std::string not_valid_before () const {
105                 return _not_valid_before;
106         }
107
108         /** @return end of the validity period as a string */
109         std::string not_valid_after () const {
110                 return _not_valid_after;
111         }
112
113         /** @return the key itself */
114         Key key () const {
115                 return _key;
116         }
117
118         /** @param cert Cerfificate.
119          *  @return The data block encrypted with a certificate's public key and converted to base 64.
120          */
121         std::string encrypted_base64 (boost::shared_ptr<const Certificate> cert) const;
122
123 private:
124         friend class ::kdm_key_test;
125
126         void get (uint8_t *, uint8_t const **, int) const;
127         std::string get (uint8_t const **, int) const;
128         std::string get_uuid (uint8_t const **) const;
129         void put (uint8_t **, uint8_t const *, int) const;
130         void put (uint8_t **, std::string) const;
131         void put_uuid (uint8_t **, std::string) const;
132
133         friend bool operator== (KDMKey const &, KDMKey const &);
134
135         uint8_t _signer_thumbprint[20];
136         std::string _cpl_id;
137         std::string _key_type;
138         std::string _key_id;
139         std::string _not_valid_before;
140         std::string _not_valid_after;
141         Key _key;
142 };
143
144 /** @class KDM
145  *  @brief A class representing a Key Delivery Message (KDM).
146  *
147  *  A KDM wraps one or more content keys (which we wrap into KDMKey objects) and various
148  *  other metadata.  This class can read and decrypt existing KDMs (provided you have
149  *  the private key that the KDM was targeted at).  It can also create new KDMs for
150  *  a given CPL.
151  */
152 class KDM
153 {
154 public:
155         /** Load and decrypt a KDM.  After this constructor the KDMKeys can be read
156          *  and used to decrypt MXFs.
157          *
158          *  @param kdm KDM file name.
159          *  @param private_key Private key file name.
160          */
161         KDM (boost::filesystem::path kdm, boost::filesystem::path private_key);
162
163         enum Formulation
164         {
165                 MODIFIED_TRANSITIONAL_1,
166                 DCI_ANY,
167                 DCI_SPECIFIC
168         };
169
170
171         /** Create a new KDM.
172          *  @param cpl CPL file that the KDM is for.
173          *  @param signer Certificate chain to sign the KDM with.
174          *  @param recipient_cert Certificate of the projector that this KDM is targeted at.
175          *  @param key Key used to encrypt all MXF data.
176          *  @param not_valid_before Start of validity period.
177          *  @param not_valid_after End of validity period.
178          *  @param annotation_text Text for the <AnnotationText> node.
179          *  @param issue_date Text for the <IssueDate> node.
180          */
181         KDM (
182                 boost::filesystem::path cpl,
183                 boost::shared_ptr<const Signer> signer,
184                 boost::shared_ptr<const Certificate> recipient_cert,
185                 Key key,
186                 boost::posix_time::ptime not_valid_before, boost::posix_time::ptime not_valid_after,
187                 std::string annotation_text, std::string issue_date,
188                 Formulation formulation
189                 );
190
191         KDM (KDM const &);
192         KDM & operator= (KDM const &);
193
194         /** @return The unencrypted content keys from this KDM */
195         std::list<KDMKey> keys () const {
196                 return _keys;
197         }
198
199         /** Write this KDM to a file.
200          *  @param file File to write to.
201          */
202         void as_xml (boost::filesystem::path file) const;
203
204         /** Obtain this KDM as an XML string.
205          *  @return XML string.
206          */
207         std::string as_xml () const;
208
209 private:
210         /** Unencrypted MXF content keys */
211         std::list<KDMKey> _keys;
212
213         /** The KDM's contents, mapped 1:1-ish to the XML */
214         boost::shared_ptr<xml::DCinemaSecurityMessage> _xml_kdm;
215 };
216
217
218 }
219
220 #endif