Skip to content

Commit

Permalink
Bug 1308076 - Use PsshParser to validate CENC init data. r=jwwang
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Chris Pearce committed Oct 6, 2016
1 parent 8b3c096 commit ef74aeb
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 14 deletions.
4 changes: 3 additions & 1 deletion dom/media/eme/MediaKeySession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "mozilla/EMEUtils.h"
#include "GMPUtils.h"
#include "nsPrintfCString.h"
#include "psshparser/PsshParser.h"

namespace mozilla {
namespace dom {
Expand Down Expand Up @@ -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;
Expand Down
28 changes: 16 additions & 12 deletions media/psshparser/PsshParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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) {
Expand All @@ -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.
Expand All @@ -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));
Expand All @@ -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();

Expand All @@ -185,4 +188,5 @@ ParseCENCInitData(const uint8_t* aInitData,
reader.Seek(end);
}
}
return true;
}
2 changes: 1 addition & 1 deletion media/psshparser/PsshParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit ef74aeb

Please sign in to comment.