diff options
| author | Carl Hetherington <cth@carlh.net> | 2022-03-07 22:00:06 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2022-03-07 22:00:06 +0100 |
| commit | 8cfa594156923c51a23c64375800ed950fcad16e (patch) | |
| tree | 5e0aee9f1a83a80e90cde27ae5df83fcef30b369 | |
| parent | 03a4fab49fd5a0b3c4b82ee174501b650db78d80 (diff) | |
| -rw-r--r-- | src/verify.cc | 33 | ||||
| -rw-r--r-- | src/verify.h | 4 |
2 files changed, 37 insertions, 0 deletions
diff --git a/src/verify.cc b/src/verify.cc index a0c329d0..410d32e8 100644 --- a/src/verify.cc +++ b/src/verify.cc @@ -76,6 +76,7 @@ #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> @@ -1256,6 +1257,33 @@ pkl_has_encrypted_assets (shared_ptr<DCP> dcp, shared_ptr<PKL> pkl) } +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, @@ -1306,6 +1334,7 @@ dcp::verify ( 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}); @@ -1553,6 +1582,7 @@ dcp::verify ( 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()); @@ -1763,6 +1793,8 @@ dcp::note_to_string (VerificationNote note) 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 ""; @@ -1815,3 +1847,4 @@ dcp::operator<< (std::ostream& s, dcp::VerificationNote const& note) return s; } + diff --git a/src/verify.h b/src/verify.h index 424b29e7..1fd9f5f4 100644 --- a/src/verify.h +++ b/src/verify.h @@ -392,6 +392,10 @@ public: MISMATCHED_CLOSED_CAPTION_VALIGN, /** Some closed captions are not listed in the XML in the order of their vertical position */ INCORRECT_CLOSED_CAPTION_ORDERING, + /** An XML file has an invalid signature + * file contains the XML filename + */ + INVALID_SIGNATURE, }; VerificationNote (Type type, Code code) |
