Some work on encryption / signing.
authorCarl Hetherington <cth@carlh.net>
Tue, 1 Jan 2013 20:11:25 +0000 (20:11 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 1 Jan 2013 20:11:25 +0000 (20:11 +0000)
20 files changed:
README
src/certificates.cc [new file with mode: 0644]
src/certificates.h [new file with mode: 0644]
src/dcp.cc
src/dcp.h
src/dcp_time.h
src/wscript
test/ref/DCP/bar/402c5a88-2512-4465-9c0b-cfa687dbc5d0_pkl.xml [new file with mode: 0644]
test/ref/DCP/bar/63c3aece-c581-4603-b612-75e43f0c0430_cpl.xml [new file with mode: 0644]
test/ref/DCP/bar/ASSETMAP.xml [new file with mode: 0644]
test/ref/DCP/bar/VOLINDEX.xml [new file with mode: 0644]
test/ref/DCP/bar/audio.mxf [new file with mode: 0644]
test/ref/DCP/bar/video.mxf [new file with mode: 0644]
test/ref/DCP/foo/81fb54df-e1bf-4647-8788-ea7ba154375b_cpl.xml [new file with mode: 0644]
test/ref/DCP/foo/ASSETMAP.xml [new file with mode: 0644]
test/ref/DCP/foo/VOLINDEX.xml [new file with mode: 0644]
test/ref/DCP/foo/audio.mxf [new file with mode: 0644]
test/ref/DCP/foo/df0e4141-13c3-4a7a-bef8-b5a04fcbc4bb_pkl.xml [new file with mode: 0644]
test/ref/DCP/foo/video.mxf [new file with mode: 0644]
test/tests.cc

diff --git a/README b/README
index 0a8f3c2e386f1c948af4f0fbce19c6635ea58ee3..6fe5521b09c9ad69c1e58a6c0dc5204f352019eb 100644 (file)
--- a/README
+++ b/README
@@ -3,6 +3,14 @@
 Hello.
 
 
+== Acknowledgements
+
+Wolfgang Woehl's cinemaslides was most informative on the
+nasty details of encryption.
+
+
+
+
 == Building:
 
 ./waf configure
diff --git a/src/certificates.cc b/src/certificates.cc
new file mode 100644 (file)
index 0000000..c1e71b1
--- /dev/null
@@ -0,0 +1,120 @@
+#include <sstream>
+#include <vector>
+#include <boost/algorithm/string.hpp>
+#include <openssl/x509.h>
+#include <openssl/ssl.h>
+#include <openssl/asn1.h>
+#include "certificates.h"
+#include "exceptions.h"
+
+using std::list;
+using std::string;
+using std::stringstream;
+using std::vector;
+using boost::shared_ptr;
+using namespace libdcp;
+
+/** @param c X509 certificate, which this object will take ownership of */
+Certificate::Certificate (X509* c)
+       : _certificate (c)
+{
+       
+}
+
+Certificate::~Certificate ()
+{
+       X509_free (_certificate);
+}
+
+string
+Certificate::issuer () const
+{
+       X509_NAME* n = X509_get_issuer_name (_certificate);
+       assert (n);
+
+       char b[256];
+       X509_NAME_oneline (n, b, 256);
+       return b;
+}
+
+string
+Certificate::name_for_xml (string const & n)
+{
+       stringstream x;
+       
+       vector<string> p;
+       boost::split (p, n, boost::is_any_of ("/"));
+       for (vector<string>::const_reverse_iterator i = p.rbegin(); i != p.rend(); ++i) {
+               x << *i << ",";
+       }
+
+       return x.str().substr(0, x.str().length() - 2);
+}
+
+string
+Certificate::subject () const
+{
+       X509_NAME* n = X509_get_subject_name (_certificate);
+       assert (n);
+
+       char b[256];
+       X509_NAME_oneline (n, b, 256);
+       return b;
+}
+
+string
+Certificate::serial () const
+{
+       ASN1_INTEGER* s = X509_get_serialNumber (_certificate);
+       assert (s);
+       
+       BIGNUM* b = ASN1_INTEGER_to_BN (s, 0);
+       char* c = BN_bn2dec (b);
+       BN_free (b);
+       
+       string st (c);
+       OPENSSL_free (c);
+
+       return st;
+}
+               
+
+/** @param filename Text file of PEM-format certificates,
+ *  in the order:
+ *
+ *  1. self-signed root certificate
+ *  2. intermediate certificate signed by root certificate
+ *  ...
+ *  n. leaf certificate signed by previous intermediate.
+ */
+
+CertificateChain::CertificateChain (string const & filename)
+{
+       FILE* f = fopen (filename.c_str(), "r");
+       if (!f) {
+               throw FileError ("could not open file", filename);
+       }
+       
+       while (1) {
+               X509* c = 0;
+               if (!PEM_read_X509 (f, &c, 0, 0)) {
+                       break;
+               }
+
+               _certificates.push_back (shared_ptr<Certificate> (new Certificate (c)));
+       }
+}
+
+shared_ptr<Certificate>
+CertificateChain::root () const
+{
+       assert (!_certificates.empty());
+       return _certificates.front ();
+}
+
+shared_ptr<Certificate>
+CertificateChain::leaf () const
+{
+       assert (_certificates.size() >= 2);
+       return _certificates.back ();
+}
diff --git a/src/certificates.h b/src/certificates.h
new file mode 100644 (file)
index 0000000..6baea84
--- /dev/null
@@ -0,0 +1,46 @@
+#ifndef LIBDCP_CERTIFICATES_H
+#define LIBDCP_CERTIFICATES_H
+
+#include <string>
+#include <list>
+#include <boost/noncopyable.hpp>
+#include <boost/shared_ptr.hpp>
+#include <openssl/x509.h>
+
+class certificates;
+
+namespace libdcp {
+
+class Certificate : public boost::noncopyable
+{
+public:
+       Certificate (X509 *);
+       ~Certificate ();
+
+       std::string issuer () const;
+       std::string serial () const;
+       std::string subject () const;
+
+       static std::string name_for_xml (std::string const &);
+
+private:
+       X509* _certificate;
+};
+
+class CertificateChain
+{
+public:
+       CertificateChain () {}
+       CertificateChain (std::string const &);
+
+       boost::shared_ptr<Certificate> root () const;
+       boost::shared_ptr<Certificate> leaf () const;
+
+private:
+       friend class ::certificates;
+       std::list<boost::shared_ptr<Certificate> > _certificates;
+};
+
+}
+
+#endif
index 5db29beba7a2dafe1732b01a1ed7ae2919ae9313..4b5e6789ce01ca075f9ea061ff6e3bddbb234a78 100644 (file)
@@ -51,6 +51,7 @@ using namespace libdcp;
 
 DCP::DCP (string directory)
        : _directory (directory)
+       , _encrypted (false)
 {
        boost::filesystem::create_directories (directory);
 }
@@ -59,7 +60,7 @@ void
 DCP::write_xml () const
 {
        for (list<shared_ptr<const CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) {
-               (*i)->write_xml ();
+               (*i)->write_xml (_encrypted, _certificates);
        }
 
        string pkl_uuid = make_uuid ();
@@ -423,7 +424,7 @@ CPL::add_reel (shared_ptr<const Reel> reel)
 }
 
 void
-CPL::write_xml () const
+CPL::write_xml (bool encrypted, CertificateChain const & certificates) const
 {
        boost::filesystem::path p;
        p /= _directory;
@@ -453,8 +454,19 @@ CPL::write_xml () const
 
        os << "      </AssetList>\n"
           << "    </Reel>\n"
-          << "  </ReelList>\n"
-          << "</CompositionPlaylist>\n";
+          << "  </ReelList>\n";
+
+       if (encrypted) {
+               os << "  <dsig:X509Data>\n"
+                  << "    <dsig:X509IssuerSerial>\n"
+                  << "      <dsig:X509IssuerName>" << Certificate::name_for_xml (certificates.leaf()->issuer()) << "</dsig:IssuerName>\n"
+                  << "      <dsig:X509SerialNumber>" << certificates.leaf()->serial() << "</dsig:X509SerialNumber>\n"
+                  << "    <dsig:X509IssuerSerial>\n"
+                  << "    <dsig:X509SubjectName>" << Certificate::name_for_xml (certificates.leaf()->subject()) << "</dsig:X509SubjectName>\n"
+                  << "  </dsig:X509Data>\n";
+       }
+       
+       os << "</CompositionPlaylist>\n";
 
        os.close ();
 
index d4f6aff9aba9a64a377da1caed718eb789b4b1f8..ca011c360cf9c5e212100896b11c0383844d8b80 100644 (file)
--- a/src/dcp.h
+++ b/src/dcp.h
@@ -29,6 +29,7 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/signals2.hpp>
 #include "types.h"
+#include "certificates.h"
 
 namespace xmlpp {
        class Node;
@@ -85,7 +86,7 @@ public:
        
        bool equals (CPL const & other, EqualityOptions options, std::list<std::string>& notes) const;
        
-       void write_xml () const;
+       void write_xml (bool, CertificateChain const &) const;
        void write_to_assetmap (std::ostream& s) const;
        void write_to_pkl (std::ostream& s) const;
        
@@ -182,6 +183,9 @@ private:
        /** the directory that we are writing to */
        std::string _directory;
        std::list<boost::shared_ptr<const CPL> > _cpls;
+
+       bool _encrypted;
+       CertificateChain _certificates;
 };
 
 }
index 8033348b6b14ba97155f1a1a91f916c4a0530003..eff69579736a8cd040301d25697d84e10374b23d 100644 (file)
@@ -56,6 +56,9 @@ public:
 
        std::string to_string () const;
        int64_t to_ticks () const;
+
+private:
+       void set (double);
 };
 
 extern bool operator== (Time const & a, Time const & b);
