diff options
| author | Carl Hetherington <cth@carlh.net> | 2019-01-20 20:26:41 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2019-01-24 02:03:05 +0000 |
| commit | a266fc223ecb7a696fa9dc35422ef0264b1c3c40 (patch) | |
| tree | 27273528c69e91c7461d9349f9f1467886ddf977 | |
| parent | 49f9ec23d00bec2f284118fed3d48d10a6cc8537 (diff) | |
Attempt to fix Sony digest validation by indenting the <Signer>
and <Signature> before signing. This is in the belief that, perhaps,
the Sony software "reformats" the XML before checking that the signature
is correct (or something).
| -rw-r--r-- | src/certificate_chain.cc | 35 | ||||
| -rw-r--r-- | src/certificate_chain.h | 2 | ||||
| -rw-r--r-- | src/cpl.cc | 7 | ||||
| -rw-r--r-- | src/dcp.cc | 5 | ||||
| -rw-r--r-- | src/encrypted_kdm.cc | 2 | ||||
| -rw-r--r-- | src/pkl.cc | 2 | ||||
| -rw-r--r-- | 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<xmlpp::Element*>(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 { /* <Signer> */ + 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); + /* <Signature> */ + 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<std::string> key () const { return _key; @@ -140,6 +140,10 @@ CPL::write_xml (boost::filesystem::path file, Standard standard, shared_ptr<cons root = doc.create_root_node ("CompositionPlaylist", cpl_smpte_ns); } + if (signer) { + root->set_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_ptr<cons signer->sign (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); } @@ -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<xmlpp::Element*>(*i), "ds"); } } @@ -113,7 +113,7 @@ PKL::write (boost::filesystem::path file, shared_ptr<const CertificateChain> sig signer->sign (pkl, _standard); } - doc.write_to_file (file.string(), "UTF-8"); + doc.write_to_file_formatted (file.string(), "UTF-8"); } optional<string> 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' |
