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,
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;
230 void OnResolve(PromiseResult expected) {
231 EXPECT_EQ(expected, RESOLVED);
234 void OnReject(PromiseResult expected,
235 MediaKeys::Exception exception_code,
237 const std::string& error_message) {
238 EXPECT_EQ(expected, REJECTED);
241 scoped_ptr<SimpleCdmPromise> CreatePromise(PromiseResult expected) {
242 scoped_ptr<SimpleCdmPromise> promise(new SimpleCdmPromise(
244 &AesDecryptorTest::OnResolve, base::Unretained(this), expected),
246 &AesDecryptorTest::OnReject, base::Unretained(this), expected)));
247 return promise.Pass();
250 scoped_ptr<NewSessionCdmPromise> CreateSessionPromise(
251 PromiseResult expected) {
252 scoped_ptr<NewSessionCdmPromise> promise(new NewSessionCdmPromise(
253 base::Bind(&AesDecryptorTest::OnResolveWithSession,
254 base::Unretained(this),
257 &AesDecryptorTest::OnReject, base::Unretained(this), expected)));
258 return promise.Pass();
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());
265 OnSessionMessage(IsNotEmpty(), key_id, GURL::EmptyGURL()));
266 decryptor_.CreateSession(std::string(),
269 MediaKeys::TEMPORARY_SESSION,
270 CreateSessionPromise(RESOLVED));
271 // This expects the promise to be called synchronously, which is the case
273 return web_session_id_;
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));
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());
289 decryptor_.UpdateSession(session_id,
290 reinterpret_cast<const uint8*>(key.c_str()),
292 CreatePromise(result));
295 MOCK_METHOD2(BufferDecrypted, void(Decryptor::Status,
296 const scoped_refptr<DecoderBuffer>&));
298 enum DecryptExpectation {
301 DATA_AND_SIZE_MISMATCH,
306 void DecryptAndExpect(const scoped_refptr<DecoderBuffer>& encrypted,
307 const std::vector<uint8>& plain_text,
308 DecryptExpectation result) {
309 scoped_refptr<DecoderBuffer> decrypted;
314 case DATA_AND_SIZE_MISMATCH:
315 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kSuccess, NotNull()))
316 .WillOnce(SaveArg<1>(&decrypted));
319 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kError, IsNull()))
320 .WillOnce(SaveArg<1>(&decrypted));
323 EXPECT_CALL(*this, BufferDecrypted(Decryptor::kNoKey, IsNull()))
324 .WillOnce(SaveArg<1>(&decrypted));
328 decryptor_.Decrypt(Decryptor::kVideo, encrypted, decrypt_cb_);
330 std::vector<uint8> decrypted_text;
331 if (decrypted && decrypted->data_size()) {
332 decrypted_text.assign(
333 decrypted->data(), decrypted->data() + decrypted->data_size());
338 EXPECT_EQ(plain_text, decrypted_text);
341 EXPECT_EQ(plain_text.size(), decrypted_text.size());
342 EXPECT_NE(plain_text, decrypted_text);
344 case DATA_AND_SIZE_MISMATCH:
345 EXPECT_NE(plain_text.size(), decrypted_text.size());
349 EXPECT_TRUE(decrypted_text.empty());
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));
360 AesDecryptor decryptor_;
361 AesDecryptor::DecryptCB decrypt_cb_;
362 std::string web_session_id_;
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_;
374 TEST_F(AesDecryptorTest, CreateSessionWithNullInitData) {
376 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
377 decryptor_.CreateSession(std::string(),
380 MediaKeys::TEMPORARY_SESSION,
381 CreateSessionPromise(RESOLVED));
384 TEST_F(AesDecryptorTest, MultipleCreateSession) {
386 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
387 decryptor_.CreateSession(std::string(),
390 MediaKeys::TEMPORARY_SESSION,
391 CreateSessionPromise(RESOLVED));
394 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
395 decryptor_.CreateSession(std::string(),
398 MediaKeys::TEMPORARY_SESSION,
399 CreateSessionPromise(RESOLVED));
402 OnSessionMessage(IsNotEmpty(), IsEmpty(), GURL::EmptyGURL()));
403 decryptor_.CreateSession(std::string(),
406 MediaKeys::TEMPORARY_SESSION,
407 CreateSessionPromise(RESOLVED));
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);
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);
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);
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_);
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_);
445 UpdateSessionAndExpect(session_id, kWrongKeyAsJWK, RESOLVED);
446 ASSERT_NO_FATAL_FAILURE(DecryptAndExpect(
447 encrypted_buffer, original_data_, DATA_MISMATCH));
449 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
450 ASSERT_NO_FATAL_FAILURE(
451 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
454 TEST_F(AesDecryptorTest, WrongSizedKey) {
455 std::string session_id = CreateSession(key_id_);
456 UpdateSessionAndExpect(session_id, kWrongSizedKeyAsJWK, REJECTED);
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));
467 UpdateSessionAndExpect(session_id, kKey2AsJWK, RESOLVED);
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));
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(
482 std::vector<uint8>(kOriginalData2,
483 kOriginalData2 + arraysize(kOriginalData2) - 1),
487 TEST_F(AesDecryptorTest, CorruptedIv) {
488 std::string session_id = CreateSession(key_id_);
489 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
491 std::vector<uint8> bad_iv = iv_;
494 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
495 encrypted_data_, key_id_, bad_iv, no_subsample_entries_);
497 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
500 TEST_F(AesDecryptorTest, CorruptedData) {
501 std::string session_id = CreateSession(key_id_);
502 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
504 std::vector<uint8> bad_data = encrypted_data_;
507 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
508 bad_data, key_id_, iv_, no_subsample_entries_);
509 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH);
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);
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);
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);
539 TEST_F(AesDecryptorTest, SubsampleWrongSize) {
540 std::string session_id = CreateSession(key_id_);
541 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
543 std::vector<SubsampleEntry> subsample_entries_wrong_size(
544 kSubsampleEntriesWrongSize,
545 kSubsampleEntriesWrongSize + arraysize(kSubsampleEntriesWrongSize));
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);
552 TEST_F(AesDecryptorTest, SubsampleInvalidTotalSize) {
553 std::string session_id = CreateSession(key_id_);
554 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
556 std::vector<SubsampleEntry> subsample_entries_invalid_total_size(
557 kSubsampleEntriesInvalidTotalSize,
558 kSubsampleEntriesInvalidTotalSize +
559 arraysize(kSubsampleEntriesInvalidTotalSize));
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);
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);
572 std::vector<SubsampleEntry> clear_only_subsample_entries(
573 kSubsampleEntriesClearOnly,
574 kSubsampleEntriesClearOnly + arraysize(kSubsampleEntriesClearOnly));
576 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
577 original_data_, key_id_, iv_, clear_only_subsample_entries);
578 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
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);
586 std::vector<SubsampleEntry> cypher_only_subsample_entries(
587 kSubsampleEntriesCypherOnly,
588 kSubsampleEntriesCypherOnly + arraysize(kSubsampleEntriesCypherOnly));
590 scoped_refptr<DecoderBuffer> encrypted_buffer = CreateEncryptedBuffer(
591 encrypted_data_, key_id_, iv_, cypher_only_subsample_entries);
592 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS);
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_);
600 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
601 ASSERT_NO_FATAL_FAILURE(
602 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
604 ReleaseSession(session_id);
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_);
612 UpdateSessionAndExpect(session_id, kKeyAsJWK, RESOLVED);
613 ASSERT_NO_FATAL_FAILURE(
614 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
616 ReleaseSession(session_id);
617 ASSERT_NO_FATAL_FAILURE(
618 DecryptAndExpect(encrypted_buffer, original_data_, NO_KEY));
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_);
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));
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);
635 // Should be able to decode with latest key.
636 ASSERT_NO_FATAL_FAILURE(
637 DecryptAndExpect(encrypted_buffer, original_data_, SUCCESS));
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));
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);
652 // Should not be able to decode with new key.
653 ASSERT_NO_FATAL_FAILURE(
654 DecryptAndExpect(encrypted_buffer, original_data_, DATA_MISMATCH));
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));
662 TEST_F(AesDecryptorTest, JWKKey) {
663 std::string session_id = CreateSession(key_id_);
665 // Try a simple JWK key (i.e. not in a set)
666 const std::string kJwkSimple =
669 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
670 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
672 UpdateSessionAndExpect(session_id, kJwkSimple, REJECTED);
674 // Try a key list with multiple entries.
675 const std::string kJwksMultipleEntries =
680 " \"kid\": \"AAECAwQFBgcICQoLDA0ODxAREhM\","
681 " \"k\": \"FBUWFxgZGhscHR4fICEiIw\""
685 " \"kid\": \"JCUmJygpKissLS4vMA\","
686 " \"k\":\"MTIzNDU2Nzg5Ojs8PT4/QA\""
690 UpdateSessionAndExpect(session_id, kJwksMultipleEntries, RESOLVED);
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);
699 // Try some non-ASCII characters.
700 UpdateSessionAndExpect(
701 session_id, "This is not ASCII due to \xff\xfe\xfd in it.", REJECTED);
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);
708 // Try passing some valid JSON that is not a dictionary at the top level.
709 UpdateSessionAndExpect(session_id, "40", REJECTED);
711 // Try an empty dictionary.
712 UpdateSessionAndExpect(session_id, "{ }", REJECTED);
714 // Try an empty 'keys' dictionary.
715 UpdateSessionAndExpect(session_id, "{ \"keys\": [] }", REJECTED);
717 // Try with 'keys' not a dictionary.
718 UpdateSessionAndExpect(session_id, "{ \"keys\":\"1\" }", REJECTED);
720 // Try with 'keys' a list of integers.
721 UpdateSessionAndExpect(session_id, "{ \"keys\": [ 1, 2, 3 ] }", REJECTED);
723 // Try padding(=) at end of 'k' base64 string.
724 const std::string kJwksWithPaddedKey =
729 " \"kid\": \"AAECAw\","
730 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw==\""
734 UpdateSessionAndExpect(session_id, kJwksWithPaddedKey, REJECTED);
736 // Try padding(=) at end of 'kid' base64 string.
737 const std::string kJwksWithPaddedKeyId =
742 " \"kid\": \"AAECAw==\","
743 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
747 UpdateSessionAndExpect(session_id, kJwksWithPaddedKeyId, REJECTED);
749 // Try a key with invalid base64 encoding.
750 const std::string kJwksWithInvalidBase64 =
755 " \"kid\": \"!@#$%^&*()\","
756 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
760 UpdateSessionAndExpect(session_id, kJwksWithInvalidBase64, REJECTED);
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 =
770 " \"kid\": \"Kiss\","
771 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
775 UpdateSessionAndExpect(session_id, kJwksWithNoPadding, RESOLVED);
778 const std::string kJwksWithEmptyKeyId =
784 " \"k\": \"BAUGBwgJCgsMDQ4PEBESEw\""
788 UpdateSessionAndExpect(session_id, kJwksWithEmptyKeyId, REJECTED);
789 ReleaseSession(session_id);