X-Git-Url: https://main.carlh.net/gitweb/?p=libdcp.git;a=blobdiff_plain;f=src%2Fdecrypted_kdm.cc;h=174efb1b983de9865a40c240471d8eef8294fbbc;hp=72070fe723936bf657cad832ffae398c48a0fd41;hb=ceaf7bc52712cb60708ed5eb5c62c5e463dd8e89;hpb=adb4f8a5014c3888f3322d1765fb0ee52b1d3169 diff --git a/src/decrypted_kdm.cc b/src/decrypted_kdm.cc index 72070fe7..174efb1b 100644 --- a/src/decrypted_kdm.cc +++ b/src/decrypted_kdm.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013-2017 Carl Hetherington + Copyright (C) 2013-2021 Carl Hetherington This file is part of libdcp. @@ -31,6 +31,12 @@ files in the program, then also delete it here. */ + +/** @file src/decrypted_kdm.cc + * @brief DecryptedKDM class + */ + + #include "decrypted_kdm.h" #include "decrypted_kdm_key.h" #include "encrypted_kdm.h" @@ -47,7 +53,7 @@ #include #include #include -#include + using std::list; using std::vector; @@ -57,13 +63,15 @@ using std::setfill; using std::hex; using std::pair; using std::map; -using boost::shared_ptr; +using std::shared_ptr; using boost::optional; using namespace dcp; + /* Magic value specified by SMPTE S430-1-2006 */ static uint8_t smpte_structure_id[] = { 0xf1, 0xdc, 0x12, 0x44, 0x60, 0x16, 0x9a, 0x0e, 0x85, 0xbc, 0x30, 0x06, 0x42, 0xf8, 0x66, 0xab }; + static void put (uint8_t ** d, string s) { @@ -71,6 +79,7 @@ put (uint8_t ** d, string s) (*d) += s.length(); } + static void put (uint8_t ** d, uint8_t const * s, int N) { @@ -78,6 +87,7 @@ put (uint8_t ** d, uint8_t const * s, int N) (*d) += N; } + void DecryptedKDM::put_uuid (uint8_t ** d, string id) { @@ -97,11 +107,16 @@ DecryptedKDM::put_uuid (uint8_t ** d, string id) *d += 16; } + string DecryptedKDM::get_uuid (unsigned char ** p) { char buffer[37]; +#ifdef LIBDCP_WINDOWS + __mingw_snprintf ( +#else snprintf ( +#endif buffer, sizeof(buffer), "%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", (*p)[0], (*p)[1], (*p)[2], (*p)[3], (*p)[4], (*p)[5], (*p)[6], (*p)[7], (*p)[8], (*p)[9], (*p)[10], (*p)[11], (*p)[12], (*p)[13], (*p)[14], (*p)[15] @@ -111,6 +126,7 @@ DecryptedKDM::get_uuid (unsigned char ** p) return buffer; } + static string get (uint8_t ** p, int N) { @@ -123,33 +139,38 @@ get (uint8_t ** p, int N) return g; } + DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key) { /* Read the private key */ - BIO* bio = BIO_new_mem_buf (const_cast (private_key.c_str ()), -1); + auto bio = BIO_new_mem_buf (const_cast(private_key.c_str()), -1); if (!bio) { throw MiscError ("could not create memory BIO"); } - RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0); + auto rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0); if (!rsa) { throw FileError ("could not read RSA private key file", private_key, errno); } /* Use the private key to decrypt the keys */ - BOOST_FOREACH (string const & i, kdm.keys ()) { + for (auto const& i: kdm.keys()) { /* Decode the base-64-encoded cipher value from the KDM */ unsigned char cipher_value[256]; int const cipher_value_len = base64_decode (i, cipher_value, sizeof (cipher_value)); /* Decrypt it */ - unsigned char * decrypted = new unsigned char[RSA_size(rsa)]; + auto decrypted = new unsigned char[RSA_size(rsa)]; int const decrypted_len = RSA_private_decrypt (cipher_value_len, cipher_value, decrypted, rsa, RSA_PKCS1_OAEP_PADDING); if (decrypted_len == -1) { delete[] decrypted; - throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0)); +#if OPENSSL_VERSION_NUMBER > 0x10100000L + throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0), cipher_value_len, RSA_bits(rsa)); +#else + throw KDMDecryptionError (ERR_error_string (ERR_get_error(), 0), cipher_value_len, rsa->n->dmax); +#endif } unsigned char* p = decrypted; @@ -170,7 +191,7 @@ DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key) /* 93 is not-valid-after (a string) [25 bytes] */ p += 25; /* 118 is the key [ASDCP::KeyLen bytes] */ - add_key (optional(), key_id, Key (p), cpl_id, INTEROP); + add_key (optional(), key_id, Key(p), cpl_id, Standard::INTEROP); break; } case 138: @@ -192,7 +213,7 @@ DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key) /* 97 is not-valid-after (a string) [25 bytes] */ p += 25; /* 112 is the key [ASDCP::KeyLen bytes] */ - add_key (key_type, key_id, Key (p), cpl_id, SMPTE); + add_key (key_type, key_id, Key(p), cpl_id, Standard::SMPTE); break; } default: @@ -210,6 +231,7 @@ DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key) _issue_date = kdm.issue_date (); } + DecryptedKDM::DecryptedKDM ( LocalTime not_valid_before, LocalTime not_valid_after, @@ -226,6 +248,7 @@ DecryptedKDM::DecryptedKDM ( } + DecryptedKDM::DecryptedKDM ( string cpl_id, map, Key> keys, @@ -242,10 +265,11 @@ DecryptedKDM::DecryptedKDM ( , _issue_date (issue_date) { for (map, Key>::const_iterator i = keys.begin(); i != keys.end(); ++i) { - add_key (i->first->key_type(), i->first->key_id().get(), i->second, cpl_id, SMPTE); + add_key (i->first->key_type(), i->first->key_id().get(), i->second, cpl_id, Standard::SMPTE); } } + DecryptedKDM::DecryptedKDM ( shared_ptr cpl, Key key, @@ -263,10 +287,9 @@ DecryptedKDM::DecryptedKDM ( { /* Create DecryptedKDMKey objects for each encryptable asset */ bool did_one = false; - BOOST_FOREACH(shared_ptr i, cpl->reel_assets ()) { - shared_ptr mxf = boost::dynamic_pointer_cast (i); - if (mxf && mxf->key_id ()) { - add_key (mxf->key_type(), mxf->key_id().get(), key, cpl->id(), SMPTE); + for (auto i: cpl->reel_mxfs()) { + if (i->key_id()) { + add_key (i->key_type(), i->key_id().get(), key, cpl->id(), Standard::SMPTE); did_one = true; } } @@ -276,31 +299,44 @@ DecryptedKDM::DecryptedKDM ( } } -/** @param type (MDIK, MDAK etc.) - * @param key_id Key ID. - * @param key The actual symmetric key. - * @param cpl_id ID of CPL that the key is for. - */ + void DecryptedKDM::add_key (optional type, string key_id, Key key, string cpl_id, Standard standard) { _keys.push_back (DecryptedKDMKey (type, key_id, key, cpl_id, standard)); } + void DecryptedKDM::add_key (DecryptedKDMKey key) { _keys.push_back (key); } + EncryptedKDM DecryptedKDM::encrypt ( - shared_ptr signer, Certificate recipient, vector trusted_devices, Formulation formulation + shared_ptr signer, + Certificate recipient, + vector trusted_devices, + Formulation formulation, + bool disable_forensic_marking_picture, + optional disable_forensic_marking_audio ) const { - list > key_ids; - list keys; - BOOST_FOREACH (DecryptedKDMKey const & i, _keys) { + DCP_ASSERT (!_keys.empty ()); + + for (auto i: signer->leaf_to_root()) { + if (day_greater_than_or_equal(dcp::LocalTime(i.not_before()), _not_valid_before)) { + throw BadKDMDateError (true); + } else if (day_less_than_or_equal(dcp::LocalTime(i.not_after()), _not_valid_after)) { + throw BadKDMDateError (false); + } + } + + vector> key_ids; + vector keys; + for (auto const& i: _keys) { /* We're making SMPTE keys so we must have a type for each one */ DCP_ASSERT (i.type()); key_ids.push_back (make_pair (i.type().get(), i.id ())); @@ -359,6 +395,8 @@ DecryptedKDM::encrypt ( _not_valid_before, _not_valid_after, formulation, + disable_forensic_marking_picture, + disable_forensic_marking_audio, key_ids, keys );