/*
- 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
*/
-/** @file src/certificates.cc
- * @brief Certificate and CertificateChain classes.
+/** @file src/certificate.cc
+ * @brief Certificate class.
*/
#include "KM_util.h"
/*
- 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
*/
-/** @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>
#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>
return dig;
}
-boost::filesystem::path
-dcp::make_certificate_chain (
+CertificateChain::CertificateChain (
boost::filesystem::path openssl,
string organisation,
string organisational_unit,
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 */
}
/** 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;
}
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,
_certificates = original;
return false;
}
+
+/** Add a <Signer> and <ds:Signature> 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);
+}
#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 {
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);
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
/*
- 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
#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"
* @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;
DCP_ASSERT (false);
}
}
-
class Reel;
class XMLMetadata;
class MXFMetadata;
-class Signer;
+class CertificateChain;
class DecryptedKDM;
/** @class CPL
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> >);
#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"
}
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);
DCP::write_xml (
Standard standard,
XMLMetadata metadata,
- shared_ptr<const Signer> signer
+ shared_ptr<const CertificateChain> signer
)
{
BOOST_FOREACH (shared_ptr<CPL> i, cpls ()) {
class Reel;
class CPL;
class XMLMetadata;
-class Signer;
+class CertificateChain;
class DecryptedKDM;
class Asset;
class DCPReadError;
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:
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;
#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"
}
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;
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 ());
class DecryptedKDMKey;
class EncryptedKDM;
-class Signer;
+class CertificateChain;
class CPL;
/** @class DecryptedKDM
);
/** 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 {
#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>
}
EncryptedKDM::EncryptedKDM (
- shared_ptr<const Signer> signer,
+ shared_ptr<const CertificateChain> signer,
Certificate recipient,
string device_list_description,
string cpl_id,
/* 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 ();
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;
class EncryptedKDMData;
}
-class Signer;
+class CertificateChain;
class Certificate;
/** @class EncryptedKDM
/** 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,
+++ /dev/null
-/*
- 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 <Signer> and <ds:Signature> 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;
-}
+++ /dev/null
-/*
- 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
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);
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
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
#include <boost/test/unit_test.hpp>
#include "certificate.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include "util.h"
using std::list;
chain.add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem")));
chain.add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem")));
chain.add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem")));
- dcp::Signer signer (chain, dcp::file_to_string ("test/ref/crypt/leaf.key"));
- BOOST_CHECK (signer.valid ());
+ chain.set_key (dcp::file_to_string ("test/ref/crypt/leaf.key"));
+ BOOST_CHECK (chain.valid ());
/* Put in an unrelated key and the signer should no longer be valid */
- dcp::Signer another_signer ("openssl");
- signer.set_key (another_signer.key ());
- BOOST_CHECK (!signer.valid ());
+ dcp::CertificateChain another_chain ("openssl");
+ chain.set_key (another_chain.key().get ());
+ BOOST_CHECK (!chain.valid ());
}
#include "metadata.h"
#include "certificate.h"
#include "dcp.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include "cpl.h"
#include "mono_picture_asset.h"
#include "picture_asset_writer.h"
dcp::DCP d ("build/test/DCP/encryption_test");
/* Use test/ref/crypt so this test is repeatable */
- dcp::CertificateChain chain;
- chain.add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem")));
- chain.add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem")));
- chain.add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem")));
-
- shared_ptr<dcp::Signer> signer (
- new dcp::Signer (
- chain,
- dcp::file_to_string ("test/ref/crypt/leaf.key")
- )
- );
+ shared_ptr<dcp::CertificateChain> signer (new dcp::CertificateChain ());
+ signer->add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem")));
+ signer->add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem")));
+ signer->add (dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem")));
+ signer->set_key (dcp::file_to_string ("test/ref/crypt/leaf.key"));
shared_ptr<dcp::CPL> cpl (new dcp::CPL ("A Test DCP", dcp::FEATURE));
"2012-07-17T04:45:18+00:00"
);
- kdm.encrypt (signer, signer->certificates().leaf(), dcp::MODIFIED_TRANSITIONAL_1).as_xml ("build/test/encryption_test.kdm.xml");
+ kdm.encrypt (signer, signer->leaf(), dcp::MODIFIED_TRANSITIONAL_1).as_xml ("build/test/encryption_test.kdm.xml");
int r = system (
"xmllint --path schema --nonet --noout --schema schema/SMPTE-430-1-2006-Amd-1-2009-KDM.xsd build/test/encryption_test.kdm.xml "
#include "certificate.h"
#include "decrypted_kdm.h"
#include "encrypted_kdm.h"
-#include "signer.h"
+#include "certificate_chain.h"
#include "mono_picture_asset.h"
#include "sound_asset.h"
#include "reel.h"
/** Build an encrypted picture asset and a KDM for it and check that the KDM can be decrypted */
BOOST_AUTO_TEST_CASE (round_trip_test)
{
- shared_ptr<dcp::Signer> signer (new dcp::Signer ("openssl"));
+ shared_ptr<dcp::CertificateChain> signer (new dcp::CertificateChain ("openssl"));
boost::filesystem::path work_dir = "build/test/round_trip_test";
boost::filesystem::create_directory (work_dir);
boost::filesystem::path const kdm_file = work_dir / "kdm.xml";
- kdm_A.encrypt(signer, signer->certificates().leaf(), dcp::MODIFIED_TRANSITIONAL_1).as_xml (kdm_file);
+ kdm_A.encrypt(signer, signer->leaf(), dcp::MODIFIED_TRANSITIONAL_1).as_xml (kdm_file);
/* Reload the KDM, using our private key to decrypt it */
- dcp::DecryptedKDM kdm_B (dcp::EncryptedKDM (dcp::file_to_string (kdm_file)), signer->key ());
+ dcp::DecryptedKDM kdm_B (dcp::EncryptedKDM (dcp::file_to_string (kdm_file)), signer->key().get ());
/* Check that the decrypted KDMKeys are the same as the ones we started with */
BOOST_CHECK_EQUAL (kdm_A.keys().size(), kdm_B.keys().size());