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