summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2026-04-26 22:39:24 +0200
committerCarl Hetherington <cth@carlh.net>2026-04-26 22:39:27 +0200
commit81b15e9e131094879b416b26601c673e6ae0d508 (patch)
tree492430de6d648b3460fb662b0eeb0f983c87ceb2
parent25ac279e5b7ae6593185230a0fe5a4022a6f689d (diff)
Add --trusted-device-chain option to KDM CLI.HEADmain
-rw-r--r--cscript2
-rw-r--r--src/lib/kdm_cli.cc10
-rw-r--r--test/kdm_cli_test.cc32
3 files changed, 42 insertions, 2 deletions
diff --git a/cscript b/cscript
index c55a824cb..f4828ce86 100644
--- a/cscript
+++ b/cscript
@@ -506,7 +506,7 @@ def build_with_cpp17(target):
def dependencies(target, options):
- deps = [('libdcp', 'v1.10.56', {'c++17': build_with_cpp17(target)})]
+ deps = [('libdcp', 'ee236adf5362053a8ae3ce28242db6d4265b9938', {'c++17': build_with_cpp17(target)})]
deps.append(('libsub', 'v1.6.61'))
deps.append(('leqm-nrt', 'd75d0af984d9c14bfefca8f1bdbc215c3bf3a388'))
if target.platform != 'linux' or target.distro != 'arch':
diff --git a/src/lib/kdm_cli.cc b/src/lib/kdm_cli.cc
index 1b625e50c..bd400b458 100644
--- a/src/lib/kdm_cli.cc
+++ b/src/lib/kdm_cli.cc
@@ -96,6 +96,7 @@ help(std::function<void (string)> out)
out(" -S, --screen <name> screen name (when using -C) or screen name (to filter screens when using -c)");
out(" -C, --projector-certificate <file> file containing projector certificate");
out(" -T, --trusted-device-certificate <file> file containing a trusted device's certificate");
+ out(" --trusted-device-chain <file> file containing a trusted device's chain; the leaf certificate will be used");
out(" --decryption-key <file> file containing the private key which can decrypt the given DKDM");
out(variant::insert_dcpomatic(" ({}'s configured private key will be used otherwise)"));
out(" --cinemas-file <file> use the given file as a list of cinemas instead of the current configuration");
@@ -525,12 +526,13 @@ try
{ "screen", required_argument, 0, 'S' },
{ "projector-certificate", required_argument, 0, 'C' },
{ "trusted-device-certificate", required_argument, 0, 'T' },
+ { "trusted-device-chain", required_argument, 0, 'H' },
{ "decryption-key", required_argument, 0, 'G' },
{ "cinemas-file", required_argument, 0, 'E' },
{ 0, 0, 0, 0 }
};
- int c = getopt_long(argc, argv, "ho:K:Z:f:t:d:F:pae::zvc:S:C:T:E:G", long_options, &option_index);
+ int c = getopt_long(argc, argv, "ho:K:Z:f:t:d:F:pae::zvc:S:C:T:E:G:H", long_options, &option_index);
if (c == -1) {
break;
@@ -603,6 +605,12 @@ try
case 'T':
trusted_devices.push_back(TrustedDevice(dcp::Certificate(dcp::file_to_string(optarg))));
break;
+ case 'H':
+ {
+ auto chain = dcp::CertificateChain(dcp::file_to_string(optarg));
+ trusted_devices.push_back(TrustedDevice(chain.leaf()));
+ break;
+ }
case 'G':
decryption_key = optarg;
break;
diff --git a/test/kdm_cli_test.cc b/test/kdm_cli_test.cc
index b5088b938..4913986f3 100644
--- a/test/kdm_cli_test.cc
+++ b/test/kdm_cli_test.cc
@@ -390,3 +390,35 @@ BOOST_AUTO_TEST_CASE(kdm_cli_formulation_warning)
BOOST_CHECK(boost::filesystem::exists(kdm_filename));
}
+
+
+BOOST_AUTO_TEST_CASE(kdm_cli_trusted_device_chain)
+{
+ vector<string> args = {
+ "kdm_cli",
+ "--valid-from", "now",
+ "--valid-duration", "2 weeks",
+ "--trusted-device-chain", "test/data/decryption_chain",
+ "--projector-certificate", "test/data/cert.pem",
+ "-S", "my great screen",
+ "-o", "build/test",
+ "-F", "multiple-modified-transitional-1",
+ "test/data/dkdm.xml"
+ };
+
+ boost::filesystem::path const kdm_filename = "build/test/KDM_Test_FTR-1_F-133_XX-XX_MOS_2K_20220109_SMPTE_OV__my_great_screen.xml";
+ boost::system::error_code ec;
+ boost::filesystem::remove(kdm_filename, ec);
+
+ vector<string> output;
+ auto error = run(args, output);
+ BOOST_CHECK(!error);
+ BOOST_CHECK(output.empty());
+
+ BOOST_CHECK(boost::filesystem::exists(kdm_filename));
+
+ dcp::EncryptedKDM kdm(dcp::file_to_string(kdm_filename));
+ BOOST_REQUIRE_EQUAL(kdm.trusted_devices().size(), 1U);
+ BOOST_CHECK_EQUAL(kdm.trusted_devices()[0], "KTEVkrCuEsqjXQSPy/H/lpVC9ys=");
+}
+