diff options
| author | Carl Hetherington <cth@carlh.net> | 2021-06-04 14:37:43 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2021-06-04 14:37:43 +0200 |
| commit | a5bd2e9eeecccb1a64aa7f3ae936698fce78bea5 (patch) | |
| tree | 34136bd6b8dc487d578ded06da9d223424da910a | |
| parent | e8c71ec28755e77bd6851b9ffd698794d214208a (diff) | |
Add option to ignore mismatched HMACs when reading MXFs.
| -rw-r--r-- | src/asset_reader.h | 8 | ||||
| -rw-r--r-- | src/frame.h | 4 | ||||
| -rw-r--r-- | src/mono_picture_frame.cc | 5 | ||||
| -rw-r--r-- | src/mono_picture_frame.h | 2 | ||||
| -rw-r--r-- | src/sound_frame.cc | 4 | ||||
| -rw-r--r-- | src/sound_frame.h | 2 | ||||
| -rw-r--r-- | src/stereo_picture_frame.cc | 5 | ||||
| -rw-r--r-- | src/stereo_picture_frame.h | 2 | ||||
| -rw-r--r-- | tools/dcpdecryptmxf.cc | 17 |
9 files changed, 32 insertions, 17 deletions
diff --git a/src/asset_reader.h b/src/asset_reader.h index 2da67bd8..8478b51f 100644 --- a/src/asset_reader.h +++ b/src/asset_reader.h @@ -72,13 +72,17 @@ public: std::shared_ptr<const F> get_frame (int n) const { /* Can't use make_shared here as the constructor is private */ - return std::shared_ptr<const F> (new F(_reader, n, _crypto_context)); + return std::shared_ptr<const F> (new F(_reader, n, _crypto_context, _check_hmac)); } R* reader () const { return _reader; } + void set_check_hmac (bool check) { + _check_hmac = check; + } + protected: R* _reader = nullptr; std::shared_ptr<DecryptionContext> _crypto_context; @@ -100,6 +104,8 @@ private: boost::throw_exception (FileError("could not open MXF file for reading", asset->file().get(), r)); } } + + bool _check_hmac = true; }; diff --git a/src/frame.h b/src/frame.h index 74bd616f..01dfe8b4 100644 --- a/src/frame.h +++ b/src/frame.h @@ -54,12 +54,12 @@ template <class R, class B> class Frame { public: - Frame (R* reader, int n, std::shared_ptr<const DecryptionContext> c) + Frame (R* reader, int n, std::shared_ptr<const DecryptionContext> c, bool check_hmac) { /* XXX: unfortunate guesswork on this buffer size */ _buffer = std::make_shared<B>(Kumu::Megabyte); - if (ASDCP_FAILURE(reader->ReadFrame(n, *_buffer, c->context(), c->hmac()))) { + if (ASDCP_FAILURE(reader->ReadFrame(n, *_buffer, c->context(), check_hmac ? c->hmac() : nullptr))) { boost::throw_exception (ReadError ("could not read frame")); } } diff --git a/src/mono_picture_frame.cc b/src/mono_picture_frame.cc index fb451e08..df75126c 100644 --- a/src/mono_picture_frame.cc +++ b/src/mono_picture_frame.cc @@ -80,13 +80,14 @@ MonoPictureFrame::MonoPictureFrame (boost::filesystem::path path) * @param reader Reader for the asset's MXF file. * @param n Frame within the asset, not taking EntryPoint into account. * @param c Context for decryption, or 0. + * @param check_hmac true to check the HMAC and give an error if it is not as expected. */ -MonoPictureFrame::MonoPictureFrame (ASDCP::JP2K::MXFReader* reader, int n, shared_ptr<DecryptionContext> c) +MonoPictureFrame::MonoPictureFrame (ASDCP::JP2K::MXFReader* reader, int n, shared_ptr<DecryptionContext> c, bool check_hmac) { /* XXX: unfortunate guesswork on this buffer size */ _buffer = make_shared<ASDCP::JP2K::FrameBuffer>(4 * Kumu::Megabyte); - auto const r = reader->ReadFrame (n, *_buffer, c->context(), c->hmac()); + auto const r = reader->ReadFrame (n, *_buffer, c->context(), check_hmac ? c->hmac() : nullptr); if (ASDCP_FAILURE(r)) { boost::throw_exception (ReadError(String::compose ("could not read video frame %1 (%2)", n, static_cast<int>(r)))); diff --git a/src/mono_picture_frame.h b/src/mono_picture_frame.h index 95b0d111..3ca16bf2 100644 --- a/src/mono_picture_frame.h +++ b/src/mono_picture_frame.h @@ -101,7 +101,7 @@ private: */ friend class AssetReader<ASDCP::JP2K::MXFReader, MonoPictureFrame>; - MonoPictureFrame (ASDCP::JP2K::MXFReader* reader, int n, std::shared_ptr<DecryptionContext>); + MonoPictureFrame (ASDCP::JP2K::MXFReader* reader, int n, std::shared_ptr<DecryptionContext>, bool check_hmac); std::shared_ptr<ASDCP::JP2K::FrameBuffer> _buffer; }; diff --git a/src/sound_frame.cc b/src/sound_frame.cc index 9c8087c2..25845d88 100644 --- a/src/sound_frame.cc +++ b/src/sound_frame.cc @@ -46,8 +46,8 @@ using std::cout; using namespace dcp; -SoundFrame::SoundFrame (ASDCP::PCM::MXFReader* reader, int n, std::shared_ptr<const DecryptionContext> c) - : Frame<ASDCP::PCM::MXFReader, ASDCP::PCM::FrameBuffer> (reader, n, c) +SoundFrame::SoundFrame (ASDCP::PCM::MXFReader* reader, int n, std::shared_ptr<const DecryptionContext> c, bool check_hmac) + : Frame<ASDCP::PCM::MXFReader, ASDCP::PCM::FrameBuffer> (reader, n, c, check_hmac) { ASDCP::PCM::AudioDescriptor desc; reader->FillAudioDescriptor (desc); diff --git a/src/sound_frame.h b/src/sound_frame.h index 85082299..0f5021e2 100644 --- a/src/sound_frame.h +++ b/src/sound_frame.h @@ -51,7 +51,7 @@ namespace dcp { class SoundFrame : public Frame<ASDCP::PCM::MXFReader, ASDCP::PCM::FrameBuffer> { public: - SoundFrame (ASDCP::PCM::MXFReader* reader, int n, std::shared_ptr<const DecryptionContext> c); + SoundFrame (ASDCP::PCM::MXFReader* reader, int n, std::shared_ptr<const DecryptionContext> c, bool check_hmac); int channels () const; int samples () const; int32_t get (int channel, int sample) const; diff --git a/src/stereo_picture_frame.cc b/src/stereo_picture_frame.cc index 4cb9f2a1..8d3a2757 100644 --- a/src/stereo_picture_frame.cc +++ b/src/stereo_picture_frame.cc @@ -94,13 +94,14 @@ StereoPictureFrame::Part::size () const /** Make a picture frame from a 3D (stereoscopic) asset. * @param reader Reader for the MXF file. * @param n Frame within the asset, not taking EntryPoint into account. + * @param check_hmac true to check the HMAC and give an error if it is not as expected. */ -StereoPictureFrame::StereoPictureFrame (ASDCP::JP2K::MXFSReader* reader, int n, shared_ptr<DecryptionContext> c) +StereoPictureFrame::StereoPictureFrame (ASDCP::JP2K::MXFSReader* reader, int n, shared_ptr<DecryptionContext> c, bool check_hmac) { /* XXX: unfortunate guesswork on this buffer size */ _buffer = make_shared<ASDCP::JP2K::SFrameBuffer>(4 * Kumu::Megabyte); - if (ASDCP_FAILURE (reader->ReadFrame (n, *_buffer, c->context(), c->hmac()))) { + if (ASDCP_FAILURE (reader->ReadFrame (n, *_buffer, c->context(), check_hmac ? c->hmac() : nullptr))) { boost::throw_exception (ReadError (String::compose ("could not read video frame %1 of %2", n))); } } diff --git a/src/stereo_picture_frame.h b/src/stereo_picture_frame.h index 096c821a..09d684c4 100644 --- a/src/stereo_picture_frame.h +++ b/src/stereo_picture_frame.h @@ -105,7 +105,7 @@ private: */ friend class AssetReader<ASDCP::JP2K::MXFSReader, StereoPictureFrame>; - StereoPictureFrame (ASDCP::JP2K::MXFSReader* reader, int n, std::shared_ptr<DecryptionContext>); + StereoPictureFrame (ASDCP::JP2K::MXFSReader* reader, int n, std::shared_ptr<DecryptionContext>, bool check_hmac); std::shared_ptr<ASDCP::JP2K::SFrameBuffer> _buffer; }; diff --git a/tools/dcpdecryptmxf.cc b/tools/dcpdecryptmxf.cc index cf8df735..4c615f99 100644 --- a/tools/dcpdecryptmxf.cc +++ b/tools/dcpdecryptmxf.cc @@ -68,13 +68,15 @@ help (string n) << " -o, --output output filename\n" << " -k, --kdm KDM file\n" << " -p, --private-key private key file\n" - << " -t, --type MXF type: picture or atmos\n"; + << " -t, --type MXF type: picture or atmos\n" + << " -i, --ignore-hmac don't raise an error if HMACs don't agree\n"; } template <class T, class U> -void copy (T const& in, shared_ptr<U> writer) +void copy (T const& in, shared_ptr<U> writer, bool ignore_hmac) { auto reader = in.start_read(); + reader->set_check_hmac (!ignore_hmac); for (int64_t i = 0; i < in.intrinsic_duration(); ++i) { auto frame = reader->get_frame (i); writer->write (frame->data(), frame->size()); @@ -92,6 +94,7 @@ main (int argc, char* argv[]) optional<boost::filesystem::path> output_file; optional<boost::filesystem::path> kdm_file; optional<boost::filesystem::path> private_key_file; + bool ignore_hmac = false; enum class Type { PICTURE, @@ -110,10 +113,11 @@ main (int argc, char* argv[]) { "kdm", required_argument, 0, 'k'}, { "private-key", required_argument, 0, 'p'}, { "type", required_argument, 0, 't' }, + { "ignore-hmac", no_argument, 0, 'i' }, { 0, 0, 0, 0 } }; - int c = getopt_long (argc, argv, "Avho:k:p:t:", long_options, &option_index); + int c = getopt_long (argc, argv, "Avho:k:p:t:i", long_options, &option_index); if (c == -1) { break; @@ -148,6 +152,9 @@ main (int argc, char* argv[]) exit (EXIT_FAILURE); } break; + case 'i': + ignore_hmac = true; + break; } } @@ -214,7 +221,7 @@ main (int argc, char* argv[]) in.atmos_version() ); auto writer = out.start_write (output_file.get()); - copy (in, writer); + copy (in, writer, ignore_hmac); break; } case Type::PICTURE: @@ -223,7 +230,7 @@ main (int argc, char* argv[]) add_key (in, decrypted_kdm); dcp::MonoPictureAsset out (in.edit_rate(), dcp::Standard::SMPTE); auto writer = out.start_write (output_file.get(), false); - copy (in, writer); + copy (in, writer, ignore_hmac); break; } } |
