SinfParser.cpp (2549B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "SinfParser.h" 6 7 #include "AtomType.h" 8 #include "Box.h" 9 #include "ByteStream.h" 10 #include "mozilla/Try.h" 11 12 namespace mozilla { 13 14 Sinf::Sinf(const Box& aBox) : mDefaultIVSize(0) { 15 SinfParser parser(aBox); 16 if (parser.GetSinf().IsValid()) { 17 *this = parser.GetSinf(); 18 } 19 } 20 21 SinfParser::SinfParser(const Box& aBox) { 22 for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { 23 if (box.IsType("schm")) { 24 (void)ParseSchm(box); 25 } else if (box.IsType("schi")) { 26 (void)ParseSchi(box); 27 } 28 } 29 } 30 31 Result<Ok, nsresult> SinfParser::ParseSchm(const Box& aBox) { 32 BoxReader reader(aBox); 33 34 if (reader->Remaining() < 8) { 35 return Err(NS_ERROR_FAILURE); 36 } 37 38 MOZ_TRY(reader->ReadU32()); // flags -- ignore 39 mSinf.mDefaultEncryptionType = MOZ_TRY(reader->ReadU32()); 40 return Ok(); 41 } 42 43 Result<Ok, nsresult> SinfParser::ParseSchi(const Box& aBox) { 44 for (Box box = aBox.FirstChild(); box.IsAvailable(); box = box.Next()) { 45 if (box.IsType("tenc") && ParseTenc(box).isErr()) { 46 return Err(NS_ERROR_FAILURE); 47 } 48 } 49 return Ok(); 50 } 51 52 Result<Ok, nsresult> SinfParser::ParseTenc(const Box& aBox) { 53 BoxReader reader(aBox); 54 55 if (reader->Remaining() < 24) { 56 return Err(NS_ERROR_FAILURE); 57 } 58 59 uint32_t flags = MOZ_TRY(reader->ReadU32()); 60 uint8_t version = flags >> 24; 61 62 // Skip reserved byte 63 MOZ_TRY(reader->ReadU8()); 64 if (version >= 1) { 65 uint8_t pattern = MOZ_TRY(reader->ReadU8()); 66 mSinf.mDefaultCryptByteBlock = pattern >> 4; 67 mSinf.mDefaultSkipByteBlock = pattern & 0x0f; 68 } else { 69 // Reserved if version is less than 1 70 MOZ_TRY(reader->ReadU8()); 71 mSinf.mDefaultCryptByteBlock = 0; 72 mSinf.mDefaultSkipByteBlock = 0; 73 } 74 75 uint8_t isEncrypted = MOZ_TRY(reader->ReadU8()); 76 mSinf.mDefaultIVSize = MOZ_TRY(reader->ReadU8()); 77 memcpy(mSinf.mDefaultKeyID, reader->Read(16), 16); 78 79 if (isEncrypted && mSinf.mDefaultIVSize == 0) { 80 uint8_t defaultConstantIVSize = MOZ_TRY(reader->ReadU8()); 81 if (!mSinf.mDefaultConstantIV.SetLength(defaultConstantIVSize, 82 mozilla::fallible)) { 83 return Err(NS_ERROR_FAILURE); 84 } 85 for (uint8_t i = 0; i < defaultConstantIVSize; i++) { 86 mSinf.mDefaultConstantIV.ElementAt(i) = MOZ_TRY(reader->ReadU8()); 87 } 88 } 89 return Ok(); 90 } 91 92 } // namespace mozilla