Home | History | Annotate | Download | only in cdm
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <string>
      6 #include <vector>
      7 
      8 #include "base/basictypes.h"
      9 #include "base/bind.h"
     10 #include "base/json/json_reader.h"
     11 #include "base/values.h"
     12 #include "media/base/cdm_promise.h"
     13 #include "media/base/decoder_buffer.h"
     14 #include "media/base/decrypt_config.h"
     15 #include "media/base/mock_filters.h"
     16 #include "media/cdm/aes_decryptor.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 
     20 using ::testing::_;
     21 using ::testing::Gt;
     22 using ::testing::IsNull;
     23 using ::testing::NotNull;
     24 using ::testing::SaveArg;
     25 using ::testing::StrNe;
     26 
     27 MATCHER(IsEmpty, "") { return arg.empty(); }
     28 MATCHER(IsNotEmpty, "") { return !arg.empty(); }
     29 MATCHER(IsJSONDictionary, "") {
     30   std::string result(arg.begin(), arg.end());
     31   scoped_ptr<base::Value> root(base::JSONReader().ReadToValue(result));
     32   return (root.get() && root->GetType() == base::Value::TYPE_DICTIONARY);
     33 }
     34 
     35 class GURL;
     36 
     37 namespace media {
     38 
     39 const uint8 kOriginalData[] = "Original subsample data.";
     40 const int kOriginalDataSize = 24;
     41 
     42 // In the examples below, 'k'(key) has to be 16 bytes, and will always require
     43 // 2 bytes of padding. 'kid'(keyid) is variable length, and may require 0, 1,
     44 // or 2 bytes of padding.
     45 
     46 const uint8 kKeyId[] = {
     47     // base64 equivalent is AAECAw
     48     0x00, 0x01, 0x02, 0x03
     49 };
     50 
     51 // Key is 0x0405060708090a0b0c0d0e0f10111213,
     52 // base64 equivalent is BAUGBwgJCgsMDQ4PEBESEw.
     53 const char kKeyAsJWK[] =
     54     "{"
     55     "  \"keys\": ["
     56     "    {"
     57     "      \"kty\": \"oct\","
     58     "      \"kid\": \"AAECAw\","
     59     "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
     60     "    }"
     61     "  ],"
     62     "  \"type\": \"temporary\""
     63     "}";
     64 
     65 // Same kid as kKeyAsJWK, key to decrypt kEncryptedData2
     66 const char kKeyAlternateAsJWK[] =
     67     "{"
     68     "  \"keys\": ["
     69     "    {"
     70     "      \"kty\": \"oct\","
     71     "      \"kid\": \"AAECAw\","
     72     "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
     73     "    }"
     74     "  ]"
     75     "}";
     76 
     77 const char kWrongKeyAsJWK[] =
     78     "{"
     79     "  \"keys\": ["
     80     "    {"
     81     "      \"kty\": \"oct\","
     82     "      \"kid\": \"AAECAw\","
     83     "      \"k\": \"7u7u7u7u7u7u7u7u7u7u7g\""
     84     "    }"
     85     "  ]"
     86     "}";
     87 
     88 const char kWrongSizedKeyAsJWK[] =
     89     "{"
     90     "  \"keys\": ["
     91     "    {"
     92     "      \"kty\": \"oct\","
     93     "      \"kid\": \"AAECAw\","
     94     "      \"k\": \"AAECAw\""
     95     "    }"
     96     "  ]"
     97     "}";
     98 
     99 const uint8 kIv[] = {
    100   0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    101   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    102 };
    103 
    104 // kOriginalData encrypted with kKey and kIv but without any subsamples (or
    105 // equivalently using kSubsampleEntriesCypherOnly).
    106 const uint8 kEncryptedData[] = {
    107   0x2f, 0x03, 0x09, 0xef, 0x71, 0xaf, 0x31, 0x16,
    108   0xfa, 0x9d, 0x18, 0x43, 0x1e, 0x96, 0x71, 0xb5,
    109   0xbf, 0xf5, 0x30, 0x53, 0x9a, 0x20, 0xdf, 0x95
    110 };
    111 
    112 // kOriginalData encrypted with kSubsampleKey and kSubsampleIv using
    113 // kSubsampleEntriesNormal.
    114 const uint8 kSubsampleEncryptedData[] = {
    115   0x4f, 0x72, 0x09, 0x16, 0x09, 0xe6, 0x79, 0xad,
    116   0x70, 0x73, 0x75, 0x62, 0x09, 0xbb, 0x83, 0x1d,
    117   0x4d, 0x08, 0xd7, 0x78, 0xa4, 0xa7, 0xf1, 0x2e
    118 };
    119 
    120 const uint8 kOriginalData2[] = "Changed Original data.";
    121 
    122 const uint8 kIv2[] = {
    123   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    124   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    125 };
    126 
    127 const uint8 kKeyId2[] = {
    128     // base64 equivalent is AAECAwQFBgcICQoLDA0ODxAREhM=
    129     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    130     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    131     0x10, 0x11, 0x12, 0x13
    132 };
    133 
    134 const char kKey2AsJWK[] =
    135     "{"
    136     "  \"keys\": ["
    137     "    {"
    138     "      \"kty\": \"oct\","
    139     "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
    140     "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
    141     "    }"
    142     "  ]"
    143     "}";
    144 
    145 // 'k' in bytes is x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20x21x22x23
    146 
    147 const uint8 kEncryptedData2[] = {
    148   0x57, 0x66, 0xf4, 0x12, 0x1a, 0xed, 0xb5, 0x79,
    149   0x1c, 0x8e, 0x25, 0xd7, 0x17, 0xe7, 0x5e, 0x16,
    150   0xe3, 0x40, 0x08, 0x27, 0x11, 0xe9
    151 };
    152 
    153 // Subsample entries for testing. The sum of |cypher_bytes| and |clear_bytes| of
    154 // all entries must be equal to kOriginalDataSize to make the subsample entries
    155 // valid.
    156 
    157 const SubsampleEntry kSubsampleEntriesNormal[] = {
    158   { 2, 7 },
    159   { 3, 11 },
    160   { 1, 0 }
    161 };
    162 
    163 const SubsampleEntry kSubsampleEntriesWrongSize[] = {
    164   { 3, 6 }, // This entry doesn't match the correct entry.
    165   { 3, 11 },
    166   { 1, 0 }
    167 };
    168 
    169 const SubsampleEntry kSubsampleEntriesInvalidTotalSize[] = {
    170   { 1, 1000 }, // This entry is too large.
    171   { 3, 11 },
    172   { 1, 0 }
    173 };
    174 
    175 const SubsampleEntry kSubsampleEntriesClearOnly[] = {
    176   { 7, 0 },
    177   { 8, 0 },
    178   { 9, 0 }
    179 };
    180 
    181 const SubsampleEntry kSubsampleEntriesCypherOnly[] = {
    182   { 0, 6 },
    183   { 0, 8 },
    184   { 0, 10 }
    185 };
    186 
    187 static scoped_refptr<DecoderBuffer> CreateEncryptedBuffer(
    188     const std::vector<uint8>& data,
    189     const std::vector<uint8>& key_id,
    190     const std::vector<uint8>& iv,
    191     const std::vector<SubsampleEntry>& subsample_entries) {
    192   DCHECK(!data.empty());
    193   scoped_refptr<DecoderBuffer> encrypted_buffer(new DecoderBuffer(data.size()));
    194   memcpy(encrypted_buffer->writable_data(), &data[0], data.size());
    195   CHECK(encrypted_buffer.get());
    196   std::string key_id_string(
    197       reinterpret_cast<const char*>(key_id.empty() ? NULL : &key_id[0]),
    198       key_id.size());
    199   std::string iv_string(
    200       reinterpret_cast<const char*>(iv.empty() ? NULL : &iv[0]), iv.size());
    201   encrypted_buffer->set_decrypt_config(scoped_ptr<DecryptConfig>(
    202       new DecryptConfig(key_id_string, iv_string, subsample_entries)));
    203   return encrypted_buffer;
    204 }
    205 
    206 enum PromiseResult { RESOLVED, REJECTED };
    207 
    208 class AesDecryptorTest : public testing::Test {
    209  public:
    210   AesDecryptorTest()
    211       : decryptor_(base::Bind(&AesDecryptorTest::OnSessionMessage,
    212                               base::Unretained(this)),
    213                    base::Bind(&AesDecryptorTest::OnSessionClosed,
    214                               base::Unretained(this)),
    215                    base::Bind(&AesDecryptorTest::OnSessionKeysChange,
    216                               base::Unretained(this))),
    217         decrypt_cb_(base::Bind(&AesDecryptorTest::BufferDecrypted,
    218                                base::Unretained(this))),
    219         original_data_(kOriginalData, kOriginalData + kOriginalDataSize),
    220         encrypted_data_(kEncryptedData,
    221                         kEncryptedData + arraysize(kEncryptedData)),
    222         subsample_encrypted_data_(
    223             kSubsampleEncryptedData,
    224             kSubsampleEncryptedData + arraysize(kSubsampleEncryptedData)),
    225         key_id_(kKeyId, kKeyId + arraysize(kKeyId)),
    226         iv_(kIv, kIv + arraysize(kIv)),
    227         normal_subsample_entries_(
    228             kSubsampleEntriesNormal,
    229             kSubsampleEntriesNormal + arraysize(kSubsampleEntriesNormal)) {
    230   }
    231 
    232  protected:
    233   void OnResolveWithSession(PromiseResult expected_result,
    234                             const std::string& web_session_id) {
    235     EXPECT_EQ(expected_result, RESOLVED) << "Unexpectedly resolved.";
    236     EXPECT_GT(web_session_id.length(), 0ul);
    237     web_session_id_ = web_session_id;
    238   }
    239 
    240   void OnResolve(PromiseResult expected_result) {
    241     EXPECT_EQ(expected_result, RESOLVED) << "Unexpectedly resolved.";
    242   }
    243 
    244   void OnResolveWithUsableKeyIds(PromiseResult expected_result,
    245                                  uint32 expected_count,
    246                                  const KeyIdsVector& useable_key_ids) {
    247     EXPECT_EQ(expected_result, RESOLVED) << "Unexpectedly resolved.";
    248     EXPECT_EQ(expected_count, useable_key_ids.size());
    249     useable_key_ids_ = useable_key_ids;
    250   }
    251 
    252   void OnReject(PromiseResult expected_result,
    253                 MediaKeys::Exception exception_code,
    254                 uint32 system_code,
    255                 const std::string& error_message) {
    256     EXPECT_EQ(expected_result, REJECTED) << "Unexpectedly rejected.";
    257   }
    258 
    259   scoped_ptr<SimpleCdmPromise> CreatePromise(PromiseResult expected_result) {
    260     scoped_ptr<SimpleCdmPromise> promise(
    261         new SimpleCdmPromise(base::Bind(&AesDecryptorTest::OnResolve,
    262                                         base::Unretained(this),
    263                                         expected_result),
    264                              base::Bind(&AesDecryptorTest::OnReject,
    265                                         base::Unretained(this),
    266                                         expected_result)));
    267     return promise.Pass();
    268   }
    269 
    270   scoped_ptr<NewSessionCdmPromise> CreateSessionPromise(
    271       PromiseResult expected_result) {
    272     scoped_ptr<NewSessionCdmPromise> promise(new NewSessionCdmPromise(
    273         base::Bind(&AesDecryptorTest::OnResolveWithSession,
    274                    base::Unretained(this),
    275                    expected_result),
    276         base::Bind(&AesDecryptorTest::OnReject,
    277                    base::Unretained(this),
    278                    expected_result)));
    279     return promise.Pass();
    280   }
    281 
    282   scoped_ptr<KeyIdsPromise> CreateUsableKeyIdsPromise(
    283       PromiseResult expected_result,
    284       uint32 expected_count) {
    285     scoped_ptr<KeyIdsPromise> promise(new KeyIdsPromise(
    286         base::Bind(&AesDecryptorTest::OnResolveWithUsableKeyIds,
    287                    base::Unretained(this),
    288                    expected_result,
    289                    expected_count),
    290         base::Bind(&AesDecryptorTest::OnReject,
    291                    base::Unretained(this),
    292                    expected_result)));
    293     return promise.Pass();
    294   }
    295 
    296   // Creates a new session using |key_id|. Returns the session ID.
    297   std::string CreateSession(const std::vector<uint8>& key_id) {
    298     DCHECK(!key_id.empty());
    299     EXPECT_CALL(*this,
    300                 OnSessionMessage(
    301                     IsNotEmpty(), IsJSONDictionary(), GURL::EmptyGURL()));
    302     decryptor_.CreateSession(std::string(),
    303                              &key_id[0],
    304                              key_id.size(),
    305                              MediaKeys::TEMPORARY_SESSION,
    306                              CreateSessionPromise(RESOLVED));
    307     // This expects the promise to be called synchronously, which is the case
    308     // for AesDecryptor.
    309     return web_session_id_;
    310   }
    311 
    312   // Closes the session specified by |session_id|.
    313   void CloseSession(const std::string& session_id) {
    314     EXPECT_CALL(*this, OnSessionClosed(session_id));
    315     decryptor_.CloseSession(session_id, CreatePromise(RESOLVED));
    316   }
    317 
    318   // Removes the session specified by |session_id|. This should simply do a
    319   // CloseSession().
    320   // TODO(jrummell): Clean this up when the prefixed API is removed.
    321   // http://crbug.com/249976.
    322   void RemoveSession(const std::string& session_id) {
    323     EXPECT_CALL(*this, OnSessionClosed(session_id));
    324     decryptor_.RemoveSession(session_id, CreatePromise(RESOLVED));
    325   }
    326 
    327   // Updates the session specified by |session_id| with |key|. |result|
    328   // tests that the update succeeds or generates an error.
    329   void UpdateSessionAndExpect(std::string session_id,
    330                               const std::string& key,
    331                               PromiseResult expected_result) {
    332     DCHECK(!key.empty());
    333 
    334     if (expected_result == RESOLVED) {
    335       EXPECT_CALL(*this, OnSessionKeysChange(session_id, true));
    336     } else {
    337       EXPECT_CALL(*this, OnSessionKeysChange(_, _)).Times(0);
    338     }
    339 
    340     decryptor_.UpdateSession(session_id,
    341                              reinterpret_cast<const uint8*>(key.c_str()),
    342                              key.length(),
    343                              CreatePromise(expected_result));
    344   }
    345 
    346   void GetUsableKeyIdsAndExpect(const std::string& session_id,
    347                                 PromiseResult expected_result,
    348                                 uint32 expected_count) {
    349     decryptor_.GetUsableKeyIds(
    350         session_id, CreateUsableKeyIdsPromise(expected_result, expected_count));
    351   }
    352 
    353   bool UsableKeyIdsContains(std::vector<uint8> expected) {
    354     for (KeyIdsVector::iterator it = useable_key_ids_.begin();
    355          it != useable_key_ids_.end();
    356          ++it) {
    357       if (*it == expected)
    358         return true;
    359     }
    360     return false;
    361   }
    362 
    363   MOCK_METHOD2(BufferDecrypted, void(Decryptor::Status,
    364                                      const scoped_refptr<DecoderBuffer>&));
    365 
    366   enum DecryptExpectation {
    367     SUCCESS,
    368     DATA_MISMATCH,
    369     DATA_AND_SIZE_MISMATCH,
    370     DECRYPT_ERROR,
    371     NO_KEY
    372   };
    373 
    374   void DecryptAndExpect(const scoped_refptr<DecoderBuffer>& encrypted,
    375                         const std::vector<uint8>& plain_text,
    376                         DecryptExpectation result) {
    377     scoped_refptr<DecoderBuffer> decrypted;
    378 
    379     switch (result) {
    380       case SUCCESS:
    381       case DATA_MISMATCH:
    382       case DATA_AND_SIZE_MISMATCH:
    383         EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, NotNull()))
    384             .WillOnce(SaveArg<1>(&decrypted));
    385         break;
    386       case DECRYPT_ERROR:
    387         EXPECT_CALL(*this, BufferDecrypted(Decryptor::kError, IsNull()))
    388             .WillOnce(SaveArg<1>(&decrypted));
    389         break;
    390       case NO_KEY:
    391         EXPECT_CALL(*this, BufferDecrypted(Decryptor::kNoKey, IsNull()))
    392             .WillOnce(SaveArg<1>(&decrypted));
    393         break;
    394     }
    395 
    396     decryptor_.Decrypt(Decryptor::kVideo, encrypted, decrypt_cb_);
    397 
    398     std::vector<uint8> decrypted_text;
    399     if (decrypted.get() && decrypted->data_size()) {
    400       decrypted_text.assign(
    401         decrypted->data(), decrypted->data() + decrypted->data_size());
    402     }
    403 
    404     switch (result) {
    405       case SUCCESS:
    406         EXPECT_EQ(plain_text, decrypted_text);
    407         break;
    408       case DATA_MISMATCH:
    409         EXPECT_EQ(plain_text.size(), decrypted_text.size());
    410         EXPECT_NE(plain_text, decrypted_text);
    411         break;
    412       case DATA_AND_SIZE_MISMATCH:
    413         EXPECT_NE(plain_text.size(), decrypted_text.size());
    414         break;
    415       case DECRYPT_ERROR:
    416       case NO_KEY:
    417         EXPECT_TRUE(decrypted_text.empty());
    418         break;
    419     }
    420   }
    421 
    422   MOCK_METHOD3(OnSessionMessage,
    423                void(const std::string& web_session_id,
    424                     const std::vector<uint8>& message,
    425                     const GURL& destination_url));
    426   MOCK_METHOD2(OnSessionKeysChange,
    427                void(const std::string& web_session_id,
    428                     bool has_additional_usable_key));
    429   MOCK_METHOD1(OnSessionClosed, void(const std::string& web_session_id));
    430 
    431   AesDecryptor decryptor_;
    432   AesDecryptor::DecryptCB decrypt_cb_;
    433   std::string web_session_id_;
    434 
    435   // Copy of the vector from the last successful call to
    436   // OnResolveWithUsableKeyIds().
    437   KeyIdsVector useable_key_ids_;
    438 
    439   // Constants for testing.
    440   const std::vector<uint8> original_data_;
    441   const std::vector<uint8> encrypted_data_;
    442   const std::vector<uint8> subsample_encrypted_data_;
    443   const std::vector<uint8> key_id_;
    444   const std::vector<uint8> iv_;
    445   const std::vector<SubsampleEntry> normal_subsample_entries_;
    446   const std::vector<SubsampleEntry> no_subsample_entries_;
    447 };
    448 
    449 TEST_F(AesDecryptorTest, CreateSessionWithNullInitData) {
    450   EXPECT_CALL(*this,
    451               OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
    452   decryptor_.CreateSession(std::string(),
    453                            NULL,
    454                            0,
    455                            MediaKeys::TEMPORARY_SESSION,
    456                            CreateSessionPromise(RESOLVED));
    457 }
    458 
    459 TEST_F(AesDecryptorTest, MultipleCreateSession) {
    460   EXPECT_CALL(*this,
    461               OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
    462   decryptor_.CreateSession(std::string(),
    463                            NULL,
    464                            0,
    465                            MediaKeys::TEMPORARY_SESSION,
    466                            CreateSessionPromise(RESOLVED));
    467 
    468   EXPECT_CALL(*this,
    469               OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
    470   decryptor_.CreateSession(std::string(),
    471                            NULL,
    472                            0,
    473                            MediaKeys::TEMPORARY_SESSION,
    474                            CreateSessionPromise(RESOLVED));
    475 
    476   EXPECT_CALL(*this,
    477               OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
    478   decryptor_.CreateSession(std::string(),
    479                            NULL,
    480                            0,
    481                            MediaKeys::TEMPORARY_SESSION,
    482                            CreateSessionPromise(RESOLVED));
    483 }
    484 
    485 TEST_F(AesDecryptorTest, NormalDecryption) {
    486   std::string session_id = CreateSession(key_id_);
    487   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    488   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    489       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    490   DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
    491 }
    492 
    493 TEST_F(AesDecryptorTest, UnencryptedFrame) {
    494   // An empty iv string signals that the frame is unencrypted.
    495   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    496       original_data_, key_id_, std::vector<uint8>(), no_subsample_entries_);
    497   DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
    498 }
    499 
    500 TEST_F(AesDecryptorTest, WrongKey) {
    501   std::string session_id = CreateSession(key_id_);
    502   UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, RESOLVED);
    503   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    504       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    505   DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
    506 }
    507 
    508 TEST_F(AesDecryptorTest, NoKey) {
    509   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    510       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    511   EXPECT_CALL(*this, BufferDecrypted(AesDecryptor::kNoKey, IsNull()));
    512   decryptor_.Decrypt(Decryptor::kVideo, encrypted_buffer, decrypt_cb_);
    513 }
    514 
    515 TEST_F(AesDecryptorTest, KeyReplacement) {
    516   std::string session_id = CreateSession(key_id_);
    517   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    518       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    519 
    520   UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, RESOLVED);
    521   ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
    522       encrypted_buffer, original_data_, DATA_MISMATCH));
    523 
    524   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    525   ASSERT_NO_FATAL_FAILURE(
    526       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    527 }
    528 
    529 TEST_F(AesDecryptorTest, WrongSizedKey) {
    530   std::string session_id = CreateSession(key_id_);
    531   UpdateSessionAndExpect(session_id, kWrongSizedKeyAsJWK, REJECTED);
    532 }
    533 
    534 TEST_F(AesDecryptorTest, MultipleKeysAndFrames) {
    535   std::string session_id = CreateSession(key_id_);
    536   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    537   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    538       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    539   ASSERT_NO_FATAL_FAILURE(
    540       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    541 
    542   UpdateSessionAndExpect(session_id, kKey2AsJWK, RESOLVED);
    543 
    544   // The first key is still available after we added a second key.
    545   ASSERT_NO_FATAL_FAILURE(
    546       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    547 
    548   // The second key is also available.
    549   encrypted_buffer = CreateEncryptedBuffer(
    550       std::vector<uint8>(kEncryptedData2,
    551                          kEncryptedData2 + arraysize(kEncryptedData2)),
    552       std::vector<uint8>(kKeyId2, kKeyId2 + arraysize(kKeyId2)),
    553       std::vector<uint8>(kIv2, kIv2 + arraysize(kIv2)),
    554       no_subsample_entries_);
    555   ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
    556       encrypted_buffer,
    557       std::vector<uint8>(kOriginalData2,
    558                          kOriginalData2 + arraysize(kOriginalData2) - 1),
    559       SUCCESS));
    560 }
    561 
    562 TEST_F(AesDecryptorTest, CorruptedIv) {
    563   std::string session_id = CreateSession(key_id_);
    564   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    565 
    566   std::vector<uint8> bad_iv = iv_;
    567   bad_iv[1]++;
    568 
    569   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    570       encrypted_data_, key_id_, bad_iv, no_subsample_entries_);
    571 
    572   DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
    573 }
    574 
    575 TEST_F(AesDecryptorTest, CorruptedData) {
    576   std::string session_id = CreateSession(key_id_);
    577   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    578 
    579   std::vector<uint8> bad_data = encrypted_data_;
    580   bad_data[1]++;
    581 
    582   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    583       bad_data, key_id_, iv_, no_subsample_entries_);
    584   DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
    585 }
    586 
    587 TEST_F(AesDecryptorTest, EncryptedAsUnencryptedFailure) {
    588   std::string session_id = CreateSession(key_id_);
    589   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    590   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    591       encrypted_data_, key_id_, std::vector<uint8>(), no_subsample_entries_);
    592   DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
    593 }
    594 
    595 TEST_F(AesDecryptorTest, SubsampleDecryption) {
    596   std::string session_id = CreateSession(key_id_);
    597   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    598   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    599       subsample_encrypted_data_, key_id_, iv_, normal_subsample_entries_);
    600   DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
    601 }
    602 
    603 // Ensures noninterference of data offset and subsample mechanisms. We never
    604 // expect to encounter this in the wild, but since the DecryptConfig doesn't
    605 // disallow such a configuration, it should be covered.
    606 TEST_F(AesDecryptorTest, SubsampleDecryptionWithOffset) {
    607   std::string session_id = CreateSession(key_id_);
    608   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    609   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    610       subsample_encrypted_data_, key_id_, iv_, normal_subsample_entries_);
    611   DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
    612 }
    613 
    614 TEST_F(AesDecryptorTest, SubsampleWrongSize) {
    615   std::string session_id = CreateSession(key_id_);
    616   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    617 
    618   std::vector<SubsampleEntry> subsample_entries_wrong_size(
    619       kSubsampleEntriesWrongSize,
    620       kSubsampleEntriesWrongSize + arraysize(kSubsampleEntriesWrongSize));
    621 
    622   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    623       subsample_encrypted_data_, key_id_, iv_, subsample_entries_wrong_size);
    624   DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
    625 }
    626 
    627 TEST_F(AesDecryptorTest, SubsampleInvalidTotalSize) {
    628   std::string session_id = CreateSession(key_id_);
    629   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    630 
    631   std::vector<SubsampleEntry> subsample_entries_invalid_total_size(
    632       kSubsampleEntriesInvalidTotalSize,
    633       kSubsampleEntriesInvalidTotalSize +
    634           arraysize(kSubsampleEntriesInvalidTotalSize));
    635 
    636   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    637       subsample_encrypted_data_, key_id_, iv_,
    638       subsample_entries_invalid_total_size);
    639   DecryptAndExpect(encrypted_buffer, original_data_, DECRYPT_ERROR);
    640 }
    641 
    642 // No cypher bytes in any of the subsamples.
    643 TEST_F(AesDecryptorTest, SubsampleClearBytesOnly) {
    644   std::string session_id = CreateSession(key_id_);
    645   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    646 
    647   std::vector<SubsampleEntry> clear_only_subsample_entries(
    648       kSubsampleEntriesClearOnly,
    649       kSubsampleEntriesClearOnly + arraysize(kSubsampleEntriesClearOnly));
    650 
    651   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    652       original_data_, key_id_, iv_, clear_only_subsample_entries);
    653   DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
    654 }
    655 
    656 // No clear bytes in any of the subsamples.
    657 TEST_F(AesDecryptorTest, SubsampleCypherBytesOnly) {
    658   std::string session_id = CreateSession(key_id_);
    659   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    660 
    661   std::vector<SubsampleEntry> cypher_only_subsample_entries(
    662       kSubsampleEntriesCypherOnly,
    663       kSubsampleEntriesCypherOnly + arraysize(kSubsampleEntriesCypherOnly));
    664 
    665   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    666       encrypted_data_, key_id_, iv_, cypher_only_subsample_entries);
    667   DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
    668 }
    669 
    670 TEST_F(AesDecryptorTest, CloseSession) {
    671   std::string session_id = CreateSession(key_id_);
    672   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    673       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    674 
    675   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    676   ASSERT_NO_FATAL_FAILURE(
    677       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    678 
    679   CloseSession(session_id);
    680 }
    681 
    682 TEST_F(AesDecryptorTest, RemoveSession) {
    683   // TODO(jrummell): Clean this up when the prefixed API is removed.
    684   // http://crbug.com/249976.
    685   std::string session_id = CreateSession(key_id_);
    686   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    687       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    688 
    689   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    690   ASSERT_NO_FATAL_FAILURE(
    691       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    692 
    693   RemoveSession(session_id);
    694 }
    695 
    696 TEST_F(AesDecryptorTest, NoKeyAfterCloseSession) {
    697   std::string session_id = CreateSession(key_id_);
    698   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    699       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    700 
    701   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    702   ASSERT_NO_FATAL_FAILURE(
    703       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    704 
    705   CloseSession(session_id);
    706   ASSERT_NO_FATAL_FAILURE(
    707       DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY));
    708 }
    709 
    710 TEST_F(AesDecryptorTest, LatestKeyUsed) {
    711   std::string session_id1 = CreateSession(key_id_);
    712   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    713       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    714 
    715   // Add alternate key, buffer should not be decoded properly.
    716   UpdateSessionAndExpect(session_id1, kKeyAlternateAsJWK, RESOLVED);
    717   ASSERT_NO_FATAL_FAILURE(
    718       DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
    719 
    720   // Create a second session with a correct key value for key_id_.
    721   std::string session_id2 = CreateSession(key_id_);
    722   UpdateSessionAndExpect(session_id2, kKeyAsJWK, RESOLVED);
    723 
    724   // Should be able to decode with latest key.
    725   ASSERT_NO_FATAL_FAILURE(
    726       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    727 }
    728 
    729 TEST_F(AesDecryptorTest, LatestKeyUsedAfterCloseSession) {
    730   std::string session_id1 = CreateSession(key_id_);
    731   scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
    732       encrypted_data_, key_id_, iv_, no_subsample_entries_);
    733   UpdateSessionAndExpect(session_id1, kKeyAsJWK, RESOLVED);
    734   ASSERT_NO_FATAL_FAILURE(
    735       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    736 
    737   // Create a second session with a different key value for key_id_.
    738   std::string session_id2 = CreateSession(key_id_);
    739   UpdateSessionAndExpect(session_id2, kKeyAlternateAsJWK, RESOLVED);
    740 
    741   // Should not be able to decode with new key.
    742   ASSERT_NO_FATAL_FAILURE(
    743       DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
    744 
    745   // Close second session, should revert to original key.
    746   CloseSession(session_id2);
    747   ASSERT_NO_FATAL_FAILURE(
    748       DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
    749 }
    750 
    751 TEST_F(AesDecryptorTest, JWKKey) {
    752   std::string session_id = CreateSession(key_id_);
    753 
    754   // Try a simple JWK key (i.e. not in a set)
    755   const std::string kJwkSimple =
    756       "{"
    757       "  \"kty\": \"oct\","
    758       "  \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
    759       "  \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
    760       "}";
    761   UpdateSessionAndExpect(session_id, kJwkSimple, REJECTED);
    762 
    763   // Try a key list with multiple entries.
    764   const std::string kJwksMultipleEntries =
    765       "{"
    766       "  \"keys\": ["
    767       "    {"
    768       "      \"kty\": \"oct\","
    769       "      \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
    770       "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
    771       "    },"
    772       "    {"
    773       "      \"kty\": \"oct\","
    774       "      \"kid\": \"JCUmJygpKissLS4vMA\","
    775       "      \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
    776       "    }"
    777       "  ]"
    778       "}";
    779   UpdateSessionAndExpect(session_id, kJwksMultipleEntries, RESOLVED);
    780 
    781   // Try a key with no spaces and some \n plus additional fields.
    782   const std::string kJwksNoSpaces =
    783       "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
    784       "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
    785       "\",\"foo\":\"bar\"}]}\n\n";
    786   UpdateSessionAndExpect(session_id, kJwksNoSpaces, RESOLVED);
    787 
    788   // Try some non-ASCII characters.
    789   UpdateSessionAndExpect(
    790       session_id, "This is not ASCII due to \xff\xfe\xfd in it.", REJECTED);
    791 
    792   // Try a badly formatted key. Assume that the JSON parser is fully tested,
    793   // so we won't try a lot of combinations. However, need a test to ensure
    794   // that the code doesn't crash if invalid JSON received.
    795   UpdateSessionAndExpect(session_id, "This is not a JSON key.", REJECTED);
    796 
    797   // Try passing some valid JSON that is not a dictionary at the top level.
    798   UpdateSessionAndExpect(session_id, "40", REJECTED);
    799 
    800   // Try an empty dictionary.
    801   UpdateSessionAndExpect(session_id, "{ }", REJECTED);
    802 
    803   // Try an empty 'keys' dictionary.
    804   UpdateSessionAndExpect(session_id, "{ \"keys\": [] }", REJECTED);
    805 
    806   // Try with 'keys' not a dictionary.
    807   UpdateSessionAndExpect(session_id, "{ \"keys\":\"1\" }", REJECTED);
    808 
    809   // Try with 'keys' a list of integers.
    810   UpdateSessionAndExpect(session_id, "{ \"keys\": [ 1, 2, 3 ] }", REJECTED);
    811 
    812   // Try padding(=) at end of 'k' base64 string.
    813   const std::string kJwksWithPaddedKey =
    814       "{"
    815       "  \"keys\": ["
    816       "    {"
    817       "      \"kty\": \"oct\","
    818       "      \"kid\": \"AAECAw\","
    819       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
    820       "    }"
    821       "  ]"
    822       "}";
    823   UpdateSessionAndExpect(session_id, kJwksWithPaddedKey, REJECTED);
    824 
    825   // Try padding(=) at end of 'kid' base64 string.
    826   const std::string kJwksWithPaddedKeyId =
    827       "{"
    828       "  \"keys\": ["
    829       "    {"
    830       "      \"kty\": \"oct\","
    831       "      \"kid\": \"AAECAw==\","
    832       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
    833       "    }"
    834       "  ]"
    835       "}";
    836   UpdateSessionAndExpect(session_id, kJwksWithPaddedKeyId, REJECTED);
    837 
    838   // Try a key with invalid base64 encoding.
    839   const std::string kJwksWithInvalidBase64 =
    840       "{"
    841       "  \"keys\": ["
    842       "    {"
    843       "      \"kty\": \"oct\","
    844       "      \"kid\": \"!@#$%^&*()\","
    845       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
    846       "    }"
    847       "  ]"
    848       "}";
    849   UpdateSessionAndExpect(session_id, kJwksWithInvalidBase64, REJECTED);
    850 
    851   // Try a 3-byte 'kid' where no base64 padding is required.
    852   // |kJwksMultipleEntries| above has 2 'kid's that require 1 and 2 padding
    853   // bytes. Note that 'k' has to be 16 bytes, so it will always require padding.
    854   const std::string kJwksWithNoPadding =
    855       "{"
    856       "  \"keys\": ["
    857       "    {"
    858       "      \"kty\": \"oct\","
    859       "      \"kid\": \"Kiss\","
    860       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
    861       "    }"
    862       "  ]"
    863       "}";
    864   UpdateSessionAndExpect(session_id, kJwksWithNoPadding, RESOLVED);
    865 
    866   // Empty key id.
    867   const std::string kJwksWithEmptyKeyId =
    868       "{"
    869       "  \"keys\": ["
    870       "    {"
    871       "      \"kty\": \"oct\","
    872       "      \"kid\": \"\","
    873       "      \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
    874       "    }"
    875       "  ]"
    876       "}";
    877   UpdateSessionAndExpect(session_id, kJwksWithEmptyKeyId, REJECTED);
    878   CloseSession(session_id);
    879 }
    880 
    881 TEST_F(AesDecryptorTest, GetKeyIds) {
    882   std::vector<uint8> key_id1(kKeyId, kKeyId + arraysize(kKeyId));
    883   std::vector<uint8> key_id2(kKeyId2, kKeyId2 + arraysize(kKeyId2));
    884 
    885   std::string session_id = CreateSession(key_id_);
    886   GetUsableKeyIdsAndExpect(session_id, RESOLVED, 0);
    887   EXPECT_FALSE(UsableKeyIdsContains(key_id1));
    888   EXPECT_FALSE(UsableKeyIdsContains(key_id2));
    889 
    890   // Add 1 key, verify ID is returned.
    891   UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
    892   GetUsableKeyIdsAndExpect(session_id, RESOLVED, 1);
    893   EXPECT_TRUE(UsableKeyIdsContains(key_id1));
    894   EXPECT_FALSE(UsableKeyIdsContains(key_id2));
    895 
    896   // Add second key, verify both IDs returned.
    897   UpdateSessionAndExpect(session_id, kKey2AsJWK, RESOLVED);
    898   GetUsableKeyIdsAndExpect(session_id, RESOLVED, 2);
    899   EXPECT_TRUE(UsableKeyIdsContains(key_id1));
    900   EXPECT_TRUE(UsableKeyIdsContains(key_id2));
    901 }
    902 
    903 }  // namespace media
    904