Bug 1308076 - Use PsshParser to validate CENC init data. r=jwwang

Now that we can link gmp-clearkey's PSSH parser into Gecko, we can
simply use that inside MediaKeySession to validate that the CENC
init data matches the spec.

This change enforces that CENC init data uses the common system Id.
As far as I can tell, Widevine only uses that now.

MozReview-Commit-ID: HrlKQHcv5DI

--HG--
extra : source : f61138f1030e87026eb432e83d36e46c81e55b33
This commit is contained in:
Chris Pearce 2016-10-06 23:17:44 +13:00
parent 8b3c096a18
commit ef74aeb8a8
3 changed files with 20 additions and 14 deletions

View File

@ -20,6 +20,7 @@
#include "mozilla/EMEUtils.h"
#include "GMPUtils.h"
#include "nsPrintfCString.h"
#include "psshparser/PsshParser.h"
namespace mozilla {
namespace dom {
@ -192,7 +193,8 @@ ValidateInitData(const nsTArray<uint8_t>& aInitData, const nsAString& aInitDataT
if (aInitData.Length() > MAX_CENC_INIT_DATA_LENGTH) {
return false;
}
// TODO: Validate PSSH in future patch...
std::vector<std::vector<uint8_t>> keyIds;
return ParseCENCInitData(aInitData.Elements(), aInitData.Length(), keyIds);
} else if (aInitDataType.LowerCaseEqualsLiteral("keyids")) {
if (aInitData.Length() > MAX_KEY_ID_LENGTH) {
return false;

View File

@ -107,7 +107,7 @@ const uint8_t kSystemID[] = {
0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b
};
void
bool
ParseCENCInitData(const uint8_t* aInitData,
uint32_t aInitDataSize,
std::vector<std::vector<uint8_t>>& aOutKeyIds)
@ -120,23 +120,26 @@ ParseCENCInitData(const uint8_t* aInitData,
const size_t size = reader.ReadU32();
if (size > std::numeric_limits<size_t>::max() - start) {
// Ensure 'start + size' calculation below can't overflow.
return;
return false;
}
const size_t end = start + size;
if (end > reader.Length()) {
// Ridiculous sized box.
return false;
}
const size_t end = std::min<size_t>(start + size, reader.Length());
// PSSH box type.
if (!reader.CanRead32()) {
return;
return false;
}
uint32_t box = reader.ReadU32();
if (box != FOURCC('p','s','s','h')) {
reader.Seek(std::max<size_t>(reader.Offset(), end));
continue;
return false;
}
// 1 byte version, 3 bytes flags.
if (!reader.CanRead32()) {
return;
return false;
}
uint8_t version = reader.ReadU8();
if (version != 1) {
@ -149,8 +152,8 @@ ParseCENCInitData(const uint8_t* aInitData,
// SystemID
const uint8_t* sid = reader.Read(sizeof(kSystemID));
if (!sid) {
// Insufficinet bytes to read SystemID.
return;
// Insufficient bytes to read SystemID.
return false;
}
if (memcmp(kSystemID, sid, sizeof(kSystemID))) {
// Ignore pssh boxes with wrong system ID.
@ -159,14 +162,14 @@ ParseCENCInitData(const uint8_t* aInitData,
}
if (!reader.CanRead32()) {
return;
return false;
}
uint32_t kidCount = reader.ReadU32();
for (uint32_t i = 0; i < kidCount; i++) {
if (reader.Remaining() < CLEARKEY_KEY_LEN) {
// Not enough remaining to read key.
return;
return false;
}
const uint8_t* kid = reader.Read(CLEARKEY_KEY_LEN);
aOutKeyIds.push_back(std::vector<uint8_t>(kid, kid + CLEARKEY_KEY_LEN));
@ -176,7 +179,7 @@ ParseCENCInitData(const uint8_t* aInitData,
// always be 0. We explicitly read the datasize, in case the box
// size was 0, so that we get to the end of the box.
if (!reader.CanRead32()) {
return;
return false;
}
reader.ReadU32();
@ -185,4 +188,5 @@ ParseCENCInitData(const uint8_t* aInitData,
reader.Seek(end);
}
}
return true;
}

View File

@ -22,7 +22,7 @@
#define CLEARKEY_KEY_LEN ((size_t)16)
void
bool
ParseCENCInitData(const uint8_t* aInitData,
uint32_t aInitDataSize,
std::vector<std::vector<uint8_t>>& aOutKeyIds);