X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=test%2Fkdm_test.cc;h=4a9d4ff8a8efb5fb517b79e2c710e7b1865b7a6f;hb=0ca9882d9d1f8cfe2fbc797062317dc6dbda6352;hp=ee52ad8ebc207ce0c0f859385aa3a2b1db6d6c13;hpb=a641fdc912a3f0749015decdf9e23ff15186ef78;p=libdcp.git diff --git a/test/kdm_test.cc b/test/kdm_test.cc index ee52ad8e..4a9d4ff8 100644 --- a/test/kdm_test.cc +++ b/test/kdm_test.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2014 Carl Hetherington + Copyright (C) 2013-2018 Carl Hetherington This file is part of libdcp. @@ -17,15 +17,21 @@ along with libdcp. If not, see . */ -#include -#include #include "encrypted_kdm.h" #include "decrypted_kdm.h" +#include "certificate_chain.h" #include "util.h" +#include "test.h" +#include +#include +#include +#include using std::list; -using std::stringstream; +using std::string; +using std::vector; using boost::shared_ptr; +using boost::optional; /** Check reading and decryption of a KDM */ BOOST_AUTO_TEST_CASE (kdm_test) @@ -58,9 +64,7 @@ BOOST_AUTO_TEST_CASE (kdm_passthrough_test) ); shared_ptr parser (new xmlpp::DomParser ()); - stringstream s; - s << kdm.as_xml (); - parser->parse_stream (s); + parser->parse_memory (kdm.as_xml ()); parser->get_document()->write_to_file_formatted ("build/kdm.xml", "UTF-8"); int const r = system ( "xmldiff -c test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml build/kdm.xml" @@ -72,3 +76,140 @@ BOOST_AUTO_TEST_CASE (kdm_passthrough_test) BOOST_CHECK_EQUAL (WEXITSTATUS (r), 0); #endif } + +/** Test some of the utility methods of DecryptedKDM */ +BOOST_AUTO_TEST_CASE (decrypted_kdm_test) +{ + uint8_t* data = new uint8_t[16]; + uint8_t* p = data; + dcp::DecryptedKDM::put_uuid (&p, "8971c838-d0c3-405d-bc57-43afa9d91242"); + + BOOST_CHECK_EQUAL (data[0], 0x89); + BOOST_CHECK_EQUAL (data[1], 0x71); + BOOST_CHECK_EQUAL (data[2], 0xc8); + BOOST_CHECK_EQUAL (data[3], 0x38); + BOOST_CHECK_EQUAL (data[4], 0xd0); + BOOST_CHECK_EQUAL (data[5], 0xc3); + BOOST_CHECK_EQUAL (data[6], 0x40); + BOOST_CHECK_EQUAL (data[7], 0x5d); + BOOST_CHECK_EQUAL (data[8], 0xbc); + BOOST_CHECK_EQUAL (data[9], 0x57); + BOOST_CHECK_EQUAL (data[10], 0x43); + BOOST_CHECK_EQUAL (data[11], 0xaf); + BOOST_CHECK_EQUAL (data[12], 0xa9); + BOOST_CHECK_EQUAL (data[13], 0xd9); + BOOST_CHECK_EQUAL (data[14], 0x12); + BOOST_CHECK_EQUAL (data[15], 0x42); + + p = data; + BOOST_CHECK_EQUAL (dcp::DecryptedKDM::get_uuid (&p), "8971c838-d0c3-405d-bc57-43afa9d91242"); + + delete[] data; +} + +/** Check that tags have the scope attribute. + * Wolfgang Woehl believes this is compulsory and I am more-or-less inclined to agree. + */ +BOOST_AUTO_TEST_CASE (kdm_key_type_scope) +{ + dcp::EncryptedKDM kdm ( + dcp::file_to_string ("test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml") + ); + + cxml::Document doc; + doc.read_string (kdm.as_xml ()); + + list typed_key_ids = doc.node_child("AuthenticatedPublic")-> + node_child("RequiredExtensions")-> + node_child("KDMRequiredExtensions")-> + node_child("KeyIdList")-> + node_children("TypedKeyId"); + + BOOST_FOREACH (cxml::NodePtr i, typed_key_ids) { + BOOST_FOREACH (cxml::NodePtr j, i->node_children("KeyType")) { + BOOST_CHECK (j->string_attribute("scope") == "http://www.smpte-ra.org/430-1/2006/KDM#kdm-key-type"); + } + } +} + +static cxml::ConstNodePtr +kdm_forensic_test (cxml::Document& doc, bool picture, optional audio) +{ + dcp::DecryptedKDM decrypted ( + dcp::EncryptedKDM ( + dcp::file_to_string ("test/data/kdm_TONEPLATES-SMPTE-ENC_.smpte-430-2.ROOT.NOT_FOR_PRODUCTION_20130706_20230702_CAR_OV_t1_8971c838.xml") + ), + dcp::file_to_string ("test/data/private.key") + ); + + shared_ptr signer(new dcp::CertificateChain(dcp::file_to_string("test/data/certificate_chain"))); + signer->set_key(dcp::file_to_string("test/data/private.key")); + + dcp::EncryptedKDM kdm = decrypted.encrypt ( + signer, signer->leaf(), vector(), dcp::MODIFIED_TRANSITIONAL_1, picture, audio + ); + + /* Check that we can pass this through correctly */ + BOOST_CHECK_EQUAL (kdm.as_xml(), dcp::EncryptedKDM(kdm.as_xml()).as_xml()); + + doc.read_string (kdm.as_xml()); + + return doc.node_child("AuthenticatedPublic")-> + node_child("RequiredExtensions")-> + node_child("KDMRequiredExtensions")-> + optional_node_child("ForensicMarkFlagList"); +} + +/** Check ForensicMarkFlagList handling: disable picture and all audio */ +BOOST_AUTO_TEST_CASE (kdm_forensic_test1) +{ + cxml::Document doc; + cxml::ConstNodePtr forensic = kdm_forensic_test(doc, true, 0); + BOOST_REQUIRE (forensic); + list flags = forensic->node_children("ForensicMarkFlag"); + BOOST_REQUIRE_EQUAL (flags.size(), 2); + BOOST_CHECK_EQUAL (flags.front()->content(), "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-picture-disable"); + BOOST_CHECK_EQUAL (flags.back()->content(), "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-audio-disable"); +} + +/** Check ForensicMarkFlagList handling: disable picture but not audio */ +BOOST_AUTO_TEST_CASE (kdm_forensic_test2) +{ + cxml::Document doc; + cxml::ConstNodePtr forensic = kdm_forensic_test(doc, true, optional()); + BOOST_REQUIRE (forensic); + list flags = forensic->node_children("ForensicMarkFlag"); + BOOST_REQUIRE_EQUAL (flags.size(), 1); + BOOST_CHECK_EQUAL (flags.front()->content(), "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-picture-disable"); +} + +/** Check ForensicMarkFlagList handling: disable audio but not picture */ +BOOST_AUTO_TEST_CASE (kdm_forensic_test3) +{ + cxml::Document doc; + cxml::ConstNodePtr forensic = kdm_forensic_test(doc, false, 0); + BOOST_REQUIRE (forensic); + list flags = forensic->node_children("ForensicMarkFlag"); + BOOST_REQUIRE_EQUAL (flags.size(), 1); + BOOST_CHECK_EQUAL (flags.front()->content(), "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-audio-disable"); +} + +/** Check ForensicMarkFlagList handling: disable picture and audio above channel 3 */ +BOOST_AUTO_TEST_CASE (kdm_forensic_test4) +{ + cxml::Document doc; + cxml::ConstNodePtr forensic = kdm_forensic_test(doc, true, 3); + BOOST_REQUIRE (forensic); + list flags = forensic->node_children("ForensicMarkFlag"); + BOOST_REQUIRE_EQUAL (flags.size(), 2); + BOOST_CHECK_EQUAL (flags.front()->content(), "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-picture-disable"); + BOOST_CHECK_EQUAL (flags.back()->content(), "http://www.smpte-ra.org/430-1/2006/KDM#mrkflg-audio-disable-above-channel-3"); +} + +/** Check ForensicMarkFlagList handling: disable neither */ +BOOST_AUTO_TEST_CASE (kdm_forensic_test5) +{ + cxml::Document doc; + cxml::ConstNodePtr forensic = kdm_forensic_test(doc, false, optional()); + BOOST_CHECK (!forensic); +}