Skip to content
Snippets Groups Projects
Commit ef74aeb8 authored by Chris Pearce's avatar Chris Pearce
Browse files

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
parent 8b3c096a
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -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;
}
......@@ -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);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment