Add test() to cscript.
[libdcp.git] / src / kdm.h
index ffcb65a7cf426e6e221be43e63ab7878eff7bb5d..443712c4d715e84c00082f3ad468ed86644d269b 100644 (file)
--- a/src/kdm.h
+++ b/src/kdm.h
 
 */
 
+/** @file  src/kdm.h
+ *  @brief Handling of Key Delivery Messages (KDMs).
+ */
+
 #ifndef LIBDCP_KDM_H
 #define LIBDCP_KDM_H
 
 #include <boost/filesystem.hpp>
 #include <boost/scoped_ptr.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
 #include "key.h"
 #include "metadata.h"
 
+class kdm_key_test;
+
 namespace libdcp {
 
 namespace xml {
@@ -35,52 +42,95 @@ class Signer;
 class Certificate;
 class CPL;
 
-/** A single key for encrypting or decrypting an MXF.  One or more of these
- *  are delivered in a KDM.
+/** @class KDMKey
+ *  @brief A single key (and associated metadata) for encrypting or decrypting an MXF.
+ *
+ *  One or more of these are delivered (themselves encrypted) in a KDM.  The following
+ *  data is collected into a block:
+ *
+ *  A structure ID (a magic value specified by the standard)
+ *  The thumbprint of the KDM signer's certificate.
+ *  The CPL ID.
+ *  The key ID.
+ *  Validity start and end times.
+ *  The key itself
+ *
+ *  This data block is then encrypted using the projector's public key, so that
+ *  only the target projector can decrypt block.
  */
 class KDMKey
 {
 public:
-       KDMKey (uint8_t const *, int);
-
+       /** Create a KDMKey from the raw block that is encrypted in the KDM's CipherData.
+        *  @param raw Pointer to data block (134 bytes for interop, 138 bytes for SMPTE).
+        *  @param len Length of the data block in bytes.
+        */
+       KDMKey (uint8_t const * raw, int len);
+
+       /** Create a KDMKey from its constituent parts.
+        *  @param signer Signer for the KDM.
+        *  @param cpl_id ID of the CPL that the KDM is for.
+        *  @param key_type Type of data that this key is for (MDIK for image, MDAK for audio, ...)
+        *  @param key_id ID of this key.
+        *  @param from Valid-from time.
+        *  @param until Valid-until time.
+        *  @param key The key itself.
+        */
        KDMKey (
                boost::shared_ptr<const Signer> signer,
-               std::string cpl_id, std::string key_id, boost::posix_time::ptime from, boost::posix_time::ptime until, Key key
+               std::string cpl_id,
+               std::string key_type,
+               std::string key_id,
+               boost::posix_time::ptime from,
+               boost::posix_time::ptime until,
+               Key key
                );
        
        KDMKey (KDMKey const &);
 
        KDMKey& operator= (KDMKey const &);
 
+       /** @return ID of the CPL that the KDM is for */
        std::string cpl_id () const {
                return _cpl_id;
        }
        
+       /** @return ID of the key */
        std::string key_id () const {
                return _key_id;
        }
 
+       /** @return start of the validity period as a string */
        std::string not_valid_before () const {
                return _not_valid_before;
        }
 
+       /** @return end of the validity period as a string */
        std::string not_valid_after () const {
                return _not_valid_after;
        }
 
+       /** @return the key itself */
        Key key () const {
                return _key;
        }
 
-       std::string encrypted_base64 (boost::shared_ptr<const Certificate>) const;
+       /** @param cert Cerfificate.
+        *  @return The data block encrypted with a certificate's public key and converted to base 64.
+        */
+       std::string encrypted_base64 (boost::shared_ptr<const Certificate> cert) const;
        
 private:
+       friend class ::kdm_key_test;
+       
        void get (uint8_t *, uint8_t const **, int) const;
        std::string get (uint8_t const **, int) const;
        std::string get_uuid (uint8_t const **) const;
        void put (uint8_t **, uint8_t const *, int) const;
        void put (uint8_t **, std::string) const;
        void put_uuid (uint8_t **, std::string) const;
+
+       friend bool operator== (KDMKey const &, KDMKey const &);
        
        uint8_t _signer_thumbprint[20];
        std::string _cpl_id;
@@ -91,28 +141,77 @@ private:
        Key _key;
 };
 
+/** @class KDM
+ *  @brief A class representing a Key Delivery Message (KDM).
+ *
+ *  A KDM wraps one or more content keys (which we wrap into KDMKey objects) and various
+ *  other metadata.  This class can read and decrypt existing KDMs (provided you have
+ *  the private key that the KDM was targeted at).  It can also create new KDMs for
+ *  a given CPL.
+ */
 class KDM
 {
 public:
-       KDM (boost::filesystem::path, boost::filesystem::path);
+       /** Load and decrypt a KDM.  After this constructor the KDMKeys can be read
+        *  and used to decrypt MXFs.
+        *
+        *  @param kdm KDM file name.
+        *  @param private_key Private key file name.
+        */
+       KDM (boost::filesystem::path kdm, boost::filesystem::path private_key);
+
+       enum Formulation
+       {
+               MODIFIED_TRANSITIONAL_1,
+               DCI_ANY,
+               DCI_SPECIFIC
+       };
 
+       
+       /** Create a new KDM.
+        *  @param cpl CPL file that the KDM is for.
+        *  @param signer Certificate chain to sign the KDM with.
+        *  @param recipient_cert Certificate of the projector that this KDM is targeted at.
+        *  @param key Key used to encrypt all MXF data.
+        *  @param not_valid_before Start of validity period.
+        *  @param not_valid_after End of validity period.
+        *  @param annotation_text Text for the <AnnotationText> node.
+        *  @param issue_date Text for the <IssueDate> node.
+        */
        KDM (
-               boost::shared_ptr<const CPL> cpl, boost::shared_ptr<const Signer>, boost::shared_ptr<const Certificate> recipient_cert,
+               boost::filesystem::path cpl,
+               boost::shared_ptr<const Signer> signer,
+               boost::shared_ptr<const Certificate> recipient_cert,
+               Key key,
                boost::posix_time::ptime not_valid_before, boost::posix_time::ptime not_valid_after,
-               std::string annotation_text, std::string issue_date
+               std::string annotation_text, std::string issue_date,
+               Formulation formulation
                );
 
+       KDM (KDM const &);
+       KDM & operator= (KDM const &);
+
+       /** @return The unencrypted content keys from this KDM */
        std::list<KDMKey> keys () const {
                return _keys;
        }
 
-       void as_xml (boost::filesystem::path) const;
+       /** Write this KDM to a file.
+        *  @param file File to write to.
+        */
+       void as_xml (boost::filesystem::path file) const;
+
+       /** Obtain this KDM as an XML string.
+        *  @return XML string.
+        */
+       std::string as_xml () const;
 
 private:
        /** Unencrypted MXF content keys */
        std::list<KDMKey> _keys;
 
-       boost::shared_ptr<xml::DCinemaSecurityMessage> xml_kdm;
+       /** The KDM's contents, mapped 1:1-ish to the XML */
+       boost::shared_ptr<xml::DCinemaSecurityMessage> _xml_kdm;
 };