#include <xmlsec/xmldsig.h>
#include <xmlsec/dl.h>
#include <xmlsec/app.h>
+#include <xmlsec/crypto.h>
#include "KM_util.h"
#include "KM_fileio.h"
#include "AS_DCP.h"
using std::min;
using std::max;
using std::list;
+using std::setw;
+using std::setfill;
using boost::shared_ptr;
using boost::lexical_cast;
using namespace libdcp;
}
}
- byte_t byte_buffer[20];
+ byte_t byte_buffer[SHA_DIGEST_LENGTH];
SHA1_Final (byte_buffer, &sha);
char digest[64];
- return Kumu::base64encode (byte_buffer, 20, digest, 64);
+ return Kumu::base64encode (byte_buffer, SHA_DIGEST_LENGTH, digest, 64);
}
/** Convert a content kind to a string which can be used in a
if (xmlSecInit() < 0) {
throw MiscError ("could not initialise xmlsec");
}
-}
-void
-libdcp::add_signature_value (xmlpp::Element* parent, CertificateChain const & certificates, string const & signer_key, string const & ns)
-{
- parent->add_child("SignatureValue", ns);
-
- 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) {
- 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());
+#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
+ if (xmlSecCryptoDLLoadLibrary(BAD_CAST XMLSEC_CRYPTO) < 0) {
+ throw MiscError ("unable to load default xmlsec-crypto library");
}
+#endif
- xmlSecKeysMngrPtr keys_manager = xmlSecKeysMngrCreate();
- if (!keys_manager) {
- throw MiscError ("could not create keys manager");
+ if (xmlSecCryptoAppInit(0) < 0) {
+ throw MiscError ("could not initialise crypto");
}
-
- xmlSecDSigCtx signature_context;
-
- if (xmlSecDSigCtxInitialize (&signature_context, keys_manager) < 0) {
- throw MiscError ("could not initialise XMLSEC context");
- }
-
- if (xmlSecDSigCtxSign (&signature_context, parent->cobj()) < 0) {
- throw MiscError ("could not sign");
- }
-
- xmlSecDSigCtxFinalize (&signature_context);
- xmlSecKeysMngrDestroy (keys_manager);
-}
-
-void
-libdcp::add_signer (xmlpp::Element* parent, CertificateChain const & certificates, string const & ns)
-{
- xmlpp::Element* signer = parent->add_child("Signer");
-
- {
- xmlpp::Element* data = signer->add_child("X509Data", ns);
-
- {
- xmlpp::Element* serial_element = data->add_child("X509IssuerSerial", ns);
- serial_element->add_child("X509IssuerName", ns)->add_child_text (certificates.leaf()->issuer());
- serial_element->add_child("X509SerialNumber", ns)->add_child_text (certificates.leaf()->serial());
- }
-
- data->add_child("X509SubjectName", ns)->add_child_text (certificates.leaf()->subject());
+ if (xmlSecCryptoInit() < 0) {
+ throw MiscError ("could not initialise xmlsec-crypto");
}
}
-void
-libdcp::sign (xmlpp::Element* parent, CertificateChain const & certificates, string const & signer_key, bool interop)
-{
- add_signer (parent, certificates, "dsig");
-
- 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 (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");
- }
- }
-
- add_signature_value (signature, certificates, signer_key, "dsig");
-}
-
bool libdcp::operator== (libdcp::Size const & a, libdcp::Size const & b)
{
return (a.width == b.width && a.height == b.height);
return N;
}
+
+string
+libdcp::tm_to_string (struct tm* tm)
+{
+ char buffer[64];
+ strftime (buffer, 64, "%Y-%m-%dT%I:%M:%S", tm);
+
+ int offset = 0;
+
+#ifdef LIBDCP_POSIX
+ offset = tm->tm_gmtoff / 60;
+#else
+ TIME_ZONE_INFORMATION tz;
+ GetTimeZoneInformation (&tz);
+ offset = tz.Bias;
+#endif
+
+ return string (buffer) + utc_offset_to_string (offset);
+}
+
+/** @param b Offset from UTC to local time in minutes.
+ * @return string of the form e.g. -01:00.
+ */
+string
+libdcp::utc_offset_to_string (int b)
+{
+ bool const negative = (b < 0);
+ b = negative ? -b : b;
+
+ int const hours = b / 60;
+ int const minutes = b % 60;
+
+ stringstream o;
+ if (negative) {
+ o << "-";
+ } else {
+ o << "+";
+ }
+
+ 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);
+}