summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-07-30 02:10:09 +0100
committerCarl Hetherington <cth@carlh.net>2015-07-30 02:10:09 +0100
commit57b862d997857868d0c3c91a9776f854b62c6b56 (patch)
treeed3bf26ba60645094853d05918bc22750bb356f7 /src
parentd69d2d2d32b6f874cc13ecec1ce705d44a1feb24 (diff)
Merge Signer into CertificateChain.
Diffstat (limited to 'src')
-rw-r--r--src/certificate.cc6
-rw-r--r--src/certificate.h10
-rw-r--r--src/certificate_chain.cc142
-rw-r--r--src/certificate_chain.h53
-rw-r--r--src/cpl.cc7
-rw-r--r--src/cpl.h4
-rw-r--r--src/dcp.cc6
-rw-r--r--src/dcp.h6
-rw-r--r--src/decrypted_kdm.cc6
-rw-r--r--src/decrypted_kdm.h6
-rw-r--r--src/encrypted_kdm.cc10
-rw-r--r--src/encrypted_kdm.h4
-rw-r--r--src/signer.cc195
-rw-r--r--src/signer.h96
-rw-r--r--src/util.h4
-rw-r--r--src/wscript2
16 files changed, 205 insertions, 352 deletions
diff --git a/src/certificate.cc b/src/certificate.cc
index fcc7b0ae..73f403bf 100644
--- a/src/certificate.cc
+++ b/src/certificate.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,8 +17,8 @@
*/
-/** @file src/certificates.cc
- * @brief Certificate and CertificateChain classes.
+/** @file src/certificate.cc
+ * @brief Certificate class.
*/
#include "KM_util.h"
diff --git a/src/certificate.h b/src/certificate.h
index c2121a83..6225cf31 100644
--- a/src/certificate.h
+++ b/src/certificate.h
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,12 +17,12 @@
*/
-/** @file src/certificates.h
- * @brief Certificate and CertificateChain classes.
+/** @file src/certificate.h
+ * @brief Certificate class.
*/
-#ifndef LIBDCP_CERTIFICATES_H
-#define LIBDCP_CERTIFICATES_H
+#ifndef LIBDCP_CERTIFICATE_H
+#define LIBDCP_CERTIFICATE_H
#undef X509_NAME
#include <openssl/x509.h>
diff --git a/src/certificate_chain.cc b/src/certificate_chain.cc
index e7de5bd8..c0bfd52f 100644
--- a/src/certificate_chain.cc
+++ b/src/certificate_chain.cc
@@ -26,11 +26,20 @@
#include "util.h"
#include "dcp_assert.h"
#include "KM_util.h"
+#include "compose.hpp"
+#include <libcxml/cxml.h>
+#include <libxml++/libxml++.h>
+#include <xmlsec/xmldsig.h>
+#include <xmlsec/dl.h>
+#include <xmlsec/app.h>
+#include <xmlsec/crypto.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
+#include <openssl/pem.h>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/foreach.hpp>
#include <fstream>
#include <sstream>
@@ -157,8 +166,7 @@ public_key_digest (boost::filesystem::path private_key, boost::filesystem::path
return dig;
}
-boost::filesystem::path
-dcp::make_certificate_chain (
+CertificateChain::CertificateChain (
boost::filesystem::path openssl,
string organisation,
string organisational_unit,
@@ -280,7 +288,13 @@ dcp::make_certificate_chain (
boost::filesystem::current_path (cwd);
- return directory;
+ _certificates.push_back (dcp::Certificate (dcp::file_to_string (directory / "ca.self-signed.pem")));
+ _certificates.push_back (dcp::Certificate (dcp::file_to_string (directory / "intermediate.signed.pem")));
+ _certificates.push_back (dcp::Certificate (dcp::file_to_string (directory / "leaf.signed.pem")));
+
+ _key = dcp::file_to_string (directory / "leaf.key");
+
+ boost::filesystem::remove_all (directory);
}
/** @return Root certificate */
@@ -351,12 +365,15 @@ CertificateChain::remove (int i)
}
/** Check to see if the chain is valid (i.e. root signs the intermediate, intermediate
- * signs the leaf and so on).
+ * signs the leaf and so on) and that the private key (if there is one) matches the
+ * leaf certificate.
* @return true if it's ok, false if not.
*/
bool
CertificateChain::valid () const
{
+ /* Check the certificate chain */
+
X509_STORE* store = X509_STORE_new ();
if (!store) {
return false;
@@ -398,7 +415,24 @@ CertificateChain::valid () const
}
X509_STORE_free (store);
- return true;
+
+ /* Check that the leaf certificate matches the private key, if there is one */
+
+ if (!_key) {
+ return true;
+ }
+
+ BIO* bio = BIO_new_mem_buf (const_cast<char *> (_key->c_str ()), -1);
+ if (!bio) {
+ throw MiscError ("could not create memory BIO");
+ }
+
+ RSA* private_key = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
+ RSA* public_key = leaf().public_key ();
+ bool const valid = !BN_cmp (private_key->n, public_key->n);
+ BIO_free (bio);
+
+ return valid;
}
/** @return true if the chain is now in order from root to leaf,
@@ -418,3 +452,101 @@ CertificateChain::attempt_reorder ()
_certificates = original;
return false;
}
+
+/** Add a &lt;Signer&gt; and &lt;ds:Signature&gt; nodes to an XML node.
+ * @param parent XML node to add to.
+ * @param standard INTEROP or SMPTE.
+ */
+void
+CertificateChain::sign (xmlpp::Element* parent, Standard standard) const
+{
+ /* <Signer> */
+
+ xmlpp::Element* signer = parent->add_child("Signer");
+ xmlpp::Element* data = signer->add_child("X509Data", "dsig");
+ xmlpp::Element* serial_element = data->add_child("X509IssuerSerial", "dsig");
+ serial_element->add_child("X509IssuerName", "dsig")->add_child_text (leaf().issuer());
+ serial_element->add_child("X509SerialNumber", "dsig")->add_child_text (leaf().serial());
+ data->add_child("X509SubjectName", "dsig")->add_child_text (leaf().subject());
+
+ /* <Signature> */
+
+ xmlpp::Element* signature = parent->add_child("Signature", "dsig");
+
+ 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");
+
+ if (standard == INTEROP) {
+ signed_info->add_child("SignatureMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
+ } else {
+ signed_info->add_child("SignatureMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
+ }
+
+ xmlpp::Element* reference = signed_info->add_child("Reference", "dsig");
+ reference->set_attribute ("URI", "");
+
+ xmlpp::Element* transforms = reference->add_child("Transforms", "dsig");
+ transforms->add_child("Transform", "dsig")->set_attribute (
+ "Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
+ );
+
+ reference->add_child("DigestMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
+ /* This will be filled in by the signing later */
+ reference->add_child("DigestValue", "dsig");
+
+ signature->add_child("SignatureValue", "dsig");
+ signature->add_child("KeyInfo", "dsig");
+ add_signature_value (signature, "dsig");
+}
+
+
+/** Sign an XML node.
+ *
+ * @param parent Node to sign.
+ * @param ns Namespace to use for the signature XML nodes.
+ */
+void
+CertificateChain::add_signature_value (xmlpp::Node* parent, string ns) const
+{
+ cxml::Node cp (parent);
+ xmlpp::Node* key_info = cp.node_child("KeyInfo")->node ();
+
+ /* Add the certificate chain to the KeyInfo child node of parent */
+ CertificateChain::List c = leaf_to_root ();
+ BOOST_FOREACH (Certificate const & i, leaf_to_root ()) {
+ xmlpp::Element* data = key_info->add_child("X509Data", ns);
+
+ {
+ xmlpp::Element* serial = data->add_child("X509IssuerSerial", ns);
+ serial->add_child("X509IssuerName", ns)->add_child_text (i.issuer ());
+ serial->add_child("X509SerialNumber", ns)->add_child_text (i.serial ());
+ }
+
+ data->add_child("X509Certificate", ns)->add_child_text (i.certificate());
+ }
+
+ xmlSecDSigCtxPtr signature_context = xmlSecDSigCtxCreate (0);
+ if (signature_context == 0) {
+ throw MiscError ("could not create signature context");
+ }
+
+ signature_context->signKey = xmlSecCryptoAppKeyLoadMemory (
+ reinterpret_cast<const unsigned char *> (_key->c_str()), _key->size(), xmlSecKeyDataFormatPem, 0, 0, 0
+ );
+
+ if (signature_context->signKey == 0) {
+ throw StringError ("could not read private key");
+ }
+
+ /* XXX: set key name to the PEM string: this can't be right! */
+ if (xmlSecKeySetName (signature_context->signKey, reinterpret_cast<const xmlChar *> (_key->c_str())) < 0) {
+ throw MiscError ("could not set key name");
+ }
+
+ int const r = xmlSecDSigCtxSign (signature_context, parent->cobj ());
+ if (r < 0) {
+ throw MiscError (String::compose ("could not sign (%1)", r));
+ }
+
+ xmlSecDSigCtxDestroy (signature_context);
+}
diff --git a/src/certificate_chain.h b/src/certificate_chain.h
index b4cc2485..4e13d6ee 100644
--- a/src/certificate_chain.h
+++ b/src/certificate_chain.h
@@ -25,7 +25,13 @@
#define LIBDCP_CERTIFICATE_CHAIN_H
#include "certificate.h"
+#include "types.h"
#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
+
+namespace xmlpp {
+ class Node;
+}
namespace dcp {
@@ -37,6 +43,23 @@ class CertificateChain
public:
CertificateChain () {}
+ /** Create a chain of certificates for signing things.
+ * @param openssl Name of openssl binary (if it is on the path) or full path.
+ * @return Directory (which should be deleted by the caller) containing:
+ * - ca.self-signed.pem self-signed root certificate
+ * - intermediate.signed.pem intermediate certificate
+ * - leaf.key leaf certificate private key
+ * - leaf.signed.pem leaf certificate
+ */
+ CertificateChain (
+ boost::filesystem::path openssl,
+ std::string organisation = "example.org",
+ std::string organisational_unit = "example.org",
+ std::string root_common_name = ".smpte-430-2.ROOT.NOT_FOR_PRODUCTION",
+ std::string intermediate_common_name = ".smpte-430-2.INTERMEDIATE.NOT_FOR_PRODUCTION",
+ std::string leaf_common_name = "CS.smpte-430-2.LEAF.NOT_FOR_PRODUCTION"
+ );
+
void add (Certificate c);
void remove (Certificate c);
void remove (int);
@@ -52,29 +75,25 @@ public:
bool valid () const;
bool attempt_reorder ();
+ void sign (xmlpp::Element* parent, Standard standard) const;
+ void add_signature_value (xmlpp::Node* parent, std::string ns) const;
+
+ boost::optional<std::string> key () const {
+ return _key;
+ }
+
+ void set_key (std::string k) {
+ _key = k;
+ }
+
private:
friend class ::certificates;
List _certificates;
+ /** Leaf certificate's private key, if known */
+ boost::optional<std::string> _key;
};
-/** Create a chain of certificates for signing things.
- * @param openssl Name of openssl binary (if it is on the path) or full path.
- * @return Directory (which should be deleted by the caller) containing:
- * - ca.self-signed.pem self-signed root certificate
- * - intermediate.signed.pem intermediate certificate
- * - leaf.key leaf certificate private key
- * - leaf.signed.pem leaf certificate
- */
-boost::filesystem::path make_certificate_chain (
- boost::filesystem::path openssl,
- std::string organisation = "example.org",
- std::string organisational_unit = "example.org",
- std::string root_common_name = ".smpte-430-2.ROOT.NOT_FOR_PRODUCTION",
- std::string intermediate_common_name = ".smpte-430-2.INTERMEDIATE.NOT_FOR_PRODUCTION",
- std::string leaf_common_name = "CS.smpte-430-2.LEAF.NOT_FOR_PRODUCTION"
- );
-
}
#endif
diff --git a/src/cpl.cc b/src/cpl.cc
index 766b91c3..78f49885 100644
--- a/src/cpl.cc
+++ b/src/cpl.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,7 +21,7 @@
#include "util.h"
#include "reel.h"
#include "metadata.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include "xml.h"
#include "reel_picture_asset.h"
#include "reel_sound_asset.h"
@@ -107,7 +107,7 @@ CPL::add (boost::shared_ptr<Reel> reel)
* @param signer Signer to sign the CPL, or 0 to add no signature.
*/
void
-CPL::write_xml (boost::filesystem::path file, Standard standard, shared_ptr<const Signer> signer) const
+CPL::write_xml (boost::filesystem::path file, Standard standard, shared_ptr<const CertificateChain> signer) const
{
xmlpp::Document doc;
xmlpp::Element* root;
@@ -255,4 +255,3 @@ CPL::pkl_type (Standard standard) const
DCP_ASSERT (false);
}
}
-
diff --git a/src/cpl.h b/src/cpl.h
index 7716464d..fe123fd3 100644
--- a/src/cpl.h
+++ b/src/cpl.h
@@ -42,7 +42,7 @@ class ReelAsset;
class Reel;
class XMLMetadata;
class MXFMetadata;
-class Signer;
+class CertificateChain;
class DecryptedKDM;
/** @class CPL
@@ -108,7 +108,7 @@ public:
void write_xml (
boost::filesystem::path file,
Standard standard,
- boost::shared_ptr<const Signer>
+ boost::shared_ptr<const CertificateChain>
) const;
void resolve_refs (std::list<boost::shared_ptr<Object> >);
diff --git a/src/dcp.cc b/src/dcp.cc
index 7a521141..4f1f07df 100644
--- a/src/dcp.cc
+++ b/src/dcp.cc
@@ -34,7 +34,7 @@
#include "metadata.h"
#include "exceptions.h"
#include "cpl.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include "compose.hpp"
#include "AS_DCP.h"
#include "decrypted_kdm.h"
@@ -245,7 +245,7 @@ DCP::add (DecryptedKDM const & kdm)
}
boost::filesystem::path
-DCP::write_pkl (Standard standard, string pkl_uuid, XMLMetadata metadata, shared_ptr<const Signer> signer) const
+DCP::write_pkl (Standard standard, string pkl_uuid, XMLMetadata metadata, shared_ptr<const CertificateChain> signer) const
{
boost::filesystem::path p = _directory;
p /= String::compose ("pkl_%1.xml", pkl_uuid);
@@ -400,7 +400,7 @@ void
DCP::write_xml (
Standard standard,
XMLMetadata metadata,
- shared_ptr<const Signer> signer
+ shared_ptr<const CertificateChain> signer
)
{
BOOST_FOREACH (shared_ptr<CPL> i, cpls ()) {
diff --git a/src/dcp.h b/src/dcp.h
index 44fe7621..f852b6eb 100644
--- a/src/dcp.h
+++ b/src/dcp.h
@@ -45,7 +45,7 @@ class Content;
class Reel;
class CPL;
class XMLMetadata;
-class Signer;
+class CertificateChain;
class DecryptedKDM;
class Asset;
class DCPReadError;
@@ -94,7 +94,7 @@ public:
void write_xml (
Standard standard,
XMLMetadata metadata = XMLMetadata (),
- boost::shared_ptr<const Signer> signer = boost::shared_ptr<const Signer> ()
+ boost::shared_ptr<const CertificateChain> signer = boost::shared_ptr<const CertificateChain> ()
);
private:
@@ -106,7 +106,7 @@ private:
Standard standard,
std::string pkl_uuid,
XMLMetadata metadata,
- boost::shared_ptr<const Signer> signer
+ boost::shared_ptr<const CertificateChain> signer
) const;
void write_volindex (Standard standard) const;
diff --git a/src/decrypted_kdm.cc b/src/decrypted_kdm.cc
index 62058fee..949db72b 100644
--- a/src/decrypted_kdm.cc
+++ b/src/decrypted_kdm.cc
@@ -25,7 +25,7 @@
#include "util.h"
#include "exceptions.h"
#include "cpl.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include "dcp_assert.h"
#include "AS_DCP.h"
#include "KM_util.h"
@@ -212,7 +212,7 @@ DecryptedKDM::DecryptedKDM (
}
EncryptedKDM
-DecryptedKDM::encrypt (shared_ptr<const Signer> signer, Certificate recipient, Formulation formulation) const
+DecryptedKDM::encrypt (shared_ptr<const CertificateChain> signer, Certificate recipient, Formulation formulation) const
{
list<pair<string, string> > key_ids;
list<string> keys;
@@ -227,7 +227,7 @@ DecryptedKDM::encrypt (shared_ptr<const Signer> signer, Certificate recipient, F
uint8_t structure_id[] = { 0xf1, 0xdc, 0x12, 0x44, 0x60, 0x16, 0x9a, 0x0e, 0x85, 0xbc, 0x30, 0x06, 0x42, 0xf8, 0x66, 0xab };
put (&p, structure_id, 16);
- base64_decode (signer->certificates().leaf().thumbprint (), p, 20);
+ base64_decode (signer->leaf().thumbprint (), p, 20);
p += 20;
put_uuid (&p, i.cpl_id ());
diff --git a/src/decrypted_kdm.h b/src/decrypted_kdm.h
index 710de519..45ad8fa6 100644
--- a/src/decrypted_kdm.h
+++ b/src/decrypted_kdm.h
@@ -35,7 +35,7 @@ namespace dcp {
class DecryptedKDMKey;
class EncryptedKDM;
-class Signer;
+class CertificateChain;
class CPL;
/** @class DecryptedKDM
@@ -72,12 +72,12 @@ public:
);
/** Encrypt this KDM's keys and sign the whole KDM.
- * @param signer Signer.
+ * @param signer Chain to sign with.
* @param recipient Certificate of the projector/server which should receive this KDM's keys.
* @param formulation Formulation to use for the encrypted KDM.
* @return Encrypted KDM.
*/
- EncryptedKDM encrypt (boost::shared_ptr<const Signer> signer, Certificate recipient, Formulation formulation) const;
+ EncryptedKDM encrypt (boost::shared_ptr<const CertificateChain> signer, Certificate recipient, Formulation formulation) const;
/** @return This KDM's (decrypted) keys, which could be used to decrypt assets. */
std::list<DecryptedKDMKey> keys () const {
diff --git a/src/encrypted_kdm.cc b/src/encrypted_kdm.cc
index 948e26a5..c3d8a618 100644
--- a/src/encrypted_kdm.cc
+++ b/src/encrypted_kdm.cc
@@ -19,7 +19,7 @@
#include "encrypted_kdm.h"
#include "util.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include <libcxml/cxml.h>
#include <libxml++/document.h>
#include <libxml++/nodes/element.h>
@@ -492,7 +492,7 @@ EncryptedKDM::EncryptedKDM (string s)
}
EncryptedKDM::EncryptedKDM (
- shared_ptr<const Signer> signer,
+ shared_ptr<const CertificateChain> signer,
Certificate recipient,
string device_list_description,
string cpl_id,
@@ -508,8 +508,8 @@ EncryptedKDM::EncryptedKDM (
/* Fill our XML-ish description in with the juicy bits that the caller has given */
data::AuthenticatedPublic& aup = _data->authenticated_public;
- aup.signer.x509_issuer_name = signer->certificates().leaf().issuer ();
- aup.signer.x509_serial_number = signer->certificates().leaf().serial ();
+ aup.signer.x509_issuer_name = signer->leaf().issuer ();
+ aup.signer.x509_serial_number = signer->leaf().serial ();
data::KDMRequiredExtensions& kre = _data->authenticated_public.required_extensions.kdm_required_extensions;
kre.recipient.x509_issuer_serial.x509_issuer_name = recipient.issuer ();
@@ -518,7 +518,7 @@ EncryptedKDM::EncryptedKDM (
kre.authorized_device_info.device_list_description = device_list_description;
kre.composition_playlist_id = cpl_id;
if (formulation == DCI_ANY || formulation == DCI_SPECIFIC) {
- kre.content_authenticator = signer->certificates().leaf().thumbprint ();
+ kre.content_authenticator = signer->leaf().thumbprint ();
}
kre.content_title_text = content_title_text;
kre.not_valid_before = not_valid_before;
diff --git a/src/encrypted_kdm.h b/src/encrypted_kdm.h
index dc98e1f1..247d6678 100644
--- a/src/encrypted_kdm.h
+++ b/src/encrypted_kdm.h
@@ -39,7 +39,7 @@ namespace data {
class EncryptedKDMData;
}
-class Signer;
+class CertificateChain;
class Certificate;
/** @class EncryptedKDM
@@ -77,7 +77,7 @@ private:
/** Construct an EncryptedKDM from a set of details */
EncryptedKDM (
- boost::shared_ptr<const Signer> signer,
+ boost::shared_ptr<const CertificateChain> signer,
Certificate recipient,
std::string device_list_description,
std::string cpl_id,
diff --git a/src/signer.cc b/src/signer.cc
deleted file mode 100644
index c04ac122..00000000
--- a/src/signer.cc
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-/** @file src/signer.cc
- * @brief Signer class.
- */
-
-#include "signer.h"
-#include "exceptions.h"
-#include "certificate_chain.h"
-#include "util.h"
-#include <libcxml/cxml.h>
-#include <libxml++/libxml++.h>
-#include <xmlsec/xmldsig.h>
-#include <xmlsec/dl.h>
-#include <xmlsec/app.h>
-#include <xmlsec/crypto.h>
-#include <openssl/pem.h>
-#include "compose.hpp"
-
-using std::string;
-using std::list;
-using boost::shared_ptr;
-using namespace dcp;
-
-Signer::Signer (boost::filesystem::path openssl)
-{
- create (make_certificate_chain (openssl));
-}
-
-Signer::Signer (boost::filesystem::path openssl,
- string organisation,
- string organisational_unit,
- string root_common_name,
- string intermediate_common_name,
- string leaf_common_name
- )
-{
- create (
- make_certificate_chain (
- openssl,
- organisation,
- organisational_unit,
- root_common_name,
- intermediate_common_name,
- leaf_common_name
- )
- );
-}
-
-void
-Signer::create (boost::filesystem::path directory)
-{
- _certificates.add (dcp::Certificate (dcp::file_to_string (directory / "ca.self-signed.pem")));
- _certificates.add (dcp::Certificate (dcp::file_to_string (directory / "intermediate.signed.pem")));
- _certificates.add (dcp::Certificate (dcp::file_to_string (directory / "leaf.signed.pem")));
-
- _key = dcp::file_to_string (directory / "leaf.key");
-
- boost::filesystem::remove_all (directory);
-}
-
-/** Add a &lt;Signer&gt; and &lt;ds:Signature&gt; nodes to an XML node.
- * @param parent XML node to add to.
- * @param standard INTEROP or SMPTE.
- */
-void
-Signer::sign (xmlpp::Element* parent, Standard standard) const
-{
- /* <Signer> */
-
- xmlpp::Element* signer = parent->add_child("Signer");
- xmlpp::Element* data = signer->add_child("X509Data", "dsig");
- xmlpp::Element* serial_element = data->add_child("X509IssuerSerial", "dsig");
- serial_element->add_child("X509IssuerName", "dsig")->add_child_text (_certificates.leaf().issuer());
- serial_element->add_child("X509SerialNumber", "dsig")->add_child_text (_certificates.leaf().serial());
- data->add_child("X509SubjectName", "dsig")->add_child_text (_certificates.leaf().subject());
-
- /* <Signature> */
-
- xmlpp::Element* signature = parent->add_child("Signature", "dsig");
-
- 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");
-
- if (standard == INTEROP) {
- signed_info->add_child("SignatureMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
- } else {
- signed_info->add_child("SignatureMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
- }
-
- xmlpp::Element* reference = signed_info->add_child("Reference", "dsig");
- reference->set_attribute ("URI", "");
-
- xmlpp::Element* transforms = reference->add_child("Transforms", "dsig");
- transforms->add_child("Transform", "dsig")->set_attribute (
- "Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
- );
-
- reference->add_child("DigestMethod", "dsig")->set_attribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
- /* This will be filled in by the signing later */
- reference->add_child("DigestValue", "dsig");
-
- signature->add_child("SignatureValue", "dsig");
- signature->add_child("KeyInfo", "dsig");
- add_signature_value (signature, "dsig");
-}
-
-
-/** Sign an XML node.
- *
- * @param parent Node to sign.
- * @param ns Namespace to use for the signature XML nodes.
- */
-void
-Signer::add_signature_value (xmlpp::Node* parent, string ns) const
-{
- cxml::Node cp (parent);
- xmlpp::Node* key_info = cp.node_child("KeyInfo")->node ();
-
- /* Add the certificate chain to the KeyInfo child node of parent */
- CertificateChain::List c = _certificates.leaf_to_root ();
- for (CertificateChain::List::iterator i = c.begin(); i != c.end(); ++i) {
- xmlpp::Element* data = key_info->add_child("X509Data", ns);
-
- {
- xmlpp::Element* serial = data->add_child("X509IssuerSerial", ns);
- serial->add_child("X509IssuerName", ns)->add_child_text (i->issuer ());
- serial->add_child("X509SerialNumber", ns)->add_child_text (i->serial ());
- }
-
- data->add_child("X509Certificate", ns)->add_child_text (i->certificate());
- }
-
- xmlSecDSigCtxPtr signature_context = xmlSecDSigCtxCreate (0);
- if (signature_context == 0) {
- throw MiscError ("could not create signature context");
- }
-
- signature_context->signKey = xmlSecCryptoAppKeyLoadMemory (
- reinterpret_cast<const unsigned char *> (_key.c_str()), _key.size(), xmlSecKeyDataFormatPem, 0, 0, 0
- );
-
- if (signature_context->signKey == 0) {
- throw FileError ("could not load private key file", _key, 0);
- }
-
- /* XXX: set key name to the file name: is this right? */
- if (xmlSecKeySetName (signature_context->signKey, reinterpret_cast<const xmlChar *> (_key.c_str())) < 0) {
- throw MiscError ("could not set key name");
- }
-
- int const r = xmlSecDSigCtxSign (signature_context, parent->cobj ());
- if (r < 0) {
- throw MiscError (String::compose ("could not sign (%1)", r));
- }
-
- xmlSecDSigCtxDestroy (signature_context);
-}
-
-bool
-Signer::valid () const
-{
- if (!_certificates.valid ()) {
- return false;
- }
-
- BIO* bio = BIO_new_mem_buf (const_cast<char *> (_key.c_str ()), -1);
- if (!bio) {
- throw MiscError ("could not create memory BIO");
- }
-
- RSA* private_key = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
- RSA* public_key = _certificates.leaf().public_key ();
- bool const valid = !BN_cmp (private_key->n, public_key->n);
- BIO_free (bio);
-
- return valid;
-}
diff --git a/src/signer.h b/src/signer.h
deleted file mode 100644
index b8bd5643..00000000
--- a/src/signer.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-*/
-
-#ifndef LIBDCP_SIGNER_H
-#define LIBDCP_SIGNER_H
-
-/** @file src/signer.h
- * @brief Signer class.
- */
-
-#include "certificate.h"
-#include "certificate_chain.h"
-#include "types.h"
-#include <boost/filesystem.hpp>
-
-namespace xmlpp {
- class Element;
- class Node;
-}
-
-namespace dcp {
-
-/** @class Signer
- * @brief A class which can sign XML files.
- */
-class Signer
-{
-public:
- Signer (boost::filesystem::path openssl);
-
- Signer (
- boost::filesystem::path openssl,
- std::string organisation,
- std::string organisational_unit,
- std::string root_common_name,
- std::string intermediate_common_name,
- std::string leaf_common_name
- );
-
- /** @param c Certificate chain to sign with.
- * @param k Key to sign with as a PEM-format string.
- */
- Signer (CertificateChain c, std::string k)
- : _certificates (c)
- , _key (k)
- {}
-
- void sign (xmlpp::Element* parent, Standard standard) const;
- void add_signature_value (xmlpp::Node* parent, std::string ns) const;
-
- CertificateChain const & certificates () const {
- return _certificates;
- }
-
- CertificateChain& certificates () {
- return _certificates;
- }
-
- std::string key () const {
- return _key;
- }
-
- void set_key (std::string k) {
- _key = k;
- }
-
- bool valid () const;
-
-private:
- void create (boost::filesystem::path directory);
-
- /** Certificate chain to sign with */
- CertificateChain _certificates;
- /** Key to sign with as a PEM-format string */
- std::string _key;
-};
-
-}
-
-#endif
diff --git a/src/util.h b/src/util.h
index 97ef2c55..8b72e7e0 100644
--- a/src/util.h
+++ b/src/util.h
@@ -59,10 +59,6 @@ extern bool ids_equal (std::string a, std::string b);
extern void init ();
-extern void sign (xmlpp::Element* parent, CertificateChain const & certificates, boost::filesystem::path signer_key, Standard standard);
-extern void add_signature_value (xmlpp::Element* parent, CertificateChain const & certificates, boost::filesystem::path signer_key, std::string const & ns);
-extern void add_signer (xmlpp::Element* parent, CertificateChain const & certificates, std::string const & ns);
-
extern int base64_decode (std::string const & in, unsigned char* out, int out_length);
extern boost::optional<boost::filesystem::path> relative_to_root (boost::filesystem::path root, boost::filesystem::path file);
extern FILE * fopen_boost (boost::filesystem::path, std::string);
diff --git a/src/wscript b/src/wscript
index 15d1b781..6a2be894 100644
--- a/src/wscript
+++ b/src/wscript
@@ -43,7 +43,6 @@ def build(bld):
reel_stereo_picture_asset.cc
reel_subtitle_asset.cc
rgb_xyz.cc
- signer.cc
smpte_load_font_node.cc
smpte_subtitle_asset.cc
sound_asset.cc
@@ -105,7 +104,6 @@ def build(bld):
reel_stereo_picture_asset.h
reel_subtitle_asset.h
ref.h
- signer.h
smpte_load_font_node.h
smpte_subtitle_asset.h
sound_frame.h