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
20using ::testing::_;
21using ::testing::Gt;
22using ::testing::IsNull;
23using ::testing::NotNull;
24using ::testing::SaveArg;
25using ::testing::StrNe;
26
27MATCHER(IsEmpty, "") { return arg.empty(); }
28MATCHER(IsNotEmpty, "") { return !arg.empty(); }
29MATCHER(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
35class GURL;
36
37namespace media {
38
39const uint8 kOriginalData[] = "Original subsample data.";
40const 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
46const uint8 kKeyId[] = {
47    // base64 equivalent is AAECAw
48    0x00, 0x01, 0x02, 0x03
49};
50
51// Key is 0x0405060708090a0b0c0d0e0f10111213,
52// base64 equivalent is BAUGBwgJCgsMDQ4PEBESEw.
53const 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
66const char kKeyAlternateAsJWK[] =
67    "{"
68    "  \"keys\": ["
69    "    {"
70    "      \"kty\": \"oct\","
71    "      \"kid\": \"AAECAw\","
72    "      \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
73    "    }"
74    "  ]"
75    "}";
76
77const char kWrongKeyAsJWK[] =
78    "{"
79    "  \"keys\": ["
80    "    {"
81    "      \"kty\": \"oct\","
82    "      \"kid\": \"AAECAw\","
83    "      \"k\": \"7u7u7u7u7u7u7u7u7u7u7g\""
84    "    }"
85    "  ]"
86    "}";
87
88const char kWrongSizedKeyAsJWK[] =
89    "{"
90    "  \"keys\": ["
91    "    {"
92    "      \"kty\": \"oct\","
93    "      \"kid\": \"AAECAw\","
94    "      \"k\": \"AAECAw\""
95    "    }"
96    "  ]"
97    "}";
98
99const 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).
106const 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.
114const 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
120const uint8 kOriginalData2[] = "Changed Original data.";
121
122const uint8 kIv2[] = {
123  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
125};
126
127const 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
134const 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
147const 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
157const SubsampleEntry kSubsampleEntriesNormal[] = {
158  { 2, 7 },
159  { 3, 11 },
160  { 1, 0 }
161};
162
163const SubsampleEntry kSubsampleEntriesWrongSize[] = {
164  { 3, 6 }, // This entry doesn't match the correct entry.
165  { 3, 11 },
166  { 1, 0 }
167};
168
169const SubsampleEntry kSubsampleEntriesInvalidTotalSize[] = {
170  { 1, 1000 }, // This entry is too large.
171  { 3, 11 },
172  { 1, 0 }
173};
174
175const SubsampleEntry kSubsampleEntriesClearOnly[] = {
176  { 7, 0 },
177  { 8, 0 },
178  { 9, 0 }
179};
180
181const SubsampleEntry kSubsampleEntriesCypherOnly[] = {
182  { 0, 6 },
183  { 0, 8 },
184  { 0, 10 }
185};
186
187static 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
206enum PromiseResult { RESOLVED, REJECTED };
207
208class 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
449TEST_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
459TEST_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
485TEST_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
493TEST_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
500TEST_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
508TEST_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
515TEST_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
529TEST_F(AesDecryptorTest, WrongSizedKey) {
530  std::string session_id = CreateSession(key_id_);
531  UpdateSessionAndExpect(session_id, kWrongSizedKeyAsJWK, REJECTED);
532}
533
534TEST_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
562TEST_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
575TEST_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
587TEST_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
595TEST_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.
606TEST_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
614TEST_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
627TEST_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.
643TEST_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.
657TEST_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
670TEST_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
682TEST_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
696TEST_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
710TEST_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
729TEST_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
751TEST_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
881TEST_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