index 04656976d066319585d1f64f78361aaf93b2833d..56a99063b03300f410c86c8aecaffecb7c1cbc91 100644 (file)
@@ -12,6 +12,7 @@ def build(bld):
     obj.source = """
                  asset.cc
                  asset_map.cc
+                 certificates.cc
                  cpl_file.cc
                  dcp.cc        
                  dcp_time.cc
diff --git a/test/ref/DCP/bar/402c5a88-2512-4465-9c0b-cfa687dbc5d0_pkl.xml b/test/ref/DCP/bar/402c5a88-2512-4465-9c0b-cfa687dbc5d0_pkl.xml
new file mode 100644 (file)
index 0000000..a87f9e2
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PackingList xmlns="http://www.smpte-ra.org/schemas/429-8/2007/PKL">
+  <Id>urn:uuid:402c5a88-2512-4465-9c0b-cfa687dbc5d0</Id>
+  <AnnotationText>A Test DCP</AnnotationText>
+  <IssueDate>2012-07-17T04:45:18+00:00</IssueDate>
+  <Issuer>OpenDCP 0.0.25</Issuer>
+  <Creator>OpenDCP 0.0.25</Creator>
+  <AssetList>
+    <Asset>
+      <Id>urn:uuid:2b9b857f-ab4a-440e-a313-1ace0f1cfc95</Id>
+      <AnnotationText>video.mxf</AnnotationText>
+      <Hash>fTMi9Xvr8NzuRhm7LmSTk6k1HYo=</Hash>
+      <Size>28840</Size>
+      <Type>application/mxf</Type>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:aa3fb133-0d18-4083-a039-e441b0788e79</Id>
+      <AnnotationText>audio.mxf</AnnotationText>
+      <Hash>2MlsntiFrekkQvwbRPLC2XEMU78=</Hash>
+      <Size>308398</Size>
+      <Type>application/mxf</Type>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:63c3aece-c581-4603-b612-75e43f0c0430</Id>
+      <Hash>l/g+bdCKF6ofhedin5qrLcObS1E=</Hash>
+      <Size>1526</Size>
+      <Type>text/xml</Type>
+    </Asset>
+  </AssetList>
+</PackingList>
diff --git a/test/ref/DCP/bar/63c3aece-c581-4603-b612-75e43f0c0430_cpl.xml b/test/ref/DCP/bar/63c3aece-c581-4603-b612-75e43f0c0430_cpl.xml
new file mode 100644 (file)
index 0000000..43edb1b
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CompositionPlaylist xmlns="http://www.smpte-ra.org/schemas/429-7/2006/CPL">
+  <Id>urn:uuid:63c3aece-c581-4603-b612-75e43f0c0430</Id>
+  <AnnotationText>A Test DCP</AnnotationText>
+  <IssueDate>2012-07-17T04:45:18+00:00</IssueDate>
+  <Creator>OpenDCP 0.0.25</Creator>
+  <ContentTitleText>A Test DCP</ContentTitleText>
+  <ContentKind>feature</ContentKind>
+  <ContentVersion>
+    <Id>urn:uri:63c3aece-c581-4603-b612-75e43f0c0430_2012-07-17T04:45:18+00:00</Id>
+    <LabelText>63c3aece-c581-4603-b612-75e43f0c0430_2012-07-17T04:45:18+00:00</LabelText>
+  </ContentVersion>
+  <RatingList/>
+  <ReelList>
+    <Reel>
+      <Id>urn:uuid:7d861d35-c775-48e6-a4f8-fbfdbfc1556a</Id>
+      <AssetList>
+        <MainPicture>
+          <Id>urn:uuid:2b9b857f-ab4a-440e-a313-1ace0f1cfc95</Id>
+          <AnnotationText>video.mxf</AnnotationText>
+          <EditRate>24 1</EditRate>
+          <IntrinsicDuration>24</IntrinsicDuration>
+          <EntryPoint>0</EntryPoint>
+          <Duration>24</Duration>
+          <FrameRate>24 1</FrameRate>
+          <ScreenAspectRatio>32 32</ScreenAspectRatio>
+        </MainPicture>
+        <MainSound>
+          <Id>urn:uuid:aa3fb133-0d18-4083-a039-e441b0788e79</Id>
+          <AnnotationText>audio.mxf</AnnotationText>
+          <EditRate>24 1</EditRate>
+          <IntrinsicDuration>24</IntrinsicDuration>
+          <EntryPoint>0</EntryPoint>
+          <Duration>24</Duration>
+        </MainSound>
+      </AssetList>
+    </Reel>
+  </ReelList>
+</CompositionPlaylist>
diff --git a/test/ref/DCP/bar/ASSETMAP.xml b/test/ref/DCP/bar/ASSETMAP.xml
new file mode 100644 (file)
index 0000000..359f453
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<AssetMap xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM">
+  <Id>urn:uuid:58f161a5-16d1-4896-93df-52a5a330082f</Id>
+  <Creator>OpenDCP 0.0.25</Creator>
+  <VolumeCount>1</VolumeCount>
+  <IssueDate>2012-07-17T04:45:18+00:00</IssueDate>
+  <Issuer>OpenDCP 0.0.25</Issuer>
+  <AssetList>
+    <Asset>
+      <Id>urn:uuid:402c5a88-2512-4465-9c0b-cfa687dbc5d0</Id>
+      <PackingList>true</PackingList>
+      <ChunkList>
+        <Chunk>
+          <Path>402c5a88-2512-4465-9c0b-cfa687dbc5d0_pkl.xml</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>1049</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:63c3aece-c581-4603-b612-75e43f0c0430</Id>
+      <ChunkList>
+        <Chunk>
+          <Path>63c3aece-c581-4603-b612-75e43f0c0430_cpl.xml</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>1526</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:2b9b857f-ab4a-440e-a313-1ace0f1cfc95</Id>
+      <ChunkList>
+        <Chunk>
+          <Path>video.mxf</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>28840</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:aa3fb133-0d18-4083-a039-e441b0788e79</Id>
+      <ChunkList>
+        <Chunk>
+          <Path>audio.mxf</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>308398</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+  </AssetList>
+</AssetMap>
diff --git a/test/ref/DCP/bar/VOLINDEX.xml b/test/ref/DCP/bar/VOLINDEX.xml
new file mode 100644 (file)
index 0000000..f66c004
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VolumeIndex xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM">
+  <Index>1</Index>
+</VolumeIndex>
diff --git a/test/ref/DCP/bar/audio.mxf b/test/ref/DCP/bar/audio.mxf
new file mode 100644 (file)
index 0000000..1188e5f
Binary files /dev/null and b/test/ref/DCP/bar/audio.mxf differ
diff --git a/test/ref/DCP/bar/video.mxf b/test/ref/DCP/bar/video.mxf
new file mode 100644 (file)
index 0000000..20eb6f4
Binary files /dev/null and b/test/ref/DCP/bar/video.mxf differ
diff --git a/test/ref/DCP/foo/81fb54df-e1bf-4647-8788-ea7ba154375b_cpl.xml b/test/ref/DCP/foo/81fb54df-e1bf-4647-8788-ea7ba154375b_cpl.xml
new file mode 100644 (file)
index 0000000..59d5007
--- /dev/null
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<CompositionPlaylist xmlns="http://www.smpte-ra.org/schemas/429-7/2006/CPL">
+  <Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id>
+  <AnnotationText>A Test DCP</AnnotationText>
+  <IssueDate>2012-07-17T04:45:18+00:00</IssueDate>
+  <Creator>OpenDCP 0.0.25</Creator>
+  <ContentTitleText>A Test DCP</ContentTitleText>
+  <ContentKind>feature</ContentKind>
+  <ContentVersion>
+    <Id>urn:uri:81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00</Id>
+    <LabelText>81fb54df-e1bf-4647-8788-ea7ba154375b_2012-07-17T04:45:18+00:00</LabelText>
+  </ContentVersion>
+  <RatingList/>
+  <ReelList>
+    <Reel>
+      <Id>urn:uuid:379fa64c-ad71-46cf-bef7-b45624006610</Id>
+      <AssetList>
+        <MainPicture>
+          <Id>urn:uuid:d36f4bb3-c4fa-4a95-9915-6fec3110cd71</Id>
+          <AnnotationText>video.mxf</AnnotationText>
+          <EditRate>24 1</EditRate>
+          <IntrinsicDuration>24</IntrinsicDuration>
+          <EntryPoint>0</EntryPoint>
+          <Duration>24</Duration>
+          <FrameRate>24 1</FrameRate>
+          <ScreenAspectRatio>32 32</ScreenAspectRatio>
+        </MainPicture>
+        <MainSound>
+          <Id>urn:uuid:c38bdd62-ce03-4988-8603-195f134207c7</Id>
+          <AnnotationText>audio.mxf</AnnotationText>
+          <EditRate>24 1</EditRate>
+          <IntrinsicDuration>24</IntrinsicDuration>
+          <EntryPoint>0</EntryPoint>
+          <Duration>24</Duration>
+        </MainSound>
+      </AssetList>
+    </Reel>
+  </ReelList>
+</CompositionPlaylist>
diff --git a/test/ref/DCP/foo/ASSETMAP.xml b/test/ref/DCP/foo/ASSETMAP.xml
new file mode 100644 (file)
index 0000000..defe18d
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<AssetMap xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM">
+  <Id>urn:uuid:b135d5cf-d180-43d8-b0b3-7373737b73bf</Id>
+  <Creator>OpenDCP 0.0.25</Creator>
+  <VolumeCount>1</VolumeCount>
+  <IssueDate>2012-07-17T04:45:18+00:00</IssueDate>
+  <Issuer>OpenDCP 0.0.25</Issuer>
+  <AssetList>
+    <Asset>
+      <Id>urn:uuid:df0e4141-13c3-4a7a-bef8-b5a04fcbc4bb</Id>
+      <PackingList>true</PackingList>
+      <ChunkList>
+        <Chunk>
+          <Path>df0e4141-13c3-4a7a-bef8-b5a04fcbc4bb_pkl.xml</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>1049</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id>
+      <ChunkList>
+        <Chunk>
+          <Path>81fb54df-e1bf-4647-8788-ea7ba154375b_cpl.xml</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>1526</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:c38bdd62-ce03-4988-8603-195f134207c7</Id>
+      <ChunkList>
+        <Chunk>
+          <Path>audio.mxf</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>305326</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:d36f4bb3-c4fa-4a95-9915-6fec3110cd71</Id>
+      <ChunkList>
+        <Chunk>
+          <Path>video.mxf</Path>
+          <VolumeIndex>1</VolumeIndex>
+          <Offset>0</Offset>
+          <Length>26080</Length>
+        </Chunk>
+      </ChunkList>
+    </Asset>
+  </AssetList>
+</AssetMap>
diff --git a/test/ref/DCP/foo/VOLINDEX.xml b/test/ref/DCP/foo/VOLINDEX.xml
new file mode 100644 (file)
index 0000000..f66c004
--- /dev/null
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<VolumeIndex xmlns="http://www.smpte-ra.org/schemas/429-9/2007/AM">
+  <Index>1</Index>
+</VolumeIndex>
diff --git a/test/ref/DCP/foo/audio.mxf b/test/ref/DCP/foo/audio.mxf
new file mode 100644 (file)
index 0000000..9bc735a
Binary files /dev/null and b/test/ref/DCP/foo/audio.mxf differ
diff --git a/test/ref/DCP/foo/df0e4141-13c3-4a7a-bef8-b5a04fcbc4bb_pkl.xml b/test/ref/DCP/foo/df0e4141-13c3-4a7a-bef8-b5a04fcbc4bb_pkl.xml
new file mode 100644 (file)
index 0000000..7a8ec69
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<PackingList xmlns="http://www.smpte-ra.org/schemas/429-8/2007/PKL">
+  <Id>urn:uuid:df0e4141-13c3-4a7a-bef8-b5a04fcbc4bb</Id>
+  <AnnotationText>A Test DCP</AnnotationText>
+  <IssueDate>2012-07-17T04:45:18+00:00</IssueDate>
+  <Issuer>OpenDCP 0.0.25</Issuer>
+  <Creator>OpenDCP 0.0.25</Creator>
+  <AssetList>
+    <Asset>
+      <Id>urn:uuid:c38bdd62-ce03-4988-8603-195f134207c7</Id>
+      <AnnotationText>audio.mxf</AnnotationText>
+      <Hash>+qImGHkt/XouNaJ1V/+7BtcB4VU=</Hash>
+      <Size>305326</Size>
+      <Type>application/mxf</Type>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:d36f4bb3-c4fa-4a95-9915-6fec3110cd71</Id>
+      <AnnotationText>video.mxf</AnnotationText>
+      <Hash>E2vhyxdJQhEzSQZdp31w84ZZpfk=</Hash>
+      <Size>26080</Size>
+      <Type>application/mxf</Type>
+    </Asset>
+    <Asset>
+      <Id>urn:uuid:81fb54df-e1bf-4647-8788-ea7ba154375b</Id>
+      <Hash>TTn7vvdUQi/G+KaW1Pym/DjxULM=</Hash>
+      <Size>1526</Size>
+      <Type>text/xml</Type>
+    </Asset>
+  </AssetList>
+</PackingList>
diff --git a/test/ref/DCP/foo/video.mxf b/test/ref/DCP/foo/video.mxf
new file mode 100644 (file)
index 0000000..645fb85
Binary files /dev/null and b/test/ref/DCP/foo/video.mxf differ
index a842fa4d45d7ba270aaaae2b4d6469397552ec85..71796f7205c9a112ac950732d36c63571c34cef3 100644 (file)
 #include "picture_asset.h"
 #include "sound_asset.h"
 #include "reel.h"
+#include "certificates.h"
 
 #define BOOST_TEST_DYN_LINK
 #define BOOST_TEST_MODULE libdcp_test
 #include <boost/test/unit_test.hpp>
 
 using std::string;
+using std::cout;
 using std::vector;
 using std::list;
 using boost::shared_ptr;
@@ -109,7 +111,7 @@ BOOST_AUTO_TEST_CASE (error_test)
 
 BOOST_AUTO_TEST_CASE (read_dcp)
 {
-       libdcp::DCP d ("test/ref/DCP");
+       libdcp::DCP d ("test/ref/DCP/foo");
        d.read ();
 
        list<shared_ptr<const libdcp::CPL> > cpls = d.cpls ();
@@ -607,7 +609,7 @@ BOOST_AUTO_TEST_CASE (encryption)
                                                         24,
                                                         32,
                                                         32,
-                                                        false
+                                                        true
                                                         ));
 
        shared_ptr<libdcp::SoundAsset> ms (new libdcp::SoundAsset (
@@ -618,7 +620,7 @@ BOOST_AUTO_TEST_CASE (encryption)
                                                   24,
                                                   24,
                                                   2,
-                                                  false
+                                                  true
                                                   ));
        
        cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
@@ -626,3 +628,26 @@ BOOST_AUTO_TEST_CASE (encryption)
 
        d.write_xml ();
 }
+
+BOOST_AUTO_TEST_CASE (certificates)
+{
+       libdcp::CertificateChain c ("test/data/certificate_chain");
+       BOOST_CHECK_EQUAL (c._certificates.size(), 3);
+
+       BOOST_CHECK_EQUAL (
+               c.root()->issuer(),
+               "/O=example.org/OU=example.org/CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION/dnQualifier=rTeK7x+nopFkyphflooz6p2ZM7A="
+               );
+       
+       BOOST_CHECK_EQUAL (
+               libdcp::Certificate::name_for_xml (c.root()->issuer()),
+               "dnQualifier=rTeK7x+nopFkyphflooz6p2ZM7A=,CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION,OU=example.org,O=example.org"
+               );
+
+       BOOST_CHECK_EQUAL (c.root()->serial(), "5");
+
+       BOOST_CHECK_EQUAL (
+               libdcp::Certificate::name_for_xml (c.root()->subject()),
+               "dnQualifier=rTeK7x+nopFkyphflooz6p2ZM7A=,CN=.smpte-430-2.ROOT.NOT_FOR_PRODUCTION,OU=example.org,O=example.org"
+               );
+}