From 33c2c1ddee9638fc4e59dbfdbeee2fb540778819 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sun, 20 Jan 2019 20:26:41 +0000 Subject: [PATCH] Attempt to fix Sony digest validation by indenting the and before signing. This is in the belief that, perhaps, the Sony software "reformats" the XML before checking that the signature is correct (or something). --- src/certificate_chain.cc | 35 ++++++++++++++++++++++++++++++++++- src/certificate_chain.h | 2 +- src/cpl.cc | 7 +++++-- src/dcp.cc | 5 ++--- src/encrypted_kdm.cc | 2 +- src/pkl.cc | 2 +- tools/wscript | 2 +- 7 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/certificate_chain.cc b/src/certificate_chain.cc index 6b4216b5..ebc3cc7f 100644 --- a/src/certificate_chain.cc +++ b/src/certificate_chain.cc @@ -552,6 +552,33 @@ CertificateChain::root_to_leaf () const throw CertificateChainError ("certificate chain is not consistent"); } +static string +spaces (int n) +{ + string s = ""; + for (int i = 0; i < n; ++i) { + s += " "; + } + return s; +} + +static void +indent (xmlpp::Element* element, int initial) +{ + xmlpp::Node* last = 0; + BOOST_FOREACH (xmlpp::Node * n, element->get_children()) { + xmlpp::Element* e = dynamic_cast(n); + if (e) { + element->add_child_text_before (e, "\n" + spaces(initial + 2)); + indent (e, initial + 2); + last = n; + } + } + if (last) { + element->add_child_text (last, "\n" + spaces(initial)); + } +} + /** Add a <Signer> and <ds:Signature> nodes to an XML node. * @param parent XML node to add to. * @param standard INTEROP or SMPTE. @@ -561,6 +588,7 @@ CertificateChain::sign (xmlpp::Element* parent, Standard standard) const { /* */ + parent->add_child_text(" "); xmlpp::Element* signer = parent->add_child("Signer"); signer->set_namespace_declaration ("http://www.w3.org/2000/09/xmldsig#", "dsig"); xmlpp::Element* data = signer->add_child("X509Data", "dsig"); @@ -569,11 +597,15 @@ CertificateChain::sign (xmlpp::Element* parent, Standard standard) const serial_element->add_child("X509SerialNumber", "dsig")->add_child_text (leaf().serial()); data->add_child("X509SubjectName", "dsig")->add_child_text (leaf().subject()); + indent (signer, 2); + /* */ + parent->add_child_text("\n "); xmlpp::Element* signature = parent->add_child("Signature"); signature->set_namespace_declaration ("http://www.w3.org/2000/09/xmldsig#", "dsig"); signature->set_namespace ("dsig"); + parent->add_child_text("\n"); xmlpp::Element* signed_info = signature->add_child ("SignedInfo", "dsig"); signed_info->add_child("CanonicalizationMethod", "dsig")->set_attribute ("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315"); @@ -608,7 +640,7 @@ CertificateChain::sign (xmlpp::Element* parent, Standard standard) const * @param ns Namespace to use for the signature XML nodes. */ void -CertificateChain::add_signature_value (xmlpp::Node* parent, string ns) const +CertificateChain::add_signature_value (xmlpp::Element* parent, string ns) const { cxml::Node cp (parent); xmlpp::Node* key_info = cp.node_child("KeyInfo")->node (); @@ -639,6 +671,7 @@ CertificateChain::add_signature_value (xmlpp::Node* parent, string ns) const throw runtime_error ("could not read private key"); } + indent (parent, 2); int const r = xmlSecDSigCtxSign (signature_context, parent->cobj ()); if (r < 0) { throw MiscError (String::compose ("could not sign (%1)", r)); diff --git a/src/certificate_chain.h b/src/certificate_chain.h index 365632fe..8b54604d 100644 --- a/src/certificate_chain.h +++ b/src/certificate_chain.h @@ -103,7 +103,7 @@ public: bool private_key_valid () const; void sign (xmlpp::Element* parent, Standard standard) const; - void add_signature_value (xmlpp::Node* parent, std::string ns) const; + void add_signature_value (xmlpp::Element* parent, std::string ns) const; boost::optional key () const { return _key; diff --git a/src/cpl.cc b/src/cpl.cc index 726d69b7..4a594b5a 100644 --- a/src/cpl.cc +++ b/src/cpl.cc @@ -140,6 +140,10 @@ CPL::write_xml (boost::filesystem::path file, Standard standard, shared_ptrset_namespace_declaration ("http://www.w3.org/2000/09/xmldsig#", "dsig"); + } + root->add_child("Id")->add_child_text ("urn:uuid:" + _id); root->add_child("AnnotationText")->add_child_text (_metadata.annotation_text); root->add_child("IssueDate")->add_child_text (_metadata.issue_date); @@ -164,8 +168,7 @@ CPL::write_xml (boost::filesystem::path file, Standard standard, shared_ptrsign (root, standard); } - /* This must not be the _formatted version otherwise signature digests will be wrong */ - doc.write_to_file (file.string (), "UTF-8"); + doc.write_to_file_formatted (file.string(), "UTF-8"); set_file (file); } diff --git a/src/dcp.cc b/src/dcp.cc index 8bf2f02f..5d908530 100644 --- a/src/dcp.cc +++ b/src/dcp.cc @@ -348,7 +348,7 @@ DCP::write_volindex (Standard standard) const } root->add_child("Index")->add_child_text ("1"); - doc.write_to_file (p.string (), "UTF-8"); + doc.write_to_file_formatted (p.string (), "UTF-8"); } void @@ -417,8 +417,7 @@ DCP::write_assetmap (Standard standard, string pkl_uuid, boost::filesystem::path i->write_to_assetmap (asset_list, _directory); } - /* This must not be the _formatted version otherwise signature digests will be wrong */ - doc.write_to_file (p.string (), "UTF-8"); + doc.write_to_file_formatted (p.string (), "UTF-8"); } /** Write all the XML files for this DCP. diff --git a/src/encrypted_kdm.cc b/src/encrypted_kdm.cc index 23052f8a..9d581451 100644 --- a/src/encrypted_kdm.cc +++ b/src/encrypted_kdm.cc @@ -670,7 +670,7 @@ EncryptedKDM::EncryptedKDM ( xmlpp::Node::NodeList children = doc->get_root_node()->get_children (); for (xmlpp::Node::NodeList::const_iterator i = children.begin(); i != children.end(); ++i) { if ((*i)->get_name() == "Signature") { - signer->add_signature_value (*i, "ds"); + signer->add_signature_value (dynamic_cast(*i), "ds"); } } diff --git a/src/pkl.cc b/src/pkl.cc index 43c7d092..9910b190 100644 --- a/src/pkl.cc +++ b/src/pkl.cc @@ -113,7 +113,7 @@ PKL::write (boost::filesystem::path file, shared_ptr sig signer->sign (pkl, _standard); } - doc.write_to_file (file.string(), "UTF-8"); + doc.write_to_file_formatted (file.string(), "UTF-8"); } optional diff --git a/tools/wscript b/tools/wscript index 73c58f30..98eb0df0 100644 --- a/tools/wscript +++ b/tools/wscript @@ -44,7 +44,7 @@ def build(bld): obj.source = 'dcpinfo.cc common.cc' obj.target = 'dcpinfo' - for f in ['dumpsub', 'decryptmxf', 'kdm', 'thumb', 'recover', 'verify']: + for f in ['dumpsub', 'decryptmxf', 'kdm', 'thumb', 'recover', 'verify', 'sign']: obj = bld(features='cxx cxxprogram') obj.use = ['libdcp%s' % bld.env.API_VERSION] obj.uselib = 'OPENJPEG CXML OPENMP ASDCPLIB_CTH BOOST_FILESYSTEM LIBXML++ XMLSEC1 OPENSSL' -- 2.30.2