diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-09-18 18:46:58 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-09-18 18:46:58 +0100 |
| commit | 781982ea9a78f88fef130dc08cd028b7e5f47937 (patch) | |
| tree | 5132d1abeecd40814b06d148bfd126b3b48b2604 /src | |
| parent | 56782052e43a1e010f7f07cbc0dbaed5b6cb50a3 (diff) | |
A few encryption-related fixes and comments.
Diffstat (limited to 'src')
| -rw-r--r-- | src/cpl.cc | 6 | ||||
| -rw-r--r-- | src/cpl.h | 5 | ||||
| -rw-r--r-- | src/crypt_chain.cc | 4 | ||||
| -rw-r--r-- | src/encryption.h | 7 | ||||
| -rw-r--r-- | src/exceptions.h | 10 | ||||
| -rw-r--r-- | src/util.cc | 66 | ||||
| -rw-r--r-- | src/util.h | 7 |
7 files changed, 75 insertions, 30 deletions
@@ -347,7 +347,7 @@ CPL::equals (CPL const & other, EqualityOptions opt, boost::function<void (NoteT 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, @@ -401,8 +401,8 @@ CPL::make_kdm ( 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"); @@ -25,6 +25,7 @@ #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" @@ -96,7 +97,7 @@ public: /** 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. @@ -105,7 +106,7 @@ public: */ 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, diff --git a/src/crypt_chain.cc b/src/crypt_chain.cc index d495c970..2737f12c 100644 --- a/src/crypt_chain.cc +++ b/src/crypt_chain.cc @@ -47,6 +47,8 @@ static void command (char const * c) 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"); @@ -161,4 +163,6 @@ libdcp::make_crypt_chain (boost::filesystem::path directory) } 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); } diff --git a/src/encryption.h b/src/encryption.h index f143f0df..b6d79b19 100644 --- a/src/encryption.h +++ b/src/encryption.h @@ -17,7 +17,7 @@ */ -#include <string> +#include <boost/filesystem.hpp> #include "certificates.h" namespace libdcp { @@ -25,13 +25,14 @@ 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; }; } diff --git a/src/exceptions.h b/src/exceptions.h index 4c53a66d..de744812 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -20,6 +20,8 @@ #ifndef LIBDCP_EXCEPTIONS_H #define LIBDCP_EXCEPTIONS_H +#include <boost/filesystem.hpp> + /** @file src/exceptions.h * @brief Exceptions thrown by libdcp. */ @@ -31,7 +33,7 @@ namespace 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) {} @@ -44,7 +46,7 @@ public: } /** @return filename of file that was involved */ - std::string filename () const { + boost::filesystem::path filename () const { return _filename; } @@ -52,14 +54,14 @@ private: /** 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) {} }; diff --git a/src/util.cc b/src/util.cc index 4035ffd1..f2728a38 100644 --- a/src/util.cc +++ b/src/util.cc @@ -239,13 +239,36 @@ libdcp::init () 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) { @@ -260,23 +283,26 @@ libdcp::add_signature_value (xmlpp::Element* parent, CertificateChain const & ce 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); } @@ -298,8 +324,9 @@ libdcp::add_signer (xmlpp::Element* parent, CertificateChain const & certificate } } +/** @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"); @@ -412,3 +439,10 @@ libdcp::utc_offset_to_string (int b) 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); +} @@ -28,6 +28,8 @@ #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" @@ -69,14 +71,15 @@ extern boost::shared_ptr<XYZFrame> decompress_j2k (uint8_t* data, int64_t size, 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); } |
