Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <gtest/gtest.h>
     18 #include <string.h>
     19 
     20 #include <media/stagefright/foundation/AString.h>
     21 #include <media/stagefright/foundation/base64.h>
     22 #include <utils/String8.h>
     23 #include <utils/Vector.h>
     24 
     25 #include "InitDataParser.h"
     26 
     27 namespace clearkeydrm {
     28 
     29 using namespace android;
     30 
     31 namespace {
     32     const size_t kKeyIdSize = 16;
     33     const String8 kCencMimeType("video/mp4");
     34     const String8 kWebmMimeType("video/webm");
     35     const String8 kBase64Padding("=");
     36 }
     37 
     38 class InitDataParserTest : public ::testing::Test {
     39   protected:
     40     status_t attemptParse(const Vector<uint8_t>& initData,
     41                           const String8& mimeType,
     42                           Vector<uint8_t>* licenseRequest) {
     43         InitDataParser parser;
     44         return parser.parse(initData, mimeType, licenseRequest);
     45     }
     46 
     47     void attemptParseExpectingSuccess(const Vector<uint8_t>& initData,
     48                                       const String8& mimeType,
     49                                       const Vector<String8>& expectedKeys) {
     50         const String8 kRequestPrefix("{\"kids\":[");
     51         const String8 kRequestSuffix("],\"type\":\"temporary\"}");
     52         Vector<uint8_t> request;
     53         ASSERT_EQ(android::OK, attemptParse(initData, mimeType, &request));
     54 
     55         String8 requestString(reinterpret_cast<const char*>(request.array()),
     56                               request.size());
     57         EXPECT_EQ(0, requestString.find(kRequestPrefix));
     58         EXPECT_EQ(requestString.size() - kRequestSuffix.size(),
     59                   (size_t)requestString.find(kRequestSuffix));
     60         for (size_t i = 0; i < expectedKeys.size(); ++i) {
     61             AString encodedIdAString;
     62             android::encodeBase64Url(expectedKeys[i], kKeyIdSize,
     63                                   &encodedIdAString);
     64             String8 encodedId(encodedIdAString.c_str());
     65             encodedId.removeAll(kBase64Padding);
     66             EXPECT_TRUE(requestString.contains(encodedId));
     67         }
     68     }
     69 
     70     void attemptParseExpectingFailure(const Vector<uint8_t>& initData,
     71                                       const String8& mimeType) {
     72         Vector<uint8_t> request;
     73         ASSERT_NE(android::OK, attemptParse(initData, mimeType, &request));
     74         EXPECT_EQ(0u, request.size());
     75     }
     76 };
     77 
     78 TEST_F(InitDataParserTest, ParsesSingleKeyPssh) {
     79     uint8_t pssh[52] = {
     80         0, 0, 0, 52,                                    // Total Size
     81         'p', 's', 's', 'h',                             // PSSH
     82         1, 0, 0, 0,                                     // Version
     83         0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // System ID
     84         0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
     85         0, 0, 0, 1,                                     // Key Count
     86         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // Key ID #1
     87         0x38, 0x39, 0x30, 0x41, 0x42, 0x43, 0x44, 0x45, //   "01234567890ABCDE"
     88         0, 0, 0, 0                                      // Data Size (always 0)
     89     };
     90     Vector<uint8_t> initData;
     91     initData.appendArray(pssh, 52);
     92 
     93     Vector<String8> expectedKeys;
     94     expectedKeys.push(String8("01234567890ABCDE"));
     95 
     96     attemptParseExpectingSuccess(initData, kCencMimeType, expectedKeys);
     97 }
     98 
     99 TEST_F(InitDataParserTest, ParsesMultipleKeyPssh) {
    100     uint8_t pssh[84] = {
    101         0, 0, 0, 84,                                    // Total Size
    102         'p', 's', 's', 'h',                             // PSSH
    103         1, 0, 0, 0,                                     // Version
    104         0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // System ID
    105         0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
    106         0, 0, 0, 3,                                     // Key Count
    107         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // Key ID #1
    108         0x38, 0x39, 0x30, 0x41, 0x42, 0x43, 0x44, 0x45, //   "01234567890ABCDE"
    109         0x43, 0x6c, 0x65, 0x61, 0x72, 0x4b, 0x65, 0x79, // Key ID #2
    110         0x43, 0x6c, 0x65, 0x61, 0x72, 0x4b, 0x65, 0x79, //   "ClearKeyClearKey"
    111         0x20, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x20, // Key ID #3
    112         0x20, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x20, //   " GOOGLE  GOOGLE "
    113         0, 0, 0, 0                                      // Data Size (always 0)
    114     };
    115     Vector<uint8_t> initData;
    116     initData.appendArray(pssh, 84);
    117 
    118     Vector<String8> expectedKeys;
    119     expectedKeys.push(String8("01234567890ABCDE"));
    120     expectedKeys.push(String8("ClearKeyClearKey"));
    121     expectedKeys.push(String8(" GOOGLE  GOOGLE "));
    122 
    123     attemptParseExpectingSuccess(initData, kCencMimeType, expectedKeys);
    124 }
    125 
    126 TEST_F(InitDataParserTest, ParsesWebM) {
    127     uint8_t initDataRaw[16] = {
    128         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // Key ID
    129         0x38, 0x39, 0x30, 0x41, 0x42, 0x43, 0x44, 0x45, //   "01234567890ABCDE"
    130     };
    131     Vector<uint8_t> initData;
    132     initData.appendArray(initDataRaw, 16);
    133 
    134     Vector<String8> expectedKeys;
    135     expectedKeys.push(String8("01234567890ABCDE"));
    136 
    137     attemptParseExpectingSuccess(initData, kWebmMimeType, expectedKeys);
    138 }
    139 
    140 TEST_F(InitDataParserTest, FailsForPsshTooSmall) {
    141     uint8_t pssh[16] = {
    142         0, 0, 0, 52,
    143         'p', 's', 's', 'h',
    144         1, 0, 0, 0,
    145         0x10, 0x77, 0xef, 0xec
    146     };
    147     Vector<uint8_t> initData;
    148     initData.appendArray(pssh, 16);
    149 
    150     attemptParseExpectingFailure(initData, kCencMimeType);
    151 }
    152 
    153 TEST_F(InitDataParserTest, FailsForWebMTooSmall) {
    154     uint8_t initDataRaw[8] = {
    155         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
    156     };
    157     Vector<uint8_t> initData;
    158     initData.appendArray(initDataRaw, 8);
    159 
    160     attemptParseExpectingFailure(initData, kWebmMimeType);
    161 }
    162 
    163 TEST_F(InitDataParserTest, FailsForPsshBadSystemId) {
    164     uint8_t pssh[52] = {
    165         0, 0, 0, 52,                                    // Total Size
    166         'p', 's', 's', 'h',                             // PSSH
    167         1, 0, 0, 0,                                     // Version
    168         0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b, // System ID
    169         0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02,
    170         0, 0, 0, 1,                                     // Key Count
    171         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // Key ID #1
    172         0x38, 0x39, 0x30, 0x41, 0x42, 0x43, 0x44, 0x45, //   "01234567890ABCDE"
    173         0, 0, 0, 0                                      // Data Size (always 0)
    174     };
    175     Vector<uint8_t> initData;
    176     initData.appendArray(pssh, 52);
    177 
    178     attemptParseExpectingFailure(initData, kCencMimeType);
    179 }
    180 
    181 TEST_F(InitDataParserTest, FailsForPsshBadSize) {
    182     uint8_t pssh[52] = {
    183         0, 0, 70, 200,                                  // Total Size
    184         'p', 's', 's', 'h',                             // PSSH
    185         1, 0, 0, 0,                                     // Version
    186         0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // System ID
    187         0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
    188         0, 0, 0, 1,                                     // Key Count
    189         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // Key ID #1
    190         0x38, 0x39, 0x30, 0x41, 0x42, 0x43, 0x44, 0x45, //   "01234567890ABCDE"
    191         0, 0, 0, 0                                      // Data Size (always 0)
    192     };
    193     Vector<uint8_t> initData;
    194     initData.appendArray(pssh, 52);
    195 
    196     attemptParseExpectingFailure(initData, kCencMimeType);
    197 }
    198 
    199 TEST_F(InitDataParserTest, FailsForPsshWrongVersion) {
    200     uint8_t pssh[52] = {
    201         0, 0, 0, 52,                                    // Total Size
    202         'p', 's', 's', 'h',                             // PSSH
    203         0, 0, 0, 0,                                     // Version
    204         0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // System ID
    205         0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
    206         0, 0, 0, 1,                                     // Key Count
    207         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // Key ID #1
    208         0x38, 0x39, 0x30, 0x41, 0x42, 0x43, 0x44, 0x45, //   "01234567890ABCDE"
    209         0, 0, 0, 0                                      // Data Size (always 0)
    210     };
    211     Vector<uint8_t> initData;
    212     initData.appendArray(pssh, 52);
    213 
    214     attemptParseExpectingFailure(initData, kCencMimeType);
    215 }
    216 
    217 TEST_F(InitDataParserTest, FailsForPsshBadKeyCount) {
    218     uint8_t pssh[52] = {
    219         0, 0, 0, 52,                                    // Total Size
    220         'p', 's', 's', 'h',                             // PSSH
    221         1, 0, 0, 0,                                     // Version
    222         0x10, 0x77, 0xef, 0xec, 0xc0, 0xb2, 0x4d, 0x02, // System ID
    223         0xac, 0xe3, 0x3c, 0x1e, 0x52, 0xe2, 0xfb, 0x4b,
    224         0, 0, 0, 7,                                     // Key Count
    225         0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // Key ID #1
    226         0x38, 0x39, 0x30, 0x41, 0x42, 0x43, 0x44, 0x45, //   "01234567890ABCDE"
    227         0, 0, 0, 0                                      // Data Size (always 0)
    228     };
    229     Vector<uint8_t> initData;
    230     initData.appendArray(pssh, 52);
    231 
    232     attemptParseExpectingFailure(initData, kCencMimeType);
    233 }
    234 }  // namespace clearkeydrm
    235