#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xercesc/sax/HandlerBase.hpp>
#include <xercesc/util/PlatformUtils.hpp>
+#include <xmlsec/xmldsig.h>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <map>
}
+static void
+verify_signature (boost::filesystem::path xml_file, vector<VerificationNote>& notes)
+{
+ cxml::Document doc;
+ doc.read_file (xml_file);
+
+ auto signature = doc.optional_node_child("Signature");
+ if (!signature) {
+ return;
+ }
+
+ auto context = xmlSecDSigCtxCreate (0);
+ if (context == nullptr) {
+ throw MiscError ("could not create signature context");
+ }
+
+ context->signKey = xmlSecCryptoAppKeyLoadMemory(
+ reinterpret_cast<const unsigned char *>(_key->c_str()), _key->size(), xmlSecKeyDataFormatPem, 0, 0, 0
+ );
+
+ auto r = xmlSecDSigCtxVerify (context, signature->node()->cobj());
+ if (r < 0) {
+ notes.push_back (dcp::VerificationNote(VerificationNote::Type::ERROR, VerificationNote::Code::INVALID_SIGNATURE, xml_file));
+ }
+}
+
+
vector<VerificationNote>
dcp::verify (
vector<boost::filesystem::path> directories,
for (auto cpl: dcp->cpls()) {
stage ("Checking CPL", cpl->file());
validate_xml (cpl->file().get(), *xsd_dtd_directory, notes);
+ verify_signature (cpl->file().get(), notes);
if (cpl->any_encrypted() && !cpl->all_encrypted()) {
notes.push_back ({VerificationNote::Type::BV21_ERROR, VerificationNote::Code::PARTIALLY_ENCRYPTED});
for (auto pkl: dcp->pkls()) {
stage ("Checking PKL", pkl->file());
validate_xml (pkl->file().get(), *xsd_dtd_directory, notes);
+ verify_signature (pkl->file().get(), notes);
if (pkl_has_encrypted_assets(dcp, pkl)) {
cxml::Document doc ("PackingList");
doc.read_file (pkl->file().get());
return "Some closed <Text> or <Image> nodes have different vertical alignments within a <Subtitle>.";
case VerificationNote::Code::INCORRECT_CLOSED_CAPTION_ORDERING:
return "Some closed captions are not listed in the order of their vertical position.";
+ case VerificationNote::Code::INVALID_SIGNATURE:
+ return "An XML file has an invalid signature.";
}
return "";
return s;
}
+