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.
{
/* <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");
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");
* @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 ();
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));
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;
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);
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);
}
}
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
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.
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");
}
}
signer->sign (pkl, _standard);
}
- doc.write_to_file (file.string(), "UTF-8");
+ doc.write_to_file_formatted (file.string(), "UTF-8");
}
optional<string>
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'