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.
8 #include "base/basictypes.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"
20 using ::testing::IsNull;
21 using ::testing::NotNull;
22 using ::testing::SaveArg;
23 using ::testing::StrNe;
25 MATCHER(IsEmpty, "") { return arg.empty(); }
26 MATCHER(IsNotEmpty, "") { return !arg.empty(); }
32 const uint8 kOriginalData[] = "Original subsample data.";
33 const int kOriginalDataSize = 24;
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.
39 const uint8 kKeyId[] = {
40 // base64 equivalent is AAECAw
41 0x00, 0x01, 0x02, 0x03
44 // Key is 0x0405060708090a0b0c0d0e0f10111213,
45 // base64 equivalent is BAUGBwgJCgsMDQ4PEBESEw.
46 const char kKeyAsJWK[] =
51 " \"kid\": \"AAECAw\","
52 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
57 // Same kid as kKeyAsJWK, key to decrypt kEncryptedData2
58 const char kKeyAlternateAsJWK[] =
63 " \"kid\": \"AAECAw\","
64 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
69 const char kWrongKeyAsJWK[] =
74 " \"kid\": \"AAECAw\","
75 " \"k\": \"7u7u7u7u7u7u7u7u7u7u7g\""
80 const char kWrongSizedKeyAsJWK[] =
85 " \"kid\": \"AAECAw\","
92 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
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
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
112 const uint8 kOriginalData2[] = "Changed Original data.";
114 const uint8 kIv2[] = {
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
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
126 const char kKey2AsJWK[] =
131 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
132 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
137 // 'k' in bytes is x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx20x21x22x23
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
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
149 const SubsampleEntry kSubsampleEntriesNormal[] = {
155 const SubsampleEntry kSubsampleEntriesWrongSize[] = {
156 { 3, 6 }, // This entry doesn't match the correct entry.
161 const SubsampleEntry kSubsampleEntriesInvalidTotalSize[] = {
162 { 1, 1000 }, // This entry is too large.
167 const SubsampleEntry kSubsampleEntriesClearOnly[] = {
173 const SubsampleEntry kSubsampleEntriesCypherOnly[] = {
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]),
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;
198 enum PromiseResult { RESOLVED, REJECTED };
200 class AesDecryptorTest : public testing::Test {
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)) {
223 void OnResolveWithSession(PromiseResult expected_result,
224 const std::string& web_session_id) {
225 EXPECT_EQ(expected_result, RESOLVED) << "Unexpectedly resolved.";
226 EXPECT_GT(web_session_id.length(), 0ul);
227 web_session_id_ = web_session_id;
230 void OnResolve(PromiseResult expected_result) {
231 EXPECT_EQ(expected_result, RESOLVED) << "Unexpectedly resolved.";
234 void OnResolveWithUsableKeyIds(PromiseResult expected_result,
235 uint32 expected_count,
236 const KeyIdsVector& useable_key_ids) {
237 EXPECT_EQ(expected_result, RESOLVED) << "Unexpectedly resolved.";
238 EXPECT_EQ(expected_count, useable_key_ids.size());
239 useable_key_ids_ = useable_key_ids;
242 void OnReject(PromiseResult expected_result,
243 MediaKeys::Exception exception_code,
245 const std::string& error_message) {
246 EXPECT_EQ(expected_result, REJECTED) << "Unexpectedly rejected.";
249 scoped_ptr<SimpleCdmPromise> CreatePromise(PromiseResult expected_result) {
250 scoped_ptr<SimpleCdmPromise> promise(
251 new SimpleCdmPromise(base::Bind(&AesDecryptorTest::OnResolve,
252 base::Unretained(this),
254 base::Bind(&AesDecryptorTest::OnReject,
255 base::Unretained(this),
257 return promise.Pass();
260 scoped_ptr<NewSessionCdmPromise> CreateSessionPromise(
261 PromiseResult expected_result) {
262 scoped_ptr<NewSessionCdmPromise> promise(new NewSessionCdmPromise(
263 base::Bind(&AesDecryptorTest::OnResolveWithSession,
264 base::Unretained(this),
266 base::Bind(&AesDecryptorTest::OnReject,
267 base::Unretained(this),
269 return promise.Pass();
272 scoped_ptr<KeyIdsPromise> CreateUsableKeyIdsPromise(
273 PromiseResult expected_result,
274 uint32 expected_count) {
275 scoped_ptr<KeyIdsPromise> promise(new KeyIdsPromise(
276 base::Bind(&AesDecryptorTest::OnResolveWithUsableKeyIds,
277 base::Unretained(this),
280 base::Bind(&AesDecryptorTest::OnReject,
281 base::Unretained(this),
283 return promise.Pass();
286 // Creates a new session using |key_id|. Returns the session ID.
287 std::string CreateSession(const std::vector<uint8>& key_id) {
288 DCHECK(!key_id.empty());
290 OnSessionMessage(IsNotEmpty(), key_id, GURL::EmptyGURL()));
291 decryptor_.CreateSession(std::string(),
294 MediaKeys::TEMPORARY_SESSION,
295 CreateSessionPromise(RESOLVED));
296 // This expects the promise to be called synchronously, which is the case
298 return web_session_id_;
301 // Releases the session specified by |session_id|.
302 void ReleaseSession(const std::string& session_id) {
303 EXPECT_CALL(*this, OnSessionClosed(session_id));
304 decryptor_.ReleaseSession(session_id, CreatePromise(RESOLVED));
307 // Updates the session specified by |session_id| with |key|. |result|
308 // tests that the update succeeds or generates an error.
309 void UpdateSessionAndExpect(std::string session_id,
310 const std::string& key,
311 PromiseResult result) {
312 DCHECK(!key.empty());
314 decryptor_.UpdateSession(session_id,
315 reinterpret_cast<const uint8*>(key.c_str()),
317 CreatePromise(result));
320 void GetUsableKeyIdsAndExpect(const std::string& session_id,
321 PromiseResult expected_result,
322 uint32 expected_count) {
323 decryptor_.GetUsableKeyIds(
324 session_id, CreateUsableKeyIdsPromise(expected_result, expected_count));
327 bool UsableKeyIdsContains(std::vector<uint8> expected) {
328 for (KeyIdsVector::iterator it = useable_key_ids_.begin();
329 it != useable_key_ids_.end();
337 MOCK_METHOD2(BufferDecrypted, void(Decryptor::Status,
338 const scoped_refptr<DecoderBuffer>&));
340 enum DecryptExpectation {
343 DATA_AND_SIZE_MISMATCH,
348 void DecryptAndExpect(const scoped_refptr<DecoderBuffer>& encrypted,
349 const std::vector<uint8>& plain_text,
350 DecryptExpectation result) {
351 scoped_refptr<DecoderBuffer> decrypted;
356 case DATA_AND_SIZE_MISMATCH:
357 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, NotNull()))
358 .WillOnce(SaveArg<1>(&decrypted));
361 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kError, IsNull()))
362 .WillOnce(SaveArg<1>(&decrypted));
365 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kNoKey, IsNull()))
366 .WillOnce(SaveArg<1>(&decrypted));
370 decryptor_.Decrypt(Decryptor::kVideo, encrypted, decrypt_cb_);
372 std::vector<uint8> decrypted_text;
373 if (decrypted && decrypted->data_size()) {
374 decrypted_text.assign(
375 decrypted->data(), decrypted->data() + decrypted->data_size());
380 EXPECT_EQ(plain_text, decrypted_text);
383 EXPECT_EQ(plain_text.size(), decrypted_text.size());
384 EXPECT_NE(plain_text, decrypted_text);
386 case DATA_AND_SIZE_MISMATCH:
387 EXPECT_NE(plain_text.size(), decrypted_text.size());
391 EXPECT_TRUE(decrypted_text.empty());
396 MOCK_METHOD3(OnSessionMessage,
397 void(const std::string& web_session_id,
398 const std::vector<uint8>& message,
399 const GURL& destination_url));
400 MOCK_METHOD1(OnSessionClosed, void(const std::string& web_session_id));
402 AesDecryptor decryptor_;
403 AesDecryptor::DecryptCB decrypt_cb_;
404 std::string web_session_id_;
406 // Copy of the vector from the last successful call to
407 // OnResolveWithUsableKeyIds().
408 KeyIdsVector useable_key_ids_;
410 // Constants for testing.
411 const std::vector<uint8> original_data_;
412 const std::vector<uint8> encrypted_data_;
413 const std::vector<uint8> subsample_encrypted_data_;
414 const std::vector<uint8> key_id_;
415 const std::vector<uint8> iv_;
416 const std::vector<SubsampleEntry> normal_subsample_entries_;
417 const std::vector<SubsampleEntry> no_subsample_entries_;
420 TEST_F(AesDecryptorTest, CreateSessionWithNullInitData) {
422 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
423 decryptor_.CreateSession(std::string(),
426 MediaKeys::TEMPORARY_SESSION,
427 CreateSessionPromise(RESOLVED));
430 TEST_F(AesDecryptorTest, MultipleCreateSession) {
432 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
433 decryptor_.CreateSession(std::string(),
436 MediaKeys::TEMPORARY_SESSION,
437 CreateSessionPromise(RESOLVED));
440 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
441 decryptor_.CreateSession(std::string(),
444 MediaKeys::TEMPORARY_SESSION,
445 CreateSessionPromise(RESOLVED));
448 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
449 decryptor_.CreateSession(std::string(),
452 MediaKeys::TEMPORARY_SESSION,
453 CreateSessionPromise(RESOLVED));
456 TEST_F(AesDecryptorTest, NormalDecryption) {
457 std::string session_id = CreateSession(key_id_);
458 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
459 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
460 encrypted_data_, key_id_, iv_, no_subsample_entries_);
461 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
464 TEST_F(AesDecryptorTest, UnencryptedFrame) {
465 // An empty iv string signals that the frame is unencrypted.
466 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
467 original_data_, key_id_, std::vector<uint8>(), no_subsample_entries_);
468 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
471 TEST_F(AesDecryptorTest, WrongKey) {
472 std::string session_id = CreateSession(key_id_);
473 UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, RESOLVED);
474 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
475 encrypted_data_, key_id_, iv_, no_subsample_entries_);
476 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
479 TEST_F(AesDecryptorTest, NoKey) {
480 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
481 encrypted_data_, key_id_, iv_, no_subsample_entries_);
482 EXPECT_CALL(*this, BufferDecrypted(AesDecryptor::kNoKey, IsNull()));
483 decryptor_.Decrypt(Decryptor::kVideo, encrypted_buffer, decrypt_cb_);
486 TEST_F(AesDecryptorTest, KeyReplacement) {
487 std::string session_id = CreateSession(key_id_);
488 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
489 encrypted_data_, key_id_, iv_, no_subsample_entries_);
491 UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, RESOLVED);
492 ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
493 encrypted_buffer, original_data_, DATA_MISMATCH));
495 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
496 ASSERT_NO_FATAL_FAILURE(
497 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
500 TEST_F(AesDecryptorTest, WrongSizedKey) {
501 std::string session_id = CreateSession(key_id_);
502 UpdateSessionAndExpect(session_id, kWrongSizedKeyAsJWK, REJECTED);
505 TEST_F(AesDecryptorTest, MultipleKeysAndFrames) {
506 std::string session_id = CreateSession(key_id_);
507 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
508 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
509 encrypted_data_, key_id_, iv_, no_subsample_entries_);
510 ASSERT_NO_FATAL_FAILURE(
511 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
513 UpdateSessionAndExpect(session_id, kKey2AsJWK, RESOLVED);
515 // The first key is still available after we added a second key.
516 ASSERT_NO_FATAL_FAILURE(
517 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
519 // The second key is also available.
520 encrypted_buffer = CreateEncryptedBuffer(
521 std::vector<uint8>(kEncryptedData2,
522 kEncryptedData2 + arraysize(kEncryptedData2)),
523 std::vector<uint8>(kKeyId2, kKeyId2 + arraysize(kKeyId2)),
524 std::vector<uint8>(kIv2, kIv2 + arraysize(kIv2)),
525 no_subsample_entries_);
526 ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
528 std::vector<uint8>(kOriginalData2,
529 kOriginalData2 + arraysize(kOriginalData2) - 1),
533 TEST_F(AesDecryptorTest, CorruptedIv) {
534 std::string session_id = CreateSession(key_id_);
535 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
537 std::vector<uint8> bad_iv = iv_;
540 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
541 encrypted_data_, key_id_, bad_iv, no_subsample_entries_);
543 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
546 TEST_F(AesDecryptorTest, CorruptedData) {
547 std::string session_id = CreateSession(key_id_);
548 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
550 std::vector<uint8> bad_data = encrypted_data_;
553 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
554 bad_data, key_id_, iv_, no_subsample_entries_);
555 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
558 TEST_F(AesDecryptorTest, EncryptedAsUnencryptedFailure) {
559 std::string session_id = CreateSession(key_id_);
560 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
561 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
562 encrypted_data_, key_id_, std::vector<uint8>(), no_subsample_entries_);
563 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
566 TEST_F(AesDecryptorTest, SubsampleDecryption) {
567 std::string session_id = CreateSession(key_id_);
568 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
569 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
570 subsample_encrypted_data_, key_id_, iv_, normal_subsample_entries_);
571 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
574 // Ensures noninterference of data offset and subsample mechanisms. We never
575 // expect to encounter this in the wild, but since the DecryptConfig doesn't
576 // disallow such a configuration, it should be covered.
577 TEST_F(AesDecryptorTest, SubsampleDecryptionWithOffset) {
578 std::string session_id = CreateSession(key_id_);
579 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
580 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
581 subsample_encrypted_data_, key_id_, iv_, normal_subsample_entries_);
582 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
585 TEST_F(AesDecryptorTest, SubsampleWrongSize) {
586 std::string session_id = CreateSession(key_id_);
587 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
589 std::vector<SubsampleEntry> subsample_entries_wrong_size(
590 kSubsampleEntriesWrongSize,
591 kSubsampleEntriesWrongSize + arraysize(kSubsampleEntriesWrongSize));
593 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
594 subsample_encrypted_data_, key_id_, iv_, subsample_entries_wrong_size);
595 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
598 TEST_F(AesDecryptorTest, SubsampleInvalidTotalSize) {
599 std::string session_id = CreateSession(key_id_);
600 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
602 std::vector<SubsampleEntry> subsample_entries_invalid_total_size(
603 kSubsampleEntriesInvalidTotalSize,
604 kSubsampleEntriesInvalidTotalSize +
605 arraysize(kSubsampleEntriesInvalidTotalSize));
607 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
608 subsample_encrypted_data_, key_id_, iv_,
609 subsample_entries_invalid_total_size);
610 DecryptAndExpect(encrypted_buffer, original_data_, DECRYPT_ERROR);
613 // No cypher bytes in any of the subsamples.
614 TEST_F(AesDecryptorTest, SubsampleClearBytesOnly) {
615 std::string session_id = CreateSession(key_id_);
616 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
618 std::vector<SubsampleEntry> clear_only_subsample_entries(
619 kSubsampleEntriesClearOnly,
620 kSubsampleEntriesClearOnly + arraysize(kSubsampleEntriesClearOnly));
622 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
623 original_data_, key_id_, iv_, clear_only_subsample_entries);
624 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
627 // No clear bytes in any of the subsamples.
628 TEST_F(AesDecryptorTest, SubsampleCypherBytesOnly) {
629 std::string session_id = CreateSession(key_id_);
630 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
632 std::vector<SubsampleEntry> cypher_only_subsample_entries(
633 kSubsampleEntriesCypherOnly,
634 kSubsampleEntriesCypherOnly + arraysize(kSubsampleEntriesCypherOnly));
636 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
637 encrypted_data_, key_id_, iv_, cypher_only_subsample_entries);
638 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
641 TEST_F(AesDecryptorTest, ReleaseSession) {
642 std::string session_id = CreateSession(key_id_);
643 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
644 encrypted_data_, key_id_, iv_, no_subsample_entries_);
646 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
647 ASSERT_NO_FATAL_FAILURE(
648 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
650 ReleaseSession(session_id);
653 TEST_F(AesDecryptorTest, NoKeyAfterReleaseSession) {
654 std::string session_id = CreateSession(key_id_);
655 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
656 encrypted_data_, key_id_, iv_, no_subsample_entries_);
658 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
659 ASSERT_NO_FATAL_FAILURE(
660 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
662 ReleaseSession(session_id);
663 ASSERT_NO_FATAL_FAILURE(
664 DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY));
667 TEST_F(AesDecryptorTest, LatestKeyUsed) {
668 std::string session_id1 = CreateSession(key_id_);
669 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
670 encrypted_data_, key_id_, iv_, no_subsample_entries_);
672 // Add alternate key, buffer should not be decoded properly.
673 UpdateSessionAndExpect(session_id1, kKeyAlternateAsJWK, RESOLVED);
674 ASSERT_NO_FATAL_FAILURE(
675 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
677 // Create a second session with a correct key value for key_id_.
678 std::string session_id2 = CreateSession(key_id_);
679 UpdateSessionAndExpect(session_id2, kKeyAsJWK, RESOLVED);
681 // Should be able to decode with latest key.
682 ASSERT_NO_FATAL_FAILURE(
683 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
686 TEST_F(AesDecryptorTest, LatestKeyUsedAfterReleaseSession) {
687 std::string session_id1 = CreateSession(key_id_);
688 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
689 encrypted_data_, key_id_, iv_, no_subsample_entries_);
690 UpdateSessionAndExpect(session_id1, kKeyAsJWK, RESOLVED);
691 ASSERT_NO_FATAL_FAILURE(
692 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
694 // Create a second session with a different key value for key_id_.
695 std::string session_id2 = CreateSession(key_id_);
696 UpdateSessionAndExpect(session_id2, kKeyAlternateAsJWK, RESOLVED);
698 // Should not be able to decode with new key.
699 ASSERT_NO_FATAL_FAILURE(
700 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
702 // Close second session, should revert to original key.
703 ReleaseSession(session_id2);
704 ASSERT_NO_FATAL_FAILURE(
705 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
708 TEST_F(AesDecryptorTest, JWKKey) {
709 std::string session_id = CreateSession(key_id_);
711 // Try a simple JWK key (i.e. not in a set)
712 const std::string kJwkSimple =
715 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
716 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
718 UpdateSessionAndExpect(session_id, kJwkSimple, REJECTED);
720 // Try a key list with multiple entries.
721 const std::string kJwksMultipleEntries =
726 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
727 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
731 " \"kid\": \"JCUmJygpKissLS4vMA\","
732 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
736 UpdateSessionAndExpect(session_id, kJwksMultipleEntries, RESOLVED);
738 // Try a key with no spaces and some \n plus additional fields.
739 const std::string kJwksNoSpaces =
740 "\n\n{\"something\":1,\"keys\":[{\n\n\"kty\":\"oct\",\"alg\":\"A128KW\","
741 "\"kid\":\"AAECAwQFBgcICQoLDA0ODxAREhM\",\"k\":\"GawgguFyGrWKav7AX4VKUg"
742 "\",\"foo\":\"bar\"}]}\n\n";
743 UpdateSessionAndExpect(session_id, kJwksNoSpaces, RESOLVED);
745 // Try some non-ASCII characters.
746 UpdateSessionAndExpect(
747 session_id, "This is not ASCII due to \xff\xfe\xfd in it.", REJECTED);
749 // Try a badly formatted key. Assume that the JSON parser is fully tested,
750 // so we won't try a lot of combinations. However, need a test to ensure
751 // that the code doesn't crash if invalid JSON received.
752 UpdateSessionAndExpect(session_id, "This is not a JSON key.", REJECTED);
754 // Try passing some valid JSON that is not a dictionary at the top level.
755 UpdateSessionAndExpect(session_id, "40", REJECTED);
757 // Try an empty dictionary.
758 UpdateSessionAndExpect(session_id, "{ }", REJECTED);
760 // Try an empty 'keys' dictionary.
761 UpdateSessionAndExpect(session_id, "{ \"keys\": [] }", REJECTED);
763 // Try with 'keys' not a dictionary.
764 UpdateSessionAndExpect(session_id, "{ \"keys\":\"1\" }", REJECTED);
766 // Try with 'keys' a list of integers.
767 UpdateSessionAndExpect(session_id, "{ \"keys\": [ 1, 2, 3 ] }", REJECTED);
769 // Try padding(=) at end of 'k' base64 string.
770 const std::string kJwksWithPaddedKey =
775 " \"kid\": \"AAECAw\","
776 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
780 UpdateSessionAndExpect(session_id, kJwksWithPaddedKey, REJECTED);
782 // Try padding(=) at end of 'kid' base64 string.
783 const std::string kJwksWithPaddedKeyId =
788 " \"kid\": \"AAECAw==\","
789 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
793 UpdateSessionAndExpect(session_id, kJwksWithPaddedKeyId, REJECTED);
795 // Try a key with invalid base64 encoding.
796 const std::string kJwksWithInvalidBase64 =
801 " \"kid\": \"!@#$%^&*()\","
802 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
806 UpdateSessionAndExpect(session_id, kJwksWithInvalidBase64, REJECTED);
808 // Try a 3-byte 'kid' where no base64 padding is required.
809 // |kJwksMultipleEntries| above has 2 'kid's that require 1 and 2 padding
810 // bytes. Note that 'k' has to be 16 bytes, so it will always require padding.
811 const std::string kJwksWithNoPadding =
816 " \"kid\": \"Kiss\","
817 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
821 UpdateSessionAndExpect(session_id, kJwksWithNoPadding, RESOLVED);
824 const std::string kJwksWithEmptyKeyId =
830 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
834 UpdateSessionAndExpect(session_id, kJwksWithEmptyKeyId, REJECTED);
835 ReleaseSession(session_id);
838 TEST_F(AesDecryptorTest, GetKeyIds) {
839 std::vector<uint8> key_id1(kKeyId, kKeyId + arraysize(kKeyId));
840 std::vector<uint8> key_id2(kKeyId2, kKeyId2 + arraysize(kKeyId2));
842 std::string session_id = CreateSession(key_id_);
843 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 0);
844 EXPECT_FALSE(UsableKeyIdsContains(key_id1));
845 EXPECT_FALSE(UsableKeyIdsContains(key_id2));
847 // Add 1 key, verify ID is returned.
848 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
849 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 1);
850 EXPECT_TRUE(UsableKeyIdsContains(key_id1));
851 EXPECT_FALSE(UsableKeyIdsContains(key_id2));
853 // Add second key, verify both IDs returned.
854 UpdateSessionAndExpect(session_id, kKey2AsJWK, RESOLVED);
855 GetUsableKeyIdsAndExpect(session_id, RESOLVED, 2);
856 EXPECT_TRUE(UsableKeyIdsContains(key_id1));
857 EXPECT_TRUE(UsableKeyIdsContains(key_id2));