shared_ptr<xmlpp::Document>
CPL::make_kdm (
CertificateChain const & certificates,
- string const & signer_key,
+ boost::filesystem::path signer_key,
shared_ptr<const Certificate> recipient_cert,
boost::posix_time::ptime from,
boost::posix_time::ptime until,
kdm_required_extensions->add_child("CompositionPlaylistId")->add_child_text("urn:uuid:" + _id);
kdm_required_extensions->add_child("ContentTitleText")->add_child_text(_name);
kdm_required_extensions->add_child("ContentAuthenticator")->add_child_text(certificates.leaf()->thumbprint());
- kdm_required_extensions->add_child("ContentKeysNotValidBefore")->add_child_text("XXX");
- kdm_required_extensions->add_child("ContentKeysNotValidAfter")->add_child_text("XXX");
+ kdm_required_extensions->add_child("ContentKeysNotValidBefore")->add_child_text(ptime_to_string (from));
+ kdm_required_extensions->add_child("ContentKeysNotValidAfter")->add_child_text(ptime_to_string (until));
{
xmlpp::Element* authorized_device_info = kdm_required_extensions->add_child("AuthorizedDeviceInfo");
#include <boost/function.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/optional.hpp>
+#include <boost/filesystem.hpp>
#include <libxml++/libxml++.h>
#include "types.h"
#include "certificates.h"
/** Make a KDM for this CPL.
* @param certificates
- * @param signer_key
+ * @param signer_key Filename of private key to sign the KDM with.
* @param recipient_cert The certificate of the projector that this KDM is targeted at. This will contain the
* projector's public key (P) which is used to encrypt the content keys.
* @param from Time that the KDM should be valid from.
*/
boost::shared_ptr<xmlpp::Document> make_kdm (
CertificateChain const & certificates,
- std::string const & signer_key,
+ boost::filesystem::path signer_key,
boost::shared_ptr<const Certificate> recipient_cert,
boost::posix_time::ptime from,
boost::posix_time::ptime until,
void
libdcp::make_crypt_chain (boost::filesystem::path directory)
{
+ boost::filesystem::path const cwd = boost::filesystem::current_path ();
+
boost::filesystem::current_path (directory);
command ("openssl genrsa -out ca.key 2048");
}
command ("openssl x509 -req -sha256 -days 3648 -CA intermediate.signed.pem -CAkey intermediate.key -set_serial 7 -in leaf.csr -extfile leaf.cnf -extensions v3_ca -out leaf.signed.pem");
+
+ boost::filesystem::current_path (cwd);
}
*/
-#include <string>
+#include <boost/filesystem.hpp>
#include "certificates.h"
namespace libdcp {
class Encryption
{
public:
- Encryption (CertificateChain c, std::string const & k)
+ Encryption (CertificateChain c, boost::filesystem::path k)
: certificates (c)
, signer_key (k)
{}
CertificateChain certificates;
- std::string signer_key;
+ /** Filename of signer key */
+ boost::filesystem::path signer_key;
};
}
#ifndef LIBDCP_EXCEPTIONS_H
#define LIBDCP_EXCEPTIONS_H
+#include <boost/filesystem.hpp>
+
/** @file src/exceptions.h
* @brief Exceptions thrown by libdcp.
*/
class FileError : public std::exception
{
public:
- FileError (std::string const & message, std::string const & filename)
+ FileError (std::string const & message, boost::filesystem::path filename)
: _message (message)
, _filename (filename)
{}
}
/** @return filename of file that was involved */
- std::string filename () const {
+ boost::filesystem::path filename () const {
return _filename;
}
/** error message */
std::string _message;
/** filename of file that was involved */
- std::string _filename;
+ boost::filesystem::path _filename;
};
/** @brief An exception related to an MXF file */
class MXFFileError : public FileError
{
public:
- MXFFileError (std::string const & message, std::string const & filename)
+ MXFFileError (std::string const & message, boost::filesystem::path filename)
: FileError (message, filename)
{}
};
if (xmlSecInit() < 0) {
throw MiscError ("could not initialise xmlsec");
}
+
+#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
+ if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
+ throw MiscError ("unable to load default xmlsec-crypto library");
+ }
+#endif
+
+ if (xmlSecCryptoAppInit(0) < 0) {
+ throw MiscError ("could not initialise crypto");
+ }
+
+ if (xmlSecCryptoInit() < 0) {
+ throw MiscError ("could not initialise xmlsec-crypto");
+ }
}
+/** Sign an XML node. This function takes a certificate chain (to prove that the sender is bona fide) and
+ * a private key with which to sign the node.
+ *
+ * @param parent Node to sign.
+ * @param certificates Certificate chain for the signer.
+ * @param signer_key Filename of the private key of the signer.
+ * @param ns Namespace to use for the signature XML nodes.
+ */
void
-libdcp::add_signature_value (xmlpp::Element* parent, CertificateChain const & certificates, string const & signer_key, string const & ns)
+libdcp::add_signature_value (xmlpp::Element* parent, CertificateChain const & certificates, boost::filesystem::path signer_key, string const & ns)
{
parent->add_child("SignatureValue", ns);
-
+
+ /* Add the certificate chain to a KeyInfo child node of parent */
xmlpp::Element* key_info = parent->add_child("KeyInfo", ns);
list<shared_ptr<Certificate> > c = certificates.leaf_to_root ();
for (list<shared_ptr<Certificate> >::iterator i = c.begin(); i != c.end(); ++i) {
data->add_child("X509Certificate", ns)->add_child_text((*i)->certificate());
}
- xmlSecKeysMngrPtr keys_manager = xmlSecKeysMngrCreate();
- if (!keys_manager) {
- throw MiscError ("could not create keys manager");
+ xmlSecDSigCtxPtr signature_context = xmlSecDSigCtxCreate (0);
+ if (signature_context == 0) {
+ throw MiscError ("could not create signature context");
}
-
- xmlSecDSigCtx signature_context;
-
- if (xmlSecDSigCtxInitialize (&signature_context, keys_manager) < 0) {
- throw MiscError ("could not initialise XMLSEC context");
+
+ signature_context->signKey = xmlSecCryptoAppKeyLoad (signer_key.c_str(), xmlSecKeyDataFormatPem, 0, 0, 0);
+ if (signature_context->signKey == 0) {
+ throw FileError ("could not load private key file", signer_key);
}
-
- if (xmlSecDSigCtxSign (&signature_context, parent->cobj()) < 0) {
+
+ /* XXX: set key name to the file name: is this right? */
+ if (xmlSecKeySetName (signature_context->signKey, reinterpret_cast<const xmlChar *> (signer_key.c_str())) < 0) {
+ throw MiscError ("could not set key name");
+ }
+
+ if (xmlSecDSigCtxSign (signature_context, parent->cobj ()) < 0) {
throw MiscError ("could not sign");
}
-
- xmlSecDSigCtxFinalize (&signature_context);
- xmlSecKeysMngrDestroy (keys_manager);
+
+ xmlSecDSigCtxDestroy (signature_context);
}
}
}
+/** @param signer_key Filename of private key to sign with */
void
-libdcp::sign (xmlpp::Element* parent, CertificateChain const & certificates, string const & signer_key, bool interop)
+libdcp::sign (xmlpp::Element* parent, CertificateChain const & certificates, boost::filesystem::path signer_key, bool interop)
{
add_signer (parent, certificates, "dsig");
o << setw(2) << setfill('0') << hours << ":" << setw(2) << setfill('0') << minutes;
return o.str ();
}
+
+string
+libdcp::ptime_to_string (boost::posix_time::ptime t)
+{
+ struct tm t_tm = boost::posix_time::to_tm (t);
+ return tm_to_string (&t_tm);
+}
#include <stdint.h>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/filesystem.hpp>
#include <openjpeg.h>
#include "types.h"
extern void init ();
-extern void sign (xmlpp::Element* parent, CertificateChain const & certificates, std::string const & signer_key, bool interop);
-extern void add_signature_value (xmlpp::Element* parent, CertificateChain const & certificates, std::string const & signer_key, std::string const & ns);
+extern void sign (xmlpp::Element* parent, CertificateChain const & certificates, boost::filesystem::path signer_key, bool interop);
+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 std::string tm_to_string (struct tm *);
extern std::string utc_offset_to_string (int);
+extern std::string ptime_to_string (boost::posix_time::ptime);
}
*/
-/* Load a certificate chain from build/test/data/*.pem and then build
+/* Load a certificate chain from build/test/data/ *.pem and then build
an encrypted DCP and a KDM using it.
*/
BOOST_AUTO_TEST_CASE (encryption)
libdcp::DCP d ("build/test/DCP/bar");
libdcp::CertificateChain chain;
- chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/data/ca.self-signed.pem")));
- chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/data/intermediate.signed.pem")));
- chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/data/leaf.signed.pem")));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/crypt/ca.self-signed.pem")));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/crypt/intermediate.signed.pem")));
+ chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate ("build/test/crypt/leaf.signed.pem")));
shared_ptr<libdcp::Encryption> crypt (
new libdcp::Encryption (
24,
true,
libdcp::Size (32, 32),
+ false,
mxf_metadata
));
24,
2,
true,
+ false,
mxf_metadata
));
cpl->add_reel (shared_ptr<libdcp::Reel> (new libdcp::Reel (mp, ms, shared_ptr<libdcp::SubtitleAsset> ())));
d.add_cpl (cpl);
- d.write_xml (xml_metadata, crypt);
+ d.write_xml (false, xml_metadata, crypt);
shared_ptr<xmlpp::Document> kdm = cpl->make_kdm (
crypt->certificates,
crypt->certificates.leaf(),
boost::posix_time::time_from_string ("2013-01-01 00:00:00"),
boost::posix_time::time_from_string ("2013-01-08 00:00:00"),
+ false,
mxf_metadata,
xml_metadata
);
#include "recovery_test.cc"
#include "certificates_test.cc"
-//BOOST_AUTO_TEST_CASE (crypt_chain)
-//{
-// boost::filesystem::remove_all ("build/test/crypt");
-// boost::filesystem::create_directory ("build/test/crypt");
-// libdcp::make_crypt_chain ("build/test/crypt");
-//}
+BOOST_AUTO_TEST_CASE (crypt_chain)
+{
+ boost::filesystem::remove_all ("build/test/crypt");
+ boost::filesystem::create_directory ("build/test/crypt");
+ libdcp::make_crypt_chain ("build/test/crypt");
+}
-//#include "encryption_test.cc"
+#include "encryption_test.cc"